0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

サブスクリプション申し込み時に表示する初回請求の見積額を、StripeのRetrieveUpcoming Invoice APIで計算する

Posted at

Stripeでは、「定額料金 + 数量や利用量ベースの段階的料金」のような複雑な料金体系のサブスクリプションも簡単に作成することができます。

スクリーンショット 2023-12-13 14.27.27.png

このような料金体系を利用することで、「利用した分だけ支払う」サービスを顧客に提供することができます。また、大口契約に対する割引なども、個別対応を行うことなく実現できます。一方で複雑な料金体系を作成する場合、顧客が「この数量・プランだといくら支払うことになるのか?」を調べやすくする必要もあります。

RetrieveUpcoming Invoice APIで、契約前のサブスクリプションの請求額を見積もりする

Stripeでは、「次回の請求内容をプレビューする」ことができる「Retrieve upcoming Invoice API」を用意しています。

curl -G https://api.stripe.com/v1/invoices/upcoming \
  -u 'REPLACE_WITH_YOUR_SECRET_KEY':  \
  -d customer=cus_NeZwdNtLEOXuvB

このAPIにsubscription_itemsパラメータを渡すことで、まだ作成・契約が完了していないサブスクリプションに対する金額のプレビューが行えます。

curl -X GET "https://api.stripe.com/v1/invoices/upcoming" \
  -u 'REPLACE_WITH_YOUR_SECRET_KEY':  \
  -d "subscription_items[0][price]"="price_1NzvVRL8xlxrZ26gHdYI8j1Y" \
  -d "subscription_items[0][quantity]"=1

請求金額や請求明細などがAPIレスポンスとして取得できます。

{
  "object": "invoice",
  "account_country": "JP",
  "account_tax_ids": null,
  "amount_due": 9800,
  "amount_paid": 0,
  "amount_remaining": 9800,
  "amount_shipping": 0,
  "application": null,
  "application_fee_amount": null,
  "attempt_count": 0,
  "attempted": false,
  "automatic_tax": {
    "enabled": false,
    "status": null
  },
  "billing_reason": "subscription_create",
  "charge": null,
  "collection_method": "charge_automatically",
  "lines": {
    "object": "list",
    "data": [
      {
        "id": "il_tmp_1463b4L8xlxrZ26g09a794ec",
        "object": "line_item",
        "amount": 9800,
        "amount_excluding_tax": 9800,
        "currency": "jpy",
        "description": "1 × スタンダードプラン (at ¥9,800 / month)",
        "discount_amounts": [],
        "discountable": true,
        "discounts": [],
        "livemode": false,
        "metadata": {},
        "period": {
          "end": 1705124379,
          "start": 1702445979
        },
...

JavaScript / TypeScriptで請求内容のプレビューを作る

取得したAPIレスポンスを元に、「初回の請求が何円で、どんな請求項目があるか?」を計算するコードを書いてみましょう。

請求の明細については、lines.dataの中にある配列から取得できます。

        const stripe = new Stripe(c.env.STRIPE_SECRET_KEY, {
            apiVersion: '2023-10-16'
        });
        
        const estimateTheFirstInvoiceFromSubscription = await stripe.invoices.retrieveUpcoming({
            subscription_items: [{
                price: 'price_1NzvVRL8xlxrZ26gHdYI8j1Y',
                quantity: 1
            }],
        });
        estimateTheFirstInvoiceFromSubscription.lines.data.forEach((line, i) => {
            console.log(`#${i} - ${line.description}: ${line.amount.toLocaleString()}`);
        });
        console.log(`#Amount - ${estimateTheFirstInvoiceFromSubscription.subtotal.toLocaleString()}`);

このスクリプトを実行すると、次のように設定したsubscription_itemsの内容に応じた金額や明細が表示されます。

#0 - 1 × スタンダードプラン (at ¥9,800 / month): 9,800
#Amount - 9,800

複雑な料金体系で計算してみる

続いて冒頭に紹介した複雑な料金体系についても試してみましょう。今回は次の画像に紹介するような、「定額の手数料 + 数量に応じた追加料金(11ユーザー以降は値引き)」で設定しました。

スクリーンショット 2023-12-13 11.06.46.png

まずはquantity = 1で実行してみましょう。料金表の通り5,000円が出力されました。

#0 - 1 × スタンダードプラン (Tier 1 at ¥0 / month): 0
#1 - スタンダードプラン (Tier 1 at ¥5,000 / month): 5,000
#Amount - 5,000

複雑にするため、quantity = 90にしてみましょう。定額手数料や単価が値引きされていることや、設定した数量で計算がされていることがわかります。

#0 - 50 × スタンダードプラン (Tier 3 at ¥90 / month): 4,500
#1 - スタンダードプラン (Tier 3 at ¥4,980 / month): 4,980
#Amount - 9,480

請求サイクルを指定場合は、subscription_billing_cycle_anchorを利用する

「月初を請求日とする」など、請求サイクルを固定化したいケースについて考えてみましょう。こちらはサブスクリプションを作成する際に利用するbilling_cycle_anchorと同じように、UNIXタイムスタンプをsubscription_billing_cycle_anchorに設定します。

        const stripe = new Stripe(c.env.STRIPE_SECRET_KEY, {
            apiVersion: '2023-10-16'
        });
        const now: Date = new Date();
        const nextMonth: Date = new Date(now.getFullYear(), now.getMonth() + 1, 1);
        const unixTimestamp: number = Math.floor(nextMonth.getTime() / 1000);

        const estimateTheFirstInvoiceFromSubscription = await stripe.invoices.retrieveUpcoming({
            customer: 'cus_P5r7uozm9GP09E',
            subscription_items: [{
                price: 'price_1NzvVRL8xlxrZ26gHdYI8j1Y',
                quantity: 1
            }],
            subscription_billing_cycle_anchor: unixTimestamp
        });
        estimateTheFirstInvoiceFromSubscription.lines.data.forEach((line, i) => {
            console.log(`#${i} - ${line.description}: ${line.amount.toLocaleString()}`);
        });

月の中頃(12/13)にスクリプトを動かしたため、9,800円のサブスクリプション料金が比例配分されて出力されました。

#0 - Time on スタンダードプラン after 13 Dec 2023: 5,860
#Amount - 5,860

プラン変更時の見積もりだけでなく、初回申し込み時にもRetrieveUpcoming Invoice APIを活用しよう

Stripe Billingでサブスクリプションを提供する場合、比例配分への対応のため請求内容のプレビューが欠かせません。

RetrieveUpcoming Invoice APIは比例配分や複雑な料金体系を、「初回申し込み時」にも「プランの変更時」にもプレビューすることができます。

よりユーザーが安心して利用できるサービス提供やユーザー体験を提供するためにも、ぜひこのAPIをご活用ください。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?