Stripeで実装した決済システムが3Dセキュア2 (EMV3DS) に対応しているかを確認する方法

通販サイトなどのオンライン決済では、常に不正なカード利用による注文への対処が必要です。

不正利用への対応策の一つとして用いられるのが、3Dセキュアです。

この記事では、Stripeを組み込んだアプリやシステムで、**3Dセキュア2**による認証に対応できているかを確認する方法を紹介します。

## 3Dセキュアによる認証を実施するメリット

3Dセキュアによる認証を実施することで、クレジットカードの所有者本人による決済かどうかの確認を追加で行うことができます。

![phone1-de50512572d9508bb9fd022fe61ac793.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/a0c4b650-aeda-bc24-3492-e61b190d35bd.png)
https://stripe.com/jp/guides/3d-secure-2

また、3Dセキュアを通して認証された支払いについては、不正請求の申し立てがあった場合の責任が、カード発行会社側に移ります。ただし、「注文した商品が届いていない」ケースや「注文した商品と異なる」ケースなど、不正利用以外で申し立てがあった場合は対象外となりますのでご注意ください。（参考: [異議申し立てのカテゴリ](https://stripe.com/docs/disputes/categories)）

そのため、顧客が不正利用を理由としたチャージバックの申請をしても、カード発行会社が売上金を補償します。この仕組みを「ライアビリティシフト」とよびます。

## 3Dセキュア1と3Dセキュア2

3Dセキュアでの認証には、二つのバージョンがあります。

3Dセキュア1では、**常に決済時**にカード発行会社が提供する**認証画面にリダイレクト**させる必要があります。認証が成功した場合は、元のサイトにリダイレクトされて、決済フローが再開されます。

このフローの問題点は、認証ページへのリダイレクトが発生するために、いわゆる「カゴ落ち」が発生しやすくなることです。認証時に、カード所有者が設定したID・パスワードを要求することが多く、これもまたカゴ落ちの要因になりました。

リダイレクトによる決済フローの中断を減らすため、3Dセキュア2では摩擦のない認証（Frictionless authentication）をサポートしています。
これは決済（トランザクション）ごとに配送先住所や顧客のデバイスIDなどのデータを送信し、カード会社側のシステムが「リスクの高い決済」と判断した場合にのみ追加認証を行う方法です。

3Dセキュア2の認証フローに切り替えることで、顧客が認証のための追加情報入力を省略できるケースを増やすことができます。

![スクリーンショット 2022-10-11 9.50.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/22f1a504-08b0-3114-135d-e51e1f14e677.png)
https://stripe.com/jp/guides/3d-secure-2

また、3Dセキュア2では、追加情報を入力する画面をリダイレクトではなくアプリ・ブラウザ内で表示します。これによって、セッションの中断やアプリからブラウザへの移動などを回避でき、実装やユーザーの動線をシンプルにできます。

![phone2-679c89fc729fc2af5302b134554f5dfd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/de0e445b-e414-149d-e320-d06197a8b703.png)
https://stripe.com/jp/guides/3d-secure-2

### 2022/10に多くの地域・カードネットワークで3Dセキュア1が廃止

現在３Dセキュア1を利用している場合、2022/10までに3Dセキュア2へ切り替える必要があります。

これは複数のクレジットカードブランドが、2022/10までに3Dセキュア1におけるライアビリティシフトやサポートを終了することを発表しているためです。

### Stripeを利用している場合の3Dセキュア1から3Dセキュア2への切り替え方法

#### 追加対応が不要のケース

Stripeを利用している場合、**Payment Intent**および**Setup Intent**、そして**Checkout・Payment Links・InvoiceなどのStripeがホストする決済ページ**を利用中であれば、変更のために実装を変更する必要はほぼありません。

ただし「**`2019-02-11`より古いバージョンのAPIを利用し、手動でリダイレクト設定を実装している場合**」など、一部のケースではパラメータ名などが変わっているケースがあるため、注意が必要です。

https://stripe.com/docs/payments/3d-secure#when-to-use-3d-secure

#### 追加対応（コードの変更）が必要なケース

もし`Source　API`や`Charge　API`・`Token API`など、古いAPIを利用したカードフォームを実装している場合は、`Setup Intent`または`Payment Intent`、あるいはCheckoutへの切り替えが必要です。

主な変更点は、以下のとおりです。

+ 1: Elements(Stripe.js)の要素を表示する前に、サーバー側でPayment IntentまたはSetup Intentを作成する
+ 2: Elements(Stripe.js)の`stripe.elements`または`<Elements />`の引数に、Payment IntentまたはSetup Intentの`client_secret`を設定する
+ 3: Elements(Stripe.js)の`createToken`や`createSource`を`confirmCardPayment`（`CardElement`）または`confirmPayment`(`PaymentElement`)に変更する
+ 4: `createSource`の戻り値から3Dセキュアのリダイレクトの実施判定や処理をしているコードを削除する（Stripe.js側の認証フローを利用する場合）
+ 5: `createToken`や`createSource`の実施後に、サーバー側で実行していた`charges.create`などの実装を削除する

より詳細な変更方法や言語別のAPIについては、以下のStripe Documentをご確認ください。

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

https://stripe.com/docs/payments/payment-intents/migration


## Stripeで3Dセキュア1と2の決済をテストする方法

運用しているアプリ・システムで3Dセキュア２が利用できるか否かをテストしてみましょう。

テストする上で最もシンプルな方法は、「3Dセキュア2での認証が必須のテストカード番号」を利用することです。

Stripeでは、カード番号`4000000000003220`をテスト環境で利用すると、必ず3Dセキュア2での認証を要求します。

![スクリーンショット 2022-09-14 15.17.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/fe26587b-1064-0bcb-a5d5-f1d8713f273e.png)

Source APIの`createSource`で3Dセキュア1に対応している場合、３Dセキュア１の認証画面にリダイレクトされます。しかし認証後にURLのクエリ文字列から取得できる`source`を使って決済を実施しようとすると、エラーが発生します。

```bash
% stripe charges create --currency jpy --amount 1000 --source src_xxxx
{
  "error": {
    "charge": "ch_3Lhov2L6R1kGwUF41gexGMBV",
    "code": "authentication_required",
    "decline_code": "authentication_required",
    "doc_url": "https://stripe.com/docs/error-codes/authentication-required",
    "message": "Your card was declined. This transaction requires authentication.",
    "type": "card_error"
  }
}
```

Payment IntentまたはSetup Intentを利用している場合は、画面上に３Dセキュア２の認証テスト画面が表示されます。これはPayment LinksやCheckoutを利用している場合でも表示されます。

![スクリーンショット 2022-09-14 15.22.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/100d6fa0-6cde-5285-cdc2-0a0b4c1bff53.png)

認証のテスト画面で、`COMPLETE`をクリックすると３Dセキュア2での認証が成功したケース・`FAIL`をクリックすると失敗したケースをテストできます。

### SetupIntent / Payment Intent APIで、手動で3Dセキュア認証をリクエストする

サーバー側でSetup IntentまたはPayment Intent APIを利用している場合、テスト環境または特定の条件に対して3Dセキュアによる認証を手動でリクエストできます。

それぞれのAPIにある、`payment_method_options[card][request_three_d_secure]`パラメータを、`any`に設定しましょう。

```diff_javascript
  stripe.setupIntents.create({
    customer: customer.id,
    payment_method_types: ['card'],
    usage: 'off_session',
+    payment_method_options: {
+      card: {
+        request_three_d_secure: 'any'
+      }
+    },
  })
```

特定の条件でのみ手動リクエストを行いたい場合は、次のように実装します。

```diff_javascript
  stripe.setupIntents.create({
    customer: customer.id,
    payment_method_types: ['card'],
    usage: 'off_session',
    payment_method_options: {
      card: {
-        request_three_d_secure: 'any'
+        request_three_d_secure: isManual3DS ? 'any' : 'automatic'
      }
    },
  })
```

デフォルト値である`automatic`を設定することで、不必要な追加認証を減らすことができます。

- Payment Intent API: https://stripe.com/docs/api/payment_intents/create#create_payment_intent-payment_method_options-card-request_three_d_secure
- Setup Intent API: https://stripe.com/docs/api/setup_intents/create#create_setup_intent-payment_method_options-card-request_three_d_secure



### ダッシュボードで３Dセキュアによる認証があったかを確認する

ダッシュボードからは、実際に3Dセキュア2での認証が実行されているかを確認することもできます。

[支払い > すべての支払い]から[支払い方法]を選択しましょう。
ここで[3Dセキュア2]を選択すると、3Dセキュア２を利用した支払いを確認できます。

![スクリーンショット 2022-09-14 15.26.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/7118f912-7da6-b17f-7799-8d2a9d9a848f.png)


## その他の参考リソース

https://stripe.com/jp/guides/3d-secure-2

https://stripe.com/docs/payments/3d-secure

https://stripe.com/docs/strong-customer-authentication

https://support.stripe.com/questions/3d-secure-2-device-information

https://www.youtube.com/watch?v=2kc-FjU2-mY

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