Stripe Checkoutで入力したカード情報を保存して次回以降の支払いに利用する方法

ECサイトなど、顧客が繰り返し決済を行うサービスでは、「2回目以降のカード情報入力をいかにスムーズにするか」が重要です。

そのため、初回の決済で利用したカード情報を保存し、2回目以降でも利用できるようにする実装を行います。

この記事では、Stripe Checkoutを利用して、決済に利用したカード情報を保存する方法を紹介します。

## Stripe Checkoutでの、カード情報を保存する決済フローの作り方


### Customerを作成する

次回以降の支払いで、同一の顧客であることを特定する必要があります。

そのため、Stripe上に顧客（Customer）データを作成しましょう。

```js
const customer = await stripe.customers.create()
const customerId = customer.id // cus_xxx
```

実際の運用では、FirebaseやCognito / Auth0などのユーザー管理システム上に顧客のIDを保存しましょう。

### Checkoutのセッションを作成する

カードを保存できるセッションを作成しましょう。

```js
      const session = await stripe.checkout.sessions.create({
        customer: customerId,
        mode: 'payment',
        success_url: 'http://localhost:3000/success?session_id={CHECKOUT_SESSION_ID}',
        cancel_url: 'http://localhost:3000?cancel',
        line_items: [{
          price_data: {
            unit_amount: 1000,
            currency: 'jpy',
            product_data: {
              name: 'dummy'
            }
          },
          quantity: 2
        }],
        payment_method_options: {
          card: {
            setup_future_usage: 'on_session',
          }
        }
      })
```

`payment_method_options.card.setup_future_usage`に値を設定しています。

ECなど、顧客が操作して決済を行うフローのみの場合は`on_session`を指定します。

キャンセル手数料を請求する場合や追加料金を別途請求するケースなど、決済のタイミングで顧客の操作が発生しないケースがある場合は、`off_session`を指定しましょう。

#### 決済ページの画面比較

カード情報の保存について、Checkoutの決済ページで表示がされます。

設定による表記の違いを確認してみましょう。

**指定なしの場合**

指定がない場合、決済ボタンの下にテキストは表示されません。

![スクリーンショット 2022-06-27 14.15.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/c780de73-9ff7-d20d-3934-16f7c2402867.png)

**on_sessionの場合**

`on_session`を設定すると、「次回以降のために、支払いを保存すること」が表記されます。

![スクリーンショット 2022-06-27 14.16.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/5b5b8c24-6fb9-b78b-c82a-17f23a867bee.png)


**off_sessionの場合**

`off_session`の場合は、「今後の支払い」についても保存・利用することが表記されます。

![スクリーンショット 2022-06-27 14.14.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/913fcb51-7595-245c-422d-755f3cfcebc0.png)

## `payment_intent_data.setup_future_usage`を使わないケース

ブログやチュートリアルの中には、`payment_intent_data.setup_future_usage`で設定するケースが紹介されていることもあります。
こちらでもカード情報の保存は可能です。

ただし、この値を利用すると、**カード決済以外の支払い方法**が決済画面に表示されなくなります。

### `payment_intent_data.setup_future_usage`で設定した画面

この値を設定すると、カード決済のみが利用できるUIが表示されます。

![スクリーンショット 2022-06-27 14.27.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/f25ee9ab-e98a-af31-0b55-2cdcfa6c99e2.png)

### `payment_method_options.card.setup_future_usage`で設定した画面

本記事で紹介した方法の場合、カード決済以外の支払い方法も選択ができます。

![スクリーンショット 2022-06-27 14.28.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/9abfe4d8-bff8-b23e-3071-18950be450ab.png)



## 2回目以降の決済での表示

2回目以降の決済でも、Checkoutのセッションを作成するコードは同一です。
Customer IDの設定を忘れないようにしましょう。

```js
      const session = await stripe.checkout.sessions.create({
        customer: 'cus_xxx',
        mode: 'payment',
        success_url: 'http://localhost:3000/success?session_id={CHECKOUT_SESSION_ID}',
        cancel_url: 'http://localhost:3000?cancel',
        line_items: [{
          price_data: {
            unit_amount: 1000,
            currency: 'jpy',
            product_data: {
              name: 'dummy'
            }
          },
          quantity: 2
        }],
        payment_method_options: {
          card: {
            setup_future_usage: 'on_session',
          }
        }
      })
```

カードの保存ができている顧客であれば、保存したカード情報が表示されます。

![スクリーンショット 2022-06-27 14.18.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/211a5cd5-cb95-51b5-b087-7fba414d34b2.png)

## Documents

- https://stripe.com/docs/api/checkout/sessions/create#create_checkout_session-payment_method_options-card-setup_future_usage
- https://stripe.com/docs/payments/save-and-reuse?platform=checkout