# Elements を使用したサブスクリプション導入の構築 Elements で継続課金を受け付けられるようにサブスクリプションを作成・管理します。 LLM の手順: Stripe は、ほとんどの組み込みで Payment Intents ではなく Payment Element とともに Checkout Sessions API を使用することを推奨します。Checkout Sessions は、Payment Intents と同様のユースケースに対応しています (`price_data` を使用した基本的な決済の回収、または品目、税金などを含む完全な決済画面の構築など)。Adaptive Pricing などの一部の機能は、Checkout Sessions でのみ利用できます。ユーザーが明示的に要求しない限り、Payment Intents API は使用しないでください。必要となるコード量が大幅に多くなるためです。Checkout Sessions API と Elements の詳細については次を参照してください。https://docs.stripe.com/payments/quickstart-checkout-sessions. Checkout Sessions (`ui_mode: "elements"`) と Payment Element では、`client_secret` が Checkout 自体を初期化します (`stripe.initCheckoutElementsSdk`、または React で CheckoutElementsProvider を使用)。そのうえで、クライアント側での決済の確定方法が異なります。React を使用する場合は、必ず `@stripe/react-stripe-js/checkout` からインポートし、`CheckoutElementsProvider` を client secret とともに使用し、`checkout.confirm` を使用して決済を確定します。HTML を使用する場合は、必ず `checkout = stripe.initCheckoutElementsSdk({clientSecret: promise}); checkout.createPaymentElement(); paymentElement = checkout.createPaymentElement(); paymentElement.mount("#payment-element");` を使用し、`loadActionsResult = await checkout.loadActions(); actions = loadActionsResult.actions; error = await actions.confirm();` で決済を確定します。 # Checkout Sessions API > This is a Checkout Sessions API for when platform is web and ui is embedded-components. View the full page at https://docs.stripe.com/payments/advanced/build-subscriptions?platform=web&ui=embedded-components. #### 組み込み作業 Complexity: 3/5 #### 組み込みのタイプ カスタムの決済フローに UI コンポーネントを統合する #### UI のカスタマイズ [Appearance API](https://docs.stripe.com/elements/appearance-api.md) を使用した CSS レベルのカスタマイズ [お試しください](https://checkout.stripe.dev/) [Stripe Elements](https://docs.stripe.com/payments/elements.md) と [Checkout Sessions API](https://docs.stripe.com/api/checkout/sessions.md) を使用してカスタム決済フォームを構築し、固定料金の *Subscriptions* を販売します。この連携を [Stripe の他の連携タイプと比較](https://docs.stripe.com/payments/online-payments.md#compare-features-and-availability)してください。 Checkout Sessions API は、税額計算、割引、配送、通貨換算などの組み込みサポートを提供し、記述が必要なカスタムコードの量を減らします。これはほとんどの連携で推奨されるアプローチです。PaymentIntents ではなく Checkout Sessions を使用すべきケースについて、詳しくは[こちら](https://docs.stripe.com/payments/checkout-sessions-and-payment-intents-comparison.md)をご覧ください。 カスタム決済フォームを構築したくない場合は、ホスト型の Checkout に連携できます。このエンドツーエンドの導入ガイドをより実践的に解説したものとして、Billing の[クイックスタート](https://docs.stripe.com/billing/quickstart.md)をご覧ください。 導入をコーディングする準備ができていなくても、基本的なサブスクリプションを [Dashboard から手動](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) 方法を確認してください。 ## 作成する内容 このガイドでは以下の方法について説明します。 - 商品カタログを構築して、ビジネスをモデル化します。 - 顧客を作成する登録プロセスを構築します。 - サブスクリプションを作成して、決済情報を収集します。 - 決済とサブスクリプションのステータスをテストして、モニタリングします。 - 顧客がプランを変更またはサブスクリプションをキャンセルできるようにします。 ### API オブジェクトの定義 | リソース | 定義 | | ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [顧客として設定されたアカウント](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) | サブスクリプションを購入する Accounts v2 API の顧客を表します。`Account` オブジェクトを顧客として設定し、それをサブスクリプションに関連付けて、継続課金の作成と追跡、サブスクリプション登録している商品の管理を行います。詳細については、[Use Accounts as customers ガイド](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md)を参照してください。 | | [Customer (顧客)](https://docs.stripe.com/api/customers.md) | サブスクリプションを購入する Customers API の顧客を表します。サブスクリプションに関連付けられた `Customer` オブジェクトを使用して、継続課金の作成と追跡、登録している商品の管理を行います。 | | [Entitlement (エンタイトルメント)](https://docs.stripe.com/api/entitlements/active-entitlement.md) | 顧客が登録したサービス商品に含まれる機能への顧客のアクセスを表します。顧客の商品の継続購入のサブスクリプションを作成すると、その商品に関連付けられた機能ごとに、有効な権利が自動的に作成されます。顧客がサービスにアクセスするときに、その有効な資格を使用して、サブスクリプションに含まれる機能を有効にします。 | | [Feature (機能)](https://docs.stripe.com/api/entitlements/feature.md) | 顧客がサービス商品に登録すると利用できる機能や機能を表します。ProductFeatures を作成することで、商品に機能を含めることができます。 | | [Invoice (請求書)](https://docs.stripe.com/api/invoices.md) | 顧客が支払うべき金額の明細書であり、下書きから支払い済み、またはその他の方法で確定された支払いステータスを追跡します。サブスクリプションでは請求書が自動的に生成されます。 | | [PaymentIntent](https://docs.stripe.com/api/payment_intents.md) | 動的な支払いフローを構築する方法です。Payment Intent は、顧客の決済フローのライフサイクルを追跡し、規制で必須とされる同意書、Radar のカスタムの不正利用ルール、またはリダイレクトベースの支払い方法によって要求されたときに、追加の認証ステップを開始します。Payment Intent は、請求書によって自動的に作成されます。 | | [PaymentMethod](https://docs.stripe.com/api/payment_methods.md) | 顧客が商品の支払いに使用する決済手段。たとえば、顧客が設定した `Account` または `Customer` オブジェクトにクレジットカードを保存して、その顧客の継続課金に使用することができます。通常、Payment Intents API または Setup Intents API とともに使用されます。 | | [Price (価格)](https://docs.stripe.com/api/prices.md) | 商品の単価、通貨、請求期間を定義します。 | | [Product (商品)](https://docs.stripe.com/api/products.md) | お客様のビジネスが販売する商品またはサービス。サービス商品には 1 つ以上の機能を含めることができます。 | | [ProductFeature](https://docs.stripe.com/api/product-feature.md) | 1 つの商品に 1 つの機能が含まれることを表します。各商品は、含まれる各機能の ProductFeature に関連付けられ、各機能は、それを含む各商品の ProductFeature に関連付けられます。 | | [Subscription (サブスクリプション)](https://docs.stripe.com/api/subscriptions.md) | 顧客の商品の継続的な購入を表します。サブスクリプションを使用して、支払いを回収し、商品の繰り返し提供や継続的なアクセスを提供します。 | 製品、機能、利用権がどのように連携するかの例をご紹介します。例えば、基本機能を提供する標準プランと、拡張機能を追加した上位プランの 2 つのプランを持つ定期サービスを設定するとします。 1. `basic_features` と `extended_features` の 2 つの機能を作成します。 1. `standard_product` と `advanced_product` の 2 つの商品を作成します。 1. 標準商品の場合、`basic_features` を `standard_product` に関連付ける ProductFeature を 1 つ作成します。 1. 高度な商品の場合、2 つの ProductFeatures を作成します。1 つは `basic_features` を `advanced_product` に関連付け、もう 1 つは `extended_features` を `advanced_product` に関連付けます。 顧客の `first_customer` は、標準商品に登録します。サブスクリプションを作成すると、Stripe は、`first_customer` を `basic_features` に関連付けるエンタイトルメントを自動的に作成します。 別の顧客no `second_customer` は高度な商品に登録します。 サブスクリプションを作成すると、Stripe は自動的に 2 つのエンタイトルメントを作成します。1 つは `second_customer` を `basic_features` に関連付け、もう 1 つは `second_customer` を `extended_features` に関連付けます。 [有効なエンタイトルメントを取得するか、有効なエンタイトルメントのサマリーイベントをリッスンする](https://docs.stripe.com/billing/entitlements.md#entitlements)ことで、顧客に提供する機能を決定できます。顧客のサブスクリプション、商品、機能を取得する必要はありません。 ## 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 のテストを提供します。これを実行すると Stripe への API コールを実行できます。このガイドの後続セクションでは、CLI を使った料金体系モデルの設定方法を紹介します。 その他のインストールオプションについては、[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 } ``` ## 顧客の作成 [クライアントおよびサーバー] Stripe では、サブスクリプションごとに顧客が必要です。申し込みのフロントエンドで、ユーザーから必要な情報を収集し、バックエンドに渡します。 住所の詳細を収集する必要がある場合は、Address Element を使用することで顧客の配送先住所または請求先住所を収集できます。Address Element の詳細については、[Address Element](https://docs.stripe.com/elements/address-element.md) ページをご覧ください。 ```html
``` ```javascript 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()); ``` サーバーで、顧客を表すオブジェクトを作成します。これは、顧客が設定した `Account` オブジェクトまたは `Customer` オブジェクトのいずれかです。Checkout Session で使用するオブジェクトの ID を保存します。 > #### Accounts v2 API を使用した顧客の表現 > > Accounts v2 API では、Connect ユーザーには一般提供され、その他の Stripe ユーザーには公開プレビューで提供されます。Accounts v2 プレビューの一部である場合は、コードで[プレビューバージョン](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning)を指定する必要があります。 > > Accounts v2 プレビューへのアクセスをリクエストするには、 > > ほとんどのユースケースでは、[Customer](https://docs.stripe.com/api/customers.md) オブジェクトを使用するのではなく、[顧客を顧客設定済みの Account オブジェクトとしてモデル化する](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md)ことをお勧めします。 #### Accounts v2 ```curl curl -X POST https://api.stripe.com/v2/core/accounts \ -H "Authorization: Bearer <>" \ -H "Stripe-Version: 2026-04-22.preview" \ --json '{ "contact_email": "jenny.rosen@example.com", "display_name": "Jenny Rosen", "identity": { "individual": { "given_name": "Jenny Rosen", "address": { "city": "San Francisco", "country": "US", "line1": "123 Main Street", "postal_code": "94605", "state": "CA" } } }, "configuration": { "customer": { "capabilities": { "automatic_indirect_tax": { "requested": true } }, "shipping": { "address": { "city": "San Francisco", "country": "US", "line1": "123 Main Street", "postal_code": "94605", "state": "CA" } } } }, "include": [ "configuration.customer", "identity" ] }' ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/customers \ -u "<>:" \ --data-urlencode "email=jenny.rosen@example.com" \ -d "name=Jenny Rosen" \ -d "shipping[address][city]=San Francisco" \ -d "shipping[address][country]=US" \ -d "shipping[address][line1]=123 Main Street" \ -d "shipping[address][postal_code]=9460" \ -d "shipping[address][state]=CA" \ -d "shipping[name]=Jenny Rosen" \ -d "address[city]=San Francisco" \ -d "address[country]=US" \ -d "address[line1]=123 Main Street" \ -d "address[postal_code]=9460" \ -d "address[state]=CA" ``` ## Checkout Session を作成 [サーバー] アプリケーションのバックエンドで、フロントエンドが呼び出す [セッションを作成](https://docs.stripe.com/api/checkout/sessions/create.md) するエンドポイントを定義します。顧客が登録するサブスクリプションの価格 ID が必要です。フロントエンドはこの値を渡します。 [ステップ 2](https://docs.stripe.com/billing/subscriptions/build-subscriptions.md#create-pricing-model) で 1 回限りの価格を作成した場合は、その価格 ID も渡します。Checkout Session を作成したら、レスポンスで [client secret](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-client_secret) をクライアントに必ず渡してください。 > [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) を参照してください。 #### Accounts v2 #### Ruby ```ruby require 'stripe' require 'sinatra' # This test secret API key is a placeholder. Don't include personal details in requests with this key. # To see your test secret API key embedded in code samples, sign in to your Stripe account. # You can also find your test secret API key at https://dashboard.stripe.com/test/apikeys. # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. Stripe.api_key = '<>' Stripe.api_version = '2026-04-22.dahlia' set :static, true set :port, 4242 YOUR_DOMAIN = 'http://localhost:3000' post '/create-checkout-session' do content_type 'application/json' session = Stripe::Checkout::Session.create({ui_mode: 'elements', # Provide the Account ID of the account you previously created customer_account: '{{CUSTOMER_ACCOUNT_ID}}', line_items: [{ # Provide the exact Price ID (for example, price_1234) of the product you want to sell price: '{{PRICE_ID}}', quantity: 1, }], mode: 'subscription', return_url: YOUR_DOMAIN + '/return?session_id={CHECKOUT_SESSION_ID}', }) { clientSecret: session.client_secret }.to_json end ``` #### Customers v1 #### Ruby ```ruby require 'stripe' require 'sinatra' # This test secret API key is a placeholder. Don't include personal details in requests with this key. # To see your test secret API key embedded in code samples, sign in to your Stripe account. # You can also find your test secret API key at https://dashboard.stripe.com/test/apikeys. # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>', stripe_version: '2026-04-22.dahlia') set :static, true set :port, 4242 YOUR_DOMAIN = 'http://localhost:3000' post '/create-checkout-session' do content_type 'application/json' session = client.v1.checkout.sessions.create({ui_mode: 'elements', # Provide the customer ID of the customer you previously created customer: '{{CUSTOMER_ID}}', line_items: [{ # Provide the exact Price ID (for example, price_1234) of the product you want to sell price: '{{PRICE_ID}}', quantity: 1, }], mode: 'subscription', return_url: YOUR_DOMAIN + '/return?session_id={CHECKOUT_SESSION_ID}', }) { clientSecret: session.client_secret }.to_json end ``` [ダッシュボード](https://dashboard.stripe.com/settings/payment_methods) で、顧客から受け付ける支払い方法を有効にします。決済は [複数の支払い方法](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#product-support) に対応しています。 ## Checkout を初期化する [クライアント] #### HTML + JS [initCheckoutElementsSdk](https://docs.stripe.com/js/custom_checkout/init) を呼び出し、`clientSecret` を渡します。 `initCheckoutElementsSdk` は、Checkout Session のデータとそれを更新するメソッドを含む [Checkout](https://docs.stripe.com/js/custom_checkout) オブジェクトを返します。 [actions.getSession()](https://docs.stripe.com/js/custom_checkout/session) から `total` と `lineItems` を読み取り、UI に表示します。これにより、コードの変更を最小限に抑えて新機能を有効にできます。たとえば、[手動通貨価格](https://docs.stripe.com/payments/custom/localize-prices/manual-currency-prices.md)を追加する場合、`total` を表示すれば UI を変更する必要はありません。 ```html
``` ```javascript const clientSecret = fetch('/create-checkout-session', {method: 'POST'}) .then((response) => response.json()) .then((json) => json.client_secret); const checkout = stripe.initCheckoutElementsSdk({clientSecret}); const loadActionsResult = await checkout.loadActions(); if (loadActionsResult.type === 'success') { const session = loadActionsResult.actions.getSession(); const checkoutContainer = document.getElementById('checkout-container'); checkoutContainer.append(JSON.stringify(session.lineItems, null, 2)); checkoutContainer.append(document.createElement('br')); checkoutContainer.append(`Total: ${session.total.total.amount}`); } ``` #### React [CheckoutElementsProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider) コンポーネントでアプリケーションをラップし、`clientSecret` と `stripe` インスタンスを渡します。 ```jsx import React from 'react'; import {CheckoutElementsProvider} from '@stripe/react-stripe-js/checkout'; import CheckoutForm from './CheckoutForm'; const clientSecret = fetch('/create-checkout-session', {method: 'POST'}) .then((response) => response.json()) .then((json) => json.client_secret); const App = () => { return ( ); }; export default App; ``` [Checkout](https://docs.stripe.com/js/custom_checkout) オブジェクトには、`useCheckoutElements()` フックを使用して決済フォームコンポーネントからアクセスできます。`Checkout` オブジェクトには、Checkout Session のデータとそれを更新するメソッドが含まれています。 `Checkout` オブジェクトから `lineItems` と `lineItems` を読み取り、UI に表示します。これにより、コードの変更を最小限に抑えて機能を有効にできます。たとえば、[手動通貨価格](https://docs.stripe.com/payments/custom/localize-prices/manual-currency-prices.md)を追加する場合、`total` を表示すると UI を変更する必要はありません。 ```jsx import React from 'react'; import {useCheckoutElements} from '@stripe/react-stripe-js/checkout'; const CheckoutForm = () => {const checkoutState = useCheckoutElements(); if (checkoutState.type === 'loading') { return (
Loading...
); } if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } return (
{JSON.stringify(checkoutState.checkout.lineItems, null, 2)} {/* A formatted total amount */} Total: {checkoutState.checkout.total.total.amount}
); }; ``` ## 決済情報を収集する [クライアント] [Payment Element](https://docs.stripe.com/payments/payment-element.md) を使用して、クライアントで支払い情報を収集します。Payment Element は、さまざまな決済手段で支払い情報の収集を簡略化する事前構築済みの UI コンポーネントです。 Payment Element には、HTTPS 接続を介して支払い情報を Stripe に安全に送信する iframe が含まれています。一部の支払い方法では、支払いを確定するために別のページにリダイレクトする必要があるため、Payment Element を別の iframe 内に配置しないでください。 iframe を使用して Apple Pay または Google Pay を受け付けたい場合は、iframe の [allow](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-allowpaymentrequest) 属性を `"payment *"` と等しく設定する必要があります。 構築済みのシステムを機能させるには、決済ページのアドレスの先頭を `http://` ではなく `https://` にする必要があります。HTTPS を使用しなくてもシステムをテストできますが、本番環境で決済を受け付ける準備が整ったら、必ず、HTTPS を[有効](https://docs.stripe.com/security/guide.md#tls)にしてください。 #### HTML + JS まず、コンテナーの DOM 要素を作成して、[Payment Element](https://docs.stripe.com/payments/payment-element.md) をマウントします。次に、[checkout.createPaymentElement](https://docs.stripe.com/js/custom_checkout/create_payment_element) を使用して `Payment Element` のインスタンスを作成し、[element.mount](https://docs.stripe.com/js/element/mount) を呼び出してマウントし、CSS セレクターまたはコンテナーの DOM 要素を指定します。 ```html
``` ```javascript const paymentElement = checkout.createPaymentElement(); paymentElement.mount('#payment-element'); ``` 対応しているオプションについては、[Stripe.js のドキュメント](https://docs.stripe.com/js/custom_checkout/create_payment_element#custom_checkout_create_payment_element-options) をご覧ください。 フロントエンドで Checkout を初期化するときに [elementsOptions.appearance](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-elementsOptions-appearance) を渡すことで、すべての Elements の[デザインをカスタマイズ](https://docs.stripe.com/payments/checkout/customization/appearance.md)できるようになります。 #### React [CheckoutElementsProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider) 内に [Payment Element](https://docs.stripe.com/payments/payment-element.md) コンポーネントをマウントします。 ```jsx import React from 'react';import {PaymentElement, useCheckoutElements} from '@stripe/react-stripe-js/checkout'; const CheckoutForm = () => { const checkoutState = useCheckoutElements(); if (checkoutState.type === 'loading') { return (
Loading...
); } if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } return (
{JSON.stringify(checkoutState.checkout.lineItems, null, 2)} {/* A formatted total amount */} Total: {checkoutState.checkout.total.total.amount} ); }; export default CheckoutForm; ``` 対応しているオプションについては、[Stripe.js のドキュメント](https://docs.stripe.com/js/custom_checkout/create_payment_element#custom_checkout_create_payment_element-options) をご覧ください。 [elementsOptions.appearance](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider#react_checkout_provider-options-elementsOptions-appearance) を [CheckoutElementsProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider) に渡すことで、すべての Elements の[外観をカスタマイズ](https://docs.stripe.com/payments/checkout/customization/appearance.md)できます。 ## 支払いを送信 [クライアント側] #### HTML + JS `Checkout` インスタンスから [確定](https://docs.stripe.com/js/custom_checkout/confirm) を呼び出す**支払う** ボタンをレンダリングして、決済を送信します。 ```html
``` ```js const checkout = stripe.initCheckoutElementsSdk({clientSecret}); checkout.on('change', (session) => { document.getElementById('pay-button').disabled = !session.canConfirm; }); const loadActionsResult = await checkout.loadActions(); if (loadActionsResult.type === 'success') { const {actions} = loadActionsResult; const button = document.getElementById('pay-button'); const errors = document.getElementById('confirm-errors'); button.addEventListener('click', () => { // Clear any validation errors errors.textContent = ''; actions.confirm().then((result) => { if (result.type === 'error') { errors.textContent = result.error.message; } }); }); } ``` #### React 決済を送信するために、[useCheckoutElements](https://docs.stripe.com/js/react_stripe_js/checkout/use_checkout_elements) から [confirm](https://docs.stripe.com/js/custom_checkout/confirm) を呼び出す **Pay** ボタンをレンダリングします。 ```jsx import React from 'react'; import {useCheckoutElements} from '@stripe/react-stripe-js/checkout'; const PayButton = () => { const checkoutState = useCheckoutElements(); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(null); if (checkoutState.type !== "success") { return null; } const handleClick = () => { setLoading(true);checkoutState.checkout.confirm().then((result) => { if (result.type === 'error') { setError(result.error) } setLoading(false); }) }; return (
{error &&
{error.message}
}
) }; export default PayButton; ``` ## Webhook をリッスンする [サーバー] 実装を完了するには、Stripe から送信される *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) を処理する必要があります。これらのイベントは、サブスクリプションの新しい請求書が生成されるなど、Stripe でステータスが変更されるたびに発生します。お客様のアプリケーション側では、webhook イベントを含む POST リクエストを受け取るための HTTP ハンドラーを設定して、イベントの署名を検証してください。 #### 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 # You can use webhooks to receive information about asynchronous payment events. # For more about our webhook events check out https://stripe.com/docs/webhooks. webhook_secret = ENV['STRIPE_WEBHOOK_SECRET'] 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 - used to check the status of PaymentIntents. event_type = event['type'] data = event['data'] data_object = data['object'] if event_type == 'invoice.paid' # Used to provision services after the trial has ended. # The status of the invoice will show up as paid. Store the status in your # database to reference when a user accesses your service to avoid hitting rate # limits. # puts data_object end if event_type == 'invoice.payment_failed' # If the payment fails or the customer doesn't have a valid payment method, # an invoice.payment_failed event is sent, the subscription becomes past_due. # Use this webhook to notify your user that their payment has # failed and to retrieve new card details. # puts data_object end if event_type == 'customer.subscription.deleted' # handle subscription canceled automatically based # upon your subscription settings. Or if the user cancels it. # puts data_object end content_type 'application/json' { status: 'success' }.to_json end ``` 開発中は、Stripe CLI を使用して [Webhook をモニタリングし、アプリケーション](https://docs.stripe.com/webhooks.md#test-webhook) に転送します。開発アプリの実行中に、新しい端末で以下を実行します。 #### curl ```bash stripe listen --forward-to localhost:4242/webhook ``` 本番環境では、ダッシュボードで Webhook エンドポイント URL を設定するか、[Webhook Endpoints API](https://docs.stripe.com/api/webhook_endpoints.md) を使用します。 いくつかのイベントをリッスンして、このガイドの残りのステップを完了する必要があります。サブスクリプション固有の Webhook の詳細については、[サブスクリプションのイベント](https://docs.stripe.com/billing/subscriptions/webhooks.md#events) を参照してください。 ## サービスへのアクセスを提供する [クライアントおよびサーバー] サブスクリプションが有効になりました。次は、ユーザーがサービスにアクセスできるようにします。これを行うには、`customer.subscription.created`、`customer.subscription.updated`、`customer.subscription.deleted` の各イベントを監視してください。これらのイベントは、サブスクリプションオブジェクトが渡され、そのオブジェクトには、サブスクリプションが有効か、期日経過か、キャンセルされたかを示す `status` フィールドが含まれます。ステータスの一覧については[サブスクリプションのライフサイクル](https://docs.stripe.com/billing/subscriptions/overview.md#subscription-lifecycle)を参照してください。 Webhook ハンドラーで、以下を実行します。 1. サブスクリプションのステータスを確認します。`active` の場合、ユーザーは商品の決済を実行しています。 1. 顧客が登録している商品を確認し、サービスへのアクセス権を付与します。価格ではなく商品を確認することにより、料金体系や請求期間の変更が必要になった場合に、柔軟に対応できます。 1. `product.id`、`subscription.id`、`subscription.status` を、すでに保存した `customer_account.id` または `customer.id` とともにデータベースに保存します。アプリケーションでユーザーに対して有効にする機能を判断する際は、このレコードを確認します。 サブスクリプションのステータスは、アプリケーションから直接 Stripe に呼び出しを行わなくても、そのライフサイクルのどの時点でも変更される可能性があります。たとえばクレジットカードの有効期限切れで更新ができなかった場合、サブスクリプションは past due のステータスになります。または、お客様が [customer portal](https://docs.stripe.com/customer-management.md) を実装している場合、顧客はお客様のアプリケーションに直接アクセスせずにサブスクリプションをキャンセルする可能性があります。ハンドラーを正しく実装することで、お客様のアプリケーションのステータスを Stripe と同期した状態に維持することができます。 ## サブスクリプションをキャンセルする [クライアントおよびサーバー] 顧客にサブスクリプションのキャンセルを許可するのは一般的です。この例では、アカウントの設定ページにキャンセルオプションを追加します。 ![サブスクリプションのキャンセルインターフェイスの例。](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-subscriptions-guide-account-settings.6559626ba4b434826a67abfea165e097.png) サブスクリプションのキャンセル機能が設定されたアカウント設定 ```javascript 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. }); } ``` バックエンド側で、フロントエンドが呼び出すためのエンドポイントを定義してください。 #### 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 '/cancel-subscription' do content_type 'application/json' data = JSON.parse request.body.read deleted_subscription = client.v1.subscriptions.cancel(data['subscriptionId']) deleted_subscription.to_json end ``` アプリケーションが `customer.subscription.deleted` イベントを受信します。 サブスクリプションがキャンセルされたら、以前保存していた Stripe のサブスクリプション ID をデータベースから削除し、サービスへのアクセスを制限します。 サブスクリプションをキャンセルすると、再度アクティブにすることはできません。代わりに、顧客から請求先情報の更新を収集し、顧客のデフォルトの決済手段を更新して、既存の顧客レコードから新しいサブスクリプションを作成します。 ## 導入をテストする ### 支払い方法をテストする 次の表を使用して、さまざまな支払い方法とシナリオをテストします。 | 決済手段 | シナリオ | テスト方法 | | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | 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) で表示できます。 詳しくは、[請求導入のテスト](https://docs.stripe.com/billing/testing.md) を参照してください。 ## Optional: 顧客がプランを変更できるようにする [クライアントおよびサーバー] 顧客にサブスクリプションの変更を許可するには、変更後のオプションの価格 ID を収集します。次にフロントエンドからバックエンドのエンドポイントにこの新しい価格 ID を送信します。この例ではサブスクリプション ID も渡していますが、ログインしているユーザーのデータベースから取得できます。 ```javascript 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 のプレミアムオプションになりました。 #### 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 '/update-subscription' do content_type 'application/json' data = JSON.parse request.body.read subscription = client.v1.subscriptions.retrieve(data['subscriptionId']) updated_subscription = client.v1.subscriptions.update( data['subscriptionId'], cancel_at_period_end: false, items: [ { id: subscription.items.data[0].id, price: data['newPriceId'] } ] ) updated_subscription.to_json end ``` アプリケーションが `customer.subscription.updated` イベントを受信します。 ## Optional: 価格変更をプレビューする [クライアントおよびサーバー] 顧客がサブスクリプションを変更すると、多くの場合、顧客が支払う金額の調整 ([比例配分](https://docs.stripe.com/billing/subscriptions/prorations.md)) が発生します。[プレビュー請求書エンドポイント](https://docs.stripe.com/api/invoices/create_preview.md) を使用することで、調整済みの金額を顧客に表示できます。 フロントエンドから、プレビュー請求書作成の詳細情報をバックエンドのエンドポイントに渡してください。 #### Accounts v2 ```javascript function createPreviewInvoice( customerAccountId, subscriptionId, newPriceId, trialEndDate ) { return fetch('/create-preview-invoice', { method: 'post', headers: { 'Content-type': 'application/json', }, body: JSON.stringify({ customerAccountId: customerAccountId, subscriptionId: subscriptionId, newPriceId: newPriceId, }), }) .then(response => { return response.json(); }) .then((invoice) => { return invoice; }); } ``` #### Customers v1 ```javascript 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; }); } ``` バックエンド側で、フロントエンドが呼び出すためのエンドポイントを定義してください。 #### 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('<>') post '/create-preview-invoice' do content_type 'application/json' data = JSON.parse request.body.read subscription = Stripe::Subscription.retrieve(data['subscriptionId']) invoice = Stripe::Invoice.create_preview( customer_account: data['customerAccountId'], subscription: data['subscriptionId'], subscription_details: { items: [ { id: subscription.items.data[0].id, deleted: true }, { price: data['newPriceId'], deleted: false } ] } ) invoice.to_json end ``` #### 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('<>') post '/create-preview-invoice' do content_type 'application/json' data = JSON.parse request.body.read subscription = client.v1.subscriptions.retrieve(data['subscriptionId']) invoice = client.v1.invoices.create_preview( customer: data['customerId'], subscription: data['subscriptionId'], subscription_details: { items: [ { id: subscription.items.data[0].id, deleted: true }, { price: data['newPriceId'], deleted: false } ] } ) invoice.to_json end ``` ## Optional: 顧客の決済手段を表示する [クライアントおよびサーバー] 顧客のカードのブランドとカード番号の下 4 桁を表示すると、顧客はチャージに使用するカードを確認したり、決済手段の更新が必要かどうかを判断したりできます。 フロントエンドから、決済手段の詳細を取得するバックエンドのエンドポイントに、決済手段 ID を送信します。 ```javascript 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; }); } ``` バックエンド側で、フロントエンドが呼び出すためのエンドポイントを定義してください。 #### 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 '/retrieve-customer-payment-method' do content_type 'application/json' data = JSON.parse request.body.read payment_method = client.v1.payment_methods.retrieve(data['paymentMethodId']) payment_method.to_json end ``` レスポンス例を以下に示します。 ```json { "id": "pm_1GcbHY2eZvKYlo2CoqlVxo42", "object": "payment_method", "billing_details": { "address": { "city": null, "country": null, "line1": null, "line2": null, "postal_code": null, "state": null }, "email": null, "name": null, "phone": null }, "card": { "brand": "visa", "checks": { "address_line1_check": null, "address_postal_code_check": null, "cvc_check": "pass" }, "country": "US", "exp_month": 8, "exp_year": 2021, "fingerprint": "Xt5EWLLDS7FJjR1c", "funding": "credit", "generated_from": null, "last4": "4242", "three_d_secure_usage": { "supported": true }, "wallet": null }, "created": 1588010536, "customer": "cus_HAxB7dVQxhoKLh", "livemode": false, "metadata": {}, "type": "card" } ``` > `paymentMethod.id` および `last4` は、データベースに保存することをお勧めします。たとえば、`paymentMethod.id` を `stripeCustomerPaymentMethodId` として `users` コレクションまたはテーブルに保存します。必要に応じて、`exp_month`、`exp_year`、`fingerprint`、`billing_details` を保存することもできます。これは Stripe に対して実行するコール数を制限するためのものであり、パフォーマンスの効率を向上させ、レート制限の防止に役立ちます。 ## 顧客に Stripe を開示する Stripe は顧客の Elements とのやり取りに関する情報を収集して、サービスを提供し、不正利用を防止し、サービスを向上します。これには、Cookie と IP アドレスを使用して、1 つの決済フローセッションで顧客に表示する Elements を特定することが含まれます。Stripe がこのような方法でデータを使用するために必要なすべての権利と同意について開示し、これらを取得することはお客様の責任です。詳細については、[プライバシーセンター](https://stripe.com/legal/privacy-center#as-a-business-user-what-notice-do-i-provide-to-my-end-customers-about-stripe)をご覧ください。 # Payment Intents API > This is a Payment Intents API for when platform is web and ui is elements. View the full page at https://docs.stripe.com/payments/advanced/build-subscriptions?platform=web&ui=elements. #### 組み込み作業 Complexity: 4/5 #### 組み込みのタイプ カスタムの決済フローに UI コンポーネントを統合する #### UI のカスタマイズ [Appearance API](https://docs.stripe.com/elements/appearance-api.md) を使用した CSS レベルのカスタマイズ [Stripe Elements](https://docs.stripe.com/payments/elements.md) と [Payment Intents API](https://docs.stripe.com/api/payment_intents.md) を使用してカスタム決済フォームを構築し、固定料金の *Subscriptions* を販売します。この連携を [Stripe の他の連携タイプと比較](https://docs.stripe.com/payments/online-payments.md#compare-features-and-availability)してください。 Payment Intents API は、独自の決済フローの構築に使用できる下位レベルの API ですが、非常に多くのコードと継続的なメンテナンスが必要です。ほとんどの組み込みには [Payment Element with Checkout Sessions](https://docs.stripe.com/payments/quickstart-checkout-sessions.md) をお勧めします。Payment Intents と同様の決済フローに対応しているためです。PaymentIntents の代わりに [Checkout Sessions を使用するタイミングの詳細をご確認ください](https://docs.stripe.com/payments/checkout-sessions-and-payment-intents-comparison.md)。 カスタム決済フォームを構築したくない場合は、ホスト型の Checkout に連携できます。このエンドツーエンドの導入ガイドをより実践的に解説したものとして、[Billing クイックスタート](https://docs.stripe.com/billing/quickstart.md)をご覧ください。 導入をコーディングする準備ができていなくても、基本的なサブスクリプションを [Dashboard から手動](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/billing/subscriptions/billing-mode.md) を使用して、拡張請求動作と追加機能にアクセスする方法を確認してください。 ## Stripe 上に構築する方法 [サブスクリプション](https://docs.stripe.com/api/subscriptions.md)では、*請求書* (Invoices are statements of amounts owed by a customer. They track the status of payments from draft through paid or otherwise finalized. Subscriptions automatically generate invoices, or you can manually create a one-off invoice)と [PaymentIntents](https://docs.stripe.com/api/payment_intents.md) が自動的に作成されるため、請求を簡素化できます。サブスクリプションを作成して有効化するには、まず販売する内容を定義する*商品* (Products represent what your business sells—whether that's a good or a service)と、請求金額と請求頻度を決定する*価格* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions)を作成する必要があります。また、各継続支払いに使用する*PaymentMethods* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs)を保存するために、顧客が設定した `Account` オブジェクトまたは `Customer` オブジェクトも必要です。 #### Accounts v2 一般的な Billing オブジェクトとその関係を示した図 (See full diagram at https://docs.stripe.com/payments/advanced/build-subscriptions) #### Customer v1 一般的な Billing オブジェクトとその関係を示した図 (See full diagram at https://docs.stripe.com/payments/advanced/build-subscriptions) ### API オブジェクトの定義 | リソース | 定義 | | ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [顧客として設定されたアカウント](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) | サブスクリプションを購入する Accounts v2 API の顧客を表します。`Account` オブジェクトを顧客として設定し、それをサブスクリプションに関連付けて、継続課金の作成と追跡、サブスクリプション登録している商品の管理を行います。詳細については、[Use Accounts as customers ガイド](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md)を参照してください。 | | [Customer (顧客)](https://docs.stripe.com/api/customers.md) | サブスクリプションを購入する Customers API の顧客を表します。サブスクリプションに関連付けられた `Customer` オブジェクトを使用して、継続課金の作成と追跡、登録している商品の管理を行います。 | | [Entitlement (エンタイトルメント)](https://docs.stripe.com/api/entitlements/active-entitlement.md) | 顧客が登録したサービス商品に含まれる機能への顧客のアクセスを表します。顧客の商品の継続購入のサブスクリプションを作成すると、その商品に関連付けられた機能ごとに、有効な権利が自動的に作成されます。顧客がサービスにアクセスするときに、その有効な資格を使用して、サブスクリプションに含まれる機能を有効にします。 | | [Feature (機能)](https://docs.stripe.com/api/entitlements/feature.md) | 顧客がサービス商品に登録すると利用できる機能や機能を表します。ProductFeatures を作成することで、商品に機能を含めることができます。 | | [Invoice (請求書)](https://docs.stripe.com/api/invoices.md) | 顧客が支払うべき金額の明細書であり、下書きから支払い済み、またはその他の方法で確定された支払いステータスを追跡します。サブスクリプションでは請求書が自動的に生成されます。 | | [PaymentIntent](https://docs.stripe.com/api/payment_intents.md) | 動的な支払いフローを構築する方法です。Payment Intent は、顧客の決済フローのライフサイクルを追跡し、規制で必須とされる同意書、Radar のカスタムの不正利用ルール、またはリダイレクトベースの支払い方法によって要求されたときに、追加の認証ステップを開始します。Payment Intent は、請求書によって自動的に作成されます。 | | [PaymentMethod](https://docs.stripe.com/api/payment_methods.md) | 顧客が商品の支払いに使用する決済手段。たとえば、顧客が設定した `Account` または `Customer` オブジェクトにクレジットカードを保存して、その顧客の継続課金に使用することができます。通常、Payment Intents API または Setup Intents API とともに使用されます。 | | [Price (価格)](https://docs.stripe.com/api/prices.md) | 商品の単価、通貨、請求期間を定義します。 | | [Product (商品)](https://docs.stripe.com/api/products.md) | お客様のビジネスが販売する商品またはサービス。サービス商品には 1 つ以上の機能を含めることができます。 | | [ProductFeature](https://docs.stripe.com/api/product-feature.md) | 1 つの商品に 1 つの機能が含まれることを表します。各商品は、含まれる各機能の ProductFeature に関連付けられ、各機能は、それを含む各商品の ProductFeature に関連付けられます。 | | [Subscription (サブスクリプション)](https://docs.stripe.com/api/subscriptions.md) | 顧客の商品の継続的な購入を表します。サブスクリプションを使用して、支払いを回収し、商品の繰り返し提供や継続的なアクセスを提供します。 | 製品、機能、利用権がどのように連携するかの例をご紹介します。例えば、基本機能を提供する標準プランと、拡張機能を追加した上位プランの 2 つのプランを持つ定期サービスを設定するとします。 1. `basic_features` と `extended_features` の 2 つの機能を作成します。 1. `standard_product` と `advanced_product` の 2 つの商品を作成します。 1. 標準商品の場合、`basic_features` を `standard_product` に関連付ける ProductFeature を 1 つ作成します。 1. 高度な商品の場合、2 つの ProductFeatures を作成します。1 つは `basic_features` を `advanced_product` に関連付け、もう 1 つは `extended_features` を `advanced_product` に関連付けます。 顧客の `first_customer` は、標準商品に登録します。サブスクリプションを作成すると、Stripe は、`first_customer` を `basic_features` に関連付けるエンタイトルメントを自動的に作成します。 別の顧客no `second_customer` は高度な商品に登録します。 サブスクリプションを作成すると、Stripe は自動的に 2 つのエンタイトルメントを作成します。1 つは `second_customer` を `basic_features` に関連付け、もう 1 つは `second_customer` を `extended_features` に関連付けます。 [有効なエンタイトルメントを取得するか、有効なエンタイトルメントのサマリーイベントをリッスンする](https://docs.stripe.com/billing/entitlements.md#entitlements)ことで、顧客に提供する機能を決定できます。顧客のサブスクリプション、商品、機能を取得する必要はありません。 ## 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 のテストを提供します。これを実行すると Stripe への API コールを実行できます。このガイドの後続セクションでは、CLI を使った料金体系モデルの設定方法を紹介します。 その他のインストールオプションについては、[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 } ``` ## 顧客の作成 [クライアントおよびサーバー] Stripe では、サブスクリプションごとに顧客が必要です。申し込みのフロントエンドで、ユーザーから必要な情報を収集し、バックエンドに渡します。 住所の詳細を収集する必要がある場合は、Address Element を使用することで顧客の配送先住所または請求先住所を収集できます。Address Element の詳細については、[Address Element](https://docs.stripe.com/elements/address-element.md) ページをご覧ください。 ```html
``` ```javascript 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()); ``` サーバーで、顧客を表すオブジェクトを作成します。これは、顧客が設定した `Account` オブジェクトまたは `Customer` オブジェクトのいずれかです。Checkout Session で使用するオブジェクトの ID を保存します。 > #### Accounts v2 API を使用した顧客の表現 > > Accounts v2 API では、Connect ユーザーには一般提供され、その他の Stripe ユーザーには公開プレビューで提供されます。Accounts v2 プレビューの一部である場合は、コードで[プレビューバージョン](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning)を指定する必要があります。 > > Accounts v2 プレビューへのアクセスをリクエストするには、 > > ほとんどのユースケースでは、[Customer](https://docs.stripe.com/api/customers.md) オブジェクトを使用するのではなく、[顧客を顧客設定済みの Account オブジェクトとしてモデル化する](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md)ことをお勧めします。 #### Accounts v2 ```curl curl -X POST https://api.stripe.com/v2/core/accounts \ -H "Authorization: Bearer <>" \ -H "Stripe-Version: 2026-04-22.preview" \ --json '{ "contact_email": "jenny.rosen@example.com", "display_name": "Jenny Rosen", "identity": { "individual": { "given_name": "Jenny Rosen", "address": { "city": "San Francisco", "country": "US", "line1": "123 Main Street", "postal_code": "94605", "state": "CA" } } }, "configuration": { "customer": { "capabilities": { "automatic_indirect_tax": { "requested": true } }, "shipping": { "address": { "city": "San Francisco", "country": "US", "line1": "123 Main Street", "postal_code": "94605", "state": "CA" } } } }, "include": [ "configuration.customer", "identity" ] }' ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/customers \ -u "<>:" \ --data-urlencode "email=jenny.rosen@example.com" \ -d "name=Jenny Rosen" \ -d "shipping[address][city]=San Francisco" \ -d "shipping[address][country]=US" \ -d "shipping[address][line1]=123 Main Street" \ -d "shipping[address][postal_code]=9460" \ -d "shipping[address][state]=CA" \ -d "shipping[name]=Jenny Rosen" \ -d "address[city]=San Francisco" \ -d "address[country]=US" \ -d "address[line1]=123 Main Street" \ -d "address[postal_code]=9460" \ -d "address[state]=CA" ``` ## サブスクリプションを作成する [クライアントおよびサーバー] > 最初にサブスクリプションを作成せずに Payment Element をレンダリングする場合は、[Intent を作成する前に決済の詳細を収集する](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=subscription) を参照してください。 顧客がプランを選択してからサブスクリプションを作成できるようにします。このガイドの例では、顧客は Basic プランまたは Premium プランのいずれかを選択します。 フロントエンドで、選択した価格 ID と顧客レコードの ID をバックエンドに渡します。 #### Accounts v2 ```javascript fetch('/create-subscription', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ priceId: priceId, customerAccountId: customerAccountId, }), }) ``` #### Customers v1 ```javascript fetch('/create-subscription', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ priceId: priceId, customerId: customerId, }), }) ``` バックエンドで、`payment_behavior=default_incomplete` を使用して `incomplete` ステータスのサブスクリプションを作成します。次に、サブスクリプションの最初の [PaymentIntent](https://docs.stripe.com/payments/payment-intents.md) からフロントエンドに `client_secret` を返して決済を完了します。これを行うには、サブスクリプションの最新請求書の [confirmation_secret](https://docs.stripe.com/api/invoices/object.md#invoice_object-confirmation_secret) を展開します。 [サブスクリプション動作の改善](https://docs.stripe.com/billing/subscriptions/billing-mode.md) を有効にするには、`billing_mode[type]` を `flexible` に設定します。Stripe API バージョン [2025-06-30.basil](https://docs.stripe.com/changelog/basil.md#2025-06-30.basil) 以降を使用する必要があります。 決済が完了したときに決済手段をデフォルトとして保存する場合は、[save_default_payment_method](https://docs.stripe.com/api/subscriptions/object.md#subscription_object-payment_settings-save_default_payment_method) を `on_subscription` に設定します。デフォルトの決済手段を保存すると、その後のサブスクリプションの決済の成功率が高くなります。 次の例では `Subscription` を作成すると同時に、レスポンス内で最新の請求書から `confirmation_secret` を展開して取得しています。それにより、シークレットキーをフロントエンドに渡して決済を確定できます。 #### Accounts v2 ```curl curl https://api.stripe.com/v1/subscriptions \ -u "<>:" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d "items[0][price]={{PRICE_ID}}" \ -d payment_behavior=default_incomplete \ -d "payment_settings[save_default_payment_method]=on_subscription" \ -d "billing_mode[type]=flexible" \ -d "expand[0]=latest_invoice.confirmation_secret" ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/subscriptions \ -u "<>:" \ -d "customer={{CUSTOMER_ID}}" \ -d "items[0][price]={{PRICE_ID}}" \ -d payment_behavior=default_incomplete \ -d "payment_settings[save_default_payment_method]=on_subscription" \ -d "billing_mode[type]=flexible" \ -d "expand[0]=latest_invoice.confirmation_secret" ``` > *多通貨の価格* (A single Price object can support multiple currencies. Each purchase uses one of the supported currencies for the Price, depending on how you use the Price in your integration) を使用している場合は、[currency](https://docs.stripe.com/api/subscriptions/create.md#create_subscription-currency) パラメーターを使用して、サポートする通貨をサブスクリプションに指示します。`currency` パラメーターを省略すると、サブスクリプションはデフォルト通貨を使用します。 サブスクリプションは `inactive` になり、決済を待っています。以下のレスポンスの例では、保存が必要な最小限のフィールドが強調表示されていますが、アプリケーションで頻繁にアクセスされるフィールドは保存できます。 #### Accounts v2 ```json {"id": "sub_JgRjFjhKbtD2qz", "object": "subscription", "application_fee_percent": null, "automatic_tax": { "disabled_reason": null, "enabled": false, "liability": "null" }, "billing_cycle_anchor": 1623873347, "billing_cycle_anchor_config": null, "cancel_at": null, "cancel_at_period_end": false, "canceled_at": null, "cancellation_details": { "comment": null, "feedback": null, "reason": null }, "collection_method": "charge_automatically", "created": 1623873347, "currency": "usd","customer_account": identifier("customerAccount"), "days_until_due": null, "default_payment_method": null, "default_source": null, "default_tax_rates": [ ], "discounts": [], "ended_at": null, "invoice_customer_balance_settings": { "account_tax_ids": null, "issuer": { "type": "self" } }, "items": { "object": "list", "data": [ { "id": "si_JgRjmS4Ur1khEx", "object": "subscription_item", "created": 1623873347,"current_period_end": 1626465347, "current_period_start": 1623873347, "discounts": [], "metadata": { }, "plan": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "plan", "active": true, "amount": 2000, "amount_decimal": "2000", "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "tiers": null, "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "price": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "livemode": false, "lookup_key": null, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "recurring": { "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed" }, "tiers_mode": null, "transform_quantity": null, "type": "recurring", "unit_amount": 2000, "unit_amount_decimal": "2000" }, "quantity": 1, "subscription": "sub_JgRjFjhKbtD2qz", "tax_rates": [ ] } ], "has_more": false, "total_count": 1, "url": "/v1/subscription_items?subscription=sub_JgRjFjhKbtD2qz" }, "latest_invoice": { "id": "in_1J34pzGPZ1iASj5zB87qdBNZ", "object": "invoice", "account_country": "US", "account_name": "Angelina's Store", "account_tax_ids": null, "amount_due": 2000, "amount_overpaid": 0, "amount_paid": 0, "amount_remaining": 2000, "amount_shipping": 0, "attempt_count": 0, "attempted": false, "auto_advance": false, "automatic_tax": { "disabled_reason": null, "enabled": false, "liability": null, "status": null }, "automatically_finalizes_at": null, "billing_reason": "subscription_update", "collection_method": "charge_automatically", "created": 1623873347, "currency": "usd", "custom_fields": null, "customer_account": identifier("customerAccount"), "customer_address": null, "customer_email": "angelina@stripe.com", "customer_name": null, "customer_phone": null, "customer_shipping": { "address": { "city": "", "country": "US", "line1": "Berry", "line2": "", "postal_code": "", "state": "" }, "name": "", "phone": null }, "customer_tax_exempt": "none", "customer_tax_ids": [ ], "default_payment_method": null, "default_source": null, "default_tax_rates": [ ], "description": null, "discounts": [], "due_date": null, "effective_at": "1623873347", "ending_balance": 0, "footer": null, "from_invoice": null, "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp", "invoice_pdf": "https://pay.stripe.com/invoice/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp/pdf", "last_finalization_error": null, "latest_revision": null, "lines": { "object": "list", "data": [ { "id": "il_1N2CjMBwKQ696a5NeOawRQP2", "object": "line_item", "amount": 2000, "currency": "usd", "description": "1 × Gold Special (at $20.00 / month)", "discount_amounts": [ ], "discountable": true, "discounts": [ ], "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ", "livemode": false, "metadata": { }, "parent": { "invoice_item_details": null, "subscription_item_details": { "invoice_item": null, "proration": false, "proration_details": { "credited_items": null }, "subscription": "sub_JgRjFjhKbtD2qz", "subscription_item": "si_JgRjmS4Ur1khEx" }, "type": "subscription_item_details" }, "period": { "end": 1626465347, "start": 1623873347 }, "plan": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "plan", "active": true, "amount": 2000, "amount_decimal": "2000", "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "tiers": null, "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "price": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "livemode": false, "lookup_key": null, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "recurring": { "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed" }, "tiers_mode": null, "transform_quantity": null, "type": "recurring", "unit_amount": 2000, "unit_amount_decimal": "2000" }, "quantity": 1, "taxes": [] } ], "has_more": false, "total_count": 1, "url": "/v1/invoices/in_1J34pzGPZ1iASj5zB87qdBNZ/lines" }, "livemode": false, "metadata": { }, "next_payment_attempt": null, "number": "C008FC2-0354", "on_behalf_of": null, "parent": { "quote_details": null, "subscription_details": { "metadata": {}, "pause_collection": null, "subscription": "sub_JgRjFjhKbtD2qz" } }, "payment_intent": { "id": "pi_1J34pzGPZ1iASj5zI2nOAaE6", "object": "payment_intent", "allowed_source_types": [ "card" ], "amount": 2000, "amount_capturable": 0, "amount_received": 0, "application": null, "application_fee_amount": null, "canceled_at": null, "cancellation_reason": null, "capture_method": "automatic", "charges": { "object": "list", "data": [ ], "has_more": false, "total_count": 0, "url": "/v1/charges?payment_intent=pi_1J34pzGPZ1iASj5zI2nOAaE6" }, "client_secret": "pi_1J34pzGPZ1iASj5zI2nOAaE6_secret_l7FN6ldFfXiFmJEumenJ2y2wu", "confirmation_method": "automatic", "created": 1623873347, "currency": "usd", "customer": "cus_CMqDWO2xODTZqt", "description": "Subscription creation", "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ", "last_payment_error": null, "livemode": false, "metadata": { }, "next_action": null, "next_source_action": null, "on_behalf_of": null, "payment_method": null, "payment_method_options": { "card": { "installments": null, "network": null, "request_three_d_secure": "automatic" } }, "payment_method_types": [ "card" ], "receipt_email": null, "review": null, "setup_future_usage": "off_session", "shipping": null, "source": "card_1By6iQGPZ1iASj5z7ijKBnXJ", "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "requires_confirmation", "transfer_data": null, "transfer_group": null }, "payment_settings": { "payment_method_options": null, "payment_method_types": null, "save_default_payment_method": "on_subscription" }, "period_end": 1623873347, "period_start": 1623873347, "post_payment_credit_notes_amount": 0, "pre_payment_credit_notes_amount": 0, "receipt_number": null, "starting_balance": 0, "statement_descriptor": null, "status": "open", "status_transitions": { "finalized_at": 1623873347, "marked_uncollectible_at": null, "paid_at": null, "voided_at": null }, "subscription": "sub_JgRjFjhKbtD2qz", "subtotal": 2000, "tax": null, "tax_percent": null, "total": 2000, "total_discount_amounts": [], "total_tax_amounts": [], "transfer_data": null, "webhooks_delivered_at": 1623873347 }, "livemode": false, "metadata": { }, "next_pending_invoice_item_invoice": null, "pause_collection": null, "pending_invoice_item_interval": null, "pending_setup_intent": null, "pending_update": null, "plan": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "plan", "active": true, "amount": 2000, "amount_decimal": "2000", "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "tiers": null, "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "quantity": 1, "schedule": null, "start": 1623873347, "start_date": 1623873347, "status": "incomplete", "tax_percent": null, "transfer_data": null, "trial_end": null, "trial_start": null } ``` #### Customers v1 ```json {"id": "sub_JgRjFjhKbtD2qz", "object": "subscription", "application_fee_percent": null, "automatic_tax": { "disabled_reason": null, "enabled": false, "liability": "null" }, "billing_cycle_anchor": 1623873347, "billing_cycle_anchor_config": null, "cancel_at": null, "cancel_at_period_end": false, "canceled_at": null, "cancellation_details": { "comment": null, "feedback": null, "reason": null }, "collection_method": "charge_automatically", "created": 1623873347, "currency": "usd","customer": identifier("customer"), "days_until_due": null, "default_payment_method": null, "default_source": null, "default_tax_rates": [ ], "discounts": [], "ended_at": null, "invoice_customer_balance_settings": { "account_tax_ids": null, "issuer": { "type": "self" } }, "items": { "object": "list", "data": [ { "id": "si_JgRjmS4Ur1khEx", "object": "subscription_item", "created": 1623873347,"current_period_end": 1626465347, "current_period_start": 1623873347, "discounts": [], "metadata": { }, "plan": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "plan", "active": true, "amount": 2000, "amount_decimal": "2000", "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "tiers": null, "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "price": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "livemode": false, "lookup_key": null, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "recurring": { "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed" }, "tiers_mode": null, "transform_quantity": null, "type": "recurring", "unit_amount": 2000, "unit_amount_decimal": "2000" }, "quantity": 1, "subscription": "sub_JgRjFjhKbtD2qz", "tax_rates": [ ] } ], "has_more": false, "total_count": 1, "url": "/v1/subscription_items?subscription=sub_JgRjFjhKbtD2qz" }, "latest_invoice": { "id": "in_1J34pzGPZ1iASj5zB87qdBNZ", "object": "invoice", "account_country": "US", "account_name": "Angelina's Store", "account_tax_ids": null, "amount_due": 2000, "amount_overpaid": 0, "amount_paid": 0, "amount_remaining": 2000, "amount_shipping": 0, "attempt_count": 0, "attempted": false, "auto_advance": false, "automatic_tax": { "disabled_reason": null, "enabled": false, "liability": null, "status": null }, "automatically_finalizes_at": null, "billing_reason": "subscription_update", "collection_method": "charge_automatically", "created": 1623873347, "currency": "usd", "custom_fields": null, "customer": identifier("customer"), "customer_address": null, "customer_email": "angelina@stripe.com", "customer_name": null, "customer_phone": null, "customer_shipping": { "address": { "city": "", "country": "US", "line1": "Berry", "line2": "", "postal_code": "", "state": "" }, "name": "", "phone": null }, "customer_tax_exempt": "none", "customer_tax_ids": [ ], "default_payment_method": null, "default_source": null, "default_tax_rates": [ ], "description": null, "discounts": [], "due_date": null, "effective_at": "1623873347", "ending_balance": 0, "footer": null, "from_invoice": null, "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp", "invoice_pdf": "https://pay.stripe.com/invoice/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp/pdf", "last_finalization_error": null, "latest_revision": null, "lines": { "object": "list", "data": [ { "id": "il_1N2CjMBwKQ696a5NeOawRQP2", "object": "line_item", "amount": 2000, "currency": "usd", "description": "1 × Gold Special (at $20.00 / month)", "discount_amounts": [ ], "discountable": true, "discounts": [ ], "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ", "livemode": false, "metadata": { }, "parent": { "invoice_item_details": null, "subscription_item_details": { "invoice_item": null, "proration": false, "proration_details": { "credited_items": null }, "subscription": "sub_JgRjFjhKbtD2qz", "subscription_item": "si_JgRjmS4Ur1khEx" }, "type": "subscription_item_details" }, "period": { "end": 1626465347, "start": 1623873347 }, "plan": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "plan", "active": true, "amount": 2000, "amount_decimal": "2000", "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "tiers": null, "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "price": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "livemode": false, "lookup_key": null, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "recurring": { "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed" }, "tiers_mode": null, "transform_quantity": null, "type": "recurring", "unit_amount": 2000, "unit_amount_decimal": "2000" }, "quantity": 1, "taxes": [] } ], "has_more": false, "total_count": 1, "url": "/v1/invoices/in_1J34pzGPZ1iASj5zB87qdBNZ/lines" }, "livemode": false, "metadata": { }, "next_payment_attempt": null, "number": "C008FC2-0354", "on_behalf_of": null, "parent": { "quote_details": null, "subscription_details": { "metadata": {}, "pause_collection": null, "subscription": "sub_JgRjFjhKbtD2qz" } }, "payment_intent": { "id": "pi_1J34pzGPZ1iASj5zI2nOAaE6", "object": "payment_intent", "allowed_source_types": [ "card" ], "amount": 2000, "amount_capturable": 0, "amount_received": 0, "application": null, "application_fee_amount": null, "canceled_at": null, "cancellation_reason": null, "capture_method": "automatic", "charges": { "object": "list", "data": [ ], "has_more": false, "total_count": 0, "url": "/v1/charges?payment_intent=pi_1J34pzGPZ1iASj5zI2nOAaE6" }, "client_secret": "pi_1J34pzGPZ1iASj5zI2nOAaE6_secret_l7FN6ldFfXiFmJEumenJ2y2wu", "confirmation_method": "automatic", "created": 1623873347, "currency": "usd", "customer": "cus_CMqDWO2xODTZqt", "description": "Subscription creation", "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ", "last_payment_error": null, "livemode": false, "metadata": { }, "next_action": null, "next_source_action": null, "on_behalf_of": null, "payment_method": null, "payment_method_options": { "card": { "installments": null, "network": null, "request_three_d_secure": "automatic" } }, "payment_method_types": [ "card" ], "receipt_email": null, "review": null, "setup_future_usage": "off_session", "shipping": null, "source": "card_1By6iQGPZ1iASj5z7ijKBnXJ", "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "requires_confirmation", "transfer_data": null, "transfer_group": null }, "payment_settings": { "payment_method_options": null, "payment_method_types": null, "save_default_payment_method": "on_subscription" }, "period_end": 1623873347, "period_start": 1623873347, "post_payment_credit_notes_amount": 0, "pre_payment_credit_notes_amount": 0, "receipt_number": null, "starting_balance": 0, "statement_descriptor": null, "status": "open", "status_transitions": { "finalized_at": 1623873347, "marked_uncollectible_at": null, "paid_at": null, "voided_at": null }, "subscription": "sub_JgRjFjhKbtD2qz", "subtotal": 2000, "tax": null, "tax_percent": null, "total": 2000, "total_discount_amounts": [], "total_tax_amounts": [], "transfer_data": null, "webhooks_delivered_at": 1623873347 }, "livemode": false, "metadata": { }, "next_pending_invoice_item_invoice": null, "pause_collection": null, "pending_invoice_item_interval": null, "pending_setup_intent": null, "pending_update": null, "plan": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "plan", "active": true, "amount": 2000, "amount_decimal": "2000", "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "tiers": null, "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "quantity": 1, "schedule": null, "start": 1623873347, "start_date": 1623873347, "status": "incomplete", "tax_percent": null, "transfer_data": null, "trial_end": null, "trial_start": null } ``` ## 決済情報を収集する [クライアント] [Stripe Elements](https://docs.stripe.com/payments/elements.md) を使用して決済の詳細を収集し、サブスクリプションを有効化します。Elements は、アプリケーションのデザインに合わせてカスタマイズできます。 [Payment Element](https://docs.stripe.com/payments/payment-element.md) は、サブスクリプションで[Link](https://docs.stripe.com/payments/link.md)、カード、SEPA ダイレクトデビット、BECS ダイレクトデビットをサポートします。有効な決済手段を表示し、顧客の選択に応じて決済詳細を安全に回収できます。 ### Stripe Elements を設定する Payment Element は Stripe.js の機能として自動的に使用できるようになります。決済ページに Stripe.js スクリプトを含めるには、HTML ファイルの `head` にスクリプトを追加します。常に js.stripe.com から Stripe.js を直接読み込むことにより、PCI 準拠が維持されます。スクリプトをバンドルに含めることや、そのコピーを自身でホストすることは避けてください。 ```html Checkout ``` 決済ページで以下の JavaScript を使用して、Stripe のインスタンスを作成します。 ```javascript // 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('<>'); ``` ### Payment Element をページに追加する 決済ページには Payment Element を配置する場所が必要です。決済フォームで、一意の ID を持つ空の DOM ノード (コンテナー) を作成します。 ```html
``` このフォームが読み込まれた後、Payment Element のインスタンスを作成して、それをコンテナーの DOM ノードにマウントします。[サブスクリプションの作成](https://docs.stripe.com/payments/advanced/build-subscriptions.md#create-subscription) で、フロントエンドに `client_secret` 値を渡しています。この値を、Elements のインスタンスを作成する際にオプションとして渡します。 ```javascript 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 オブジェクト](https://docs.stripe.com/js/elements_object/create#stripe_elements-options-appearance) を `options` に渡すことで、サイトのデザインに合わせて Payment Element をカスタマイズできます。 - Apple Pay インターフェイスを設定して、継続決済、自動リロード、後払いに対応する [加盟店トークン](https://docs.stripe.com/apple-pay/merchant-tokens.md?pay-element=web-pe) を返します。 ### 決済を完了する `stripe.confirmPayment` を使用して、Payment Element からの詳細を指定した決済を完了し、サブスクリプションを有効化します。これにより PaymentMethod が作成され、不完全なサブスクリプションの最初の PaymentIntent が確定され、請求が実行されます。チャージに*強力な顧客認証 (SCA)* (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) が必要とされる場合は、PaymentIntent の確定前に、Payment Element が認証プロセスを処理します。 決済の完了後に Stripe がユーザーをリダイレクトする場所を指定するには、[return_url](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-return_url) を指定します。まず、ユーザーを銀行の認証ページなどの中間サイトにリダイレクトしてから、`return_url` にリダイレクトすることができます。カード決済では、決済が正常に完了するとすぐに `return_url` にリダイレクトします。 ```javascript 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` にリダイレクトし、以下の URL クエリーパラメーターを含めます。返品ページでは、これらを使用して PaymentIntent のステータスを取得し、顧客に支払いステータスを表示できます。 `return_url` を指定する際に、返品ページで使用する独自のクエリパラメーターを追加することもできます。 | パラメーター | 説明 | | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `payment_intent` | `PaymentIntent` の一意の識別子。 | | `payment_intent_client_secret` | `PaymentIntent` オブジェクトの [client secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret)。サブスクリプションの実装の場合、この client_secret は [`confirmation_secret`](https://docs.stripe.com/api/invoices/object.md#invoice_object-confirmation_secret) を通じて `Invoice` オブジェクトでも公開されます | 顧客が自社のサイトにリダイレクトされたら、`payment_intent_client_secret` を使用して PaymentIntent をクエリし、顧客に取引ステータスを表示できます。 > 顧客のブラウザーセッションを追跡するツールを利用している場合、リファラー除外リストに `stripe.com` ドメインの追加が必要になる場合があります。リダイレクトを行うと、一部のツールでは新しいセッションが作成され、セッション全体の追跡ができなくなります。 クエリパラメーターのいずれか 1 つを使用して PaymentIntent を取得します。PaymentIntent の [ステータス](https://docs.stripe.com/payments/paymentintents/lifecycle.md) を調べて、顧客に表示する内容を決定します。また、`return_url` を指定するときに独自のクエリパラメーターを追加することもできます。このパラメーターはリダイレクトプロセスの間を通じて存続します。 ```javascript // 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; } }); ``` ## Webhook をリッスンする [サーバー] 導入を完了するには、Stripe から送信される *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) を処理する必要があります。これらのイベントは、サブスクリプションの新しい請求書が生成されるなど、Stripe でステータスが変更されるたびに発生します。アプリケーション側では、webhook イベントを含む POST リクエストを受け取るための HTTP ハンドラーを設定して、イベントの署名を検証してください。 #### 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 # You can use webhooks to receive information about asynchronous payment events. # For more about our webhook events, see https://stripe.com/docs/webhooks. webhook_secret = ENV['STRIPE_WEBHOOK_SECRET'] 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 - used to check the status of PaymentIntents. event_type = event['type'] data = event['data'] data_object = data['object'] if event_type == 'invoice.paid' # Used to provision services after the trial has ended. # The status of the invoice shows up as paid. Store the status in your # database to reference when a user accesses your service to avoid hitting rate # limits. # puts data_object end if event_type == 'invoice.payment_failed' # If the payment fails or the customer doesn't have a valid payment method, # an invoice.payment_failed event is sent and the subscription becomes past_due. # Use this webhook to notify your user that their payment has # failed and to retrieve new card details. # puts data_object end if event_type == 'customer.subscription.deleted' # handle subscription canceled automatically based # upon your subscription settings. Or if the user cancels it. # puts data_object end content_type 'application/json' { status: 'success' }.to_json end ``` 開発中は、Stripe CLI を使用して [Webhook をモニタリングし、アプリケーション](https://docs.stripe.com/webhooks.md#test-webhook) に転送します。開発アプリの実行中に、新しい端末で以下を実行します。 #### curl ```bash stripe listen --forward-to localhost:4242/webhook ``` 本番環境では、[Workbench](https://docs.stripe.com/workbench.md) で Webhook エンドポイントを設定するか、[Webhook Endpoints API](https://docs.stripe.com/api/webhook_endpoints.md) を使用します。 いくつかのイベントをリッスンして、このガイドの残りのステップを完了します。サブスクリプション固有の Webhook については、[サブスクリプションのイベント](https://docs.stripe.com/billing/subscriptions/webhooks.md#events) を確認してください。 ## サービスへのアクセスを提供する [クライアントおよびサーバー] サブスクリプションが有効になりました。次は、ユーザーがサービスにアクセスできるようにします。これを行うには、`customer.subscription.created`、`customer.subscription.updated`、`customer.subscription.deleted` の各イベントを監視してください。これらのイベントは、`Subscription` オブジェクトが渡され、その中のオブジェクトには、サブスクリプションが有効か、期日経過か、キャンセルされたかを示す `status` フィールドが含まれます。ステータスの一覧については[サブスクリプションのライフサイクル](https://docs.stripe.com/billing/subscriptions/overview.md#subscription-lifecycle)を参照してください。 Webhook ハンドラーで、以下を実行します。 1. サブスクリプションのステータスを確認します。`active` の場合、ユーザーは商品の決済を実行しています。 1. 顧客が登録している商品を確認し、サービスへのアクセス権を付与します。価格ではなく商品を確認することにより、料金体系や請求期間の変更が必要になった場合に、柔軟に対応できます。 1. `product.id`、`subscription.id`、`subscription.status` を、すでに保存した `customer_account.id` または `customer.id` とともにデータベースに保存します。アプリケーションでユーザーに対して有効にする機能を判断する際は、このレコードを確認します。 サブスクリプションのステータスは、そのライフサイクルのどの時点でも変わる可能性があります。たとえアプリケーションが Stripe に直接呼び出しを行わなくてもです。たとえば、更新時にクレジットカードの有効期限切れで決済が失敗すると、サブスクリプションは `past due` になります。また、[カスタマーポータル](https://docs.stripe.com/customer-management.md)を実装している場合、ユーザーがアプリケーションに直接アクセスせずにサブスクリプションをキャンセルすることもあります。ハンドラーを正しく導入することで、アプリケーションの状態を Stripe と同期させることができます。 ## サブスクリプションをキャンセルする [クライアントおよびサーバー] 顧客はサブスクリプションをキャンセルすることができます。この例ではアカウントの設定ページにキャンセルオプションを追加します。 ![サブスクリプションのキャンセルインターフェイスの例](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-subscriptions-guide-account-settings.6559626ba4b434826a67abfea165e097.png) サブスクリプションのキャンセル機能が設定されたアカウント設定 ```javascript 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. }); } ``` バックエンド側で、フロントエンドが呼び出すためのエンドポイントを定義してください。 #### 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 '/cancel-subscription' do content_type 'application/json' data = JSON.parse request.body.read deleted_subscription = client.v1.subscriptions.cancel(data['subscriptionId']) deleted_subscription.to_json end ``` アプリケーションが `customer.subscription.deleted` イベントを受信します。 サブスクリプションがキャンセルされたら、データベースを更新して以前に保存された Stripe サブスクリプション ID を削除し、サービスへのアクセスを制限します。 キャンセルされたサブスクリプションを、再びアクティブにすることはできません。代わりに、顧客から更新された請求先情報を収集し、顧客のデフォルトの決済手段を更新して、既存の顧客レコードから新しいサブスクリプションを作成します。 ## 導入をテストする ### 支払い方法をテストする 次の表を使用して、さまざまな支払い方法とシナリオをテストします。 | 決済手段 | シナリオ | テスト方法 | | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | 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) で表示できます。 詳しくは、[請求導入のテスト](https://docs.stripe.com/billing/testing.md) を参照してください。 ## Optional: 顧客がプランを変更できるようにする [クライアントおよびサーバー] 顧客にサブスクリプションの変更を許可するには、変更後のオプションの価格 ID を収集します。次にフロントエンドからバックエンドのエンドポイントにこの新しい価格 ID を送信します。以下の例ではサブスクリプション ID も渡していますが、ログインしているユーザーのデータベースから取得できます。 ```javascript 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 になりました。 #### 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 '/update-subscription' do content_type 'application/json' data = JSON.parse request.body.read subscription = client.v1.subscriptions.retrieve(data['subscriptionId']) updated_subscription = client.v1.subscriptions.update( data['subscriptionId'], cancel_at_period_end: false, items: [ { id: subscription.items.data[0].id, price: data['newPriceId'] } ] ) updated_subscription.to_json end ``` アプリケーションが `customer.subscription.updated` イベントを受信します。 ## Optional: 価格変更をプレビューする [クライアントおよびサーバー] 顧客がサブスクリプションを変更すると、多くの場合、顧客が支払う金額の調整 ([比例配分](https://docs.stripe.com/billing/subscriptions/prorations.md)) が発生します。[プレビュー請求書エンドポイント](https://docs.stripe.com/api/invoices/create_preview.md) を使用することで、調整済みの金額を顧客に表示できます。 フロントエンドから、`create preview invoice` の詳細情報をバックエンドのエンドポイントに渡します。 #### Accounts v2 ```javascript function createPreviewInvoice( customerAccountId, subscriptionId, newPriceId, trialEndDate ) { return fetch('/create-preview-invoice', { method: 'post', headers: { 'Content-type': 'application/json', }, body: JSON.stringify({ customerAccountId: customerAccountId, subscriptionId: subscriptionId, newPriceId: newPriceId, }), }) .then(response => { return response.json(); }) .then((invoice) => { return invoice; }); } ``` #### Customers v1 ```javascript 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; }); } ``` バックエンド側で、フロントエンドが呼び出すためのエンドポイントを定義してください。 #### 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('<>') post '/create-preview-invoice' do content_type 'application/json' data = JSON.parse request.body.read subscription = Stripe::Subscription.retrieve(data['subscriptionId']) invoice = Stripe::Invoice.create_preview( customer_account: data['customerAccountId'], subscription: data['subscriptionId'], subscription_details: { items: [ { id: subscription.items.data[0].id, deleted: true }, { price: data['newPriceId'], deleted: false } ] } ) invoice.to_json end ``` #### 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('<>') post '/create-preview-invoice' do content_type 'application/json' data = JSON.parse request.body.read subscription = client.v1.subscriptions.retrieve(data['subscriptionId']) invoice = client.v1.invoices.create_preview( customer: data['customerId'], subscription: data['subscriptionId'], subscription_details: { items: [ { id: subscription.items.data[0].id, deleted: true }, { price: data['newPriceId'], deleted: false } ] } ) invoice.to_json end ``` ## Optional: 顧客の決済手段を表示する [クライアントおよびサーバー] 顧客のカードのブランドとカード番号の下 4 桁を表示すると、顧客はチャージに使用するカードを確認したり、決済手段の更新が必要かどうかを判断したりできます。 フロントエンドから、決済手段の詳細を取得するバックエンドのエンドポイントに、決済手段 ID を送信します。 ```javascript 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; }); } ``` バックエンド側で、フロントエンドが呼び出すためのエンドポイントを定義してください。 #### 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 '/retrieve-customer-payment-method' do content_type 'application/json' data = JSON.parse request.body.read payment_method = client.v1.payment_methods.retrieve(data['paymentMethodId']) payment_method.to_json end ``` レスポンス例を以下に示します。 ```json { "id": "pm_1GcbHY2eZvKYlo2CoqlVxo42", "object": "payment_method", "billing_details": { "address": { "city": null, "country": null, "line1": null, "line2": null, "postal_code": null, "state": null }, "email": null, "name": null, "phone": null }, "card": { "brand": "visa", "checks": { "address_line1_check": null, "address_postal_code_check": null, "cvc_check": "pass" }, "country": "US", "exp_month": 8, "exp_year": 2021, "fingerprint": "Xt5EWLLDS7FJjR1c", "funding": "credit", "generated_from": null, "last4": "4242", "three_d_secure_usage": { "supported": true }, "wallet": null }, "created": 1588010536, "customer": "cus_HAxB7dVQxhoKLh", "livemode": false, "metadata": {}, "type": "card" } ``` > `paymentMethod.id` および `last4` は、データベースに保存することをお勧めします。たとえば、`paymentMethod.id` を `stripeCustomerPaymentMethodId` として `users` コレクションまたはテーブルに保存します。必要に応じて、`exp_month`、`exp_year`、`fingerprint`、`billing_details` を保存することもできます。これは Stripe に対して実行するコール数を制限するためのものであり、パフォーマンスの効率を向上させ、レート制限の防止に役立ちます。 ## 顧客に Stripe を開示する Stripe は顧客の Elements とのやり取りに関する情報を収集して、サービスを提供し、不正利用を防止し、サービスを向上します。これには、Cookie と IP アドレスを使用して、1 つの決済フローセッションで顧客に表示する Elements を特定することが含まれます。Stripe がこのような方法でデータを使用するために必要なすべての権利と同意について開示し、これらを取得することはお客様の責任です。詳細については、[プライバシーセンター](https://stripe.com/legal/privacy-center#as-a-business-user-what-notice-do-i-provide-to-my-end-customers-about-stripe)をご覧ください。