サブスクリプションの実装を構築する
サブスクリプションを作成して、継続支払いを受け付けるように管理します。

Appearance API を使用してカスタマイズします。
Payment Element を使用して、アプリケーションに埋め込む方式のカスタム決済フォームを作成し、支払いを回収します。
Checkout API を使用して決済フロー全体を作成して管理する方法については、埋め込みコンポーネントのクイックスタートをご覧ください。
このガイドで、固定料金のサブスクリプションを販売する方法をご覧いただけます。Payment Element を使用して、アプリケーションに埋め込むカスタムの決済フォームを作成できます。
カスタムの支払いフォームを作成しない場合は、Checkout に導入することもできます。一連の導入手順を説明している実践的なガイドについては、Billing のクイックスタートガイドをご覧ください。
導入をコーディングする準備ができていなくても、基本的なサブスクリプションをダッシュボードから手動で設定できます。また、Payment Linksを使用して、コードを記述することなくサブスクリプションを設定することもできます。何を決定する必要があり、どのようなリソースが必要なのかを把握するために、導入の設計方法をご覧ください。
構築する内容
このガイドでは以下の方法について説明します。
- 商品カタログを構築する。
- 顧客を作成する登録プロセスを構築します。
- サブスクリプションを作成して、支払い情報を収集します。
- 支払いとサブスクリプションのステータスをテストして、モニタリングします。
- 顧客がプランを変更したりサブスクリプションをキャンセルしたりできるようにします。
- フレキシブル請求モードを使用して、拡張請求動作と追加機能にアクセスする方法をご覧ください。
Stripe 上に構築する方法
サブスクリプション は、自動的に 請求書 と PaymentIntents を作成することで請求業務を簡素化します。 サブスクリプションを作成・有効化するには、まず販売する商品を定義する商品と、課金の頻度や金額を決める価格を作成する必要があります。また、各定期支払いに使われる 支払い方法 を保存するための 顧客 も必要です。
API オブジェクトの定義
リソース | 定義 |
---|---|
Customer (顧客) | サブスクリプションを購入する顧客を表します。サブスクリプションに関連付けられた Customer オブジェクトを使用して、継続支払いを作成して追跡し、顧客が登録する商品を管理します。 |
Entitlement (エンタイトルメント) | 顧客が登録したサービス商品に含まれる機能への顧客のアクセスを表します。顧客の商品の継続購入のサブスクリプションを作成すると、その商品に関連付けられた機能ごとに、有効な権利が自動的に作成されます。顧客がサービスにアクセスするときに、その有効な資格を使用して、サブスクリプションに含まれる機能を有効にします。 |
Feature (機能) | 顧客がサービス商品に登録すると利用できる機能や機能を表します。ProductFeatures を作成することで、商品に機能を含めることができます。 |
Invoice (請求書) | 顧客が支払うべき金額の明細書であり、下書きから支払い済み、またはその他の方法で確定された支払いステータスを追跡します。サブスクリプションでは請求書が自動的に生成されます。 |
PaymentIntent | 動的な支払いフローを構築する方法です。Payment Intent は、顧客の決済フローのライフサイクルを追跡し、規制で必須とされる同意書、Radar のカスタムの不正利用ルール、またはリダイレクトベースの支払い方法によって要求されたときに、追加の認証ステップを開始します。Payment Intent は、請求書によって自動的に作成されます。 |
PaymentMethod | 顧客が商品の支払いに使用する決済手段。たとえば、クレジットカードを Customer オブジェクトに保存して、その顧客の継続支払いに使用できます。通常、Payment Intents API または Setup Intents API とともに使用されます。 |
Price (価格) | 商品の単価、通貨、請求期間を定義します。 |
Product (商品) | お客様のビジネスが販売する商品またはサービス。サービス商品には 1 つ以上の機能を含めることができます。 |
ProductFeature | 1 つの商品に 1 つの機能が含まれることを表します。各商品は、含まれる各機能の ProductFeature に関連付けられ、各機能は、それを含む各商品の ProductFeature に関連付けられます。 |
Subscription (サブスクリプション) | 顧客の商品の継続的な購入を表します。サブスクリプションを使用して、支払いを回収し、商品の繰り返し提供や継続的なアクセスを提供します。 |
製品、機能、利用権がどのように連携するかの例をご紹介します。例えば、基本機能を提供する標準プランと、拡張機能を追加した上位プランの 2 つのプランを持つ定期サービスを設定するとします。
basic_
とfeatures extended_
の 2 つの機能を作成します。features standard_
とproduct advanced_
の 2 つの商品を作成します。product - 標準商品の場合、
basic_
をfeatures standard_
に関連付ける ProductFeature を 1 つ作成します。product - 高度な商品の場合、2 つの ProductFeatures を作成します。1 つは
basic_
をfeatures advanced_
に関連付け、もう 1 つはproduct extended_
をfeatures advanced_
に関連付けます。product
顧客の first_
は、標準商品に登録します。サブスクリプションを作成すると、Stripe は、first_
を basic_
に関連付けるエンタイトルメントを自動的に作成します。
別の顧客no second_
は高度な商品に登録します。 サブスクリプションを作成すると、Stripe は自動的に 2 つのエンタイトルメントを作成します。1 つは second_
を basic_
に関連付け、もう 1 つは second_
を extended_
に関連付けます。
有効なエンタイトルメントを取得するか、有効なエンタイトルメントのサマリーイベントをリッスンすることで、顧客に提供する機能を決定できます。顧客のサブスクリプション、商品、機能を取得する必要はありません。
Stripe を設定する
任意の Stripe クライアントをインストールします。
次に、Stripe CLI をインストールします。CLI には Webhook テスト機能があり、StripeへのAPI コールを実行することもできます。 このガイドでは、後のセクションでCLI を使用して料金体系モデルを設定する方法を説明しています。
その他のインストールオプションについては、Stripe CLI を使ってみるをご覧ください。
Customer を作成するクライアントおよびサーバー
Stripe では各サブスクリプションに対して 顧客が必要です。 アプリケーションのフロントエンドで、ユーザーから必要な情報を収集し、それをバックエンドに渡します。
住所の詳細を収集する必要がある場合は、Address Element を使用することで顧客の配送先住所または請求先住所を収集できます。Address Element の詳細については、Address Element ページをご覧ください。
<form id="signup-form"> <label> Email <input id="email" type="email" placeholder="Email address" value="test@example.com" required /> </label> <button type="submit"> Register </button> </form>
const emailInput = document.querySelector('#email'); fetch('/create-customer', { method: 'post', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email: emailInput.value, }), }).then(r => r.json());
サーバー上で、Stripe Customer オブジェクトを作成します。
注
Checkout セッションで使用するために、顧客 ID を必ず保存してください
サブスクリプションを作成するクライアントおよびサーバー
注
最初にサブスクリプションを作成せずに Payment Element をレンダリングする場合は、インテントを作成する前に支払いの詳細を収集するをご覧ください。
新しい顧客がプランを選択してからサブスクリプションを作成できるようにします。このガイドでは、顧客は基本またはプレミアムから選択します。
フロントエンドで、選択した価格 ID と顧客レコードの ID をバックエンドに渡します。
fetch('/create-subscription', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ priceId: priceId, customerId: customerId, }), })
バックエンドで、payment_
を使用して、ステータスが incomplete
のサブスクリプションを作成します。次に、サブスクリプションの最初の支払いインテントの client_
をフロントエンドに返し、サブスクリプションの最新の請求書の confirmation_
を展開して支払いを完了します。
サブスクリプション動作の向上を有効にするには、billing_
を flexible
に設定します。Stripe API バージョン2025-06-30.basil以降を使用する必要があります。
支払いが完了したときに支払い方法をデフォルトとして保存する場合は、save_default_payment_method を on_
に設定します。デフォルトの支払い方法を保存すると、その後のサブスクリプションの決済の成功率が高くなります。
注
この時点でサブスクリプションは inactive
であり、支払いを待っています。次に示すのはレスポンスの例です。強調表示されているのは保存が必要な最小限のフィールドですが、アプリケーションが頻繁にアクセスするフィールドをすべて保存します。
{ "id": "sub_JgRjFjhKbtD2qz", "object": "subscription", "application_fee_percent": null, "automatic_tax": { "disabled_reason": null, "enabled": false, "liability": "null" }, "billing_cycle_anchor": 1623873347,
支払い情報を収集するクライアント
Stripe Elements を使用して支払いの詳細を収集し、サブスクリプションを有効化します。Elements は、お使いのアプリケーションのデザインに合わせてカスタマイズできます。
Payment Element はサブスクリプションで、Link、クレジットカード、SEPA ダイレクトデビット、BECS ダイレクトデビットの決済手段に対応しています。有効になっている決済手段が表示され、顧客の選択に応じて支払いの詳細が安全に収集されます。
Stripe Elements を設定する
Payment Element は Stripe.js の機能として自動的に使用できるようになります。決済ページに Stripe.js スクリプトを含めるには、HTML ファイルのhead
にスクリプトを追加します。常に js.stripe.com から Stripe.js を直接読み込むことにより、PCI 準拠が維持されます。スクリプトをバンドルに含めることや、そのコピーを自身でホストすることは避けてください。
<head> <title>Checkout</title> <script src="https://js.stripe.com/basil/stripe.js"></script> </head> <body> <!-- content here --> </body>
決済ページで以下の JavaScript を使用して、Stripe のインスタンスを作成します。
// Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/apikeys const stripe = Stripe(
);'pk_test_TYooMQauvdEDq54NiTphI7jx'
Payment Element をページに追加する
Payment Element を本番で使用するには、支払いページへの配置場所が必要です。支払いフォームで、一意の ID を持つ空の DOM ノード (コンテナー) を作成します。
<form id="payment-form"> <div id="payment-element"> <!-- Elements will create form elements here --> </div> <button id="submit">Subscribe</button> <div id="error-message"> <!-- Display error message to your customers here --> </div> </form>
上記のフォームが読み込まれたら、Payment Element のインスタンスを作成して、それをコンテナーの DOM ノードにマウントします。サブスクリプションの作成ステップで、フロントエンドに client_
を渡しています。この値を、Elements のインスタンスを作成する際にオプションとして渡します。
const options = { clientSecret: '{{CLIENT_SECRET}}', // Fully customizable with appearance API. appearance: {/*...*/}, }; // Set up Stripe.js and Elements to use in payment form, passing the client secret obtained in step 5 const elements = stripe.elements(options); const paymentElementOptions = { layout: "tabs", }; // Create and mount the Payment Element const paymentElement = elements.create('payment', paymentElementOptions); paymentElement.mount('#payment-element');
Payment Element によって動的なフォームが表示され、顧客はここで支払い方法を選択できます。このフォームでは、顧客が選択した支払い方法で必要な決済の詳細のすべてが自動的に収集されます。
(オプション) Payment Element の設定
- お客様のサイトのデザインに合わせて Payment Element をカスタマイズする場合、Elements のインスタンスを作成する際に Appearance オブジェクトを
options
に渡します。 - 継続支払い、自動再読み込み、後払いに対応するために、マーチャントトークンを返すよう Apple Pay インターフェースを設定します。
支払いを完了する
stripe.
を使用して、Payment Element からの詳細を指定した支払いを完了し、サブスクリプションを有効化します。これにより PaymentMethod が作成され、不完全なサブスクリプションの最初の PaymentIntent が確定され、その結果支払いが実行されます。支払いに強力な顧客認証 (SCA) が必要とされる場合は、PaymentIntent の確定前に Payment Element で認証プロセスが処理されます。
支払いの完了後に Stripe がユーザーをリダイレクトする場所を指定するには、この関数に return_url を指定します。ユーザーは、最初に銀行のオーソリページなどの中間サイトにリダイレクトされてから、return_
にリダイレクトされる場合があります。カード支払いでは、支払いが正常に完了するとすぐに return_
にリダイレクトされます。
const form = document.getElementById('payment-form'); form.addEventListener('submit', async (event) => { event.preventDefault(); const {error} = await stripe.confirmPayment({ //`Elements` instance that was used to create the Payment Element elements, confirmParams: { return_url: "https://example.com/order/123/complete", } }); if (error) { // This point will only be reached if there is an immediate error when // confirming the payment. Show error to your customer (for example, payment // details incomplete) const messageContainer = document.querySelector('#error-message'); messageContainer.textContent = error.message; } else { // Your customer will be redirected to your `return_url`. For some payment // methods like iDEAL, your customer will be redirected to an intermediate // site first to authorize the payment, then redirected to the `return_url`. } });
顧客が支払いを送信すると、Stripe は顧客を return_
にリダイレクトし、以下の URL クエリーパラメーターを含めます。返品ページでは、これらを使用して PaymentIntent のステータスを取得し、顧客に支払いステータスを表示できます。
return_
を指定する際に、返品ページで使用する独自のクエリパラメーターを追加することもできます。
パラメーター | 説明 |
---|---|
payment_ | PaymentIntent の一意の識別子。 |
payment_ | PaymentIntent オブジェクトの client secret。サブスクリプションの実装の場合、この client_secret は confirmation_ を通じて Invoice オブジェクトでも公開されます |
顧客が自社のサイトにリダイレクトされたら、payment_
を使用して PaymentIntent をクエリし、顧客に取引ステータスを表示できます。
注意
顧客のブラウザーセッションを追跡するツールを利用している場合、リファラー除外リストに stripe.
ドメインの追加が必要になる場合があります。リダイレクトを行うと、一部のツールでは新しいセッションが作成され、セッション全体の追跡ができなくなります。
クエリパラメーターのいずれか 1 つを使用して PaymentIntent を取得します。PaymentIntent のステータスを調べて、顧客に表示する内容を決定します。また、return_
を指定するときにカスタムのクエリパラメーターを追加することもできます。このパラメーターはリダイレクトプロセスの間維持されます。
// Initialize Stripe.js using your publishable key const stripe = Stripe(
); // Retrieve the "payment_intent_client_secret" query parameter appended to // your return_url by Stripe.js const clientSecret = new URLSearchParams(window.location.search).get( 'payment_intent_client_secret' ); // Retrieve the PaymentIntent stripe.retrievePaymentIntent(clientSecret).then(({paymentIntent}) => { const message = document.querySelector('#message') // Inspect the PaymentIntent `status` to indicate the status of the payment // to your customer. // // Some payment methods will [immediately succeed or fail][0] upon // confirmation, while others will first enter a `processing` status. // // [0]: https://stripe.com/docs/payments/payment-methods#payment-notification switch (paymentIntent.status) { case 'succeeded': message.innerText = 'Success! Payment received.'; break; case 'processing': message.innerText = "Payment processing. We'll update you when payment is received."; break; case 'requires_payment_method': message.innerText = 'Payment failed. Please try another payment method.'; // Redirect your user back to your payment page to attempt collecting // payment again break; default: message.innerText = 'Something went wrong.'; break; } });'pk_test_TYooMQauvdEDq54NiTphI7jx'
Webhook をリッスンするサーバー
実装を完了するには、Stripe から送信される webhooks を処理する必要があります。これらのイベントは、サブスクリプションの新しい請求書が生成されるなど、Stripe でステータスが変更されるたびに発生します。お客様のアプリケーション側では、webhook イベントを含む POST リクエストを受け取るための HTTP ハンドラーを設定して、イベントの署名を検証してください。
開発中は、Stripe CLI を使用して Webhook を監視し、アプリケーションに転送します。開発アプリの実行中に、新しい端末で以下を実行します。
stripe listen --forward-to localhost:4242/webhook
For production, set up a webhook endpoint in Workbench, or use the Webhook Endpoints API.
いくつかのイベントをリッスンして、このガイドの残りのステップを完了します。サブスクリプション固有の Webhook については、サブスクリプションのイベントをご覧ください。
サービスへのアクセスを提供するクライアントおよびサーバー
ここまでのステップでサブスクリプションが有効になりました。次は、ユーザーがサービスにアクセスできるようにします。これを行うには、customer.
、customer.
、customer.
の各イベントをリッスンします。これらのイベントは、Subscription オブジェクトを渡します。このオブジェクトには、サブスクリプションが有効か、期日超過か、キャンセルされたかを示す status
フィールドが含まれます。ステータスの一覧については、サブスクリプションのライフサイクルをご覧ください。
Webhook ハンドラーで、以下を実行します。
- サブスクリプションのステータスを確認します。
active
の場合、ユーザーは商品の支払いを実行しています。 - 顧客が登録している商品を確認し、サービスへのアクセス権を付与します。価格ではなく商品を確認することにより、料金体系や請求期間の変更が必要になった場合に、柔軟に対応できます。
product.
、id subscription.
およびid subscription.
を、すでに保存されているstatus customer.
とともにデータベースに保存します。アプリケーションでユーザーに対して有効にする機能を決定する際に、このレコードを確認します。id
サブスクリプションのステータスは、アプリケーションから直接 Stripe に呼び出しを行わなくても、そのライフサイクルのどの時点でも変更される可能性があります。たとえばクレジットカードの有効期限切れで更新ができなかった場合、サブスクリプションは past due のステータスになります。または、お客様が customer portal を実装している場合、顧客はお客様のアプリケーションに直接アクセスせずにサブスクリプションをキャンセルする可能性があります。ハンドラーを正しく実装することで、お客様のアプリケーションのステータスを Stripe と同期した状態に維持することができます。
サブスクリプションをキャンセルするクライアントおよびサーバー
顧客にサブスクリプションのキャンセルを許可するのは一般的です。この例では、アカウントの設定ページにキャンセルオプションを追加します。

サブスクリプションのキャンセル機能が設定されたアカウント設定
function cancelSubscription(subscriptionId) { return fetch('/cancel-subscription', { method: 'post', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ subscriptionId: subscriptionId, }), }) .then(response => { return response.json(); }) .then(cancelSubscriptionResponse => { // Display to the user that the subscription has been canceled. }); }
バックエンドで、フロントエンドから呼び出すエンドポイントを定義します。
アプリケーションが customer.
イベントを受信します。
サブスクリプションがキャンセルされたら、データベースを更新して以前に保存された Stripe サブスクリプション ID を削除し、サービスへのアクセスを制限します。
キャンセルされたサブスクリプションを、再びアクティブにすることはできません。代わりに、顧客から更新された請求先情報を収集し、顧客のデフォルトの支払い方法を更新して、既存の顧客レコードから新しいサブスクリプションを作成します。
組み込みをテストする
支払い方法をテストする
次の表を使用して、さまざまな支払い方法とシナリオをテストします。
決済手段 | シナリオ | テスト方法 |
---|---|---|
BECS ダイレクトデビット | 顧客が BECS ダイレクトデビットによる支払いに成功します。 | アカウント番号900123456 と BSB000000 を使用して、フォームに入力します。確定された PaymentIntent のステータスは、まずprocessing に移行し、3 分後にsucceeded ステータスに移行します。 |
BECS ダイレクトデビット | 顧客の支払いが account_ エラーコードで失敗します。 | アカウント番号 111111113 と BSB 000000 を使用して、フォームに入力します。 |
クレジットカード | カード支払いは成功し、認証は必要とされません。 | クレジットカード番号 4242 4242 4242 4242 と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 |
クレジットカード | カード決済で認証が要求されます。 | クレジットカード番号 4000 0025 0000 3155 と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 |
クレジットカード | カードが insufficient_ などの拒否コードで支払い拒否されます。 | クレジットカード番号 4000 0000 0000 9995 と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 |
SEPA ダイレクトデビット | 顧客が SEPA ダイレクトデビットによる支払いに成功します。 | 口座番号 AT321904300235473204 を使用して、フォームに入力します。確定された PaymentIntent のステータスはまず、processing に移行し、3 分後に succeeded ステータスに移行します。 |
SEPA ダイレクトデビット | 顧客の PaymentIntent ステータスが processing から requires_ に移行します。 | 口座番号 AT861904300235473202 を使用して、フォームに入力します。 |
イベントをモニターする
Webhook がアップグレードやキャンセルなどのサブスクリプション変更イベントをリッスンするよう設定します。詳しくは、サブスクリプション Webhook についての記事をご覧ください。イベントは、ダッシュボードまたは Stripe CLI で表示できます。
詳しくは、Billing の導入テストをご覧ください。
オプション顧客がプランを変更できるようにするクライアントおよびサーバー
顧客がサブスクリプションを変更できるようにするには、変更後のオプションの価格 ID を収集します。次にフロントエンドからバックエンドのエンドポイントにこの新しい価格 ID を送信します。この例ではサブスクリプション ID も渡していますが、これはデータベースに保存されているログインユーザーに関する情報から取得できます。
function updateSubscription(priceId, subscriptionId) { return fetch('/update-subscription', { method: 'post', headers: { 'Content-type': 'application/json', }, body: JSON.stringify({ subscriptionId: subscriptionId, newPriceId: priceId, }), }) .then(response => { return response.json(); }) .then(response => { return response; }); }
バックエンドでは、サブスクリプション ID と新しい価格 ID を渡して、フロントエンドから呼び出すエンドポイントを定義します。これで、サブスクリプションは、月額 5 USD の基本オプションではなく、月額 15 USD のプレミアムオプションになります。
アプリケーションが customer.
イベントを受信します。
オプション価格変更をプレビューするクライアントおよびサーバー
顧客がサブスクリプションを変更すると、多くの場合、日割り計算と呼ばれる未払い額の調整が行われます。create preview invoice (請求書プレビューの作成) エンドポイントを使用して、調整後の金額を顧客に表示できます。
フロントエンドで、請求書プレビューの作成情報をバックエンドのエンドポイントに渡します。
function createPreviewInvoice( customerId, subscriptionId, newPriceId, trialEndDate ) { return fetch('/create-preview-invoice', { method: 'post', headers: { 'Content-type': 'application/json', }, body: JSON.stringify({ customerId: customerId, subscriptionId: subscriptionId, newPriceId: newPriceId, }), }) .then(response => { return response.json(); }) .then((invoice) => { return invoice; }); }
バックエンドで、フロントエンドから呼び出すエンドポイントを定義します。
オプション顧客の支払い方法を表示するクライアントおよびサーバー
顧客のカードのブランドとカード番号の下 4 桁を表示すると、顧客は支払いに使用するカードを確認したり、支払い方法の更新が必要かどうかを判断したりできます。
フロントエンドから、支払い方法の詳細を取得するバックエンドのエンドポイントに、支払い方法 ID を送信します。
function retrieveCustomerPaymentMethod(paymentMethodId) { return fetch('/retrieve-customer-payment-method', { method: 'post', headers: { 'Content-type': 'application/json', }, body: JSON.stringify({ paymentMethodId: paymentMethodId, }), }) .then((response) => { return response.json(); }) .then((response) => { return response; }); }
バックエンドで、フロントエンドから呼び出すエンドポイントを定義します。
レスポンスのサンプル:
{ "id": "pm_1GcbHY2eZvKYlo2CoqlVxo42", "object": "payment_method", "billing_details": { "address": { "city": null, "country": null, "line1": null, "line2": null, "postal_code": null,
注
paymentMethod.
および last4
は、データベースに保存することをお勧めします。たとえば、paymentMethod.
を stripeCustomerPaymentMethodId
として users
コレクションまたはテーブルに保存します。必要に応じて、exp_
、exp_
、fingerprint
、billing_
を保存することもできます。これは Stripe に対して実行するコール数を制限するためのものであり、パフォーマンスの効率を向上させ、レート制限の防止に役立ちます。
顧客に Stripe を開示する
Stripe は顧客の Elements とのやり取りに関する情報を収集して、サービスを提供し、不正利用を防止し、サービスを向上します。これには、Cookie と IP アドレスを使用して、1 つの決済フローセッションで顧客に表示する Elements を特定することが含まれます。Stripe がこのような方法でデータを使用するために必要なすべての権利と同意について開示し、これらを取得することはお客様の責任です。詳細については、プライバシーセンターをご覧ください。