サブスクリプションの実装を構築する
サブスクリプションを作成して、継続支払いを受け付けるように管理します。
Appearance API を使用してカスタマイズします。
Stripe Billing の利用をご希望の場合
Stripe は、無料トライアル、請求サイクルの起点、比例配分などのサブスクリプション機能の管理を可能にする Payment Element の導入を進めています。詳細については、支払いページの構築ガイドをご覧ください。
このガイドで、固定料金のサブスクリプションを販売する方法をご覧いただけます。Payment Element を使用して、アプリケーションに埋め込むカスタムの決済フォームを作成できます。
カスタムの支払いフォームを作成しない場合は、Checkout に導入することもできます。一連の導入手順を説明している実践的なガイドについては、Billing のクイックスタートガイドをご覧ください。
導入をコーディングする準備ができていなくても、基本的なサブスクリプションをダッシュボードから手動で設定できます。また、Payment Links を使用して、コードを記述することなくサブスクリプションを設定することもできます。何を決定する必要があり、どのようなリソースが必要なのかを把握するために、導入の設計方法をご覧ください。
構築する内容
このガイドでは以下の方法について説明します。
- 商品カタログを構築して、ビジネスをモデル化する。
- 顧客を作成する登録プロセスを構築します。
- サブスクリプションを作成して、支払い情報を収集します。
- 支払いとサブスクリプションのステータスをテストして、モニタリングします。
- 顧客がプランを変更したりサブスクリプションをキャンセルしたりできるようにします。
Stripe でモデル化する方法
Subscription (サブスクリプション) は、Invoice と PaymentIntent を自動作成することで請求業務をシンプルにします。サブスクリプションを作成して有効化するには、まず販売対象をモデル化する Product と、請求する期間と金額を決定する Price を作成する必要があります。また、毎回の継続支払いに使用される PaymentMethods を格納する Customer (顧客) も必要です。
API オブジェクトの定義
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 オブジェクトを作成します。
サブスクリプションを作成するクライアントおよびサーバー
注
最初にサブスクリプションを作成せずに Payment Element をレンダリングする場合は、インテントを作成する前に支払いの詳細を収集するをご覧ください。
新しい顧客がプランを選択してからサブスクリプションを作成できるようにします。このガイドでは、顧客は基本またはプレミアムから選択します。
フロントエンドで、選択した価格 ID と顧客レコードの ID をバックエンドに渡します。
fetch('/create-subscription', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ priceId: priceId, customerId: customerId, }), })
バックエンドで payment_
を使用することで、ステータスが incomplete
のサブスクリプションを作成できます。次に、サブスクリプションの最初の支払いインテントの client_
をフロントエンドに返して、支払いを完了します。
支払いが完了したときに支払い方法をデフォルトとして保存する場合は、save_default_payment_method を on_
に設定します。デフォルトの支払い方法を保存すると、その後のサブスクリプションの決済の成功率が高くなります。
注
この時点でサブスクリプションは inactive
であり、支払いを待っています。次に示すのはレスポンスの例です。強調表示されているのは保存が必要な最小限のフィールドですが、アプリケーションが頻繁にアクセスするフィールドをすべて保存します。
{ "id": "sub_JgRjFjhKbtD2qz", "object": "subscription", "application_fee_percent": null, "automatic_tax": { "enabled": false }, "billing": "charge_automatically", "billing_cycle_anchor": 1623873347, "billing_thresholds": null,
支払い情報を収集するクライアント
Stripe Elements を使用して支払いの詳細を収集し、サブスクリプションを有効化します。Elements は、お使いのアプリケーションのデザインに合わせてカスタマイズできます。
注
Payment Element は、多様な支払い方法で必要な決済の詳細をすべて安全に収集します。現在、Payment Element と Subscription の両方でサポートされている支払い方法は、クレジットカード、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/v3/"></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 checkout 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。 |
顧客が自社のサイトにリダイレクトされたら、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` state. // // [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 を処理する必要があります。Webhook は、サブスクリプションによって新しい請求書が作成されるなど、Stripe 内の状態が変化するたびにトリガーされるイベントです。アプリケーションで、Webhook イベントを含む POST リクエストを受け取る HTTP ハンドラーを設定し、イベントの署名を検証します。
開発中は、Stripe CLI を使用して Webhook を監視し、アプリケーションに転送します。開発アプリの実行中に、新しい端末で以下を実行します。
stripe listen --forward-to localhost:4242/webhook
本番環境では、ダッシュボードで Webhook エンドポイント URL を設定するか、Webhook Endpoint API を使用します。
いくつかのイベントをリッスンして、このガイドの残りのステップを完了します。サブスクリプション固有の Webhook については、サブスクリプションのイベントで詳細をご覧ください。
サービスへのアクセスを提供するクライアントおよびサーバー
ここまでのステップでサブスクリプションが有効になりました。次は、ユーザーがサービスにアクセスできるようにします。これを行うには、customer.
、customer.
、customer.
の各イベントをリッスンします。これらのイベントは、Subscription オブジェクトを渡します。このオブジェクトには、サブスクリプションが有効か、期日超過か、キャンセルされたかを示す status
フィールドが含まれます。ステータスの一覧については、サブスクリプションのライフサイクルをご覧ください。
Webhook ハンドラーで、以下を実行します。
- サブスクリプションのステータスを確認します。
active
の場合、ユーザーは商品の支払いを実行しています。 - 顧客が登録している商品を確認し、サービスへのアクセス権を付与します。価格ではなく商品を確認することにより、料金体系や請求間隔の変更が必要になった場合に、柔軟に対応できます。
product.
、id subscription.
およびid subscription.
を、すでに保存されているstatus customer.
とともにデータベースに保存します。アプリケーションでユーザーに対して有効にする機能を決定する際に、このレコードを確認します。id
サブスクリプションのステータスは、存続期間のどの時点でも変化する可能性があります。アプリケーションが Stripe に直接コールを行っていない場合でも同様です。例えば、クレジットカードの有効期限が切れて更新が失敗した場合、サブスクリプションは期日超過の状態になります。また、カスタマーポータルを導入している場合、ユーザーが直接アプリケーションを開かずにサブスクリプションをキャンセルすることがあります。ハンドラを正しく実装することで、いつでもアプリケーションを 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 と BSB 000-000 を使用して、フォームに入力します。確定された PaymentIntent のステータスは、まず processing に移行し、3 分後に succeeded ステータスに移行します。 |
BECS ダイレクトデビット | 顧客の支払いが account_ エラーコードで失敗します。 | 口座番号 111111113 と BSB 000-000 を使用して、フォームに入力します。 |
クレジットカード | カード支払いは成功し、認証は要求されません。 | クレジットカード番号 4242 4242 4242 4242 と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 |
クレジットカード | カード決済で認証が要求されます。 | クレジットカード番号 4000 0025 0000 3155 と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 |
クレジットカード | カードが insufficient_ などの拒否コードで支払い拒否されます。 | クレジットカード番号 4000 0000 0000 9995 と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 |
SEPA ダイレクトデビット | 顧客が SEPA ダイレクトデビットによる支払いに成功します。 | 口座番号 AT321904300235473204 を使用して、フォームに入力します。確定された PaymentIntent のステータスはまず、processing に移行し、3 分後に succeeded ステータスに移行します。 |
SEPA ダイレクトデビット | 顧客の Payment Intent のステータスが、processing から requires_ に移行します。 | 口座番号 AT861904300235473202 を使用して、フォームに入力します。 |
イベントをモニターする
Webhook を設定して、アップグレードやキャンセルなどのサブスクリプションの変更イベントをリッスンします。サブスクリプションの Webhook の詳細をご覧ください。イベントの表示は、ダッシュボードまたは Stripe CLI を使用して行うことができます。
詳しくは、Billing の導入テストをご覧ください。
Stripe について顧客に開示する
Stripe は顧客の Elements とのやり取りに関する情報を収集して、サービスを提供し、不正利用を防止し、サービスを向上します。これには、Cookie と IP アドレスを使用して、1 つの決済フローセッションで顧客に表示する Elements を特定することが含まれます。Stripe がこのような方法でデータを使用するために必要なすべての権利と同意について開示し、これらを取得することはお客様の責任です。詳細については、プライバシーセンターをご覧ください。