メインコンテンツへスキップ

サブスクリプション

サブスクリプションは定期的な収益の基盤であり、顧客に製品やサービスを繰り返しスケジュールで請求することができます。PaymentKitでは、顧客が定期的な価格の製品を購入するとサブスクリプションが作成されます。

このガイドでは、チェックアウトセッションによる作成から、そのステータスの管理、使用量ベースの課金の処理まで、サブスクリプションのライフサイクル全体を説明します。先に進む前に、製品価格を作成していることを確認してください。

サブスクリプションのライフサイクル

サブスクリプションは、支払いイベント、トライアル期間、管理アクションに応じてさまざまなステータスを遷移します。このライフサイクルを理解することは、顧客を効果的に管理するための鍵です。

Subscription Lifecycle Flow

d2
direction: down

style: {
  stroke-width: 2
  font-size: 14
}

Checkout: {
  label: "チェックアウトセッション"
  shape: circle
  style: {
    fill: "#e6f7ff"
    stroke: "#91d5ff"
  }
}

Incomplete: {
  label: "未完了"
  style: {
    fill: "#fffbe6"
    stroke: "#ffe58f"
  }
}

Trialing: {
  label: "トライアル中"
  style: {


<!-- DIAGRAM_IMAGE_START:flowchart:16:9::1765369146 -->
![Subscriptions](assets/diagram/core-concepts-subscriptions-01.ja.jpg)
<!-- DIAGRAM_IMAGE_END -->

<!-- DIAGRAM_IMAGE_START:flowchart:16:9::1765369146 -->
![Subscriptions](assets/diagram/core-concepts-subscriptions-01.ja.jpg)
<!-- DIAGRAM_IMAGE_END -->

fill: "#f6ffed"
    stroke: "#b7eb8f"
  }
}

Active: {
  label: "アクティブ"
  style: {
    fill: "#d4edda"
    stroke: "#28a745"
  }
}

Past-Due: {
  label: "支払い遅延"
  style: {
    fill: "#fff1f0"
    stroke: "#ffccc7"
  }
}

Canceled: {
  label: "キャンセル済み"
  style: {
    fill: "#fafafa"
    stroke: "#d9d9d9"
  }
}

Paused: {
  label: "一時停止中"
  style: {
    fill: "#e6f7ff"
    stroke: "#91d5ff"
  }
}

Checkout -> Incomplete: "支払いの失敗"
Checkout -> Trialing: "トライアルありで成功"
Checkout -> Active: "成功、トライアルなし"

Incomplete -> Active: "支払いの成功"

Trialing -> Active: "トライアル終了"

Active -> Past-Due: "更新の失敗"
Past-Due -> Active: "支払いの成功"
Past-Due -> Canceled: "再試行の失敗"

Active -> Canceled: "ユーザー/管理者によるキャンセル"
Trialing -> Canceled: "ユーザー/管理者によるキャンセル"

Active <-> Paused: "一時停止/再開"

サブスクリプションが持つことができる主なステータスは次のとおりです。

  • active: サブスクリプションは良好な状態で、支払いは最新です。
  • trialing: 顧客は無料トライアル期間中です。
  • past_due: 最新の支払い試行が失敗し、PaymentKitが請求を再試行しています。
  • canceled: サブスクリプションはキャンセルされ、更新されません。
  • incomplete: サブスクリプションの初回支払いが失敗しました。
  • incomplete_expired: 初回支払いが失敗し、再試行期間が終了しました。
  • paused: サブスクリプションは一時的に停止されており、請求書は生成されません。

サブスクリプションの作成

サブスクリプションは直接作成されません。代わりに、mode: 'subscription'チェックアウトセッションを作成します。このセッションは顧客を支払いプロセスに誘導し、正常に完了するとサブスクリプションが自動的に作成されます。

Create a Subscription via Checkout

javascript
import payment from '@blocklet/payment-js';

async function createSubscriptionCheckout() {
  try {
    const session = await payment.checkout.sessions.create({
      success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}',
      cancel_url: 'https://example.com/cancel',
      mode: 'subscription',
      line_items: [
        { price_id: 'price_xxx', quantity: 1 } // 定期的な価格IDに置き換えてください
      ],
      subscription_data: {
        trial_period_days: 14, // オプション:14日間の無料トライアル
        metadata: {
          project_id: 'proj_123',
        },
      },
    });
    console.log('チェックアウトセッションが作成されました:', session.url);
    // 顧客を session.url にリダイレクトします
  } catch (error) {
    console.error('チェックアウトセッションの作成中にエラーが発生しました:', error.message);
  }
}

createSubscriptionCheckout();

この例では、定期的な価格の製品に対してチェックアウトセッションが作成されます。顧客が支払いを完了すると、新しいサブスクリプションが14日間のtrialing状態で作成され、その後最初の請求が発生します。

既存のサブスクリプションの管理

サブスクリプションが作成されると、payment.subscriptionsリソースを使用して管理できます。

サブスクリプションの取得

IDを使用して特定のサブスクリプションの詳細を取得します。

Retrieve a Subscription

javascript
async function getSubscription(subscriptionId) {
  try {
    const subscription = await payment.subscriptions.retrieve(subscriptionId);
    console.log(`${subscription.id} のステータス: ${subscription.status}`);
    console.log('現在の期間の終了日:', new Date(subscription.current_period_end * 1000));
  } catch (error) {
    console.error('サブスクリプションの取得中にエラーが発生しました:', error.message);
  }
}

getSubscription('sub_xxx'); // 有効なサブスクリプションIDに置き換えてください

サブスクリプションのリスト

すべてのサブスクリプションをリスト表示したり、顧客IDやステータスなどのプロパティでフィルタリングしたりできます。

List Subscriptions

javascript
async function listActiveSubscriptionsForCustomer(customerId) {
  try {
    const subscriptions = await payment.subscriptions.list({
      customer_id: customerId,
      status: 'active',
      activeFirst: true,
      order: 'created_at:DESC',
    });

    console.log(`顧客 ${customerId} のアクティブなサブスクリプションが ${subscriptions.total} 件見つかりました:`);
    subscriptions.data.forEach(sub => {
      console.log(`- ID: ${sub.id}, ステータス: ${sub.status}`);
    });
  } catch (error) {
    console.error('サブスクリプションのリスト表示中にエラーが発生しました:', error.message);
  }
}

listActiveSubscriptionsForCustomer('cus_xxx'); // 有効な顧客IDに置き換えてください

サブスクリプションのキャンセル

サブスクリプションのキャンセルは一般的な要件です。即時キャンセルするか、現在の請求期間の終了時にキャンセルするかを選択できます。

Cancel a Subscription

javascript
async function cancelSubscription(subscriptionId) {
  try {
    const subscription = await payment.subscriptions.cancel(subscriptionId, {
      at: 'current_period_end', // サブスクリプションは請求サイクルが終了するまでアクティブなままです。
      // 即時キャンセルするには 'now' を使用します。
      reason: 'cancellation_requested',
      feedback: 'ユーザーはサービスを必要としなくなりました。',
    });
    console.log(`サブスクリプション ${subscription.id} はキャンセルが予定されました。`);
  } catch (error) {
    console.error('サブスクリプションのキャンセル中にエラーが発生しました:', error.message);
  }
}

cancelSubscription('sub_xxx'); // 有効なサブスクリプションIDに置き換えてください

サブスクリプションの一時停止と再開

サービスの一時的な保留のために、サブスクリプションを一時停止し、後で再開することができます。

Pause and Resume

javascript
async function manageSubscriptionPause(subscriptionId) {
  try {
    // サブスクリプションを一時停止する
    let subscription = await payment.subscriptions.pause(subscriptionId);
    console.log(`サブスクリプション ${subscription.id} は現在 ${subscription.status} です。`);

    // しばらくしてから再開する
    subscription = await payment.subscriptions.resume(subscriptionId);
    console.log(`サブスクリプション ${subscription.id} は現在 ${subscription.status} です。`);

  } catch (error) {
    console.error('サブスクリプションの一時停止状態の管理中にエラーが発生しました:', error.message);
  }
}

manageSubscriptionPause('sub_xxx'); // 有効なサブスクリプションIDに置き換えてください

従量制課金のための使用状況の報告

サブスクリプションがusage_type: 'metered'の価格を使用している場合、請求期間中に使用状況を報告する必要があります。これは、特定のサブスクリプションアイテムの使用状況レコードを作成することによって行われます。

Report Usage

javascript
async function reportApiUsage(subscriptionItemId) {
  try {
    const usageRecord = await payment.subscriptionItems.createUsageRecord({
      subscription_item_id: subscriptionItemId,
      quantity: 100, // 報告する使用量
      action: 'increment', // 'increment'は既存の使用量に追加し、'set'は上書きします。
      timestamp: Math.floor(Date.now() / 1000), // 使用が発生した時間
    });
    console.log('使用状況レコードが作成されました:', usageRecord.id);
  } catch (error) {
    console.error('使用状況の報告中にエラーが発生しました:', error.message);
  }
}

// subscription_item_idはサブスクリプションオブジェクトで見つけることができます。
reportApiUsage('si_xxx'); // 有効なサブスクリプションアイテムIDに置き換えてください

請求期間の終わりに、PaymentKitは報告されたすべての使用状況を合計し、それに応じて顧客に請求します。

次のステップ

これで、サブスクリプションの管理方法について確かな理解が得られました。さらに深く掘り下げるには、詳細なAPIドキュメントを探索し、サブスクリプション関連のイベントをリッスンする方法を学びましょう。