# Checkout によるサブスクリプション導入の構築 Checkout で継続課金を受け付けられるようにサブスクリプションを作成・管理します。 # 完全ホスト型ページ > This is a 完全ホスト型ページ for when payment-ui is stripe-hosted. View the full page at https://docs.stripe.com/payments/checkout/build-subscriptions?payment-ui=stripe-hosted. # 完全ホスト型ページ > This is a 完全ホスト型ページ for when platform is web and ui is stripe-hosted. View the full page at https://docs.stripe.com/payments/checkout/build-subscriptions?platform=web&ui=stripe-hosted. #### 導入作業 Complexity: 2/5 #### UI のカスタマイズ 限定的なカスタマイズ - 20 種類の事前設定されたフォント - 3 種類の事前設定されたボーダーラディウス - カスタムの背景色と枠線の配色 - カスタムロゴ #### 実装タイプ 構築済みのホストされたページを使用して決済を回収し、*サブスクリプション* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis) を管理します。 {% button variant=“secondary” icon=“external” href=“https://checkout.stripe.dev/”" %} お試しください ## 作成する内容 このガイドでは、[Stripe Checkout](https://docs.stripe.com/payments/checkout.md) を利用して月額固定料金のサブスクリプションを販売する方法について説明します。 このガイドでは以下の方法について説明します。 - 商品カタログを構築して、ビジネスをモデル化します。 - Checkout セッションをサイトに追加し、ボタン、成功ページ、キャンセルページなどを組み込む。 - サブスクリプションのイベントをモニタリングし、サービスへのアクセスを提供する。 - [カスタマーポータル](https://docs.stripe.com/customer-management.md)を設定します。 - 顧客ポータルセッションをサイトに追加し、ボタンやリダイレクトなどを組み込む。 - ポータルを使用して顧客がサブスクリプションを自身で管理できるようにする。 - [フレキシブル請求モード](https://docs.stripe.com/billing/subscriptions/billing-mode.md) を使用して、拡張請求動作と追加機能にアクセスする方法を確認してください。 導入をコーディングする準備ができていない場合は、基本的なサブスクリプションを[ダッシュボードから手動](https://docs.stripe.com/no-code/subscriptions.md)で設定するか、[Payment Links](https://docs.stripe.com/payment-links.md) を使用してコードの記述なしにサブスクリプションを設定することもできます。 [導入の設計](https://docs.stripe.com/billing/subscriptions/design-an-integration.md) の詳細をご覧になり、完全な導入において何を決定する必要があり、どのようなリソースが必要なのかを把握してください。 組み込み完了後に、以下の拡張を行うことができます。 - [税金](https://docs.stripe.com/payments/checkout/taxes.md)を表示 - [割引](https://docs.stripe.com/billing/subscriptions/coupons.md#using-coupons-in-checkout) の適用 - 顧客に [無料トライアル期間](https://docs.stripe.com/billing/subscriptions/trials.md) を提供する - [決済手段](https://docs.stripe.com/payments/payment-methods/integration-options.md) を追加する - [オンライン請求書ページ](https://docs.stripe.com/invoicing/hosted-invoice-page.md) を導入する - 決済を [設定モード](https://docs.stripe.com/payments/save-and-reuse.md) で使用する - [従量課金](https://docs.stripe.com/products-prices/pricing-models.md#usage-based-pricing)、[料金体系](https://docs.stripe.com/products-prices/pricing-models.md#tiered-pricing)、[従量課金ベースの料金体系](https://docs.stripe.com/products-prices/pricing-models.md#usage-based-pricing) を設定 - [比例配分](https://docs.stripe.com/billing/subscriptions/prorations.md) の管理 - [顧客が複数の製品に登録できるようにする](https://docs.stripe.com/billing/subscriptions/quantities.md#multiple-product-sub) - [エンタイトルメント](https://docs.stripe.com/billing/entitlements.md)を導入して商品の機能へのアクセスを管理する ## Stripe をセットアップする 任意の Stripe クライアントをインストールします。 #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` オプションで、Stripe CLI をインストールします。CLI は [Webhook](https://docs.stripe.com/webhooks.md#test-webhook) のテストを提供し、これを実行することで商品と料金を作成できます。 その他のインストールオプションについては、[Stripe CLI を使ってみる](https://docs.stripe.com/stripe-cli.md)をご覧ください。 ## 価格モデルを作成する [ダッシュボードまたは Stripe CLI] [継続的な料金体系モデル](https://docs.stripe.com/products-prices/pricing-models.md)は、お客様が販売する商品またはサービス、そのコスト、決済で受け付ける通貨、請求対象となるサービス提供期間 (サブスクリプションの場合) を表します。価格モデルを構築するには、お客様が販売する「[商品](https://docs.stripe.com/api/products.md)」と、それをいくらで、どのくらいの頻度で請求するかを示す「[価格](https://docs.stripe.com/api/prices.md)」を用います。 この例では、「基本」と「プレミアム」という 2 つのサービスレベルオプションがある固定価格のサービスを使用しています。サービスレベルオプションごとに、1 つの商品と 1 つの継続価格を作成する必要があります (セットアップ料金のような 1 回限りの支払いを追加する場合は、1 回限りの価格で 3 つ目の商品を作成します)。 各商品が月ごとに請求されます。基本商品の価格は 5 USD で、プレミアム商品の価格は 15 USD です。3 段階構成の例については、[定額料金](https://docs.stripe.com/subscriptions/pricing-models/flat-rate-pricing.md)ガイドをご覧ください。 #### ダッシュボード [商品を追加](https://dashboard.stripe.com/test/products/create)ページに移動し、2 つの商品を作成します。商品ごとに 1 つの価格を追加し、それぞれに毎月の継続請求期間を設定します。 - プレミアム商品: 追加機能を備えたプレミアムサービス - 価格:定額 | 15 USD - 基本商品: 最低限の機能を備えた基本サービス - 価格:定額 | 5 USD 価格を作成したら、価格 ID を記録しておき、他のステップで使用できるようにします。価格 ID は、`price_G0FvDp6vZvdwRZ` のように表示されます。 準備が完了したら、ページ右上の**本番環境にコピー**ボタンを使用して、[サンドボックスから本番環境に](https://docs.stripe.com/keys.md#test-live-modes)商品を複製します。 #### API API を使用して[商品](https://docs.stripe.com/api/products.md)と[価格](https://docs.stripe.com/api/prices.md)を作成できます。 プレミアム製品を作成します。 ```curl curl https://api.stripe.com/v1/products \ -u "<>:" \ --data-urlencode "name=Billing Guide: Premium Service" \ -d "description=Premium service with extra features" ``` ベーシック製品を作成します。 ```curl curl https://api.stripe.com/v1/products \ -u "<>:" \ --data-urlencode "name=Billing Guide: Basic Service" \ -d "description=Basic service with minimum features" ``` 各商品の商品 ID を記録しておきます。これは次のように表示されます。 ```json { "id": "prod_H94k5odtwJXMtQ", "object": "product", "active": true, "attributes": [ ], "created": 1587577341, "description": "Premium service with extra features", "images": [ ], "livemode": false, "metadata": { }, "name": "Billing Guide: Premium Service", "statement_descriptor": null, "type": "service", "unit_label": null, "updated": 1587577341 } ``` 商品 ID を使用して各商品の価格を作成します。[unit_amount](https://docs.stripe.com/api/prices/object.md#price_object-unit_amount) の単位はセントであるため、たとえば `1500` = 15 USD です。 プレミアム価格を作成します。 ```curl curl https://api.stripe.com/v1/prices \ -u "<>:" \ -d product={{PREMIUM_PRODUCT_ID}} \ -d unit_amount=1500 \ -d currency=usd \ -d "recurring[interval]=month" ``` 基本価格を作成します。 ```curl curl https://api.stripe.com/v1/prices \ -u "<>:" \ -d product={{BASIC_PRODUCT_ID}} \ -d unit_amount=500 \ -d currency=usd \ -d "recurring[interval]=month" ``` 各価格の価格 ID を記録しておき、後続のステップで使用できるようにします。これは次のように表示されます。 ```json { "id": "price_HGd7M3DV3IMXkC", "object": "price", "product": "prod_HGd6W1VUqqXGvr", "type": "recurring", "currency": "usd", "recurring": { "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed" }, "active": true, "billing_scheme": "per_unit", "created": 1589319695, "livemode": false, "lookup_key": null, "metadata": {}, "nickname": null, "unit_amount": 1500, "unit_amount_decimal": "1500", "tiers": null, "tiers_mode": null, "transform_quantity": null } ``` 複数の請求期間を提供している場合は、決済を使用して、請求期間の長い顧客を [アップセル](https://docs.stripe.com/payments/checkout/upsells.md) し、より多くの収入を前払いで徴収します。 その他の料金体系モデルについては、[請求書例](https://docs.stripe.com/products-prices/pricing-models.md) を参照してください。 ## Checkout Session を作成 [クライアントおよびサーバー] サーバー側のエンドポイントを呼び出して Checkout Session を作成するチェックアウトボタンを Web サイトに追加します。 ```html Checkout
``` アプリケーションのバックエンドで、フロントエンドが呼び出す[セッションを作成](https://docs.stripe.com/api/checkout/sessions/create.md)するエンドポイントを定義します。以下の値が必要です。 - 顧客が登録するサブスクリプションの価格 ID (フロントエンドがこの値を渡します) - `success_url`。お客様の Web サイト上にあり、決済完了後に顧客が戻されるページです オプションとして以下を実行できます。 - このコールでサブスクリプションへの [請求サイクルアンカー](https://docs.stripe.com/billing/subscriptions/billing-cycle.md) を設定します。 - [カスタムテキスト](https://docs.stripe.com/payments/checkout/custom-components.md?platform=web&payment-ui=stripe-hosted#customize-text)を使用して、サブスクリプションとキャンセルの規約、および顧客がサブスクリプションを更新またはキャンセルできる場所へのリンクを含めます。サブスクリプション登録者には[メールリマインダーと通知](https://docs.stripe.com/invoicing/send-email.md#email-configuration)を設定することをお勧めします。 [ステップ 2](https://docs.stripe.com/billing/subscriptions/build-subscriptions.md#create-pricing-model) で 1 回限りの価格を作成した場合は、その価格 ID も渡します。Checkout Session を作成したら、レスポンスで返された [URL](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-url) に顧客をリダイレクトします。 [請求モード](https://docs.stripe.com/billing/subscriptions/billing-mode.md)のタイプを `flexible` に設定することで、Checkout Session の作成時により正確で予測可能なサブスクリプション動作を有効にできる。Stripe API バージョン [2025-06-30.basil](https://docs.stripe.com/upgrades.md) 以降を使用する必要がある。 > [lookup_keys](https://docs.stripe.com/products-prices/manage-prices.md#lookup-keys) を使用して、価格 ID ではなく価格を取得できます。例については、[サンプルアプリケーション](https://github.com/stripe-samples/subscription-use-cases/tree/main/fixed-price-subscriptions) を参照してください。 #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') # The price ID passed from the front end. # price_id = params['priceId'] price_id = '{{PRICE_ID}}' session = client.v1.checkout.sessions.create({ success_url: 'https://example.com/success.html?session_id={CHECKOUT_SESSION_ID}', mode: 'subscription', line_items: [{ # For usage-based billing, don't pass quantity quantity: 1, price: price_id }], subscription_data: { billing_mode: { type: 'flexible' } } }) # Redirect to the URL returned on the session # redirect session.url, 303 ``` この例では、セッション ID を追加して `success_url` をカスタマイズします。[成功ページのカスタマイズ](https://docs.stripe.com/payments/checkout/custom-success-page.md) の詳細を参照してください。 [ダッシュボード](https://dashboard.stripe.com/settings/payment_methods) で、顧客から受け付ける支払い方法を有効にします。決済は [複数の支払い方法](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#product-support) に対応しています。 ## サブスクリプションを提供して監視する [サーバー] サブスクリプション登録完了後、顧客は成功ページ `success_url` に戻り、同時に、`checkout.session.completed` *Webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) が送信されます。`checkout.session.completed` イベントを受信したら、[エンタイトルメント](https://docs.stripe.com/billing/entitlements.md) 機能を使ってサブスクリプションサービスを有効化してください。`invoice.paid`イベントの受信に合わせて継続的に(月次請求の場合は毎月)サービスを提供し続けます。`invoice.payment_failed` イベントを受信した場合は、顧客に決済失敗を通知し、カスタマーポータルで決済手段を更新してもらうよう案内してください。 システムロジックの次のステップを決定するには、イベントタイプを確認し、`invoice.paid` などの各 [イベントオブジェクト](https://docs.stripe.com/api/events/object.md)のペイロードを解析します。`Subscription`と`Customer`または`Account`オブジェクトの ID をデータベースに保存して確認に使用します。 テスト目的では、[ワークベンチ](https://docs.stripe.com/workbench.md) の [イベントタブ](https://dashboard.stripe.com/workbench/events) でイベントを監視できます。本番環境では、Webhook エンドポイントを設定し、適切なイベントタイプに登録します。`STRIPE_WEBHOOK_SECRET` キーが不明な場合は、ワークベンチの [Webhook タブ](https://dashboard.stripe.com/workbench/webhooks) の送信先の詳細ビューに移動して表示します。 #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/webhook' do webhook_secret = '{{STRIPE_WEBHOOK_SECRET}}' # 例: whsec_c7681Dm payload = request.body.read if !webhook_secret.empty? # Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured. sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil begin event = Stripe::Webhook.construct_event( payload, sig_header, webhook_secret ) rescue JSON::ParserError => e # Invalid payload status 400 return rescue Stripe::SignatureVerificationError => e # Invalid signature puts '⚠️ Webhook signature verification failed.' status 400 return end else data = JSON.parse(payload, symbolize_names: true) event = Stripe::Event.construct_from(data) end # Get the type of webhook event sent event_type = event['type'] data = event['data'] data_object = data['object'] case event_type when 'checkout.session.completed' # Payment is successful and the subscription is created. # Provision the subscription and save the customer ID to your database. when 'invoice.paid' # Continue to provision the subscription as payments continue to be made. # Store the status in your database and check when a customer accesses your service. # This approach helps you avoid hitting rate limits. when 'invoice.payment_failed' # The payment failed or the customer doesn't have a valid payment method. # The subscription becomes past_due. Notify your customer and send them to the # customer portal to update their payment information. else puts "Unhandled event type: \#{event.type}" end status 200 end ``` モニタリングが必要な最小限のイベントタイプ: | イベント名 | 説明 | | ---------------------------- | ------------------------------------------------------ | | `checkout.session.completed` | 顧客が Checkout Session を正常に完了したときに送信され、新しい購入についてお知らせします。 | | `invoice.paid` | 決済が成功すると請求期間ごとに送信されます。 | | `invoice.payment_failed` | 請求期間ごとに、顧客の決済手段に問題がある場合に送信されます。 | 監視するイベントの詳細については、[サブスクリプション Webhook](https://docs.stripe.com/billing/subscriptions/webhooks.md) を参照してください。 ## カスタマーポータルを設定する [ダッシュボード] [カスタマーポータル](https://docs.stripe.com/customer-management.md) を使用すると、顧客は既存のサブスクリプションと請求書を直接管理できます。 [ダッシュボード](https://dashboard.stripe.com/test/settings/billing/portal) を使用してポータルを設定します。少なくとも、顧客が決済手段を更新できるように [ポータルを設定](https://docs.stripe.com/customer-management.md) してください。 ## ポータルセッションを作成する [サーバー] フロントエンドから呼び出せる[カスタマーポータルセッションを作成](https://docs.stripe.com/api/customer_portal/sessions/create.md)するエンドポイントを定義します。`checkout.session.completed` Webhook の処理中に保存した Checkout Session によって作成された顧客の ID を含めます。ポータルのデフォルトのリダイレクトリンクは、ダッシュボードで設定することもできます。 サイトのページを示す `return_url` 値をオプションで渡して、サブスクリプションの管理を終えた顧客をこのページにリダイレクトします。 #### Accounts v2 #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') # This is the URL that users are redirected to after they're done # managing their billing. return_url = '{{DOMAIN_URL}}' # 例: http://example.com customer_account_id = '{{CUSTOMER_ACCOUNT_ID}}' # 例: acct_GBV60HKsE0mb5v session = Stripe::BillingPortal::Session.create({ customer_account: customer_account_id, return_url: return_url, }) # Redirect to the URL for the session # redirect session.url, 303 ``` #### Customers v1 #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') # This is the URL that users are redirected to after they're done # managing their billing. return_url = '{{DOMAIN_URL}}' # 例: http://example.com customer_id = '{{CUSTOMER_ID}}' # 例: cus_GBV60HKsE0mb5v session = client.v1.billing_portal.sessions.create({ customer: customer_id, return_url: return_url, }) # Redirect to the URL for the session # redirect session.url, 303 ``` ## 顧客をカスタマーポータルに移動させる [クライアント] フロントエンドで、カスタマーポータルへのリンクを提供するボタンを `success_url` のページに追加します。 ```html Manage Billing
``` 顧客がカスタマーポータルから退出すると、`return_url` に指定された Web サイトに戻ります。引き続き [イベントを監視](https://docs.stripe.com/billing/subscriptions/webhooks.md) することで、顧客のサブスクリプションのステータスを追跡することができます。 サブスクリプションのキャンセルなどのアクションを許可するようにカスタマーポータルを設定する場合は、[追加イベントを監視](https://docs.stripe.com/customer-management/integrate-customer-portal.md#webhooks) します。 ## 導入をテストする ### 支払い方法をテストする 次の表を使用して、さまざまな支払い方法とシナリオをテストします。 | 決済手段 | シナリオ | テスト方法 | | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | BECS ダイレクトデビット | 顧客が BECS ダイレクトデビットによる支払いに成功します。 | アカウント番号`900123456`と BSB`000000`を使用して、フォームに入力します。確定された PaymentIntent のステータスは、まず`processing`に移行し、3 分後に`succeeded`ステータスに移行します。 | | BECS ダイレクトデビット | 顧客の支払いが `account_closed` エラーコードで失敗します。 | アカウント番号 `111111113`と BSB `000000`を使用して、フォームに入力します。 | | クレジットカード | カード支払いは成功し、認証は必要とされません。 | クレジットカード番号 `4242 4242 4242 4242` と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 | | クレジットカード | カード決済で*認証* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase)が要求されます。 | クレジットカード番号 `4000 0025 0000 3155` と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 | | クレジットカード | カードが `insufficient_funds` などの拒否コードで支払い拒否されます。 | クレジットカード番号 `4000 0000 0000 9995` と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 | | SEPA ダイレクトデビット | 顧客が SEPA ダイレクトデビットによる支払いに成功します。 | 口座番号 `AT321904300235473204` を使用して、フォームに入力します。確定された PaymentIntent のステータスはまず、processing に移行し、3 分後に succeeded ステータスに移行します。 | | SEPA ダイレクトデビット | 顧客の PaymentIntent ステータスが `processing` から `requires_payment_method` に移行します。 | 口座番号 `AT861904300235473202` を使用して、フォームに入力します。 | ### イベントを監視する Webhook を設定して、アップグレードやキャンセルなどのサブスクリプション変更イベントをリッスンします。[サブスクリプション Webhook イベント](https://docs.stripe.com/billing/subscriptions/webhooks.md) は、[ダッシュボード](https://dashboard.stripe.com/test/events) または [Stripe CLI](https://docs.stripe.com/webhooks.md#test-webhook) で表示できます。 [Billing 導入テスト](https://docs.stripe.com/billing/testing.md) の詳細を参照してください。 ## See also - [顧客に無料トライアル期間を提供する](https://docs.stripe.com/billing/subscriptions/trials.md) - [割引の適用](https://docs.stripe.com/billing/subscriptions/coupons.md#using-coupons-in-checkout) - [比例配分](https://docs.stripe.com/billing/subscriptions/prorations.md) の管理 - [エンタイトルメントを導入して商品の機能へのアクセスを管理する](https://docs.stripe.com/billing/entitlements.md) # 完全埋め込みページ > This is a 完全埋め込みページ for when payment-ui is embedded-page. View the full page at https://docs.stripe.com/payments/checkout/build-subscriptions?payment-ui=embedded-page. # 完全埋め込みページ > This is a 完全埋め込みページ for when platform is web and ui is embedded-page. View the full page at https://docs.stripe.com/payments/checkout/build-subscriptions?platform=web&ui=embedded-page. #### 導入作業 Complexity: 2/5 #### UI のカスタマイズ 外観をカスタマイズします。 #### 実装タイプ 構築済みのオンラインフォームを使用して支払いを回収し、*サブスクリプション* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis) を管理します。 ## サーバーを設定する ### Stripe をセットアップする 任意の Stripe クライアントをインストールします。 #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ### 商品と価格を作成する [継続的な料金体系モデル](https://docs.stripe.com/products-prices/pricing-models.md)は、お客様が販売する商品またはサービス、そのコスト、決済で受け付ける通貨、請求対象となるサービス提供期間 (サブスクリプションの場合) を表します。価格モデルを構築するには、お客様が販売する「[商品](https://docs.stripe.com/api/products.md)」と、それをいくらで、どのくらいの頻度で請求するかを示す「[価格](https://docs.stripe.com/api/prices.md)」を用います。 この例では、「基本」と「プレミアム」という 2 つのサービスレベルオプションがある固定価格のサービスを使用しています。サービスレベルオプションごとに、1 つの商品と 1 つの継続価格を作成する必要があります (セットアップ料金のような 1 回限りの支払いを追加する場合は、1 回限りの価格で 3 つ目の商品を作成します)。 各商品が月ごとに請求されます。基本商品の価格は 5 USD で、プレミアム商品の価格は 15 USD です。3 段階構成の例については、[定額料金](https://docs.stripe.com/subscriptions/pricing-models/flat-rate-pricing.md)ガイドをご覧ください。 #### ダッシュボード [商品を追加](https://dashboard.stripe.com/test/products/create)ページに移動し、2 つの商品を作成します。商品ごとに 1 つの価格を追加し、それぞれに毎月の継続請求期間を設定します。 - プレミアム商品: 追加機能を備えたプレミアムサービス - 価格:定額 | 15 USD - 基本商品: 最低限の機能を備えた基本サービス - 価格:定額 | 5 USD 価格を作成したら、価格 ID を記録しておき、他のステップで使用できるようにします。価格 ID は、`price_G0FvDp6vZvdwRZ` のように表示されます。 準備が完了したら、ページ右上の**本番環境にコピー**ボタンを使用して、[サンドボックスから本番環境に](https://docs.stripe.com/keys.md#test-live-modes)商品を複製します。 #### API API を使用して[商品](https://docs.stripe.com/api/products.md)と[価格](https://docs.stripe.com/api/prices.md)を作成できます。 プレミアム製品を作成します。 ```curl curl https://api.stripe.com/v1/products \ -u "<>:" \ --data-urlencode "name=Billing Guide: Premium Service" \ -d "description=Premium service with extra features" ``` ベーシック製品を作成します。 ```curl curl https://api.stripe.com/v1/products \ -u "<>:" \ --data-urlencode "name=Billing Guide: Basic Service" \ -d "description=Basic service with minimum features" ``` 各商品の商品 ID を記録しておきます。これは次のように表示されます。 ```json { "id": "prod_H94k5odtwJXMtQ", "object": "product", "active": true, "attributes": [ ], "created": 1587577341, "description": "Premium service with extra features", "images": [ ], "livemode": false, "metadata": { }, "name": "Billing Guide: Premium Service", "statement_descriptor": null, "type": "service", "unit_label": null, "updated": 1587577341 } ``` 商品 ID を使用して各商品の価格を作成します。[unit_amount](https://docs.stripe.com/api/prices/object.md#price_object-unit_amount) の単位はセントであるため、たとえば `1500` = 15 USD です。 プレミアム価格を作成します。 ```curl curl https://api.stripe.com/v1/prices \ -u "<>:" \ -d product={{PREMIUM_PRODUCT_ID}} \ -d unit_amount=1500 \ -d currency=usd \ -d "recurring[interval]=month" ``` 基本価格を作成します。 ```curl curl https://api.stripe.com/v1/prices \ -u "<>:" \ -d product={{BASIC_PRODUCT_ID}} \ -d unit_amount=500 \ -d currency=usd \ -d "recurring[interval]=month" ``` 各価格の価格 ID を記録しておき、後続のステップで使用できるようにします。これは次のように表示されます。 ```json { "id": "price_HGd7M3DV3IMXkC", "object": "price", "product": "prod_HGd6W1VUqqXGvr", "type": "recurring", "currency": "usd", "recurring": { "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed" }, "active": true, "billing_scheme": "per_unit", "created": 1589319695, "livemode": false, "lookup_key": null, "metadata": {}, "nickname": null, "unit_amount": 1500, "unit_amount_decimal": "1500", "tiers": null, "tiers_mode": null, "transform_quantity": null } ``` 複数の請求期間を提供している場合は、決済を使用して、請求期間の長い顧客を[アップセル](https://docs.stripe.com/payments/checkout/upsells.md)し、より多くの収入を前払いで徴収します。 その他の料金体系モデルについては、[請求書例](https://docs.stripe.com/products-prices/pricing-models.md) を参照してください。 ### Checkout Session を作成 *Checkout Session* (A Checkout Session represents your customer's session as they pay for one-time purchases or subscriptions through Checkout. After a successful payment, the Checkout Session contains a reference to the Customer, and either the successful PaymentIntent or an active Subscription) を作成するサーバー上にエンドポイントを追加します。 [Checkout Session](https://docs.stripe.com/api/checkout/sessions/create.md)を作成する際に、次のパラメーターを渡します。 - 埋め込み型決済画面を使用するには、[ui_mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-ui_mode) を `embedded_page` に設定します。 - 顧客の購入時にサブスクリプションを作成するには、[mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-mode) を`subscription`に設定します。 - 決済を完了または試行した際に顧客が戻るページを定義するには、[return_url](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-return_url) を指定します。URL に `{CHECKOUT_SESSION_ID}` のテンプレート変数を含めます。Checkout はこの変数を `CheckoutSession` ID に置き換えてから、顧客をリダイレクトします。ウェブサイトに戻り先ページを作成してホストします。 - サブスクリプションとキャンセルの規約、および顧客がサブスクリプションを更新またはキャンセルできるリンクを含めるには、必要に応じて[カスタムテキスト](https://docs.stripe.com/payments/checkout/custom-components.md?ui=embedded-page#customize-payment-method-reuse-agreement-and-subscription-terms)を使用します。サブスクリプション登録者向けに、[お知らせメールと通知](https://docs.stripe.com/invoicing/send-email.md#email-configuration)を設定することをおすすめします。 Checkout をマウントするには、レスポンスで返される Checkout Session の `client_secret` を使用します。 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d mode=subscription \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d ui_mode=embedded_page \ --data-urlencode "return_url=https://example.com/checkout/return?session_id={CHECKOUT_SESSION_ID}" ``` ## サブスクリプションページを構築する [クライアント] ### Checkout をマウントする #### HTML + JS #### Stripe.js を読み込む *PCI 準拠* (Any party involved in processing, transmitting, or storing credit card data must comply with the rules specified in the Payment Card Industry (PCI) Data Security Standards. PCI compliance is a shared responsibility and applies to both Stripe and your business) を維持するには、*Stripe.js* (Use Stripe.js’ APIs to tokenize customer information, collect sensitive card data, and accept payments with browser payment APIs) を使用して、支払い詳細がお客様のサーバーを経由せずに直接 Stripe に送られるようにします。Stripe.js を常に js.stripe.com から読み込むことにより、PCI 準拠が維持されます。このスクリプトをバンドルに含めたり、自分でホストしたりしないでください。 #### 決済フォームを定義する 顧客の情報を安全に収集するには、空のプレースホルダー `div` を作成します。Stripe はこの `div` に iframe を挿入します。 Checkout は [Stripe.js](https://docs.stripe.com/js.md) の一部として利用できます。HTML ファイルのヘッダーに Stripe.js スクリプトを追加してページに含めます。次に、マウンティングに使用する空の DOM ノード (コンテナー) を作成します。 ```html Accept a payment
``` #### Stripe.js を初期化する 公開可能な API キーで Stripe.js を初期化します。 #### Checkout Session の client secret を取得する サーバーに [Checkout Session の作成](https://docs.stripe.com/api/checkout/sessions/create.md) をリクエストする非同期の `fetchClientSecret` 関数を作成し、client secret を取得します。 #### Checkout を初期化する `fetchClientSecret` 関数を使用して Checkout を初期化し、決済フォームのプレースホルダーにマウントします。`
` 支払いフォームで。決済は iframe でレンダリングされ、HTTPS 接続経由で支払い情報が安全に Stripe に送信されます。 一部の支払い方法では、別のページにリダイレクトして支払いを確定する必要があるため、Checkout は別の iframe 内に配置しないでください。 ```javascript // Initialize Stripe.js const stripe = Stripe('<>'); initialize(); // Fetch Checkout Session and retrieve the client secret async function initialize() { const fetchClientSecret = async () => { const response = await fetch("/create-checkout-session", { method: "POST", }); const { clientSecret } = await response.json(); return clientSecret; }; // Initialize Checkout const checkout = await stripe.createEmbeddedCheckoutPage({ fetchClientSecret, }); // Mount Checkout checkout.mount('#checkout'); } ``` #### React #### Stripe を React アプリに追加する PCI への準拠性を保持するには、[React Stripe.js](https://docs.stripe.com/sdks/stripejs-react.md) をインストールして、支払い詳細がお客様のサーバーに届くことなく Stripe に直接送信されるようにします。 ```bash npm install --save @stripe/react-stripe-js @stripe/stripe-js ``` #### Stripe.js を読み込む Stripe ライブラリを設定するには、Stripe の公開可能な API キーを使用して `loadStripe()` を呼び出します。`EmbeddedCheckoutProvider` を作成します。返された `Promise` をプロバイダーに渡します。 #### Checkout Session の client secret を取得する サーバーに [Checkout Session の作成](https://docs.stripe.com/api/checkout/sessions/create.md) をリクエストする非同期の `fetchClientSecret` 関数を作成し、client secret を取得します。 #### Checkout を初期化する 子コンポーネントが組み込み型 Checkout コンシューマーを介して Stripe サービスにアクセスできるようにするには、`loadStripe` の結果として生成されたプロミスと `fetchClientSecret` 関数を `option` として組み込み型 Checkout プロバイダーに渡します。 ```jsx import * as React from 'react'; import {loadStripe} from '@stripe/stripe-js'; import { EmbeddedCheckoutProvider, EmbeddedCheckout } from '@stripe/react-stripe-js'; // Make sure to call `loadStripe` outside of a component's render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('pk_test_123', { }); const App = ({fetchClientSecret}) => { const options = {fetchClientSecret}; return ( ) } ``` ## 戻りページを表示する 顧客は決済を試行した後、お客様のサイトにホストされている戻り先ページにリダイレクトされます。戻り先ページは、Checkout Session の作成時に [return_url](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-return_url) パラメーターで指定した URL です。 > 決済の進行中、決済手段によっては、銀行認証ページなどの中間ページに顧客がリダイレクトされる場合があります。そのページでの操作を完了した顧客は、Stripe によって戻り先ページにリダイレクトされます。 #### エンドポイントを作成して Checkout Session を取得する エンドポイントを追加し、URL で Checkout Session の ID を指定して Checkout Session のステータスを取得します。 #### Checkout Session を取得する Checkout Session の詳細を使用するには、戻り先ページが読み込まれたらすぐに URL の Checkout Session ID を使用して、[Checkout Session のステータスを取得](https://docs.stripe.com/api/checkout/sessions/retrieve.md) するリクエストをサーバー上のエンドポイントに行います。 #### セッションを処理する セッションステータスに基づく結果の処理: - `complete`: 決済が成功しました。Checkout Session の情報を使用して成功ページを表示します。 - `open`: 決済が失敗またはキャンセルされました。顧客がやり直せるように Checkout を再度マウントします。 ```js // Retrieve a Checkout Session // Use the session ID initialize(); async function initialize() { const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); const sessionId = urlParams.get('session_id'); const response = await fetch(`/session-status?session_id=${sessionId}`); const session = await response.json(); // Handle the session according to its status if (session.status == 'open') { // Remount embedded Checkout window.location.replace('http://localhost:4242/checkout.html') } else if (session.status == 'complete') { document.getElementById('success').classList.remove('hidden'); document.getElementById('customer-email').textContent = session.customer_email; // Show success page // Optionally use session.payment_status or session.customer_email // to customize the success page } } ``` #### Accounts v2 ```javascript // Add an endpoint to fetch the Checkout Session status app.get('/session_status', async (req, res) => { const session = await stripe.checkout.sessions.retrieve(req.query.session_id); const customer_account = await stripe.v2.core.accounts(session.customer_account); res.send({ status: session.status, payment_status: session.payment_status, customer_email: customer_account.contact_email }); }); ``` #### Customers v1 ```javascript // Add an endpoint to fetch the Checkout Session status app.get('/session_status', async (req, res) => { const session = await stripe.checkout.sessions.retrieve(req.query.session_id); const customer = await stripe.customers.retrieve(session.customer); res.send({ status: session.status, payment_status: session.payment_status, customer_email: customer.email }); }); ``` ## Optional: カスタマーポータルを設定する *カスタマーポータル* (The customer portal is a secure, Stripe-hosted page that lets your customers manage their subscriptions and billing details) を設定すると、顧客が各自の既存のサブスクリプションと請求書を直接管理できるようになります。 ポータルはダッシュボードで設定できます。解約を減らすには、決済が失敗した場合に、顧客が決済手段を各自で更新できるようにポータルを設定してください。 顧客がサブスクリプションを各自で管理できるよう、カスタマーポータルにリダイレクトするボタンをウェブサイト上の見つけやすい位置に追加します。このボタンをクリックすると、顧客は Stripe がホストするカスタマーポータルページにリダイレクトされます。 [カスタマーポータル](https://docs.stripe.com/customer-management.md) とその他の顧客管理オプションの詳細をご確認ください。 #### ポータルセッションを作成する カスタマーポータルを追加するには、フロントエンドから呼び出せる[カスタマーポータルセッションを作成する](https://docs.stripe.com/api/customer_portal/sessions/create.md)エンドポイントを定義します。`checkout.session.completed` webhook の処理中に保存した Checkout Session によって作成された顧客の ID を含めます。ポータルのデフォルトのリダイレクトリンクは、Dashboard で設定することもできます。 サイトのページを示す `return_url` 値をオプションで渡して、サブスクリプションの管理を終えた顧客をこのページにリダイレクトします。 #### Accounts v2 #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') # This is the URL that users are redirected to after they're done # managing their billing. return_url = '{{DOMAIN_URL}}' # 例: http://example.com customer_account_id = '{{CUSTOMER_ACCOUNT_ID}}' # 例: acct_GBV60HKsE0mb5v session = Stripe::BillingPortal::Session.create({ customer_account: customer_account_id, return_url: return_url, }) # Redirect to the URL for the session # redirect session.url, 303 ``` #### Customers v1 #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') # This is the URL that users are redirected to after they're done # managing their billing. return_url = '{{DOMAIN_URL}}' # 例: http://example.com customer_id = '{{CUSTOMER_ID}}' # 例: cus_GBV60HKsE0mb5v session = client.v1.billing_portal.sessions.create({ customer: customer_id, return_url: return_url, }) # Redirect to the URL for the session # redirect session.url, 303 ``` #### 顧客をカスタマーポータルに移動させる フロントエンドで、カスタマーポータルへのリンクを提供するボタンを `success_url` のページに追加します。 ```html Manage Billing
``` 顧客がカスタマーポータルから退出すると、`return_url` に指定された Web サイトに戻ります。引き続き [イベントを監視](https://docs.stripe.com/billing/subscriptions/webhooks.md) することで、顧客のサブスクリプションのステータスを追跡することができます。 サブスクリプションのキャンセルなどのアクションを許可するようにカスタマーポータルを設定する場合は、必ず[追加イベント](https://docs.stripe.com/customer-management/integrate-customer-portal.md#webhooks) を監視してください。 ## アクセスを提供 サブスクリプションが有効になったら、顧客にサービスへのアクセスを許可します。これを行うには、`customer.subscription.created`、`customer.subscription.updated`、`customer.subscription.deleted` の各イベントを監視します (顧客設定の`Account`を使用している場合も同様です)。これらのイベントは、サブスクリプションが有効か、期限超過か、キャンセルされたかを示す `status` フィールドを含む `Subscription`オブジェクトを渡します。ステータスの一覧については、[サブスクリプションライフサイクル](https://docs.stripe.com/billing/subscriptions/overview.md#subscription-lifecycle)を参照してください。製品の機能へのアクセスを管理するには、[エンタイトルメントの導入](https://docs.stripe.com/billing/entitlements.md)を参照してください。 Webhook ハンドラーで、以下を実行します。 1. サブスクリプションのステータスを確認します。`active` の場合、顧客は製品の決済を完了しています。 1. 顧客が登録している商品を確認し、サービスへのアクセス権を付与します。価格ではなく商品を確認することにより、料金体系や請求期間の変更が必要になった場合に、柔軟に対応できます。 1. `product.id`、`subscription.id`、`subscription.status` を、すでに保存した `customer_account.id` または `customer.id` とともにデータベースに保存します。アプリケーションで顧客に対して有効にする機能を判断する際は、このレコードを確認してください。 サブスクリプションのステータスは、アプリケーションから直接 Stripe に呼び出しを行わなくても、そのライフサイクルのどの時点でも変更される可能性があります。たとえば、クレジットカードの有効期限切れで更新ができなかった場合、サブスクリプションは期限超過のステータスになります。または、[カスタマーポータル](https://docs.stripe.com/customer-management.md)を実装している場合、顧客は、アプリケーションに直接アクセスせずにサブスクリプションをキャンセルする可能性があります。ハンドラーを正しく実装することで、アプリケーションのステータスを Stripe と同期した状態に維持できます。 ## 導入をテストする ### 支払い方法をテストする 次の表を使用して、さまざまな支払い方法とシナリオをテストします。 | 決済手段 | シナリオ | テスト方法 | | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | BECS ダイレクトデビット | 顧客が BECS ダイレクトデビットによる支払いに成功します。 | アカウント番号`900123456`と BSB`000000`を使用して、フォームに入力します。確定された PaymentIntent のステータスは、まず`processing`に移行し、3 分後に`succeeded`ステータスに移行します。 | | BECS ダイレクトデビット | 顧客の支払いが `account_closed` エラーコードで失敗します。 | アカウント番号 `111111113`と BSB `000000`を使用して、フォームに入力します。 | | クレジットカード | カード支払いは成功し、認証は必要とされません。 | クレジットカード番号 `4242 4242 4242 4242` と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 | | クレジットカード | カード決済で*認証* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase)が要求されます。 | クレジットカード番号 `4000 0025 0000 3155` と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 | | クレジットカード | カードが `insufficient_funds` などの拒否コードで支払い拒否されます。 | クレジットカード番号 `4000 0000 0000 9995` と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 | | SEPA ダイレクトデビット | 顧客が SEPA ダイレクトデビットによる支払いに成功します。 | 口座番号 `AT321904300235473204` を使用して、フォームに入力します。確定された PaymentIntent のステータスはまず、processing に移行し、3 分後に succeeded ステータスに移行します。 | | SEPA ダイレクトデビット | 顧客の PaymentIntent ステータスが `processing` から `requires_payment_method` に移行します。 | 口座番号 `AT861904300235473202` を使用して、フォームに入力します。 | ### イベントを監視する Webhook を設定して、アップグレードやキャンセルなどのサブスクリプション変更イベントをリッスンします。[サブスクリプション Webhook イベント](https://docs.stripe.com/billing/subscriptions/webhooks.md) は、[ダッシュボード](https://dashboard.stripe.com/test/events)または [Stripe CLI](https://docs.stripe.com/webhooks.md#test-webhook) で表示できます。 [Billing 導入テスト](https://docs.stripe.com/billing/testing.md) の詳細を参照してください。