Stripe Payment Elementsでリダイレクトを３Dセキュア認証など、必要な時だけにする

Stripeの組み込み型決済フォーム、`Payment Element`を利用すると、決済完了時にリダイレクトが発生します。

```js
  const stripe = useStripe()
  const elements = useElements()
  if (!stripe || !elements) return null
  stripe.confirmPayment({
    elements,
    confirmParams: {
      return_url: 'http://localhost:5173',
    },
  })
```

これはBNPL（後払い）決済などで発生するリダイレクトを、SDK側でハンドルするために行われています。

ただし、設定を行うことで「必要になった時だけリダイレクトする」挙動に変更できます。

## `confirmPayment`で`redirect: 'if_required'`を設定しよう

クレジットカード決済やコンビニ決済・銀行振込などでは、リダイレクトせずに決済を完了させることができます。

Stripe.jsやReactのフックで`stripe.confirmPayment`を呼び出す際に、`redirect: 'if_required'`を設定しましょう。

```diff_javascript
  const stripe = useStripe()
  const elements = useElements()
  if (!stripe || !elements) return null
  await stripe.confirmPayment({
    elements,
    confirmParams: {
      return_url: 'http://localhost:5173',
    },
+    redirect: 'if_required',
  })
```

この値を設定することで、決済処理を完了するためにリダイレクトが必要な場合以外ではリダイレクトされなくなります。

### Tips: 3Dセキュア認証も、原則リダイレクトは発生しません

3Dセキュア2に切り替わったため、3Dセキュアの認証が必要な場合にもリダイレクトは発生しなくなりました。

Stripeで3Dセキュア認証をテストできるカード番号（`4000002760003184`など）を入力すると、以下のようにモーダルで認証画面が表示されます。

![スクリーンショット 2022-11-18 23.59.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/05895f8d-a82d-cecb-8bd9-6007c64276ab.png)

**関連**

https://qiita.com/hideokamoto/items/7920051d7476439e5a5e


## 決済処理の結果は、`confirmPayment`の戻り値から

決済が成功したか否かは、`confirmPayment`の戻り値で判断できます。

```js
const { paymentIntent, error } = await stripe.confirmPayment(...)
```

「`error`が`null`か否か」で成否の判断ができます。

また、`paymentIntent`のデータを使って後続の処理を行うことも可能です。

## 決済手段を固定するか、リダイレクト型決済への対応を

Stripe.jsで決済フォームを組み込みしている場合、**顧客に表示する決済手段を自動表示**にできます。

```diff_javascript
    const paymentIntent = await stripe.paymentIntents.create({
        amount: 200,
        currency: 'jpy',
+        automatic_payment_methods: {
+            enabled: true
+        }
    })
```

https://qiita.com/hideokamoto/items/c34f5489c1bc00f04858

この設定を利用している場合、「リダイレクトが発生する決済手段が、ダッシュボード有効化されているか否か」を確認しましょう。

もし有効になっている場合、顧客の選択によっては決済時にリダイレクトが発生し、`confirmPayment`の戻り値を利用した処理が動かなくなります。

「リダイレクトが発生しない決済手段をダッシュボードまたはコードで設定する」か「リダイレクトなし・ありどちらも対応できるように処理を実装する」かが、`redirect: 'if_required'`を設定する場合に必要ですので、ご注意ください。

「クレジットカード・コンビニ決済・銀行振込のみ」などで固定したい場合には、Payment Intent作成処理を次のように設定します。

```js
    const paymentIntent = await stripe.paymentIntents.create({
        amount: 200,
        currency: 'jpy',
        payment_method_types: ['card', 'konbini', 'customer_balance'],
        payment_method_data: {
          type: 'customer_balance'
        },
        statement_descriptor_suffix: 'Food subscription',
        payment_method_options: {
          customer_balance: {
            funding_type: 'bank_transfer',
            bank_transfer: {
              type: 'jp_bank_transfer'
            }
          },
          card: {
            statement_descriptor_suffix_kanji: '食料品定期販売',
            statement_descriptor_suffix_kana: 'ショクリョウヒンテイキ',
          },
          konbini: {
              product_description: "食料品定期販売",
              expires_after_days: 7
          }
        },
    })
```

## Document

https://stripe.com/docs/js/payment_intents/confirm_payment#confirm_payment_intent-options-redirect


https://stripe.com/docs/payments/payment-methods/integration-options

## Stripeでの3Dセキュア義務化対応について知りたい方は、こちらもどうぞ

2025年3月より始まる3Dセキュア義務化に関する記事を複数用意しております。現在対応方法をお探し中の方は、ぜひこちらの記事もご覧ください。

https://qiita.com/hideokamoto/items/7920051d7476439e5a5e

https://qiita.com/hideokamoto/items/710f9f006fe59ab83b27

https://qiita.com/hideokamoto/items/0f6d4e5fa34e8e673140

https://qiita.com/hideokamoto/items/fa8223470ad75f5307d1

https://qiita.com/hideokamoto/items/c30eded3fa8cd73f1a93