
EMV 3-Dセキュア(3DS)の実装例と考慮点
概要
近年、オンライン取引の急速な拡大に伴い、クレジットカードの不正利用が深刻な問題となっています。これに対応するため、ECサイト事業者はEMV 3-Dセキュア(3Dセキュア2.0)の導入が義務付けられました。本ブログでは、EMV 3-Dセキュアの全体像から、実装時のポイント、そして不正検知サービスとの併用について技術的な視点で解説します。
この記事が、これから3Dセキュアを導入しようとしている開発者の参考になれば幸いです。
対象読者
- ECサイトの開発者や技術担当者
本文
はじめに
近年、オンライン取引の拡大に伴い、クレジットカードの不正利用が年々増加しています。日本クレジット協会によると、2023年のクレジットカード不正利用被害額は過去最高の540.9億円となりました。また、最新データを確認すると、2024年4月~6月までの被害額は前年同期比で3億円増加の144億円でした。

出典: 日本クレジット協会
このような状況を受け、クレジット取引セキュリティ対策協議会は「セキュリティガイドライン」を策定し、EC加盟店における具体的な不正利用対策の一つとしてEMV 3-Dセキュア(3Dセキュア2.0)の導入を義務付けました。これにより、Stripeを利用する事業者を始めすべてのECサイト事業者は2025年3月末までにEMV 3-Dセキュアを導入する必要があります。
詳しくは、クレジットカード・セキュリティガイドラインをご参照ください。
3Dセキュアとは
**EMV 3-Dセキュア(3Dセキュア2.0)**とは、クレジットカード決済時に本人認証を行うサービスのことです。カード会社がカード利用者のデバイス情報などを用いて不正利用のリスク判断を行い、必要に応じてパスワード入力等を求めることで取引の安全性を高める仕組みです。
-
3Dセキュア1.0と2.0の違い
3Dセキュア1.0と2.0(EMV 3-Dセキュア)の大きな違いは、リスクベース認証が導入されたことです。3Dセキュア1.0では全てのクレジットカード決済に対して都度追加認証が行われていました。しかし、EMV 3-Dセキュアでは、リスクベース認証により不正利用のリスクが低い取引だと、パスワードなど追加の情報を入力しなくても認証が完了します。
また、3Dセキュア1.0ではモバイルに対応していませんでしたが、2.0(EMV 3-Dセキュア)からはモバイルに対応し、ネイティブアプリ向けのSDKも提供されています。
-
3Dセキュアの3つのドメイン
3Dセキュアは「3-Domain Secure」の略で、以下の3つのドメインが連携することを意味します。
- Issuer Domain(イシュアドメイン): カード発行会社
- アクセスコントロールサーバー(ACS): イシュアが管理し、カード会員のリスクベース認証を行います。
- Interoperability Domain(相互運用ドメイン): 国際カードブランド(Visa、JCB、Mastercardなど)
- ディレクトリサーバー(DSサーバー): カードブランドが提供し、認証リクエストを適切なイシュアのACSに振り分けます。
- Acquirer Domain(アクワイアラドメイン): 加盟店管理会社とEC加盟店
- ECサイト: 商品やサービスを提供する加盟店。
- 3Dセキュアサーバー(3DSサーバー): 決済代行会社(PSP)が提供し、認証リクエストを処理します。代表的なPSPにはPaygent、Stripe、GMOペイメントゲートウェイなどがあります。
以下のシーケンス図は、EMV 3-Dセキュアにおける各ドメイン間の認証フローを示しています。
図のソース(Mermaid)
sequenceDiagram box Acquirer Domain participant EC as ECサイト participant 3DS as 3DSサーバー<br/>(PSP提供) end box Interoperability Domain participant DS as DSサーバー<br/>(カードブランド) end box Issuer Domain participant ACS as ACS<br/>(イシュアー) end Note over EC,ACS: EMV 3-Dセキュア認証フロー EC->>3DS: 決済開始要求 Note over EC,3DS: 取引情報送信 3DS->>DS: 認証要求 Note over 3DS,DS: デバイス情報<br/>取引データ等 DS->>ACS: 認証要求転送 Note over DS,ACS: 本人認証に<br/>必要な情報転送 ACS->>ACS: リスク判定 Note over ACS: リスクベース認証 alt リスク低 ACS-->>DS: フリクションレス完了 DS-->>3DS: 認証結果転送 else リスク高 ACS->>DS: チャレンジ要求 DS->>3DS: チャレンジ要求転送 3DS->>EC: チャレンジ画面表示 EC->>ACS: 追加認証実施 ACS-->>DS: 認証結果 DS-->>3DS: 結果転送 end 3DS->>EC: 認証結果通知※ 実際の導入では、決済代行サービス(PSP)とのAPI通信が中心となるため、3つのドメイン間の詳細なやり取りはあまり意識する必要はありません。
- Issuer Domain(イシュアドメイン): カード発行会社
ECサイトでの具体的な実装フロー
上では、EMV 3-Dセキュアの全体的な認証フローと各ドメインの役割について簡単に説明しました。ここでは、先に示したシーケンス図の「ECサイト」の部分を詳細にしたフローとして、フロントエンドとバックエンドを分けた構成を例に、具体的なシーケンスを書いてみます。
図のソース(Mermaid)
sequenceDiagram
autonumber
participant Frontend
participant Backend
participant PSP
participant Issuer
Frontend->>Backend: 支払い情報を送信
Backend->>PSP: 3Dセキュア開始
PSP->>Issuer: 認証リクエスト転送
Issuer-->>Issuer: リスク評価を実施
Issuer-->>PSP: 認証結果返却
alt リスク評価の結果、低リスク(フリクションレス認証)
PSP-->>Backend: 認証成功
Backend->>PSP: 決済(与信)リクエスト
PSP->>Issuer: 与信リクエスト
Issuer-->>PSP: 与信結果返却
PSP-->>Backend: 決済結果を返却
Backend->>Frontend: 決済結果を通知
Note over Frontend: 購入完了画面表示
else リスク評価の結果、高リスク(ステップアップ認証)
PSP-->>Backend: チャレンジ要求
Backend->>Frontend: チャレンジ情報を返却
Frontend->>PSP: 認証画面表示・認証実行
PSP->>Issuer: 認証データ転送
Issuer-->>PSP: 認証結果返却
PSP-->>Backend: 認証成功
Backend->>PSP: 決済(与信)リクエスト
PSP->>Issuer: 与信リクエスト
Issuer-->>PSP: 与信結果返却
PSP-->>Backend: 決済結果を返却
Backend->>Frontend: 決済結果を通知
Note over Frontend: 購入完了画面表示
end
※ このシーケンス図は実装パターンの一例です。実際の実装ではPSPの仕様によって、認証結果の通知方法やフロントエンド/バックエンド間の役割分担が異なる場合があります。採用するPSPのドキュメントを確認の上、実装を進めることをお勧めします。
実装時のポイント
3Dセキュアの実装は、基本的にPSPの提供するAPIやSDKを使用するため、こちらで複雑な遷移ロジックを作成する必要はなく、必要なパラメータを収集してPSPに送信することが主な作業です。ただし、気をつけるべきポイントがあります。
-
トランザクション管理
3Dセキュアの認証プロセスはいくつかに分かれてるので1つのDBトランザクションで制御することができません。また、リダイレクトや外部システムとの通信中にトランザクションを維持しようとすると、DB接続が長時間占有され、他のリクエストへの影響を招く恐れがあります。これを避けるために、認証プロセスを複数のトランザクションに分割し、手続きを進めるたびに状態をコミットしておくことが重要です。それにより、処理状況やエラー発生状況も追跡し易くなります。
先ほどの図に注文情報(
orders)と支払い情報(payments)のステータス更新を追記してみたシーケンスが以下です。図のソース(Mermaid)
sequenceDiagram autonumber participant Frontend participant Backend participant PSP participant Issuer Frontend->>Backend: 支払い情報を送信 Note over Backend: orders.status = pending<br/>payments.status = initialized Backend->>PSP: 3Dセキュア開始 PSP->>Issuer: 認証リクエスト転送 Issuer-->>Issuer: リスク評価を実施 Issuer-->>PSP: 認証結果返却 alt リスク評価の結果、低リスク(フリクションレスフロー) PSP-->>Backend: 認証成功 Note over Backend: payments.status = authenticated Backend->>PSP: 決済(与信)リクエスト PSP->>Issuer: 与信リクエスト Issuer-->>PSP: 与信結果返却 PSP-->>Backend: 決済結果を返却 Note over Backend: orders.status = completed<br/>payments.status = captured Backend->>Frontend: 決済結果を通知 Note over Frontend: 購入完了画面表示 else リスク評価の結果、高リスク(チャレンジフロー) PSP-->>Backend: チャレンジ要求 Note over Backend: payments.status = challenge_required Backend->>Frontend: チャレンジ情報を返却 Frontend->>PSP: 認証画面表示・認証実行 PSP->>Issuer: 認証データ転送 Issuer-->>PSP: 認証結果返却 PSP-->>Backend: 認証成功 Note over Backend: payments.status = authenticated Backend->>PSP: 決済(与信)リクエスト PSP->>Issuer: 与信リクエスト Issuer-->>PSP: 与信結果返却 PSP-->>Backend: 決済結果を返却 Note over Backend: orders.status = completed<br/>payments.status = captured Backend->>Frontend: 決済結果を通知 Note over Frontend: 購入完了画面表示 end処理をイメージし易いように、なるべくシンプルに書いていますが、最低限これだけのステータス管理が必要になりそうだということは理解していただけたかと思います。
注意点:
- 図では
payments.statusに3Dセキュアの認証ステータスも含めていますが、3Dセキュア用のstatusはpayments.statusとは別に定義した方が都合が良いかもしれません。 - 図はステータスに焦点を当てて記載していますが、実際にはPSPからの返却値等はDBに保存しておいた方が良いでしょう。特にエラーに関しては詳細な状況を後で確認できるようにしておくことが重要です。
- 図では
-
エラーハンドリング
3Dセキュアの認証プロセスでは、ネットワークエラーや認証タイムアウト、ユーザーのブラウザバック、認証中断など、様々なエラーケースが発生する可能性があります。特に、チャレンジフロー時はユーザーの操作も介在するため、適切なエラーハンドリングと状態管理が重要です。3Dセキュアの認証状態は支払い状態とは独立して管理することをお勧めします(例:3Dセキュア認証用のテーブルを作成し、認証前、認証完了、チャレンジ要求、エラー、タイムアウトなどの状態を管理)。また、エラー発生時にはユーザーに適切なメッセージを表示し、必要に応じて再試行可能な導線を用意することをお勧めします。
-
3Dセキュア認証後のフロントエンドへの結果通知方法
このシーケンスのようにフロントエンドとバックエンドで処理を分担する実装での考慮ポイントとして、シーケンス図の22. 決済結果を通知 の実装方法があります。
前提として、3Dセキュアの認証画面は別タブ(またはポップアップウィンドウ)で開かれるとします。また、要件として、最終的にメインウィンドウで処理結果(決済成功/失敗)の表示する必要があるとしましょう。
シーケンス図を振り返ると、フロントエンドからバックエンドへのAPIリクエストは1. 支払い情報を送信の一度だけです。そして、そのリクエストに対するバックエンドからのレスポンスは、11. 決済結果を通知 か 13. チャレンジ情報を返却 のどちらかになります。13. チャレンジ情報を返却 が返ってきた場合、フロントエンドはその情報を受け取り、ユーザーに3Dセキュアの認証画面を表示します。フロントエンドはバックエンドから受け取ったチャレンジ情報をもとに、直接PSPと通信します。以後フロントエンドとバックエンドの間で新たな通信は行われず、バックエンドはユーザーが認証を完了するまで処理を待機している状態になります。
しかし、バックエンドが21. 決済結果を返却でPSPから認証結果を受け取った後、どのようにフロントエンドに結果を通知するかが課題となります。一般的にバックエンドからフロントエンドへの通知方法としては、フロントへのリダイレクト、ポーリング、WebSocket、SSE(Server-Sent Events )などが考えられます。ただし、今回のケースだとポップアップウィンドウからメインウィンドウに結果を伝える必要があります。
そこで、以前私が関わったプロジェクトでは、postMessageを使いFrontendのメインウィンドウに通知する方法を採用しました。具体的には、
window.opener.postMessage()を使ってメインウィンドウに結果を送信後、window.close()します。メインウィンドウは受け取った結果に応じて、ユーザーに決済結果のモーダルを表示することができます。※ このプロジェクトではStripeではありませんでしたが、Stripeの実装例でもpostMessageが使われています。
注意点:
- ネットワークの問題などで
postMessageが受信できない場合、フロントエンドが無限に待ち続けてしまう可能性があります。そのため、タイムアウト処理やエラーハンドリングを適切に実装することが重要です。
- ネットワークの問題などで
不正検知サービスとの併用
3Dセキュアでは、ACSがカード発行会社の情報(属性情報など)を基にリスク評価を行います。一方、不正検知サービスは多くのECサイトの取引データや行動パターンなど、より多角的な情報を活用して不正を検知できます。
クレジットカード・セキュリティガイドラインでも、単一の対策ではなく「多面的・重層的な対策」の必要性が強調されています。
参考までに、いくつかのサービスを紹介します。
(ここではそれぞれの比較は行いません。気になる方は各サービスのウェブサイトや比較サイトをご確認ください。)
不正検知サービスを併用することで、例えば、不正検知サービスで算出されたスコアリングに基づいて、ブラック判定であればその時点で取引中止などの制御が可能になりますし、グレイ判定であれば3Dセキュアのパラメータとして渡すことでACSのリスク評価を補完できます。
EMV 3-Dセキュア仕様では、加盟店やPSPがカスタムパラメータ(例: merchantRiskIndicator)を設定して送信することが可能になっています。
日本クレジット協会関連資料の【EMV 3-Dセキュア】統合版_AReq設定項目及び3RIの仕様・ユースケース(公表版)参照
このように、3Dセキュアの認証と不正検知サービスの組み合わせにより、より堅牢な防御が実現できそうです。
まとめ
EMV 3-Dセキュアの導入は、ECサイトにとって避けて通れない課題となっています。本ブログでは、その全体像から具体的な実装フロー、実装時のポイント、不正検知サービスとの併用について解説しました。
EMV 3-Dセキュアの実装では、フロントエンドとバックエンドの適切な役割分担、トランザクション管理、エラーハンドリングなど、様々な技術的な考慮が必要になります。一方で、リスクベース認証によって低リスクな取引ではパスワード入力などの追加認証を省略でき、ユーザー体験を損なうことなくセキュリティを強化できます。さらに、不正検知システムと組み合わせることで、より堅牢な不正対策の実現が可能です。
導入に際しては、本記事の内容を参考に、採用するPSPの仕様に沿って実装を進めることをお勧めします。
参考リンク