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

Appearance API を使用してカスタマイズします。
Payment Element を使用して、アプリケーションに埋め込むカスタム決済フォームを作成し、決済を徴収します。
Checkout API を使用して決済フロー全体を作成および管理する方法については、組み込みコンポーネントクイックスタート を参照してください。
このガイドで、固定料金の サブスクリプション を販売する方法を確認できます。Payment Element を使用して、アプリケーションに埋め込むカスタムの決済フォームを作成できます。
カスタムの決済フォームを作成しない場合は、Checkout に導入することもできます。一連の導入手順を説明している実践的なガイドについては、Billing クイックスタート を参照してください。
導入をコーディングする準備ができていなくても、基本的なサブスクリプションを Dashboard から手動 で設定できます。また、Payment Links を使用して、コードを記述することなくサブスクリプションを設定することもできます。何を決定する必要があり、どのようなリソースが必要なのかを把握するために、導入の設計 方法を確認してください。
作成する内容
このガイドでは以下の方法について説明します。
- 商品カタログを構築する。
- 顧客を作成する登録プロセスを構築します。
- サブスクリプションを作成して、決済情報を収集します。
- 決済とサブスクリプションのステータスをテストして、モニタリングします。
- 顧客がプランを変更またはサブスクリプションをキャンセルできるようにします。
- フレキシブル請求モード を使用して、拡張請求動作と追加機能にアクセスする方法を確認してください。
Stripe 上に構築する方法
Subscriptions は、 請求書 と PaymentIntents を自動的に作成することで請求をシンプルにします。サブスクリプションを作成して有効化するには、まず 商品 を作成して販売する商品を定義し、 価格 を作成してチャージ金額とチャージ頻度を決定します。また、顧客 が、各継続決済に使用される PaymentMethods を格納する必要があります。
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 を使ってみるをご覧ください。
顧客の作成クライアントおよびサーバー
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 をレンダリングする場合は、Intent を作成する前に決済の詳細を収集する を参照してください。
顧客がプランを選択してからサブスクリプションを作成できるようにします。このガイドの例では、顧客は Basic プランまたは Premium プランのいずれかを選択します。
フロントエンドで、選択した価格 ID と顧客レコードの ID をバックエンドに渡します。
fetch('/create-subscription', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ priceId: priceId, customerId: customerId, }), })
バックエンドで、payment_ を使用して incomplete ステータスのサブスクリプションを作成します。次に、サブスクリプションの最初の PaymentIntent からフロントエンドに client_ を返して決済を完了します。これを行うには、サブスクリプションの最新請求書の confirmation_secret を展開します。
サブスクリプション動作の改善 を有効にするには、billing_ を flexible に設定します。Stripe API バージョン 2025-06-30.basil 以降を使用する必要があります。
決済が完了したときに決済手段をデフォルトとして保存する場合は、save_default_payment_method を on_ に設定します。デフォルトの決済手段を保存すると、その後のサブスクリプションの決済の成功率が高くなります。
注
サブスクリプションは 非アクティブ になり、決済を待っています。以下のレスポンスの例では、保存が必要な最小限のフィールドが強調表示されていますが、アプリケーションで頻繁にアクセスされるフィールドは保存できます。
{ "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/clover/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 the 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 の設定
必要に応じて、以下を実行できます。
- Elements のインスタンスを作成する際に appearance オブジェクト を
optionsに渡すことで、サイトのデザインに合わせて Payment Element をカスタマイズできます。 - 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 is reached only if there's an immediate error when // confirming the payment. Show an error to your customer (for example, payment // details incomplete) const messageContainer = document.querySelector('#error-message'); messageContainer.textContent = error.message; } else { // Your customer redirects to your `return_url`. For some payment // methods, such as iDEAL, your customer redirects to an intermediate // site first to authorize the payment, and then redirects 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 [immediately succeed or fail][0] upon // confirmation, while others 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 から送信される webhook を処理する必要があります。これらのイベントは、サブスクリプションの新しい請求書が生成されるなど、Stripe でステータスが変更されるたびに発生します。アプリケーション側では、webhook イベントを含む POST リクエストを受け取るための HTTP ハンドラーを設定して、イベントの署名を検証してください。
開発中は、Stripe CLI を使用して Webhook をモニタリングし、アプリケーション に転送します。開発アプリの実行中に、新しい端末で以下を実行します。
stripe listen --forward-to localhost:4242/webhook
本番環境では、Workbench で Webhook エンドポイントを設定するか、Webhook Endpoints API を使用します。
いくつかのイベントをリッスンして、このガイドの残りのステップを完了します。サブスクリプション固有の Webhook については、サブスクリプションのイベント を確認してください。
サービスへのアクセスを提供するクライアントおよびサーバー
サブスクリプションが有効になりました。次は、ユーザーがサービスにアクセスできるようにします。これを行うには、customer.、customer.、customer. の各イベントをリッスンします。これらのイベントは、Subscription オブジェクトを渡します。このオブジェクトには、サブスクリプションが有効か、期日経過か、キャンセルされたかを示す ステータス フィールドが含まれます。ステータスの一覧については、サブスクリプションのライフサイクル を参照してください。
Webhook ハンドラーで、以下を実行します。
- サブスクリプションのステータスを確認します。
activeの場合、ユーザーは商品の決済を実行しています。 - 顧客が登録している商品を確認し、サービスへのアクセス権を付与します。価格ではなく商品を確認することにより、料金体系や請求期間の変更が必要になった場合に、柔軟に対応できます。
product.、id subscription.およびid subscription.を、すでに保存されているstatus customer.とともにデータベースに保存します。アプリケーションでユーザーに対して有効にする機能を決定する際に、このレコードを確認します。id
サブスクリプションのステータスは、アプリケーションから直接 Stripe に呼び出しを行わなくても、そのライフサイクルのどの時点でも変更される可能性があります。たとえばクレジットカードの有効期限切れで更新ができなかった場合、サブスクリプションは past due のステータスになります。または、カスタマーポータル を実装している場合、顧客はアプリケーションに直接アクセスせずにサブスクリプションをキャンセルする可能性があります。ハンドラーを正しく実装することで、アプリケーションのステータスを 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 で表示できます。
詳しくは、請求導入のテスト を参照してください。
オプション顧客がプランを変更できるようにするクライアントおよびサーバー
顧客にサブスクリプションの変更を許可するには、変更後のオプションの価格 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 の Basic ではなく、月額 15 USD の Premium になりました。
アプリケーションが customer. イベントを受信します。
オプション価格変更をプレビューするクライアントおよびサーバー
顧客がサブスクリプションを変更すると、多くの場合、顧客が支払う金額の調整 (比例配分) が発生します。プレビュー請求書エンドポイント を使用することで、調整済みの金額を顧客に表示できます。
フロントエンドから、プレビュー請求書の作成 の詳細情報をバックエンドのエンドポイントに渡します。
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 がこのような方法でデータを使用するために必要なすべての権利と同意について開示し、これらを取得することはお客様の責任です。詳細については、プライバシーセンターをご覧ください。