# サブスクリプションの実装を構築する

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

## まずこちらをご覧ください: エージェントスキルのインストール

Stripe では、ベストプラクティスに沿って API と連携するために、公式スキルの使用を推奨しています。詳細は以下の手順をご確認ください。

**ヒント: Fetch ツールではなく curl を使用してください。** スキルは 10 ～ 20 KB の詳細なマークダウンファイルです。Fetch ツールは内容を要約します。`curl -sL` を使うと、完全な内容を取得できます。

**`npx skills` の使用方法**: `npx` がシステムにインストールされているか確認します。`npx` が使用可能な場合は、`npx skills addhttps://docs.stripe.com --list` を実行して利用可能なスキルを一覧表示し、続いて`npx skills addhttps://docs.stripe.com --yes --skill<skill-name> <--skill other-skills>` を実行して個別のスキルをインストールします。

**`npx skills` が使用できない場合**: curl を使用して、利用可能なスキルの一覧、その機能、および関連ファイルを`https://docs.stripe.com/.well-known/skills/index.json`. から取得できます。スキルとその関連ファイルをダウンロードするには、curl を使用して`https://docs.stripe.com/.well-known/skills/<filepath>`. からダウンロードします。

この記事では、次のスキルの使用を推奨します: `stripe-best-practices`

#### Checkout

#### Stripe がホストするページ

# ホスト型ページ

> This is a ホスト型ページ for when platform is web and ui is stripe-hosted. View the full page at https://docs.stripe.com/billing/subscriptions/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 "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Premium Service" \
  -d "description=Premium service with extra features"
```

ベーシック製品を作成します。

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --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 "<<YOUR_SECRET_KEY>>:" \
  -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 "<<YOUR_SECRET_KEY>>:" \
  -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
<html>
  <head>
    <title>Checkout</title>
  </head>
  <body>
    <form action="/create-checkout-session" method="POST">
      <!-- Note: If using PHP set the action to /create-checkout-session.php -->

      <input type="hidden" name="priceId" value="price_G0FvDp6vZvdwRZ" />
      <button type="submit">Checkout</button>
    </form>
  </body>
</html>
```

アプリケーションのバックエンドで、フロントエンドが呼び出す [セッションを作成](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/changelog/basil.md#2025-06-30.basil) 以降を使用する必要があります。

> [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('<<YOUR_SECRET_KEY>>')

# 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` などの各 [Event オブジェクト](https://docs.stripe.com/api/events/object.md) のペイロードを解析します。データベースに `subscription.id` と `customer.id` の Event オブジェクトを保存して確認に使用します。

テスト目的では、[ワークベンチ](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('<<YOUR_SECRET_KEY>>')

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.
    # You should 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 user 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) するエンドポイントを定義します。`CUSTOMER_ID` は、Checkout Session で作成されたものであり、`checkout.session.completed` イベントの処理中に保存した顧客 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('<<YOUR_SECRET_KEY>>')

# 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('<<YOUR_SECRET_KEY>>')

# 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
<html>
  <head>
    <title>Manage Billing</title>
  </head>
  <body>
    <form action="/customer-portal" method="POST">
      <!-- Note: If using PHP set the action to /customer-portal.php -->
      <button type="submit">Manage Billing</button>
    </form>
  </body>
</html>
```

顧客がカスタマーポータルから退出すると、`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 platform is web and ui is embedded-form. View the full page at https://docs.stripe.com/billing/subscriptions/build-subscriptions?platform=web&ui=embedded-form.

#### 導入作業
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 "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Premium Service" \
  -d "description=Premium service with extra features"
```

ベーシック製品を作成します。

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --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 "<<YOUR_SECRET_KEY>>:" \
  -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 "<<YOUR_SECRET_KEY>>:" \
  -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)を作成する際に、次のパラメーターを渡します。

- embedded_page 決済フォームを使用するには、[ui_mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-ui_mode) を `embedded` に設定します。
- 顧客の購入時にサブスクリプションを作成するには、[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 はこの変数を Checkout Session ID に置き換えてから、顧客をリダイレクトします。Web サイトに戻り先ページを作成してホストしてください。
- サブスクリプションとキャンセルの規約、および顧客がサブスクリプションを更新またはキャンセルできるリンクを含めるには、オプションで[カスタムテキスト](https://docs.stripe.com/payments/checkout/custom-components.md?ui=embedded-form#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 "<<YOUR_SECRET_KEY>>:" \
  -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
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Accept a payment</title>
    <meta name="description" content="A demo of a payment on Stripe" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" href="style.css" /><!-- Add the Stripe.js script here -->
    <script src="https://js.stripe.com/dahlia/stripe.js"></script>
    <script src="checkout.js" defer></script>
  </head><body>
    <!-- Display a payment form -->
      <div id="checkout">
        <!-- Checkout inserts the payment form here -->
      </div>
  </body>
</html>
```

#### 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 を初期化し、決済フォームのプレースホルダーにマウントします。`<div>` 支払いフォームで。決済は iframe でレンダリングされ、HTTPS 接続経由で支払い情報が安全に Stripe に送信されます。

一部の支払い方法では、別のページにリダイレクトして支払いを確定する必要があるため、Checkout は別の iframe 内に配置しないでください。

```javascript
// Initialize Stripe.js
const stripe = Stripe('<<YOUR_PUBLISHABLE_KEY>>');

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 (
    <EmbeddedCheckoutProvider
      stripe={stripePromise}
      options={options}
    >
      <EmbeddedCheckout />
    </EmbeddedCheckoutProvider>
  )
}
```

## 戻りページを表示する

顧客は決済を試行した後、お客様のサイトにホストされている戻り先ページにリダイレクトされます。戻り先ページは、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('<<YOUR_SECRET_KEY>>')

# 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('<<YOUR_SECRET_KEY>>')

# 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
<html>
  <head>
    <title>Manage Billing</title>
  </head>
  <body>
    <form action="/customer-portal" method="POST">
      <!-- Note: If using PHP set the action to /customer-portal.php -->
      <button type="submit">Manage Billing</button>
    </form>
  </body>
</html>
```

顧客がカスタマーポータルから退出すると、`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` の各イベントを監視してください。これらのイベントは、`Subscription` オブジェクトが渡され、その中のオブジェクトには、サブスクリプションが有効か、期日経過か、キャンセルされたかを示す `status` フィールドが含まれます。ステータスの一覧については、[サブスクリプションライフサイクル](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) の詳細を参照してください。


#### Elements

#### Checkout Sessions API

#### 組み込み作業
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/connect/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 "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Premium Service" \
  -d "description=Premium service with extra features"
```

ベーシック製品を作成します。

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --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 "<<YOUR_SECRET_KEY>>:" \
  -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 "<<YOUR_SECRET_KEY>>:" \
  -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
<form id="signup-form">
  <label>
    Email
    <input id="email" type="email" placeholder="Email address" value="test@example.com" required />
  </label>

  <button type="submit">
    Register
  </button>
</form>
```

```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/connect/use-accounts-as-customers.md)ことをお勧めします。

#### Accounts v2

```curl
curl -X POST https://api.stripe.com/v2/core/accounts \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-03-25.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 "<<YOUR_SECRET_KEY>>:" \
  --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 = '<<YOUR_SECRET_KEY>>'
Stripe.api_version = '2026-03-25.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('<<YOUR_SECRET_KEY>>', stripe_version: '2026-03-25.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
<div id="checkout-container"></div>
```

```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 (
    <CheckoutElementsProvider
      stripe={stripe}options={{clientSecret}}
    >
      <CheckoutForm />
    </CheckoutElementsProvider>
  );
};

export default App;
```

`useCheckout()` フックを使用して、CheckoutForm コンポーネントの [Checkout](https://docs.stripe.com/js/custom_checkout) オブジェクトにアクセスします。`Checkout` オブジェクトには、決済セッションからのデータと、それを更新するメソッドが含まれます。

`Checkout` オブジェクトから `lineItems` と `lineItems` を読み取り、UI に表示します。これにより、コードの変更を最小限に抑えて機能を有効にできます。たとえば、[手動通貨価格](https://docs.stripe.com/payments/custom/localize-prices/manual-currency-prices.md)を追加する場合、`total` を表示すると UI を変更する必要はありません。

```jsx
import React from 'react';
import {useCheckout} from '@stripe/react-stripe-js/checkout';

const CheckoutForm = () => {const checkoutState = useCheckout();

  if (checkoutState.type === 'loading') {
    return (
      <div>Loading...</div>
    );
  }

  if (checkoutState.type === 'error') {
    return (
      <div>Error: {checkoutState.error.message}</div>
    );
  }

  return (
    <form>{JSON.stringify(checkoutState.checkout.lineItems, null, 2)}
      {/* A formatted total amount */}
      Total: {checkoutState.checkout.total.total.amount}
    </form>
  );
};
```

## 決済情報を収集する [クライアント]

[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
<div id="payment-element"></div>
```

```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, useCheckout} from '@stripe/react-stripe-js/checkout';

const CheckoutForm = () => {
  const checkoutState = useCheckout();

  if (checkoutState.type === 'loading') {
    return (
      <div>Loading...</div>
    );
  }

  if (checkoutState.type === 'error') {
    return (
      <div>Error: {checkoutState.error.message}</div>
    );
  }

  return (
    <form>

      {JSON.stringify(checkoutState.checkout.lineItems, null, 2)}
      {/* A formatted total amount */}
      Total: {checkoutState.checkout.total.total.amount}
<PaymentElement options={{layout: 'accordion'}}/>
    </form>
  );
};

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
<button id="pay-button">Pay</button>
<div id="confirm-errors"></div>
```

```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

[useCheckout](https://docs.stripe.com/js/react_stripe_js/checkout/use_checkout) から [confirm](https://docs.stripe.com/js/custom_checkout/confirm) を呼び出して決済を送信する **Pay** ボタンをレンダリングします。

```jsx
import React from 'react';
import {useCheckout} from '@stripe/react-stripe-js/checkout';

const PayButton = () => {
  const checkoutState = useCheckout();
  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 (
    <div>
      <button disabled={!checkoutState.checkout.canConfirm || loading} onClick={handleClick}>
        Pay
      </button>
      {error && <div>{error.message}</div>}
    </div>
  )
};

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('<<YOUR_SECRET_KEY>>')

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('<<YOUR_SECRET_KEY>>')

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('<<YOUR_SECRET_KEY>>')

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('<<YOUR_SECRET_KEY>>')

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('<<YOUR_SECRET_KEY>>')

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('<<YOUR_SECRET_KEY>>')

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

#### 組み込み作業
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/billing/subscriptions/build-subscriptions)
#### Customer v1
一般的な Billing オブジェクトとその関係を示した図 (See full diagram at https://docs.stripe.com/billing/subscriptions/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/connect/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 "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Premium Service" \
  -d "description=Premium service with extra features"
```

ベーシック製品を作成します。

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --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 "<<YOUR_SECRET_KEY>>:" \
  -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 "<<YOUR_SECRET_KEY>>:" \
  -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
<form id="signup-form">
  <label>
    Email
    <input id="email" type="email" placeholder="Email address" value="test@example.com" required />
  </label>

  <button type="submit">
    Register
  </button>
</form>
```

```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/connect/use-accounts-as-customers.md)ことをお勧めします。

#### Accounts v2

```curl
curl -X POST https://api.stripe.com/v2/core/accounts \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-03-25.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 "<<YOUR_SECRET_KEY>>:" \
  --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 "<<YOUR_SECRET_KEY>>:" \
  -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 "<<YOUR_SECRET_KEY>>:" \
  -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
<head>
  <title>Checkout</title>
  <script src="https://js.stripe.com/dahlia/stripe.js"></script>
</head>
<body>
  <!-- content here -->
</body>
```

決済ページで以下の 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('<<YOUR_PUBLISHABLE_KEY>>');
```

### Payment Element をページに追加する

決済ページには Payment Element を配置する場所が必要です。決済フォームで、一意の ID を持つ空の DOM ノード (コンテナー) を作成します。

```html
<form id="payment-form">
  <div id="payment-element">
    <!-- Elements will create form elements here -->
  </div>
  <button id="submit">Subscribe</button>
  <div id="error-message">
    <!-- Display error message to your customers here -->
  </div>
</form>
```

このフォームが読み込まれた後、Payment Element のインスタンスを作成して、それをコンテナーの DOM ノードにマウントします。[サブスクリプションの作成](https://docs.stripe.com/billing/subscriptions/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('<<YOUR_PUBLISHABLE_KEY>>');

// 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('<<YOUR_SECRET_KEY>>')

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('<<YOUR_SECRET_KEY>>')

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('<<YOUR_SECRET_KEY>>')

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('<<YOUR_SECRET_KEY>>')

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('<<YOUR_SECRET_KEY>>')

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('<<YOUR_SECRET_KEY>>')

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)をご覧ください。

#### モバイル

#### iOS

固定料金の*サブスクリプション* (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)を販売する方法をご覧いただけます。[Mobile Payment Element](https://docs.stripe.com/payments/accept-a-payment.md) を使用して、アプリケーションに組み込むカスタム支払いフォームを作成できます。
![Mobile Payment Element を使用した固定価格のサブスクリプションページ](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-collect-payment-details-mobile.b11cdc8fa8952d753238df4df3375fa6.png)

> アプリ内で使用されるデジタル商品やサービス (サブスクリプション、ゲーム内通貨、ゲームレベル、プレミアムコンテンツへのアクセス、フルバージョンのロック解除など) を販売している場合は、Apple のアプリ内課金 API を使用する必要があります。このルールには、1 対 1 の個人向けサービスや[特定の地域に所在するアプリ](https://support.stripe.com/questions/changes-to-mobile-app-store-rules)など、いくつかの例外があります。詳細については、[App Store の Review ガイドライン](https://developer.apple.com/app-store/review/guidelines/#payments)をご覧ください。

## サブスクリプションを構築する

このガイドは以下の方法を説明します。

- 商品カタログを構築して、ビジネスをモデル化します。
- 顧客を追加するための登録プロセスを作成します。
- サブスクリプションを作成して、決済情報を収集します。
- 支払いとサブスクリプションのステータスをテストして、モニタリングします。
- 顧客がプランを変更したりサブスクリプションをキャンセルしたりできるようにします。
- [フレキシブル請求モード](https://docs.stripe.com/billing/subscriptions/billing-mode.md)を使用して、拡張請求動作と追加機能にアクセスする方法をご覧ください。

## Stripe でモデル化する方法

[Subscriptions](https://docs.stripe.com/api/subscriptions.md) では、*Invoices* (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) が自動的に作成されるため、請求を簡素化できます。サブスクリプションを作成して有効化するには、まず販売する内容を表す *Product* (Products represent what your business sells—whether that's a good or a service) と、請求の間隔および金額を決定する *Price* (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/billing/subscriptions/build-subscriptions)
#### Customer v1
一般的な Billing オブジェクトとその関係を示した図 (See full diagram at https://docs.stripe.com/billing/subscriptions/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/connect/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 iOS SDK](https://github.com/stripe/stripe-ios) はオープンソースです。[詳細なドキュメントが提供されており](https://stripe.dev/stripe-ios/index.html)、iOS 13 以降をサポートするアプリと互換性があります。

#### Swift Package Manager

SDK をインストールするには、以下のステップに従います。

1. Xcode で、**File (ファイル)** > **Add Package Dependencies… (パッケージ依存関係を追加)** を選択し、リポジトリー URL として `https://github.com/stripe/stripe-ios-spm` を入力します。
1. [リリースページ](https://github.com/stripe/stripe-ios/releases)から最新のバージョン番号を選択します。
1. **StripePaymentSheet** 製品を[アプリのターゲット](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app)に追加します。

#### CocoaPods

1. まだインストールしていない場合は、[CocoaPods](https://guides.cocoapods.org/using/getting-started.html) の最新バージョンをインストールします。
1. 既存の [Podfile](https://guides.cocoapods.org/syntax/podfile.html) がない場合は、以下のコマンドを実行して作成します。
   ```bash
   pod init
   ```
1. この行を `Podfile` に追加します。
   ```podfile
   pod 'StripePaymentSheet'
   ```
1. 以下のコマンドを実行します。
   ```bash
   pod install
   ```
1. これ以降は、Xcode でプロジェクトを開く際に、`.xcodeproj` ファイルではなく、必ず `.xcworkspace` ファイルを使用するということを忘れないでください。
1. 今後、SDK の最新バージョンに更新するには、以下を実行します。
   ```bash
   pod update StripePaymentSheet
   ```

#### Carthage

1. まだインストールしていない場合は、[Carthage](https://github.com/Carthage/Carthage#installing-carthage) の最新バージョンをインストールします。
1. この行を `Cartfile` に追加します。
   ```cartfile
   github "stripe/stripe-ios"
   ```
1. [Carthage のインストール手順](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos)に従います。必ず、[こちら](https://github.com/stripe/stripe-ios/tree/master/StripePaymentSheet/README.md#manual-linking)にリストされている必要なフレームワークのすべてを埋め込んでください。
1. 今後、SDK の最新バージョンに更新するには、以下のコマンドを実行します。
   ```bash
   carthage update stripe-ios --platform ios
   ```

#### 手動のフレームワーク

1. Stripe の [GitHub リリースページ](https://github.com/stripe/stripe-ios/releases/latest)に移動して、**Stripe.xcframework.zip** をダウンロードして解凍します。
1. **StripePaymentSheet.xcframework** を、Xcode プロジェクトの **General (一般) ** 設定の **Embedded Binaries (埋め込みバイナリー)** セクションにドラッグします。**Copy items if needed (必要に応じてアイテムをコピーする)** を必ず選択してください。
1. [こちら](https://github.com/stripe/stripe-ios/tree/master/StripePaymentSheet/README.md#manual-linking)にリストされている必要なフレームワークのすべてに対して、ステップ 2 を繰り返します。
1. 今後、Stripe の SDK の最新バージョンに更新するには、ステップ 1 から 3 を繰り返します。

> SDK の最新リリースおよび過去バージョンの詳細については、GitHub の [Releases (リリース)](https://github.com/stripe/stripe-ios/releases) ページをご覧ください。リポジトリの[リリースをウォッチ](https://help.github.com/en/articles/watching-and-unwatching-releases-for-a-repository#watching-releases-for-a-repository)して、新しいリリースの公開時に通知を受け取ることも可能です。

アプリの起動時に Stripe [公開可能キー](https://dashboard.stripe.com/test/apikeys)を使用して SDK を設定します。これにより、アプリが Stripe API にリクエストを送信できるようになります。

#### Swift

```swift
import UIKitimportStripePaymentSheet

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {StripeAPI.defaultPublishableKey = "<<YOUR_PUBLISHABLE_KEY>>"
        // do any other necessary launch configuration
        return true
    }
}
```

> テストおよび開発時には[テストキー](https://docs.stripe.com/keys.md#obtain-api-keys)を使用し、アプリの公開時には[本番環境](https://docs.stripe.com/keys.md#test-live-modes)キーを使用します。

次に 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 "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Premium Service" \
  -d "description=Premium service with extra features"
```

ベーシック製品を作成します。

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --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 "<<YOUR_SECRET_KEY>>:" \
  -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 "<<YOUR_SECRET_KEY>>:" \
  -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) のページをご覧ください。

```swift
struct RegisterView: View {
    @State var email = ""
    var body: some View {
        VStack {
            TextField(text: $email) {
                Text("Email")
            }
            Button {
                Task {
                    var request = URLRequest(url: URL(string: "http://localhost:4242/create-customer")!)
                    request.httpMethod = "POST"
                    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
                    request.httpBody = try! JSONEncoder().encode(["email": email])
                    let (data, _) = try! await URLSession.shared.data(for: request)
                    let responseJSON = try! JSONSerialization.jsonObject(with: data) as! [String: Any]
                    // Return the customer ID here
                    print(responseJSON["customer"])
                }
            } label: {
                Text("Submit")
            }
        }
    }
}
```

サーバーで、Stripe の Customer オブジェクトを作成します。

> #### 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/connect/use-accounts-as-customers.md)ことをお勧めします。

#### Accounts v2

```curl
curl -X POST https://api.stripe.com/v2/core/accounts \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-03-25.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 "<<YOUR_SECRET_KEY>>:" \
  --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 をレンダリングする場合は、[インテントを作成する前に支払いの詳細を収集する](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=subscription)をご覧ください。

新しい顧客がプランを選択してからサブスクリプションを作成できるようにします。このガイドでは、顧客は基本またはプレミアムから選択します。

アプリで、選択した価格 ID と顧客レコードの ID をバックエンドに渡します。

#### Accounts v2

```swift
func createSubscription(priceId: String, customerAccountId: String) async -> SubscriptionsResponse {
    var request = URLRequest(url: URL(string: "http://localhost:4242/create-subscription")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try! JSONEncoder().encode(["customerAccountId": customerAccountId, "priceId": priceId])
    let (responseData, _) = try! await URLSession.shared.data(for: request)
    // SubscriptionsResponse is a Decodable struct conforming to the expected response from your backend.
    // It should include the client_secret, as discussed below.
    let subscriptionsResponse = try! JSONDecoder().decode(SubscriptionsResponse.self, from: responseData)
    return subscriptionsResponse
}
```

#### Customers v1

```swift
func createSubscription(priceId: String, customerId: String) async -> SubscriptionsResponse {
    var request = URLRequest(url: URL(string: "http://localhost:4242/create-subscription")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try! JSONEncoder().encode(["customerId": customerId, "priceId": priceId])
    let (responseData, _) = try! await URLSession.shared.data(for: request)
    // SubscriptionsResponse is a Decodable struct conforming to the expected response from your backend.
    // It should include the client_secret, as discussed below.
    let subscriptionsResponse = try! JSONDecoder().decode(SubscriptionsResponse.self, from: responseData)
    return subscriptionsResponse
}
```

バックエンドで、`payment_behavior=default_incomplete` を使用して、ステータスが `incomplete` のサブスクリプションを作成します。次に、サブスクリプションの最初の [Payment Intent](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 "<<YOUR_SECRET_KEY>>:" \
  -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 "<<YOUR_SECRET_KEY>>:" \
  -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"
```

> *多通貨の Price* (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) パラメーターを使用して、サブスクリプションに使用する Price の通貨を指定します (`currency` パラメーターを省略すると、サブスクリプションは Price のデフォルトの通貨を使用します)。

Subscription は `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
}
```

### サーバーエンドポイントを更新します。

サブスクリプションエンドポイントに一時キーの作成を追加し、レスポンスで返します。

#### Accounts v2

#### Ruby

```ruby
ephemeral_key = Stripe::EphemeralKey.create(
  {customer_account: customer_account_id},
  {stripe_version: '2026-03-25.dahlia'}
)

{
  subscriptionId: subscription.id,
  clientSecret: subscription.latest_invoice.confirmation_secret.client_secret,
  ephemeralKey: ephemeral_key.secret,
  customerAccountId: customer_account_id,
}.to_json
```

#### Customers v1

#### Ruby

```ruby
ephemeral_key = client.v1.ephemeral_keys.create(
  {customer: customer_id},
  {stripe_version: '2025-06-30.basil'}
)

{
  subscriptionId: subscription.id,
  clientSecret: subscription.latest_invoice.confirmation_secret.client_secret,
  ephemeralKey: ephemeral_key.secret,
  customerId: customer_id,
}.to_json
```

### レスポンスモデルを更新する

#### Accounts v2

```swift
struct SubscriptionsResponse: Decodable {
    let subscriptionId: String
    let clientSecret: String
    let ephemeralKey: String
    let customerAccountId: String
}
```

#### Customers v1

```swift
struct SubscriptionsResponse: Decodable {
    let subscriptionId: String
    let clientSecret: String
    let ephemeralKey: String
    let customerId: String
}
```

### 顧客設定を PaymentSheet に渡す

#### Accounts v2

PaymentSheet を設定する際に以下を追加します。

```swift
config.customerAccount = .init(id: customerAccountId, ephemeralKeySecret: ephemeralKey)
```

#### Customers v1

PaymentSheet を設定する際に以下を追加します。

```swift
config.customer = .init(id: customerId, ephemeralKeySecret: ephemeralKey)
```

## 決済情報を収集する [クライアント]

[Payment Sheet](https://docs.stripe.com/payments/mobile/payment-sheet.md) を使用して決済の詳細を収集し、サブスクリプションを有効化します。Elements は、お使いのアプリケーションのデザインに合わせてカスタマイズできます。

Payment Sheetは、さまざまな支払い方法に必要なすべての支払い詳細を安全に収集します。Payment SheetとSubscriptionsで[サポートされる支払い方法](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#product-support)をご確認ください。

### アプリに Payment Element を追加する

> このステップは始める方法の 1 つですが、任意の[アプリ内決済導入](https://docs.stripe.com/payments/mobile.md)を使用できます。

PaymentSheet クラスを使用して、Mobile Payment Element を初期化して表示します。

```swift
struct SubscribeView: View {
    let paymentSheet: PaymentSheet
    @State var isPaymentSheetPresented = false
    init(clientSecret: String) {
        var config = PaymentSheet.Configuration()
        // Set `allowsDelayedPaymentMethods` to true if your business handles
        // delayed notification payment methods like US bank accounts.
        config.allowsDelayedPaymentMethods = true
        config.primaryButtonLabel = "Subscribe for $15/month"
        self.paymentSheet = PaymentSheet(paymentIntentClientSecret: clientSecret, configuration: config)
    }
    var body: some View {
        Button {
            isPaymentSheetPresented = true
        } label: {
            Text("Subscribe")
        }.paymentSheet(isPresented: $isPaymentSheetPresented, paymentSheet: paymentSheet) { result in
            switch result {
            case .completed:
                // Handle completion
            case .canceled:
                break
            case .failed(let error):
                // Handle error
            }
        }
    }
}
```

Mobile Payment Element によって支払い画面が表示され、顧客はここで支払い方法を選択できます。このフォームでは、顧客が選択した支払い方法で必要な支払い詳細のすべてが自動的に収集されます。

`allowsDelayedPaymentMethods` を true に設定すると、アメリカの銀行口座などの [遅延通知型](https://docs.stripe.com/payments/payment-methods.md#payment-notification)の支払い方法を使用できます。これらの支払い方法では、`PaymentSheet` が完了した時点では最終的な支払いステータスが判明せず、後になって成功または失敗が確定します。このようなタイプの支払い方法に対応する場合は、注文が確定済みであることを顧客に通知し、支払いが成功した場合にのみ注文のフルフィルメント (商品の発送など) を実行するようにします。

`PaymentSheet.Configuration` オブジェクトの [`appearance` プロパティ](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=ios) を使用して、アプリのデザインに合わせて Payment Element をカスタマイズできます。

### 支払いを確定する

Mobile Payment Element によって PaymentMethod が作成され、未完了のサブスクリプションの最初の PaymentIntent が確定され、その結果支払いが実行されます。支払いに*強力な顧客認証* (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) (SCA) が必要とされる場合は、PaymentIntent の確定前に Payment Element で認証プロセスが処理されます。

## 戻り先 URL を設定する [クライアント側]

顧客はお客様のアプリから離れて、(Safari やバンキングアプリなどで) 認証する場合があります。ユーザーが認証後にアプリに自動的に戻れるようにするには、[カスタム URL スキームを構成](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app)し、URL を SDK に転送するようにアプリのデリゲートを設定します。Stripe は[ユニバーサルリンク](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content)には対応していません。

#### SceneDelegate

#### Swift

```swift
// This method handles opening custom URL schemes (for example, "your-app://stripe-redirect")
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    guard let url = URLContexts.first?.url else {
        return
    }
    let stripeHandled = StripeAPI.handleURLCallback(with: url)
    if (!stripeHandled) {
        // This was not a Stripe url – handle the URL normally as you would
    }
}

```

#### AppDelegate

#### Swift

```swift
// This method handles opening custom URL schemes (for example, "your-app://stripe-redirect")
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
    let stripeHandled = StripeAPI.handleURLCallback(with: url)
    if (stripeHandled) {
        return true
    } else {
        // This was not a Stripe url – handle the URL normally as you would
    }
    return false
}
```

#### SwiftUI

#### Swift

```swift

@main
struct MyApp: App {
  var body: some Scene {
    WindowGroup {
      Text("Hello, world!").onOpenURL { incomingURL in
          let stripeHandled = StripeAPI.handleURLCallback(with: incomingURL)
          if (!stripeHandled) {
            // This was not a Stripe url – handle the URL normally as you would
          }
        }
    }
  }
}
```

さらに、[PaymentSheet.Configuration](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html) オブジェクトの [returnURL](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:6Stripe12PaymentSheetC13ConfigurationV9returnURLSSSgvp) をアプリの URL に設定します。

```swift
var configuration = PaymentSheet.Configuration()
configuration.returnURL = "your-app://stripe-redirect"
```

## Optional: Apple Pay を有効にする

### Apple 加盟店 ID を登録する

Apple Developer Web サイトで [新規 ID を登録](https://developer.apple.com/account/resources/identifiers/add/merchant) して、Apple 加盟店 ID を取得します。

フォームに説明と ID を入力します。説明はお客様の記録用であり、後で変更できます。アプリの名前を ID として使用することをお勧めします (`merchant.com.{{YOUR_APP_NAME}}` など)。

### 新しい Apple Pay 証明書を作成する

支払いデータを暗号化するためのアプリの証明書を作成します。

ダッシュボードの [iOS certificate settings (iOS 証明書の設定)](https://dashboard.stripe.com/settings/ios_certificates) に移動して、**新規アプリケーションを追加**をクリックし、表示されるガイドに従います。

証明書署名リクエスト (CSR) ファイルをダウンロードして、Apple Pay の利用を可能にする安全な証明書を Apple から取得します。

1 つの CSR ファイルを使用して証明書を 1 つだけ発行する必要があります。Apple 加盟店 ID を切り替えた場合、ダッシュボードの [iOS Certificate Settings (iOS 証明書の設定)](https://dashboard.stripe.com/settings/ios_certificates) に移動して、新しい CSR と証明書を取得する必要があります。

### Xcode を使用して組み込む

Apple Pay ケイパビリティをアプリに追加します。Xcode でプロジェクト設定を開き、**Signing & Capabilities (署名およびケイパビリティ)** タブを選択して、**Apple Pay** ケイパビリティを追加します。この段階で開発者アカウントへのログインを要求される場合があります。前の手順で作成した加盟店 ID を選択すると、アプリで Apple Pay を受け付けられるようになります。
![](https://b.stripecdn.com/docs-statics-srv/assets/xcode.a701d4c1922d19985e9c614a6f105bf1.png)

Xcode で Apple Pay ケイパビリティを有効化する

### Apple Pay を追加する

#### 継続支払い

Apple Pay を PaymentSheet に追加するには、Apple 加盟店 ID と[お客様のビジネスの国コード](https://dashboard.stripe.com/settings/account)で `PaymentSheet.Configuration` を初期化してから、[applePay](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:6Stripe12PaymentSheetC13ConfigurationV8applePayAC05ApplefD0VSgvp) を設定します。

継続支払いに関する [Apple のガイドライン](https://developer.apple.com/design/human-interface-guidelines/apple-pay#Supporting-subscriptions)に従い、`PKPaymentRequest` で追加の属性を設定する必要もあります。[ApplePayConfiguration.paymentRequestHandlers](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/paymentrequesthandler) にハンドラーを追加して、請求する予定の金額 (たとえば月額 9.95 USD) を指定して [PKPaymentRequest.paymentSummaryItems](https://developer.apple.com/documentation/passkit/pkpaymentrequest/1619231-paymentsummaryitems) を設定します。

`PKPaymentRequest` で `recurringPaymentRequest` または `automaticReloadPaymentRequest` プロパティを設定することで、[加盟店トークン](https://developer.apple.com/apple-pay/merchant-tokens/)を導入することもできます。

Apple Pay で継続支払いを使用する方法の詳細については、[Apple の PassKit に関するドキュメント](https://developer.apple.com/documentation/passkit/pkpaymentrequest)をご覧ください。

#### iOS (Swift)

```swift
let customHandlers = PaymentSheet.ApplePayConfiguration.Handlers(
    paymentRequestHandler: { request in
        // PKRecurringPaymentSummaryItem is available on iOS 15 or later
        if #available(iOS 15.0, *) {
            let billing = PKRecurringPaymentSummaryItem(label: "My Subscription", amount: NSDecimalNumber(string: "59.99"))

            // Payment starts today
            billing.startDate = Date()

            // Payment ends in one year
            billing.endDate = Date().addingTimeInterval(60 * 60 * 24 * 365)

            // Pay once a month.
            billing.intervalUnit = .month
            billing.intervalCount = 1

            // recurringPaymentRequest is only available on iOS 16 or later
            if #available(iOS 16.0, *) {
                request.recurringPaymentRequest = PKRecurringPaymentRequest(paymentDescription: "Recurring",
                                                                            regularBilling: billing,
                                                                            managementURL: URL(string: "https://my-backend.example.com/customer-portal")!)
                request.recurringPaymentRequest?.billingAgreement = "You'll be billed $59.99 every month for the next 12 months. To cancel at any time, go to Account and click 'Cancel Membership.'"
            }
            request.paymentSummaryItems = [billing]
            request.currencyCode = "USD"
        } else {
            // On older iOS versions, set alternative summary items.
            request.paymentSummaryItems = [PKPaymentSummaryItem(label: "Monthly plan starting July 1, 2022", amount: NSDecimalNumber(string: "59.99"), type: .final)]
        }
        return request
    }
)
var configuration = PaymentSheet.Configuration()
configuration.applePay = .init(merchantId: "merchant.com.your_app_name",
                                merchantCountryCode: "US",
                                customHandlers: customHandlers)
```

### 注文の追跡

iOS 16 以降で[注文の追跡](https://developer.apple.com/design/human-interface-guidelines/technologies/wallet/designing-order-tracking)情報を追加するには、`PaymentSheet.ApplePayConfiguration.Handlers` で [authorizationResultHandler](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/authorizationresulthandler) を設定します。支払いの完了後、Stripe は iOS が Apple Pay の決済画面を閉じる前に実装を呼び出します。

`authorizationResultHandler` の実装で、完了した注文の注文の詳細をサーバーから取得します。提供された [PKPaymentAuthorizationResult](https://developer.apple.com/documentation/passkit/pkpaymentauthorizationresult) に詳細を追加し、変更された結果を返します。

注文の追跡の詳細については、[Apple のウォレットでの注文に関するドキュメント](https://developer.apple.com/documentation/walletorders)をご覧ください。

#### iOS (Swift)

```swift
let customHandlers = PaymentSheet.ApplePayConfiguration.Handlers(
    authorizationResultHandler: { result in
      do {
        // Fetch the order details from your service
        let myOrderDetails = try await MyAPIClient.shared.fetchOrderDetails(orderID: orderID)
        result.orderDetails = PKPaymentOrderDetails(
          orderTypeIdentifier: myOrderDetails.orderTypeIdentifier, // "com.myapp.order"
          orderIdentifier: myOrderDetails.orderIdentifier, // "ABC123-AAAA-1111"
          webServiceURL: myOrderDetails.webServiceURL, // "https://my-backend.example.com/apple-order-tracking-backend"
          authenticationToken: myOrderDetails.authenticationToken) // "abc123"
        // Return your modified PKPaymentAuthorizationResult
        return result
      } catch {
        return PKPaymentAuthorizationResult(status: .failure, errors: [error])
      }
    }
)
var configuration = PaymentSheet.Configuration()
configuration.applePay = .init(merchantId: "merchant.com.your_app_name",
                               merchantCountryCode: "US",
                               customHandlers: customHandlers)
```

## Webhook をリッスンする [サーバー]

導入を完了するには、Stripe から送信される *Webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) を処理する必要があります。Webhook は、サブスクリプションによって新しい請求書が作成されるなど、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('<<YOUR_SECRET_KEY>>')

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 does not 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.id` とともにデータベースに保存します。アプリケーションでユーザーに対して有効にする機能を決定する際に、このレコードを確認します。

サブスクリプションのステータスは、存続期間のどの時点でも変化する可能性があります。アプリケーションが Stripe に直接コールを行っていない場合でも同様です。例えば、クレジットカードの期限超過で更新が失敗した場合、サブスクリプションは期日超過の状態になります。また、[カスタマーポータル](https://docs.stripe.com/customer-management.md)を導入している場合、ユーザーが直接アプリケーションを開かずにサブスクリプションをキャンセルすることがあります。ハンドラを正しく導入することで、アプリケーションを Stripe と常に同期した状態に維持できます。

## サブスクリプションをキャンセルする [クライアントとサーバー]

顧客にサブスクリプションのキャンセルを許可するのは一般的です。この例では、アカウントの設定ページにキャンセルオプションを追加します。

このサンプルではフロントエンドでサブスクリプション ID を収集していますが、アプリケーションではこの情報をデータベース内のログインユーザーに関する情報から取得できます。
![サブスクリプションのキャンセルインターフェイスの例。](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-subscriptions-guide-account-settings.6559626ba4b434826a67abfea165e097.png)

サブスクリプションのキャンセル機能が設定されたアカウント設定

```swift
func cancelSubscription() async {
    var request = URLRequest(url: URL(string: "http://localhost:4242/cancel-subscription")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try! JSONEncoder().encode(["subscriptionId": subscription.id])
    let (subscriptionResponse, _) = try! await URLSession.shared.data(for: request)
    // Update the state to show the subscription has been cancelled
}
```

バックエンドで、アプリから呼び出すエンドポイントを定義します。

#### 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('<<YOUR_SECRET_KEY>>')

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) で表示できます。

詳しくは、[Billing の実装のテスト](https://docs.stripe.com/billing/testing.md)をご覧ください。

## Optional: 顧客がプランを変更できるようにする [クライアントとサーバー]

顧客にサブスクリプションの変更を許可するには、変更後のオプションの価格 ID を収集します。次にアプリからバックエンドのエンドポイントにこの新しい価格 ID を送信します。この例ではサブスクリプション ID も渡していますが、これはログインしているユーザーのデータベースから取得できます。

```swift
func updateSubscription(priceId: String, subscriptionId: String) async -> SubscriptionsResponse {
    var request = URLRequest(url: URL(string: "http://localhost:4242/update-subscription")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try! JSONEncoder().encode(["subscriptionId": subscriptionId, "priceId": priceId])
    let (responseData, _) = try! await URLSession.shared.data(for: request)
    // SubscriptionsResponse is a Decodable struct conforming to the expected response from your backend
    let subscriptionsResponse = try! JSONDecoder().decode(SubscriptionsResponse.self, from: responseData)
    return subscriptionsResponse
}
```

フロントエンドから呼び出すエンドポイントをバックエンドで定義し、サブスクリプション 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('<<YOUR_SECRET_KEY>>')

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)と呼ばれる未払い額の調整が行われます。[create preview invoice (請求書プレビューの作成) エンドポイント](https://docs.stripe.com/api/invoices/create_preview.md)を使用して、調整後の金額を顧客に表示できます。

アプリから、請求書のプレビューの詳細をバックエンドのエンドポイントに渡します。

```swift
func createPreviewInvoice(customerId: String, subscriptionId: String, newPriceId: String) async -> InvoiceResponse {
    var request = URLRequest(url: URL(string: "http://localhost:4242/create-preview-invoice")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try! JSONEncoder().encode(["subscriptionId": subscriptionId, "customerId": customerId, "newPriceId": newPriceId])
    let (responseData, _) = try! await URLSession.shared.data(for: request)
    // Invoice is a Decodable struct conforming to the expected response from your backend
    let invoiceResponse = try! JSONDecoder().decode(InvoiceResponse.self, from: responseData)
    return invoiceResponse
}
```

バックエンドで、フロントエンドから呼び出すエンドポイントを定義します。

#### 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('<<YOUR_SECRET_KEY>>')

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('<<YOUR_SECRET_KEY>>')

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 を送信します。

```swift
func retrieveCustomerPaymentMethod(paymentMethodId: String) async -> PaymentMethodResponse {
    var request = URLRequest(url: URL(string: "http://localhost:4242/retrieve-customer-payment-method")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try! JSONEncoder().encode(["paymentMethodId": paymentMethodId])
    let (responseData, _) = try! await URLSession.shared.data(for: request)
    // PaymentMethodResponse is a Decodable struct conforming to the expected response from your backend
    let paymentMethodResponse = try! JSONDecoder().decode(PaymentMethodResponse.self, from: responseData)
    return paymentMethodResponse
}
```

バックエンドで、アプリから呼び出すエンドポイントを定義します。

#### 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('<<YOUR_SECRET_KEY>>')

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)をご覧ください。

#### Android

固定料金の*サブスクリプション* (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)を販売する方法をご覧いただけます。[Mobile Payment Element](https://docs.stripe.com/payments/accept-a-payment.md) を使用して、アプリケーションに組み込むカスタム支払いフォームを作成できます。
![Mobile Payment Element を使用した固定価格のサブスクリプションページ](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-collect-payment-details-mobile.b11cdc8fa8952d753238df4df3375fa6.png)

> アプリ内で使用されるデジタル商品やサービス (サブスクリプション、ゲーム内通貨、ゲームレベル、プレミアムコンテンツへのアクセス、フルバージョンのロック解除など) を販売している場合は、Apple のアプリ内課金 API を使用する必要があります。このルールには、1 対 1 の個人向けサービスや[特定の地域に所在するアプリ](https://support.stripe.com/questions/changes-to-mobile-app-store-rules)など、いくつかの例外があります。詳細については、[App Store の Review ガイドライン](https://developer.apple.com/app-store/review/guidelines/#payments)をご覧ください。

## サブスクリプションを構築する

このガイドは以下の方法を説明します。

- 商品カタログを構築して、ビジネスをモデル化します。
- 顧客を追加するための登録プロセスを作成します。
- サブスクリプションを作成して、決済情報を収集します。
- 支払いとサブスクリプションのステータスをテストして、モニタリングします。
- 顧客がプランを変更したりサブスクリプションをキャンセルしたりできるようにします。
- [フレキシブル請求モード](https://docs.stripe.com/billing/subscriptions/billing-mode.md)を使用して、拡張請求動作と追加機能にアクセスする方法をご覧ください。

## Stripe でモデル化する方法

[Subscriptions](https://docs.stripe.com/api/subscriptions.md) では、*Invoices* (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) が自動的に作成されるため、請求を簡素化できます。サブスクリプションを作成して有効化するには、まず販売する内容を表す *Product* (Products represent what your business sells—whether that's a good or a service) と、請求の間隔および金額を決定する *Price* (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/billing/subscriptions/build-subscriptions)
#### Customer v1
一般的な Billing オブジェクトとその関係を示した図 (See full diagram at https://docs.stripe.com/billing/subscriptions/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/connect/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 Android SDK](https://github.com/stripe/stripe-android) はオープンソースであり、[詳細なドキュメントが提供されています](https://stripe.dev/stripe-android/)。

SDK をインストールするには、[app/build.gradle](https://developer.android.com/studio/build/dependencies) ファイルの `dependencies` ブロックに `stripe-android` を追加します。

#### Kotlin

```kotlin
plugins {
    id("com.android.application")
}

android { ... }

dependencies {
  // ...

  // Stripe Android SDK
  implementation("com.stripe:stripe-android:23.3.0")
  // Include the financial connections SDK to support US bank account as a payment method
  implementation("com.stripe:financial-connections:23.3.0")
}
```

> SDK の最新リリースおよび過去バージョンの詳細については、GitHub の [Releases](https://github.com/stripe/stripe-android/releases) ページをご覧ください。新しいリリースの公開時に通知を受け取るには、[リポジトリのリリースを確認](https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository)してください。

Stripe の[公開可能キー](https://dashboard.stripe.com/apikeys)を使用して SDK を設定し、 `Application` サブクラスなどで、Stripe API へのリクエストを実行できるようにします。

#### Kotlin

```kotlin
import com.stripe.android.PaymentConfiguration

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        PaymentConfiguration.init(
            applicationContext,
            "<<YOUR_PUBLISHABLE_KEY>>"
        )
    }
}
```

> テストおよび開発時には[テストキー](https://docs.stripe.com/keys.md#obtain-api-keys)を使用し、アプリの公開時には[本番環境](https://docs.stripe.com/keys.md#test-live-modes)キーを使用します。

次に 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 "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Premium Service" \
  -d "description=Premium service with extra features"
```

ベーシック製品を作成します。

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --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 "<<YOUR_SECRET_KEY>>:" \
  -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 "<<YOUR_SECRET_KEY>>:" \
  -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 では、サブスクリプションごとに顧客が必要です。アプリケーションのフロントエンドで、ユーザーから必要な情報を収集し、バックエンドに渡します。

ネットワークライブラリを使用してバックエンドにネットワークリクエストを送信できます。このドキュメントでは [okhttp](https://square.github.io/okhttp/) を使用しますが、プロジェクトに最適なライブラリを選択できます。

```groovy
dependencies {
  ...
  implementation "com.squareup.okhttp3:okhttp:4.12.0"
}
```

住所の詳細を収集する必要がある場合、Address Element を使用すると顧客の配送先住所または請求先住所を収集できます。Address Element についての詳細は、[Address Element](https://docs.stripe.com/elements/address-element.md) のページをご覧ください。

```kotlin
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Button
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject

@Composable
fun RegisterView() {
    var email by remember { mutableStateOf("") }
    Column {
        OutlinedTextField(value = email,
            label = { Text(text = "Email") },
            onValueChange = { email = it })
        Button(onClick = {
            val body = JSONObject().put("email", email).toString()
                .toRequestBody("application/json".toMediaType())
            val request =
                Request.Builder().url("http://10.0.2.2:4567/create-customer").post(body).build()
            CoroutineScope(Dispatchers.IO).launch {
                OkHttpClient().newCall(request).execute().use { response ->
                    if (response.isSuccessful) {
                        println(JSONObject(response.body!!.string()).get("customer"))
                    }
                }
            }
        }) {
            Text(text = "Submit")
        }
    }
}
```

サーバーで、Stripe の Customer オブジェクトを作成します。

> #### 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/connect/use-accounts-as-customers.md)ことをお勧めします。

#### Accounts v2

```curl
curl -X POST https://api.stripe.com/v2/core/accounts \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-03-25.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 "<<YOUR_SECRET_KEY>>:" \
  --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 をレンダリングする場合は、[インテントを作成する前に支払いの詳細を収集する](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=subscription)をご覧ください。

新しい顧客がプランを選択してからサブスクリプションを作成できるようにします。このガイドでは、顧客は基本またはプレミアムから選択します。

アプリで、選択した価格 ID と顧客レコードの ID をバックエンドに渡します。

#### Accounts v2

```kotlin
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject

fun createSubscription(priceId: String, customerAccountId: String): SubscriptionResponse? {
    val body = JSONObject()
        .put("priceId", priceId)
        .put("customerAccountId", customerAccountId).toString()
        .toRequestBody("application/json".toMediaType())
    val request =
        Request.Builder().url("http://10.0.2.2:4567/create-subscription").post(body).build()
    OkHttpClient().newCall(request).execute().use { response ->
        if (response.isSuccessful) {
            // SubscriptionsResponse is data class conforming to the expected response from your backend.
            // It should include the client_secret, as discussed below.
            return Gson().fromJson(response.body!!.string(), SubscriptionResponse::class.java)
        }
    }
    return null
}
```

#### Customers v1

```kotlin
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject

fun createSubscription(priceId: String, customerId: String): SubscriptionResponse? {
    val body = JSONObject()
        .put("priceId", priceId)
        .put("customerId", customerId).toString()
        .toRequestBody("application/json".toMediaType())
    val request =
        Request.Builder().url("http://10.0.2.2:4567/create-subscription").post(body).build()
    OkHttpClient().newCall(request).execute().use { response ->
        if (response.isSuccessful) {
            // SubscriptionsResponse is data class conforming to the expected response from your backend.
            // It should include the client_secret, as discussed below.
            return Gson().fromJson(response.body!!.string(), SubscriptionResponse::class.java)
        }
    }
    return null
}
```

バックエンドで、`payment_behavior=default_incomplete` を使用して、ステータスが `incomplete` のサブスクリプションを作成します。次に、サブスクリプションの最初の [Payment Intent](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 "<<YOUR_SECRET_KEY>>:" \
  -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 "<<YOUR_SECRET_KEY>>:" \
  -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"
```

> *多通貨の Price* (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) パラメーターを使用して、サブスクリプションに使用する Price の通貨を指定します (`currency` パラメーターを省略すると、サブスクリプションは Price のデフォルトの通貨を使用します)。

Subscription は `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
}
```

### サーバーエンドポイントを更新します。

サブスクリプションエンドポイントに一時キーの作成を追加し、レスポンスで返します。

#### Accounts v2

#### Ruby

```ruby
ephemeral_key = Stripe::EphemeralKey.create(
  {customer_account: customer_account_id},
  {stripe_version: '2026-03-25.dahlia'}
)

{
  subscriptionId: subscription.id,
  clientSecret: subscription.latest_invoice.confirmation_secret.client_secret,
  ephemeralKey: ephemeral_key.secret,
  customerAccountId: customer_account_id,
}.to_json
```

#### Customers v1

#### Ruby

```ruby
ephemeral_key = client.v1.ephemeral_keys.create(
  {customer: customer_id},
  {stripe_version: '2025-06-30.basil'}
)

{
  subscriptionId: subscription.id,
  clientSecret: subscription.latest_invoice.confirmation_secret.client_secret,
  ephemeralKey: ephemeral_key.secret,
  customerId: customer_id,
}.to_json
```

### レスポンスモデルを更新する

#### Accounts v2

```kotlin
data class SubscriptionsResponse(
    val subscriptionId: String,
    val clientSecret: String,
    val ephemeralKey: String,
    val customerAccountId: String
)
```

#### Customers v1

```kotlin
data class SubscriptionsResponse(
    val subscriptionId: String,
    val clientSecret: String,
    val ephemeralKey: String,
    val customerId: String
)
```

### 顧客設定を PaymentSheet に渡す

#### Accounts v2

PaymentSheet を設定する際に以下を追加します。

```kotlin
PaymentSheet.Configuration(
    primaryButtonLabel = "Subscribe for $15/month",
    merchantDisplayName = "My merchant name",
    customerAccount = PaymentSheet.CustomerConfiguration(
        id = customerAccountId,
        ephemeralKeySecret = ephemeralKey
    )
)
```

#### Customers v1

PaymentSheet を設定する際に以下を追加します。

```kotlin
PaymentSheet.Configuration(
    primaryButtonLabel = "Subscribe for $15/month",
    merchantDisplayName = "My merchant name",
    customer = PaymentSheet.CustomerConfiguration(
        id = customerId,
        ephemeralKeySecret = ephemeralKey
    )
)
```

## 決済情報を収集する [クライアント]

[Payment Sheet](https://docs.stripe.com/payments/mobile/payment-sheet.md) を使用して決済の詳細を収集し、サブスクリプションを有効化します。Elements は、お使いのアプリケーションのデザインに合わせてカスタマイズできます。

Payment Sheetは、さまざまな支払い方法に必要なすべての支払い詳細を安全に収集します。Payment SheetとSubscriptionsで[サポートされる支払い方法](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#product-support)をご確認ください。

### アプリに Payment Element を追加する

> このステップは始める方法の 1 つですが、任意の[アプリ内決済導入](https://docs.stripe.com/payments/mobile.md)を使用できます。

PaymentSheet クラスを使用して、Mobile Payment Element を初期化して表示します。

```kotlin
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.paymentsheet.PaymentSheetResult
import com.stripe.android.paymentsheet.rememberPaymentSheet

@Composable
fun SubscribeView(clientSecret: String) {
    val paymentSheet = rememberPaymentSheet(::onPaymentSheetResult)

    Button(onClick = {
        paymentSheet.presentWithPaymentIntent(
            clientSecret, PaymentSheet.Configuration(
                primaryButtonLabel = "Subscribe for $15/month",
                merchantDisplayName = "My merchant name",
                // Set `allowsDelayedPaymentMethods` to true if your business handles
                // delayed notification payment methods like US bank accounts.
                allowsDelayedPaymentMethods = true
            )
        )
    }) {
        Text(text = "Subscribe")
    }
}

fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {
    when (paymentSheetResult) {
        is PaymentSheetResult.Canceled -> {
            print("Canceled")
        }

        is PaymentSheetResult.Failed -> {
            print("Error: ${paymentSheetResult.error}")
        }

        is PaymentSheetResult.Completed -> {
            // Display for example, an order confirmation screen
            print("Completed")
        }
    }
}
```

Mobile Payment Element によって支払い画面が表示され、顧客はここで支払い方法を選択できます。このフォームでは、顧客が選択した支払い方法で必要な支払い詳細のすべてが自動的に収集されます。

`allowsDelayedPaymentMethods` を true に設定すると、アメリカの銀行口座などの [遅延通知型](https://docs.stripe.com/payments/payment-methods.md#payment-notification)の支払い方法を使用できます。これらの支払い方法では、`PaymentSheet` が完了した時点では最終的な支払いステータスが判明せず、後になって成功または失敗が確定します。このようなタイプの支払い方法に対応する場合は、注文が確定済みであることを顧客に通知し、支払いが成功した場合にのみ注文のフルフィルメント (商品の発送など) を実行するようにします。

`PaymentSheet.Configuration` オブジェクトの [`appearance` プロパティ](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=ios) を使用して、アプリのデザインに合わせて Payment Element をカスタマイズできます。

### 支払いを確定する

Mobile Payment Element によって PaymentMethod が作成され、未完了のサブスクリプションの最初の PaymentIntent が確定され、その結果支払いが実行されます。支払いに*強力な顧客認証* (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) (SCA) が必要とされる場合は、PaymentIntent の確定前に Payment Element で認証プロセスが処理されます。

## Webhook をリッスンする [サーバー]

導入を完了するには、Stripe から送信される *Webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) を処理する必要があります。Webhook は、サブスクリプションによって新しい請求書が作成されるなど、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('<<YOUR_SECRET_KEY>>')

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 does not 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.id` とともにデータベースに保存します。アプリケーションでユーザーに対して有効にする機能を決定する際に、このレコードを確認します。

サブスクリプションのステータスは、存続期間のどの時点でも変化する可能性があります。アプリケーションが Stripe に直接コールを行っていない場合でも同様です。例えば、クレジットカードの期限超過で更新が失敗した場合、サブスクリプションは期日超過の状態になります。また、[カスタマーポータル](https://docs.stripe.com/customer-management.md)を導入している場合、ユーザーが直接アプリケーションを開かずにサブスクリプションをキャンセルすることがあります。ハンドラを正しく導入することで、アプリケーションを Stripe と常に同期した状態に維持できます。

## サブスクリプションをキャンセルする [クライアントとサーバー]

顧客にサブスクリプションのキャンセルを許可するのは一般的です。この例では、アカウントの設定ページにキャンセルオプションを追加します。

このサンプルではフロントエンドでサブスクリプション ID を収集していますが、アプリケーションではこの情報をデータベース内のログインユーザーに関する情報から取得できます。
![サブスクリプションのキャンセルインターフェイスの例。](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-subscriptions-guide-account-settings.6559626ba4b434826a67abfea165e097.png)

サブスクリプションのキャンセル機能が設定されたアカウント設定

```kotlin
fun cancelSubscription(subscriptionId: String): SubscriptionResponse? {
    val body = JSONObject().put("subscriptionId", subscriptionId).toString()
        .toRequestBody("application/json".toMediaType())
    val request =
        Request.Builder().url("http://10.0.2.2:4567/cancel-subscription").post(body).build()
    OkHttpClient().newCall(request).execute().use { response ->
        if (response.isSuccessful) {
            return Gson().fromJson(response.body!!.string(), SubscriptionResponse::class.java)
        }
    }
    return null
}
```

バックエンドで、アプリから呼び出すエンドポイントを定義します。

#### 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('<<YOUR_SECRET_KEY>>')

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) で表示できます。

詳しくは、[Billing の実装のテスト](https://docs.stripe.com/billing/testing.md)をご覧ください。

## Optional: 顧客がプランを変更できるようにする [クライアントとサーバー]

顧客にサブスクリプションの変更を許可するには、変更後のオプションの価格 ID を収集します。次にアプリからバックエンドのエンドポイントにこの新しい価格 ID を送信します。この例ではサブスクリプション ID も渡していますが、これはログインしているユーザーのデータベースから取得できます。

```kotlin
fun updateSubscription(subscriptionId: String, priceId: String): SubscriptionResponse? {
    val body = JSONObject()
        .put("priceId", priceId)
        .put("subscriptionId", subscriptionId).toString()
        .toRequestBody("application/json".toMediaType())
    val request =
        Request.Builder().url("http://10.0.2.2:4567/update-subscription").post(body).build()
    OkHttpClient().newCall(request).execute().use { response ->
        if (response.isSuccessful) {
            // It should include the client_secret, as discussed below.
            return Gson().fromJson(response.body!!.string(), SubscriptionResponse::class.java)
        }
    }
    return null
}
```

フロントエンドから呼び出すエンドポイントをバックエンドで定義し、サブスクリプション 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('<<YOUR_SECRET_KEY>>')

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)と呼ばれる未払い額の調整が行われます。[create preview invoice (請求書プレビューの作成) エンドポイント](https://docs.stripe.com/api/invoices/create_preview.md)を使用して、調整後の金額を顧客に表示できます。

アプリから、請求書のプレビューの詳細をバックエンドのエンドポイントに渡します。

```kotlin
fun createPreviewInvoice(
    subscriptionId: String,
    priceId: String,
    newPriceId: String
): InvoiceResponse? {
    val body = JSONObject()
        .put("priceId", priceId)
        .put("subscriptionId", subscriptionId)
        .put("newPriceId", newPriceId).toString()
        .toRequestBody("application/json".toMediaType())
    val request =
        Request.Builder().url("http://10.0.2.2:4567/create-preview-invoice").post(body).build()
    OkHttpClient().newCall(request).execute().use { response ->
        if (response.isSuccessful) {
            // InvoiceResponse is a data class conforming to the expected response from your backend
            return Gson().fromJson(response.body!!.string(), InvoiceResponse::class.java)
        }
    }
    return null
}
```

バックエンドで、フロントエンドから呼び出すエンドポイントを定義します。

#### 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('<<YOUR_SECRET_KEY>>')

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('<<YOUR_SECRET_KEY>>')

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 を送信します。

```kotlin
fun retrieveCustomerPaymentMethod(paymentMethodId: String): PaymentMethodResponse? {
    val body = JSONObject()
        .put("paymentMethodId", paymentMethodId).toString()
        .toRequestBody("application/json".toMediaType())
    val request =
        Request.Builder().url("http://10.0.2.2:4567/retrieve-customer-payment-method").post(body)
            .build()
    OkHttpClient().newCall(request).execute().use { response ->
        if (response.isSuccessful) {
            // PaymentMethodResponse is a data class conforming to the expected response from your backend
            return Gson().fromJson(response.body!!.string(), PaymentMethodResponse::class.java)
        }
    }
    return null
}
```

バックエンドで、アプリから呼び出すエンドポイントを定義します。

#### 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('<<YOUR_SECRET_KEY>>')

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)をご覧ください。

#### React Native

固定料金の*サブスクリプション* (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)を販売する方法をご覧いただけます。[Mobile Payment Element](https://docs.stripe.com/payments/accept-a-payment.md) を使用して、アプリケーションに組み込むカスタム支払いフォームを作成できます。
![Mobile Payment Element を使用した固定価格のサブスクリプションページ](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-collect-payment-details-mobile.b11cdc8fa8952d753238df4df3375fa6.png)

> アプリ内で使用されるデジタル商品やサービス (サブスクリプション、ゲーム内通貨、ゲームレベル、プレミアムコンテンツへのアクセス、フルバージョンのロック解除など) を販売している場合は、Apple のアプリ内課金 API を使用する必要があります。このルールには、1 対 1 の個人向けサービスや[特定の地域に所在するアプリ](https://support.stripe.com/questions/changes-to-mobile-app-store-rules)など、いくつかの例外があります。詳細については、[App Store の Review ガイドライン](https://developer.apple.com/app-store/review/guidelines/#payments)をご覧ください。

## サブスクリプションを構築する

このガイドは以下の方法を説明します。

- 商品カタログを構築して、ビジネスをモデル化します。
- 顧客を追加するための登録プロセスを作成します。
- サブスクリプションを作成して、決済情報を収集します。
- 支払いとサブスクリプションのステータスをテストして、モニタリングします。
- 顧客がプランを変更したりサブスクリプションをキャンセルしたりできるようにします。
- [フレキシブル請求モード](https://docs.stripe.com/billing/subscriptions/billing-mode.md)を使用して、拡張請求動作と追加機能にアクセスする方法をご覧ください。

## Stripe でモデル化する方法

[Subscriptions](https://docs.stripe.com/api/subscriptions.md) では、*Invoices* (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) が自動的に作成されるため、請求を簡素化できます。サブスクリプションを作成して有効化するには、まず販売する内容を表す *Product* (Products represent what your business sells—whether that's a good or a service) と、請求の間隔および金額を決定する *Price* (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/billing/subscriptions/build-subscriptions)
#### Customer v1
一般的な Billing オブジェクトとその関係を示した図 (See full diagram at https://docs.stripe.com/billing/subscriptions/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/connect/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 を設定する

[React Native SDK](https://github.com/stripe/stripe-react-native) はオープンソースであり、詳細なドキュメントが提供されています。内部では、[ネイティブの iOS](https://github.com/stripe/stripe-ios) および [Android](https://github.com/stripe/stripe-android) の SDK を使用します。Stripe の React Native SDK をインストールするには、プロジェクトのディレクトリーで (使用するパッケージマネージャーによって異なる) 次のいずれかのコマンドを実行します。

#### yarn

```bash
yarn add @stripe/stripe-react-native
```

#### npm

```bash
npm install @stripe/stripe-react-native
```

次に、その他の必要な依存関係をインストールします。

- iOS の場合は、**ios** ディレクトリに移動して `pod install` を実行し、必要なネイティブ依存関係もインストールします。
- Android の場合は、依存関係をインストールする必要はありません。

> [公式の TypeScript ガイド](https://reactnative.dev/docs/typescript#adding-typescript-to-an-existing-project)に従って TypeScript のサポートを追加することをお勧めします。

### Stripe の初期化

React Native アプリで Stripe を初期化するには、決済画面を `StripeProvider` コンポーネントでラップするか、`initStripe` 初期化メソッドを使用します。`publishableKey` の API [公開可能キー](https://docs.stripe.com/keys.md#obtain-api-keys)のみが必要です。次の例は、`StripeProvider` コンポーネントを使用して Stripe を初期化する方法を示しています。

```jsx
import { useState, useEffect } from 'react';
import { StripeProvider } from '@stripe/stripe-react-native';

function App() {
  const [publishableKey, setPublishableKey] = useState('');

  const fetchPublishableKey = async () => {
    const key = await fetchKey(); // fetch key from your server here
    setPublishableKey(key);
  };

  useEffect(() => {
    fetchPublishableKey();
  }, []);

  return (
    <StripeProvider
      publishableKey={publishableKey}
      merchantIdentifier="merchant.identifier" // required for Apple Pay
      urlScheme="your-url-scheme" // required for 3D Secure and bank redirects
    >
      {/* Your app code here */}
    </StripeProvider>
  );
}
```

> テストおよび開発時には API の[テストキー](https://docs.stripe.com/keys.md#obtain-api-keys)を使用し、アプリの公開時には[本番環境](https://docs.stripe.com/keys.md#test-live-modes)キーを使用します。

次に 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 "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Premium Service" \
  -d "description=Premium service with extra features"
```

ベーシック製品を作成します。

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --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 "<<YOUR_SECRET_KEY>>:" \
  -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 "<<YOUR_SECRET_KEY>>:" \
  -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) のページをご覧ください。

```javascript
import React from 'react';
import {View, TextInput, StyleSheet, Button, Platform} from 'react-native';

function RegisterView() {
  const [email, setEmail] = React.useState('');

  const createCustomer = async () => {
    const apiEndpoint =
      Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567';
    const response = await fetch(`${apiEndpoint}/create-customer`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        email: email,
      }),
    });
    if (response.status === 200) {
      const customer = await response.json();
      console.log(customer);
    }
  };

  return (
    <View>
      <TextInput
        style={styles.input}
        placeholder="Email"
        value={email}
        onChangeText={setEmail}
      />
      <Button
        title="Register"
        onPress={async () => {
          await createCustomer();
        }}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  input: {
    height: 40,
    margin: 12,
    borderWidth: 1,
    padding: 10,
  },
});

export default RegisterView;
```

サーバーで、Stripe の Customer オブジェクトを作成します。

> #### 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/connect/use-accounts-as-customers.md)ことをお勧めします。

#### Accounts v2

```curl
curl -X POST https://api.stripe.com/v2/core/accounts \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-03-25.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 "<<YOUR_SECRET_KEY>>:" \
  --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 をレンダリングする場合は、[インテントを作成する前に支払いの詳細を収集する](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=subscription)をご覧ください。

新しい顧客がプランを選択してからサブスクリプションを作成できるようにします。このガイドでは、顧客は基本またはプレミアムから選択します。

アプリで、選択した価格 ID と顧客レコードの ID をバックエンドに渡します。

#### Accounts v2

```javascript
const createSubscription = async (priceId, customerAccountId) => {
  const apiEndpoint =
    Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567';
  const response = await fetch(`${apiEndpoint}/create-subscription`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      priceId: priceId,
      customerAccountId: customerAccountId,
    }),
  });
  if (response.status === 200) {
    const subscription = await response.json();
    return subscription;
  }
};
```

#### Customers v1

```javascript
const createSubscription = async (priceId, customerId) => {
  const apiEndpoint =
    Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567';
  const response = await fetch(`${apiEndpoint}/create-subscription`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      priceId: priceId,
      customerId: customerId,
    }),
  });
  if (response.status === 200) {
    const subscription = await response.json();
    return subscription;
  }
};
```

バックエンドで、`payment_behavior=default_incomplete` を使用して、ステータスが `incomplete` のサブスクリプションを作成します。次に、サブスクリプションの最初の [Payment Intent](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 "<<YOUR_SECRET_KEY>>:" \
  -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 "<<YOUR_SECRET_KEY>>:" \
  -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"
```

> *多通貨の Price* (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) パラメーターを使用して、サブスクリプションに使用する Price の通貨を指定します (`currency` パラメーターを省略すると、サブスクリプションは Price のデフォルトの通貨を使用します)。

Subscription は `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
}
```

### サーバーエンドポイントを更新します。

サブスクリプションエンドポイントに一時キーの作成を追加し、レスポンスで返します。

#### Accounts v2

#### Ruby

```ruby
ephemeral_key = Stripe::EphemeralKey.create(
  {customer_account: customer_account_id},
  {stripe_version: '2026-03-25.dahlia'}
)

{
  subscriptionId: subscription.id,
  clientSecret: subscription.latest_invoice.confirmation_secret.client_secret,
  ephemeralKey: ephemeral_key.secret,
  customerAccountId: customer_account_id,
}.to_json
```

#### Customers v1

#### Ruby

```ruby
ephemeral_key = client.v1.ephemeral_keys.create(
  {customer: customer_id},
  {stripe_version: '2025-06-30.basil'}
)

{
  subscriptionId: subscription.id,
  clientSecret: subscription.latest_invoice.confirmation_secret.client_secret,
  ephemeralKey: ephemeral_key.secret,
  customerId: customer_id,
}.to_json
```

### レスポンスモデルを更新する

#### Accounts v2

```typescript
interface SubscriptionsResponse {
  subscriptionId: string;
  clientSecret: string;
  ephemeralKey: string;
  customerAccountId: string;
}
```

#### Customers v1

```typescript
interface SubscriptionsResponse {
  subscriptionId: string;
  clientSecret: string;
  ephemeralKey: string;
  customerId: string;
}
```

### 顧客設定を PaymentSheet に渡す

#### Accounts v2

PaymentSheet を初期化する際に以下のパラメーターを追加します。

```javascript
await initPaymentSheet({
  paymentIntentClientSecret: clientSecret,
  customerAccountId: customerAccountId,
  customerEphemeralKeySecret: ephemeralKey,
  // ... other parameters
});
```

#### Customers v1

PaymentSheet を初期化する際に以下のパラメーターを追加します。

```javascript
await initPaymentSheet({
  paymentIntentClientSecret: clientSecret,
  customerId: customerId,
  customerEphemeralKeySecret: ephemeralKey,
  // ... other parameters
});
```

## 決済情報を収集する [クライアント]

[Payment Sheet](https://docs.stripe.com/payments/mobile/payment-sheet.md) を使用して決済の詳細を収集し、サブスクリプションを有効化します。Elements は、お使いのアプリケーションのデザインに合わせてカスタマイズできます。

Payment Sheetは、さまざまな支払い方法に必要なすべての支払い詳細を安全に収集します。Payment SheetとSubscriptionsで[サポートされる支払い方法](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#product-support)をご確認ください。

### アプリに Payment Element を追加する

> このステップは始める方法の 1 つですが、任意の[アプリ内決済導入](https://docs.stripe.com/payments/mobile.md)を使用できます。

PaymentSheet クラスを使用して、Mobile Payment Element を初期化して表示します。

```javascript
import React from 'react';
import {useStripe, PaymentSheetError} from '@stripe/stripe-react-native';
import {View, Button} from 'react-native';

function SubscribeView({clientSecret}) {
  const {initPaymentSheet, presentPaymentSheet} = useStripe();

  React.useEffect(() => {
    const initializePaymentSheet = async () => {
      const {error} = await initPaymentSheet({
        paymentIntentClientSecret: clientSecret,
        returnURL: 'stripe-example://payment-sheet',
        // Set `allowsDelayedPaymentMethods` to true if your business handles
        // delayed notification payment methods like US bank accounts.
        allowsDelayedPaymentMethods: true,
      });
      if (error) {
        // Handle error
      }
    };

    initializePaymentSheet();
  }, [clientSecret, initPaymentSheet]);

  return (
    <View>
      <Button
        title="Subscribe"
        onPress={async () => {
          const {error} = await presentPaymentSheet();
          if (error) {
            if (error.code === PaymentSheetError.Failed) {
              // Handle failed
            } else if (error.code === PaymentSheetError.Canceled) {
              // Handle canceled
            }
          } else {
            // Payment succeeded
          }
        }}
      />
    </View>
  );
}

export default SubscribeView;
```

Mobile Payment Element によって支払い画面が表示され、顧客はここで支払い方法を選択できます。このフォームでは、顧客が選択した支払い方法で必要な支払い詳細のすべてが自動的に収集されます。

`allowsDelayedPaymentMethods` を true に設定すると、アメリカの銀行口座などの [遅延通知型](https://docs.stripe.com/payments/payment-methods.md#payment-notification)の支払い方法を使用できます。これらの支払い方法では、`PaymentSheet` が完了した時点では最終的な支払いステータスが判明せず、後になって成功または失敗が確定します。このようなタイプの支払い方法に対応する場合は、注文が確定済みであることを顧客に通知し、支払いが成功した場合にのみ注文のフルフィルメント (商品の発送など) を実行するようにします。

`PaymentSheet.Configuration` オブジェクトの [`appearance` プロパティ](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=ios) を使用して、アプリのデザインに合わせて Payment Element をカスタマイズできます。

### 支払いを確定する

Mobile Payment Element によって PaymentMethod が作成され、未完了のサブスクリプションの最初の PaymentIntent が確定され、その結果支払いが実行されます。支払いに*強力な顧客認証* (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) (SCA) が必要とされる場合は、PaymentIntent の確定前に Payment Element で認証プロセスが処理されます。

## 戻り先 URL を設定する (iOS のみ) [クライアント側]

顧客がアプリを終了すると (Safari やバンキングアプリで認証するなど)、自動的にアプリに戻るための方法を提供します。多くの決済手段タイプで、戻り先 URL の指定が「必須」です。戻り先 URL を有効にしていても、指定がされていないと、戻り先 URL が必要な決済手段をユーザーに提示できません。

戻り先 URL を指定するには、以下のようにします。

1. カスタム URL を[登録](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app#Register-your-URL-scheme)します。ユニバーサルリンクはサポートされていません。
1. カスタム URL を[設定](https://reactnative.dev/docs/linking) します。
1. 以下のように、URL を Stripe SDK に転送するようにルートコンポーネントを設定します。

> Expo を使用している場合は、`app.json` ファイルで[スキームを設定](https://docs.expo.io/guides/linking/#in-a-standalone-app)します。

```jsx
import { useEffect, useCallback } from 'react';
import { Linking } from 'react-native';
import { useStripe } from '@stripe/stripe-react-native';

export default function MyApp() {
  const { handleURLCallback } = useStripe();

  const handleDeepLink = useCallback(
    async (url: string | null) => {
      if (url) {
        const stripeHandled = await handleURLCallback(url);
        if (stripeHandled) {
          // This was a Stripe URL - you can return or add extra handling here as you see fit
        } else {
          // This was NOT a Stripe URL – handle as you normally would
        }
      }
    },
    [handleURLCallback]
  );

  useEffect(() => {
    const getUrlAsync = async () => {
      const initialUrl = await Linking.getInitialURL();
      handleDeepLink(initialUrl);
    };

    getUrlAsync();

    const deepLinkListener = Linking.addEventListener(
      'url',
      (event: { url: string }) => {
        handleDeepLink(event.url);
      }
    );

    return () => deepLinkListener.remove();
  }, [handleDeepLink]);

  return (
    <View>
      <AwesomeAppComponent />
    </View>
  );
}
```

さらに、`initPaymentSheet` メソッドを呼び出す際に `returnURL` を設定します。

```js
await initPaymentSheet({
  ...
  returnURL: 'your-app://stripe-redirect',
  ...
});
```

ネイティブ URL スキームの詳細については、[Android](https://developer.android.com/training/app-links/deep-linking) および [iOS](https://developer.apple.com/documentation/xcode/allowing_apps_and_websites_to_link_to_your_content/defining_a_custom_url_scheme_for_your_app) のドキュメントをご覧ください。

## Optional: Apple Pay を有効にする

### Apple 加盟店 ID を登録する

Apple Developer Web サイトで [新規 ID を登録](https://developer.apple.com/account/resources/identifiers/add/merchant) して、Apple 加盟店 ID を取得します。

フォームに説明と ID を入力します。説明はお客様の記録用であり、後で変更できます。アプリの名前を ID として使用することをお勧めします (`merchant.com.{{YOUR_APP_NAME}}` など)。

### 新しい Apple Pay 証明書を作成する

支払いデータを暗号化するためのアプリの証明書を作成します。

ダッシュボードの [iOS certificate settings (iOS 証明書の設定)](https://dashboard.stripe.com/settings/ios_certificates) に移動して、**新規アプリケーションを追加**をクリックし、表示されるガイドに従います。

証明書署名リクエスト (CSR) ファイルをダウンロードして、Apple Pay の利用を可能にする安全な証明書を Apple から取得します。

1 つの CSR ファイルを使用して証明書を 1 つだけ発行する必要があります。Apple 加盟店 ID を切り替えた場合、ダッシュボードの [iOS Certificate Settings (iOS 証明書の設定)](https://dashboard.stripe.com/settings/ios_certificates) に移動して、新しい CSR と証明書を取得する必要があります。

### Xcode を使用して組み込む

Apple Pay ケイパビリティをアプリに追加します。Xcode でプロジェクト設定を開き、**Signing & Capabilities (署名およびケイパビリティ)** タブを選択して、**Apple Pay** ケイパビリティを追加します。この段階で開発者アカウントへのログインを要求される場合があります。前の手順で作成した加盟店 ID を選択すると、アプリで Apple Pay を受け付けられるようになります。
![](https://b.stripecdn.com/docs-statics-srv/assets/xcode.a701d4c1922d19985e9c614a6f105bf1.png)

Xcode で Apple Pay ケイパビリティを有効化する

### Apple Pay を追加する

#### 継続支払い

`initPaymentSheet` を呼び出す際に、`merchantCountryCode` をビジネスの国コードに設定して、[ApplePayParams](https://stripe.dev/stripe-react-native/api-reference/modules/PaymentSheet.html#ApplePayParams) を渡します。

継続課金に関する [Apple のガイドライン](https://developer.apple.com/design/human-interface-guidelines/apple-pay#Supporting-subscriptions)に従い、決済予定の金額 (「月額 59.95 USD」など)を含む `cardItems` を設定し、その中に [RecurringCartSummaryItem](https://stripe.dev/stripe-react-native/api-reference/modules/ApplePay.html#RecurringCartSummaryItem) を含める必要があります。

`type` を `PaymentRequestType.Recurring` に設定して `request` を設定することで、[マーチャントトークン](https://developer.apple.com/apple-pay/merchant-tokens/)を導入することもできます。

Apple Pay で継続支払いを使用する方法について、詳細は [Apple の PassKit に関するドキュメント](https://developer.apple.com/documentation/passkit/pkpaymentrequest)をご覧ください。

#### iOS (React Native)

```javascript
const initializePaymentSheet = async () => {
  const recurringSummaryItem = {
    label: 'My Subscription',
    amount: '59.99',
    paymentType: 'Recurring',
    intervalCount: 1,
    intervalUnit: 'month',
    // Payment starts today
    startDate: new Date().getTime() / 1000,

    // Payment ends in one year
    endDate: new Date().getTime() / 1000 + 60 * 60 * 24 * 365,
  };

  const {error} = await initPaymentSheet({
    // ...
    applePay: {
      merchantCountryCode: 'US',
      cartItems: [recurringSummaryItem],
      request: {
        type: PaymentRequestType.Recurring,
        description: 'Recurring',
        managementUrl: 'https://my-backend.example.com/customer-portal',
        billing: recurringSummaryItem,
        billingAgreement:
          "You'll be billed $59.99 every month for the next 12 months. To cancel at any time, go to Account and click 'Cancel Membership.'",
      },
    },
  });
};
```

### 注文の追跡

iOS 16 以降で[注文の追跡](https://developer.apple.com/design/human-interface-guidelines/technologies/wallet/designing-order-tracking)情報を追加するには、`setOrderTracking` コールバック関数を設定します。Stripe は決済の完了後、iOS が Apple Pay 支払い画面を閉じる前にご使用の実装を呼び出します。

`setOrderTracking` コールバック関数の実装で、完了した注文の注文の詳細をサーバーから取得し、指定された `completion` 関数にその詳細を渡します。

注文の追跡の詳細については、[Apple のウォレットでの注文に関するドキュメント](https://developer.apple.com/documentation/walletorders)をご覧ください。

#### iOS (React Native)

```javascript
await initPaymentSheet({
  // ...
  applePay: {
    // ...
    setOrderTracking: async complete => {
      const apiEndpoint =
        Platform.OS === 'ios'
          ? 'http://localhost:4242'
          : 'http://10.0.2.2:4567';
      const response = await fetch(
        `${apiEndpoint}/retrieve-order?orderId=${orderId}`,
        {
          method: 'GET',
          headers: {
            'Content-Type': 'application/json',
          },
        },
      );
      if (response.status === 200) {
        const orderDetails = await response.json();
        // orderDetails should include orderIdentifier, orderTypeIdentifier,
        // authenticationToken and webServiceUrl
        complete(orderDetails);
      }
    },
  },
});
```

## Webhook をリッスンする [サーバー]

導入を完了するには、Stripe から送信される *Webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) を処理する必要があります。Webhook は、サブスクリプションによって新しい請求書が作成されるなど、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('<<YOUR_SECRET_KEY>>')

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 does not 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.id` とともにデータベースに保存します。アプリケーションでユーザーに対して有効にする機能を決定する際に、このレコードを確認します。

サブスクリプションのステータスは、存続期間のどの時点でも変化する可能性があります。アプリケーションが Stripe に直接コールを行っていない場合でも同様です。例えば、クレジットカードの期限超過で更新が失敗した場合、サブスクリプションは期日超過の状態になります。また、[カスタマーポータル](https://docs.stripe.com/customer-management.md)を導入している場合、ユーザーが直接アプリケーションを開かずにサブスクリプションをキャンセルすることがあります。ハンドラを正しく導入することで、アプリケーションを Stripe と常に同期した状態に維持できます。

## サブスクリプションをキャンセルする [クライアントとサーバー]

顧客にサブスクリプションのキャンセルを許可するのは一般的です。この例では、アカウントの設定ページにキャンセルオプションを追加します。

このサンプルではフロントエンドでサブスクリプション ID を収集していますが、アプリケーションではこの情報をデータベース内のログインユーザーに関する情報から取得できます。
![サブスクリプションのキャンセルインターフェイスの例。](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-subscriptions-guide-account-settings.6559626ba4b434826a67abfea165e097.png)

サブスクリプションのキャンセル機能が設定されたアカウント設定

```javascript
const cancelSubscription = async subscriptionId => {
  const apiEndpoint =
    Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567';
  const response = await fetch(`${apiEndpoint}/cancel-subscription`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      subscriptionId: subscriptionId,
    }),
  });
  if (response.status === 200) {
    const subscription = await response.json();
    return subscription;
  }
};
```

バックエンドで、アプリから呼び出すエンドポイントを定義します。

#### 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('<<YOUR_SECRET_KEY>>')

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) で表示できます。

詳しくは、[Billing の実装のテスト](https://docs.stripe.com/billing/testing.md)をご覧ください。

## Optional: 顧客がプランを変更できるようにする [クライアントとサーバー]

顧客にサブスクリプションの変更を許可するには、変更後のオプションの価格 ID を収集します。次にアプリからバックエンドのエンドポイントにこの新しい価格 ID を送信します。この例ではサブスクリプション ID も渡していますが、これはログインしているユーザーのデータベースから取得できます。

```javascript
const updateSubscription = async (subscriptionId, priceId) => {
  const apiEndpoint =
    Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567';
  const response = await fetch(`${apiEndpoint}/update-subscription`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      subscriptionId: subscriptionId,
      newPriceId: priceId,
    }),
  });
  if (response.status === 200) {
    const subscription = await response.json();
    return subscription;
  }
};
```

フロントエンドから呼び出すエンドポイントをバックエンドで定義し、サブスクリプション 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('<<YOUR_SECRET_KEY>>')

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)と呼ばれる未払い額の調整が行われます。[create preview invoice (請求書プレビューの作成) エンドポイント](https://docs.stripe.com/api/invoices/create_preview.md)を使用して、調整後の金額を顧客に表示できます。

アプリから、請求書のプレビューの詳細をバックエンドのエンドポイントに渡します。

```javascript
const createPreviewInvoice = async (subscriptionId, priceId, newPriceId) => {
  const apiEndpoint =
    Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567';
  const response = await fetch(`${apiEndpoint}/create-preview-invoice`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      subscriptionId: subscriptionId,
      priceId: priceId,
      newPriceId: newPriceId,
    }),
  });
  if (response.status === 200) {
    const invoice = await response.json();
    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('<<YOUR_SECRET_KEY>>')

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('<<YOUR_SECRET_KEY>>')

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
const retrieveCustomerPaymentMethod = async paymentMethodId => {
  const apiEndpoint =
    Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567';
  const response = await fetch(
    `${apiEndpoint}/retrieve-customer-payment-method`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        paymentMethodId: paymentMethodId,
      }),
    },
  );
  if (response.status === 200) {
    const paymentMethod = await response.json();
    return paymentMethod;
  }
};
```

バックエンドで、アプリから呼び出すエンドポイントを定義します。

#### 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('<<YOUR_SECRET_KEY>>')

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)をご覧ください。
