Stripe Checkoutで銀行振込による決済をサポートする方法と、実装時の注意点

Stripe Checkoutを利用すると、カード決済以外の決済方法も簡単にサポートすることができます。

![スクリーンショット 2022-09-02 11.43.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/8a9ae9cb-9633-d258-1d94-d53993244f27.png)

今回は、その中でも2022年春に登場した「銀行振込」をサポートする方法を紹介します。

## Checkoutで銀行振込をサポートするために必要な３つの値

Checkoutで銀行振込をサポートするには、以下の値を設定する必要があります。

- `customer`: Stripe上の顧客ID
- `payment_method_types`: 利用する支払い方法の設定
- `payment_method_options`: どの国の銀行振込を利用するかなどのオプション設定

### Step1: 口座情報を紐づけるための顧客データを作成する

Stripeで銀行振込による決済を処理するには、顧客データと口座情報を紐づける必要があります。

そのため、Stripe CheckoutでCheckoutセッションを作成するAPIを呼び出す際、`customer`で顧客のIDを指定しましょう。

```diff_javascript
+    const customer = await stripe.customers.create()
    const session = await stripe.checkout.sessions.create({
+      customer: customer.id,
      line_items: [{
        price: 'price_xxxx',
        quantity: 1
      }],
      mode:'payment',
      success_url: 'https://example.com',
      cancel_url: 'https://example.com',
    })
```

`customer`の設定が漏れている場合、APIが`The payment method 'customer_balance' requires `customer` to be set.`エラーを返します。

### Step2: `payment_method_types`で銀行振込を指定する

続いて、Checkoutでサポートする決済方法を指定します。

ダッシュボード側で決済方法を指定する方法もありますので、こちらもご確認ください。

https://stripe.com/docs/payments/dashboard-payment-methods

銀行振込の場合、`payment_method_types`に`customer_balance`を指定します。

クレジットカード・コンビニ決済・銀行振込をサポートする場合は、次の通りです。

```diff_javascript
    const customer = await stripe.customers.create()
    const session = await stripe.checkout.sessions.create({
      customer: customer.id,
      line_items: [{
        price: 'price_xxxx',
        quantity: 1
      }],
      mode:'payment',
+      payment_method_types: [
+        'card',
+        'konbini',
+        'customer_balance'
+      ],
      success_url: 'https://example.com',
      cancel_url: 'https://example.com',
    })
```

### Step3: `payment_method_options`で銀行振込の設定を行う

最後に、`payment_method_options`で、「どの国の銀行振込を利用するか」を指定します。


```diff_javascript
    const customer = await stripe.customers.create()
    const session = await stripe.checkout.sessions.create({
      customer: customer.id,
      line_items: [{
        price: 'price_xxxx',
        quantity: 1
      }],
      mode:'payment',
      payment_method_types: [
        'card',
        'konbini',
        'customer_balance'
      ],
+      payment_method_options: {
+        customer_balance: {
+          funding_type: 'bank_transfer',
+          bank_transfer: {
+            type: 'jp_bank_transfer',
+          },
+        },
+      },
      success_url: 'https://example.com',
      cancel_url: 'https://example.com',
    })
```

## 表示内容を確認する

最後に、サンプルのコードを実行して、`stripe.checkout.sessions.create`の戻り値を取得しましょう。
URLにアクセスすると、銀行振込を決済方法として選択できる決済ページが表示されます。

```bash
$ node example.js
{
...
   url: 'https://checkout.stripe.com/pay/cs_test_xxxx'
}
```

![スクリーンショット 2022-09-02 13.15.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/c93cc0c5-91bf-555b-370f-8896820ab886.png)

[支払う]ボタンをクリックすると、コンビニ決済と同じく入金のための情報が表示されます。

![スクリーンショット 2022-09-02 13.16.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/028ac2bd-504e-a6db-52ff-6e832a68c5ff.png)



## Checkoutで銀行振込をサポートする際の注意点

### Checkoutでの決済完了後、リダイレクトされない

コンビニ決済や銀行振込など、振込・入金等の操作が必要な決済方法では、セッション完了後に支払い方法の案内ページに移動します。

そのため、`success_url`で指定したページへのリダイレクトが行われません。

Google Analyticsのコンバージョントラッキングや、注文後に表示したい項目があるアプリ・サービスなどでは、実装にご注意ください。

### Subscriptionの場合は、`mode: 'subscription'`に変更する

銀行振込に限らず、Checkoutを利用する際にミスしがちな点です。

「1回限りの決済」と「サブスクリプション」、そして「決済情報の登録のみ」では、`mode`の値が変わります。

１つでもサブスクリプション商品が混ざっている場合は、`mode`を`subscription`に設定しましょう。

### WebhookやZapierで、入金完了後に発送等の処理を行う

銀行振込の場合、Checkoutのセッション完了時点ではまだ顧客からの入金はありません。

そのため、すでにカード決済などで注文完了後に別のシステムと連携させている場合は、連携タイミングの調整が必要です。


#### `checkout.session.completed`を利用している場合

すでに`checkout.session.completed`のWebhookイベントを利用している場合は、「決済ステータスの確認」処理を追加しましょう。

```diff_javascript
if (event.type === 'checkout.session.completed') {
      const session = event.data.object;
+      if (session.payment_status === 'paid') {
        // 発送業務等のシステム連携処理
+      }
}
```

これにより、銀行振込やコンビニ決済・３Dセキュアによる追加認証などで、決済が未完了状態の注文を発送等の処理にまわすことを防止できます。

#### `checkout.session.async_payment_succeeded`で銀行振込の入金完了イベントを受け取る

Checkoutのみを利用している場合、`checkout.session.async_payment_succeeded`イベントを利用して、コンビニ決済や銀行振込の注文を処理します。

```js
if (event.type === 'checkout.session.async_payment_succeeded') {
  const session = event.data.object;
  // 発送業務等のシステム連携処理
}
```

#### 複数の決済方法をCheckoutでサポートする場合

`checkout.session.async_payment_succeeded`イベントは、クレジットカードなどのその場で決済が完了する決済方法では利用されません。

そのため、複数の決済方法をサポートする場合は、`checkout.session.completed`と`checkout.session.async_payment_succeeded`両方を利用しましょう。

```js
if (event.type === 'checkout.session.completed') {
      const session = event.data.object;
      if (session.payment_status === 'paid') {
        // クレジットカードなどの即時決済での、発送業務等のシステム連携処理
      }
} else if (event.type === 'checkout.session.async_payment_succeeded') {
  const session = event.data.object;
  // 銀行振込などの非同期型決済での、発送業務等のシステム連携処理
}
```

### Payment Links / Pricing Tableでは利用できない (2022/09/02時点)

現時点では、Payment Links（支払いリンク）やPricing Table(料金表)を利用した場合、銀行振込での決済ができません。

これは、２つの製品が2022/09/02時点で、`customer_id`の指定をサポートしていないためです。

今後のアップデートで、IDが指定できるようになれば、利用できる可能性がありますので、変更があれば随時更新いたします。

### Checkoutで、銀行振込でのサブスクリプションは開始できない (2022/09/02時点)

現時点では、Checkoutで開始したサブスクリプションは自動的に決済処理されます。（`collection_method="charge_automatically"`）

銀行振込は`collection_method="send_invoice"`でサブスクリプションを開始する必要があるため、サブスクリプションの支払い方法に指定すると以下のエラーが発生します。

```
The payment method `customer_balance` cannot be used in `subscription` mode.
```

銀行振込をサポートするサブスクリプションの作成方法は、以下の記事を参考にしてください。

https://qiita.com/hideokamoto/items/e03984b982574ab01c31#%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A7%E3%82%B5%E3%83%96%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B

## [PR] Stripe開発者向け情報をQiitaにて配信中！

- [Stripe Updates]：開発者向けStripeアップデート紹介・解説
- ユースケース別のStripe製品や実装サンプルの紹介
- Stripeと外部サービス・OSSとの連携方法やTipsの紹介
- 初心者向けのチュートリアル(予定)

など、Stripeを利用してオンラインビジネスを始める方法について週に２〜３本ペースで更新中です。

-> [Stripe Organizationsをフォローして最新情報をQiitaで受け取る](https://qiita.com/organizations/stripe)