1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Stripe Billingで複数のサブスクリプション契約を管理したい場合の実装方法

Posted at

StripeのBillingでは、さまざまな料金体系・契約期間のサブスクリプション契約を顧客に提供できます。

1つにまとめるか、個別にデータを作成するか

レンタルサーバーや定期購入サービスなどでは、顧客が複数のサブスクリプション契約を結ぶユースケースを考慮する必要があります。

Stripeを利用する場合、2つの方法で複数のサブスクリプションを管理することができます。

  • 1: 1つのSubscriptionデータに、「数量」として追加・削除する
  • 2: 契約の度にSubscriptionデータを作成する

管理方法1: 1つのSubscriptionデータに、「数量」として追加・削除する

Stripe APIの組み込みがシンプルなのは、契約を「数量」として扱う方法です。

この場合、顧客に対してSubscriptionは1つだけ作成します。

  await stripe.subscriptions.create({
    customer: 'cus_xxx',
    items: [{
      price: 'price_xxx',
      quantity: 1
    }]
  })

そして「レンタルサーバーサービスでの、新しいサーバーの追加注文」のように、契約を追加するケースでは、作成済みのSubscriptionを変更して対応します。

  await stripe.subscriptions.update('sub_xxx', {
    items: [{
      price: 'price_xxx',
      quantity: 2
    }]
  })

「メールオプション」など、サーバープランに付随するプランを追加したい場合は、別の料金を追加します。

  await stripe.subscriptions.update('sub_xxx', {
    items: [{
      price: 'price_yyyy',
      quantity: 1
    }]
  })

プランのキャンセル処理

プランをキャンセルする場合は、「数を減らす」または「アイテムを削除する」で対応します。

もしキャンセル後に残る契約数が0以上の場合は、updateで数量を変更します。

  await stripe.subscriptions.update('sub_xxx', {
    items: [{
      price: 'price_xxx',
      quantity: 1
    }]
  })

0になる場合は、数量の代わりにdeleted: trueを設定しましょう。

  await stripe.subscriptions.update('sub_xxx', {
    items: [{
      price: 'price_xxx',
      deleted: true
    }]
  })

もしquantity: 0をセットすると、以下のようなAPIエラーが発生します。

{
  "error": {
    "message": "Cannot add multiple subscription items with the same plan: price_xxxxxxx,
    "param": "plan",
    "request_log_url": "https://dashboard.stripe.com/test/logs/req_xxxxxxx?t=1668423793",
    "type": "invalid_request_error"
  }
}

1Subscriptionにまとめるメリットとデメリット

1つのSubscriptionにまとめることで、「その顧客がどんなサブスクリプション・プランを契約しているか」や「過去の請求履歴」などを1Subscriptionデータから確認できます。

また、月末・月初のように請求サイクルをシステムで統一している場合、請求日に複数の請求書が顧客へ送信されることを防ぐこともできます。

一方で、「1契約ごと」に追加の情報やrelationを持たせたい場合や、決済方法・配送先住所などを変更したい場合には注意が必要です。

「1契約ごとに別のクレジットカードを設定したいケース」では、Subscriptionの分割作業が必要になります。

また、自社のDB内の情報と契約を紐付けしたい場合、「Subscriptionのどのpriceと対応するか」の関係性をシステム側で持たせる必要があることにもご注意ください。

管理方法2: 契約の度にSubscriptionデータを作成する

もう1つの方法は、契約の度にSubscriptionデータを作成する方法です。

この場合は、メインの契約ごとにSubscriptionを作成します。

  await stripe.subscriptions.create({
    customer: 'cus_xxx',
    items: [{
      price: 'price_xxx',
      quantity: 1
    }]
  })

  await stripe.subscriptions.create({
    customer: 'cus_xxx',
    items: [{
      price: 'price_xxx',
      quantity: 1
    }, {
      price: 'price_yyy',
      quantity: 1
    }]
  })

1つのCustomerデータに対して、複数のSubscriptionが作成されます。

自社DBのリソースとの紐付けも、SubscriptionのIDをリソースに保存すれば、あとはStripe APIを呼び出すだけでデータの取得が可能です。

都度Subscriptionを作成するメリットとデメリット

Subscriptionデータが複数作成されるため、StripeダッシュボードやCustomer Portalで「どれがどのSubscriptionか?」を判別できる仕組みが必要です。

そのため、Subscriptionを作成する際にdescriptionを設定することをお勧めします。

  await stripe.subscriptions.create({
    customer: 'cus_xxx',
    items: [{
      price: 'price_xxx',
      quantity: 1
    }],
+    description: '定期Aコース',
  })

また、metadataに情報を登録することで、Search APIを利用した検索を実装することも可能です。

関連ドキュメント

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?