# 支払いの詳細を更新する

今後の請求書で使用される支払い方法を更新する方法をご紹介します。

以下のステップを使用して、顧客の支払いの詳細を収集して支払い方法を返す決済ページを作成します。次に、Stripe の REST API を使用して、以降の*請求書* (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)で使用する支払い方法を更新します。

> このガイドでは、Checkout を使用してサブスクリプションの支払い方法を更新します。この代わりに、[Billing カスタマーポータル](https://docs.stripe.com/customer-management.md)を実装して、Stripe がホストするダッシュボードを顧客に提供することもできます。顧客はそこでサブスクリプションと請求書の詳細を管理できます。

## Stripe を設定する [サーバ側]

まず、Stripe アカウントが必要です。[今すぐ登録](https://dashboard.stripe.com/register)してください。

アプリケーションから Stripe API にアクセスするには、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'
```

## Checkout セッションを作成する [サーバ側]

設定モードのセッションを作成するには、セッション作成時に `setup` の値を指定して `mode` パラメータを使用します。セッションの作成に使用できる全パラメータの一覧については、[Checkout Session API リファレンス](https://docs.stripe.com/api/checkout/sessions/create.md)を参照してください。

顧客が Checkout セッションを正常に完了した後でセッション ID にアクセスするための、`success_url` に `{CHECKOUT_SESSION_ID}` テンプレート変数を追加します。

最後に、[setup_intent_data.metadata](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-setup_intent_data-metadata) ディクショナリを使用して、顧客の既存の Stripe `subscription_id` を Checkout セッションに渡します。このデータをお客様のサーバーに渡す方法は他にもありますが、このガイドではメタデータを使用します。

#### curl

```bash
curl https://api.stripe.com/v1/checkout/sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -d "mode"="setup" \
  -d "customer"="cus_FOsk5sbh3ZQpAU" \
  -d "setup_intent_data[metadata][subscription_id]"="sub_8epEF0PuRhmltU" \
  -d "success_url"="https://example.com/success?session_id={CHECKOUT_SESSION_ID}"
```

## Checkout にリダイレクトする [クライアント側]

サーバーで Checkout Session を作成したら、レスポンスで返された [URL](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-url) に顧客をリダイレクトします。

#### HTML + JS

顧客が決済手段を保存または更新する準備ができたら、サーバーにリクエストを送信して Checkout Session を作成し、サーバーから返されたセッション URL に顧客をリダイレクトします。

```html
<button id="checkout-button">Update payment method</button>

<script>
const checkoutButton = document.getElementById('checkout-button');

checkoutButton.addEventListener('click', async () => {
  // Call your back end to create the Checkout Session and get the session URL.
  const response = await fetch('/create-checkout-session', { method: 'POST' });
  const { url } = await response.json();
  // Redirect to Checkout.
  window.location.href = url;
});
</script>
```

#### React

顧客が決済手段を保存または更新する準備ができたら、サーバーにリクエストを送信して Checkout Session を作成し、サーバーから返されたセッション URL に顧客をリダイレクトします。

```jsx
import React from 'react';
import ReactDOM from 'react-dom';

function App() {
  const handleClick = async (event) => {
    // Call your back end to create the Checkout Session.
    const response = await fetch('/create-checkout-session', { method: 'POST' });
    const { url } = await response.json();
    // Redirect to Checkout.
    window.location.href = url;
  };
  return (
    <button role="link" onClick={handleClick}>
      Update payment method
    </button>
  );
}
ReactDOM.render(<App />, document.getElementById('root'));
```

このコードは通常、顧客による支払いボタンのクリックなどの操作をきっかけにして、イベントハンドラにより起動されます。

## Checkout セッションを取得する [サーバ側]

顧客が Checkout セッションを正常に完了した後に、お客様は Session オブジェクトを取得する必要があります。これは、以下の 2 つの方法で実行できます。

- **非同期**: Session オブジェクトを含む `checkout.session.completed` *Webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) を処理します。[Webhook の設定](https://docs.stripe.com/webhooks.md)の詳細をご覧ください。
- **同期:** ユーザーがサイトにリダイレクトされるときに `success_url` からセッション ID を取得します。セッション ID を使用して、Session オブジェクトを[取得](https://docs.stripe.com/api/checkout/sessions/retrieve.md)します。

```curl
curl https://api.stripe.com/v1/checkout/sessions/cs_test_MlZAaTXUMHjWZ7DcXjusJnDU4MxPalbtL5eYrmS2GKxqscDtpJq8QM0k \
  -u "<<YOUR_SECRET_KEY>>:"
```

顧客が支払いの成功後に必ず `success_url` に到達するとは限らないため、ドロップオフの許容度に応じて適切な判断をする必要があります。リダイレクトが発生する前に顧客がブラウザータブを閉じることもあります。Webhook を処理することで、システムがこのようなドロップオフの影響を受けずに済みます。

Session オブジェクトの取得後、Checkout セッションの際に作成された SetupIntent の ID である `setup_intent` キーの値を入手します。[SetupIntent](https://docs.stripe.com/payments/setup-intents.md) は、今後の支払いに備えて顧客の銀行口座情報を設定するために使用されるオブジェクトです。

以下に `checkout.session.completed` ペイロードの例を示します。

```json
{
  "id": "evt_1Ep24XHssDVaQm2PpwS19Yt0",
  "object": "event",
  "api_version": "2019-03-14",
  "created": 1561420781,
  "data": {
    "object": {
      "id": "cs_test_MlZAaTXUMHjWZ7DcXjusJnDU4MxPalbtL5eYrmS2GKxqscDtpJq8QM0k",
      "object": "checkout.session",
      "billing_address_collection": null,
      "client_reference_id": null,
      "customer": "cus_FOsk5sbh3ZQpAU",
      "customer_email": null,
      "display_items": [],
      "mode": "setup",
      "setup_intent": "seti_1EzVO3HssDVaQm2PJjXHmLlM",
      "submit_type": null,
      "subscription": null,
      "success_url": "https://example.com/success"
    }
  },
  "livemode": false,
  "pending_webhooks": 1,
  "request": {
    "id": null,
    "idempotency_key": null
  },
  "type": "checkout.session.completed"
}
```

次のステップに備えて `setup_intent` ID を書き留めておきます。

## SetupIntent を取得する [サーバ側]

`setup_intent` ID を使用して、[/v1/setup_intents/:id](https://docs.stripe.com/api/setup_intents/retrieve.md) エンドポイントで SetupIntent オブジェクトを取得します。

```curl
curl https://api.stripe.com/v1/setup_intents/{{SETUPINTENT_ID}} \
  -u "<<YOUR_SECRET_KEY>>:"
```

レスポンス例:

```json
{
  "id": "seti_1EzVO3HssDVaQm2PJjXHmLlM",
  "object": "setup_intent",
  "application": null,
  "cancellation_reason": null,
  "client_secret": null,
  "created": 1561420781,
  "customer": "cus_FOsk5sbh3ZQpAU",
  "description": null,
  "last_setup_error": null,
  "livemode": false,
  "metadata": {
    "subscription_id": "sub_8epEF0PuRhmltU"
  },
  "next_action": null,
  "on_behalf_of": null,
  "payment_method": "pm_1F0c9v2eZvKYlo2CJDeTrB4n",
  "payment_method_types": [
    "card"
  ],
  "status": "succeeded",
  "usage": "off_session"
}
```

`customer` ID、`subscription_id` および `payment_method` ID を次のステップのために書き留めておきます。

> この情報を (Webhook の処理とは異なり) Stripe API から同期的にリクエストする場合は、/v1/checkout/session エンドポイントに対するリクエスト内の SetupIntent オブジェクトを[拡張](https://docs.stripe.com/api/expanding_objects.md)することで、前のステップとこのステップを結合できます。このようにすることで、新しく作成された PaymentMethod ID にアクセスするためのネットワークリクエストを二重に作成する必要がなくなります。

## デフォルトの支払い方法を設定する [サーバ側]

支払い方法を以降の請求書で使用する方法は、2 つあります。

- 顧客の `invoice_settings.default_payment_method` として設定する
- サブスクリプションの `default_payment_method` として設定する

顧客に `invoice_settings.default_payment_method` を設定すると、その顧客のそれ以降のすべての請求書が、指定された支払い方法で支払われることになります。

サブスクリプションに `default_payment_method` を設定すると、そのサブスクリプションのそれ以降の請求書はすべて、指定されたその支払い方法で支払われることになり、関連付けられた顧客に設定された `invoice_settings.default_payment_method` が上書されます。

### 顧客に invoice_settings.default_payment_method を設定する

取得した顧客 ID と PaymentMethod ID を使用して、[/v1/customers/:id](https://docs.stripe.com/api/customers/update.md) エンドポイントで、顧客に `invoice_settings.default_payment_method` を設定します。

```curl
curl https://api.stripe.com/v1/customers/{{CUSTOMER_ID}} \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "invoice_settings[default_payment_method]={{PAYMENTMETHOD_ID}}"
```

この顧客の以降の請求書はすべて、設定モードの Checkout セッションで作成された新しい PaymentMethod で請求されます。

### サブスクリプションに default_payment_method を設定する

取得したサブスクリプション ID と PaymentMethod ID を使用して、[/v1/subscriptions/:id](https://docs.stripe.com/api/subscriptions/update.md) エンドポイントで、サブスクリプションに `default_payment_method` を設定します。

#### curl

```bash
curl https://api.stripe.com/v1/subscriptions/sub_8epEF0PuRhmltU \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "default_payment_method"="pm_1F0c9v2eZvKYlo2CJDeTrB4n"
```

このサブスクリプションの以降の請求書はすべて、セットアップモードの Checkout セッションで作成された新しい PaymentMethod で請求されます。関連付けられた顧客に設定された `invoice_settings.default_payment_method` はすべて上書されます。

## See also

これで、これ以降の請求書のデフォルトの支払い方法が設定されました。テスト API キーを使用して実装内容をテストするときは、[テストカード番号](https://docs.stripe.com/testing.md#cards)を使用して、正しく機能するかを確認できます。

- [テストカード](https://docs.stripe.com/testing.md#cards)
