Skip to content

フロントエンド実装(v2)

このセクションでは、サンプルコードを使用して加盟店アプリケーションのためのフロントエンドの実装方法を示します。

サンプルコードパッケージ内の以下のファイルはフロントエンド内の3DS2認証に必須です。必要な場合はディレクトリツリーで詳細を確認してください。

  • v2/process.html - すべての認証シーケンスを実装しています。
  • v2/3ds-web-adapter.js - 3DS2データをフロントエンドからバックエンドへ渡し、コールバックURLの為に必要なiframeを生成する3DSクライアントの重要なコンポーネントです。
  • notify_3ds_events.html - ActiveServerの為に使用されるコールバックページで、認証において(ステップ 7ステップ 18(C))を開始する際に必要になります。このページはチェックアウト処理に認証イベントを渡します。

以下は認証処理認証シーケンスに基づいたフロントエンド実装の詳細です。

重要

以下のサンプルコードは開発用ガイドのための例であるため、商用環境で十分にテストされたものではありません。そのため商用環境向けにご利用いただく場合は、事前にレビューおよび修正の上、お客様の環境上適切であるかご確認ください。

処理1: 認証の初期化

認証を初期化する為に、フロントエンドが必要な事:

RBC

3DSリクエスターがブラウザ情報を提供する場合、threeDSMethodAvailablefalse であれば iframe の設定はスキップできます。

ユーザーがチェックアウトページ内のチェックアウトを続けるボタンをクリックすると、ブラウザは必要なデータをセッションストレージに保存しprocess.htmlページに移動します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//checkout.html
function checkout() {
    var apiVersion = getApiVersion();
    switch (apiVersion) {
      case "v2":
        goApiV1();
        break;
       ...
    }
}

function goApiV1() {
    var sessionData = genSessionData();
    sessionData.messageCategory = "pa";
    sessionStorage.setItem("sessionData", JSON.stringify(sessionData));
    window.location.href = "/v2/process";
}

function genSessionData() {
    var sessionData = {};
    sessionData.channel = "brw";
    sessionData.authData = genAuthData();
    sessionData.backButtonType = "toShop";
    return sessionData;
}

注目

sessionDataが含むもの:

  • channelbrwまたは3ri。上記の例では、ブラウザベースの認証を実行するためにbrwチャンネルを使用しました。

  • messageCategorypa-決済認証または npa-非決済認証のいずれか。上記の例では、paを使用しました。

  • authData:JSON形式のすべての必要なデータ。データ構造については、APIドキュメントを参照してください。

  • backButtonType:プロセスページのbackボタンタイプを示します。上記の例では戻るボタンをショップに戻るとして作成します。

注意点:ページ間通信にsessionStorageを使用するのは、デモ用です。 3DSリクエスターの実際の実装では、既存のチェックアウトプロセスと統合するために、ページ間でパラメーターを転送するための最適なアプローチを選択しましょう。

process.htmlページ内で、sessionData受信し3DS2処理を開始します。まず、認証を初期化する為の情報を3ds-web-adapterに送信します (ステップ 1)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
//process.html
var sessionData = JSON.parse(sessionStorage.getItem("sessionData"));
...
switch (sessionData.channel) {
  case "brw":
    var container = $('#iframeDiv');
    brw(sessionData.authData, container, _callbackFn, sessionData.messageCategory,
        sessionData.options, sessionData.transType);
    break;
  ...     

3ds-web-adapter内のbrw()関数は以下のパラメータを含みます:

  • authData:JSON形式のすべての必要なデータ。データ構造については、APIドキュメントを参照してください。
  • container:複数のiframeを生成する3ds-web-adapterの事前定義されたコンテナー。
  • callbackFn:認証結果を処理するためのコールバック関数。この関数は、3ds-web-adapterからのコールバックを処理するために、加盟店側で実装する必要があります。callbackFnは、typedataの2つのパラメーターを受け取る必要があります。

    • typeイベントの種類を示します。受け入れられる値:
      • onAuthResult認証結果を示します
      • on3RIResult3riの結果を示す
      • onEnrolResultEnrolの結果を示します
      • onChallengeStart チャレンジを開始することを示す
      • onDecoupledAuthStartデカップルド認証を開始することを示します。
      • onErrorエラーを示します
    • data 3ds-web-adapterから返されたデータ。データには、「auth」、「3ri」の結果、またはエラーメッセージのいずれかが含まれます。

    例として、process.htmlページの_callbackFn(type、data){...}関数を利用できます。

  • options:3DSリクエスターのオプションのパラメーター。次のオプションを使用できます。

    • チャレンジキャンセル - options.cancelChallenge = trueを設定して、チャレンジが不要な場合にチャレンジをキャンセルするかどうかを指定します。

    • チャレンジキャンセル理由 - options.cancelReasonを次のように設定することにより、DS/ACSに詳細情報を提供するためにチャレンジがキャンセルされた場合に提供するオプション。

      • 01またはCReqNotSent(大文字と小文字は区別されません)

      • 02またはAuthResultNotDelivered(大文字と小文字は区別されません)

    • チャレンジウィンドウサイズ - options.challengeWindowSizeを次のように設定して、ACSから要求されるチャレンジウィンドウサイズを指定します。

      • 01 = 250 x400ピクセル

      • 02 = 390 x400ピクセル

      • 03 = 500 x600ピクセル

      • 04 = 600 x400ピクセル

      • 05 = フルスクリーン

  • transTypeDSプロファイルを選択するためのパラメーター。transType = prodを使用して本番ディレクトリサーバーを使用します。それ以外の場合は、TestLabディレクトリサーバーが使用されます。

次に3ds-web-adapter内のbrw()メソッドから3DSリクエスターバックエンドに認証を初期化する為の情報を送信します(ステップ 2)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//3ds-web-adapter.js
function brw(authData, container, callbackFn, options, transType) {

  _callbackFn = callbackFn;
  iframeContainer = container;
  _authData = authData;

  if (options) {
    _options = options;
  }

  //iframeのためにランダムな番号を作成する
  iframeId = String(Math.floor(100000 + Math.random() * 900000));

  // trans-type=prod を使用し本番環境DSを利用する
  var initAuthUrl = "/v2/auth/init";

  // 本番環境DSを利用するためにtrans-type=prodを追加する。詳細はhttps://docs.activeserver.cloudをご参照ください。
  if (transType === "prod") {
    initAuthUrl = initAuthUrl + "?trans-type=prod";
  }

  var initAuthData = {};
  initAuthData.acctNumber = authData.acctNumber;
  initAuthData.merchantId = authData.merchantId;
  if (options && options.challengeWindowSize) {
    initAuthData.challengeWindowSize = options.challengeWindowSize;
  }

  if (authData.skipAutoBrowserInfoCollect) {
    initAuthData.skipAutoBrowserInfoCollect = true;
  }

  console.log('init authentication', initAuthData);

  // /auth/initに認証を初期化するためにデータを送信する
  doPost(initAuthUrl, initAuthData, _onInitAuthSuccess, _onError)
}

brw()関数はバックエンド/api/v2/auth/initPOSTリクエストを送信します。APIメッセージオブジェクトはJSON形式で送信されます。バックエンドがどのようにこのリクエストを処理するかを確認するにはこちらを参照してください。

3ds-web-adapterは成功した応答を処理する為に_onInitAuthSuccess()関数を使用します(ステップ 5)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//3ds-web-adapter.js
function _onInitAuthSuccess(data) {
  console.log('init auth returns:', data);

  if (!data.authUrl) {
    _onError(data);
    return;
  }

  serverTransId = data.threeDSServerTransID;

  if (_authData.skipAutoBrowserInfoCollect) {
    // ブラウザ情報収集処理がスキップされていれば、3DSメソッドは実行可能。
    if (data.threeDSServerCallbackUrl) {
      executeIframes(data)
    } else {
      // 3DSメソッドが利用不可の場合、認証処理へ移行する。
      _doAuth(data.threeDSRequestorTransID, _authData.browserInfoCollected)
    }
  } else {
    // 通常通りiframesを実行し、デフォルトのブラウザ情報収集処理を利用する。
    if (data.threeDSServerCallbackUrl) {
      executeIframes(data)
    } else {
      _onError(data);
    }
  }
}

3ds-web-adapterは2つの隠しiframeをチェックアウトページに挿入します (ステップ 6)。1つ目のiframe(ステップ 7.1 ~ 7.4) 用で、threeDSServerCallbackUrlを使用してブラウザの情報がACSとActiveServerにより収集出来るようにします。

2つ目はオプションのモニタリングiframeで、ブラウザ情報を収集する間もしくは3DSメソッドの処理中に何かしらのエラーが発生した時に、InitAuthTimedOutイベントをActiveServer受信できるようになります。このイベントのタイムアウトは15秒です。

注目

シーケンス図のステップ 1からステップ 7はこの処理で実装されています。

処理 2: 認証の実行

認証を実行するためにはフロントエンドはブラウザ情報の収集、3DSメソッドデータの収集(収集が可能な場合のみ)を終える必要があります。これらの2つの処理が完了した後、notify_3ds_events.html3ds-web-adapterに認証を続けるよう通知します。この処理内で、何らかの理由によりデータ収集が失敗したか、もしくは完了出来なかった場合、InitAuth処理内でセットアップした別のモニタリングiframeによってInitAuthTimedOutのイベントが3ds-web-adapterに通知され、認証処理は終了されます。

以下は認証を実行するためのステップです。

  • notify_3ds_events.htmlを実装もしくは提供されたものを再利用し、データ収集についてのイベントを受信します。
  • _on3DSMethodSkippedもしくは_on3DSMethodFinishedイベントが通知された後、認証の実行メッセージを3DSリクエスターに送信します (ステップ 8ステップ 9) 。
  • 認証結果をフリクションレスフローもしくはチャレンジフローで処理します。(ステップ 13に続き、ステップ 14(F)またはステップ 14(C)) または、デカップルド・フロー(Step. 14(D))。

notify_3ds_events.htmlは認証処理を開始するのに使用されます (ステップ 8)3DSリクエスターnotify_3ds_events.htmltransIdcallbackNameとオプションのparam変数を提供します。バックエンド実装を確認するにはこちらを参照してください。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!--notify_3ds_events.html-->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8"/>
  <title>3DSecure 2.0 Authentication</title>
</head>
<body>

<form>
  <input type="hidden" id="notifyCallback" name="notifyCallback" value={{callbackName}}>
  <input type="hidden" id="transId" name="transId" value={{transId}}>
  <input type="hidden" id="param" name="param" value={{callbackParam}}>
</form>

<script src="https://code.jquery.com/jquery-3.3.1.min.js"
        integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
        crossorigin="anonymous"></script>
<script>
  //チェックアウトページに通知を送り、以降の処理を実行する。

  var callbackFn = parent[$('#notifyCallback').val()];
  //callbackFnは3ds-notifyハンドラーメソッドにより定義されています。
  if (typeof callbackFn === 'function') {
    callbackFn($('#transId').val(), $('#param').val());
  }
</script>

</body>
</html>

callbackNameに応じて3ds-web-adapter内の異なるメソッドを呼んでいる事が分かります(ステップ 8)callbackNameの値は_onThreeDSMethodFinished_onThreeDSMethodSkipped_onAuthResult、もしくは_onInitAuthTimedOutです。たとえば、_onInitAuthTimedOutイベントは、3DSメソッドがタイムアウトしたときに使用できます。それぞれのメソッドの説明は以下に記載します。

イベント説明
_onThreeDSMethodFinished3DSメソッドがACSにより終了し、_doAuth()を呼び出す時である事を通知します
_onThreeDSMethodSkipped3DSメソッドが(利用出来ない、もしくは別の理由により)スキップされ、_doAuth()を呼び出す時である事を通知します3DSメソッドがスキップされたか否かに関わらず、3DSサーバーのブラウザ情報収集は3DSメソッドよりも前に実行される事に注意してください。
_onAuthResultこのイベントは認証結果がActiveServerから取得可能になったことを通知します。フリクションレスフローとチャレンジフローで使用されます (ステップ 17(F) と 19(C))
_onInitAuthTimedOut3DSメソッド中もしくはブラウザ情報収集中にエラーが発生した事を通知します。デモ内ではこのイベントが発生した場合、このデモでは、エラーメッセージが出力され、認証プロセスが続行されます。
詳細については、 3ds-web-adapter.js_onInitAuthTimedOut()関数を確認してください。

timeout result

ここステップ 8ActiveServerにより返されるcallbackName_onThreeDSMethodFinishedもしくは _onThreeDSMethodSkippedのどちらかです。3ds-web-adapterはこれらのイベントを受信すると、POSTリクエストを送信し認証を実行する為に _doAuth()を呼び出します (ステップ 9)

そしてバックエンドはAPI /api/v2/auth/brw の呼び出しを作成します。バックエンドがどのようにそのリクエストを処理するか確認するにはこちらを参照してください。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
//3ds-web-adapter.js
function _doAuth(transId) {

  console.log('Do Authentication for transId', transId);

  //最初に3DSメソッド用のiframeを取り除く
  $("#3ds_" + iframeId).remove();

  var authData = _authData;
  if (!authData.skipAutoBrowserInfoCollect) {
    // skipAutoBrowserInfoCollectが使われなかった場合、通常通りブラウザ情報を収集する。
    authData.browserInfo = param;
  }

  // 認証処理では不要となるためskipAutoBrowserInfoCollectを除外する。
  delete authData.skipAutoBrowserInfoCollect;
  authData.threeDSRequestorTransID = transId;
  authData.threeDSServerTransID = serverTransId;
  console.log("authData: ", authData);
  doPost("/v2/auth", authData, _onDoAuthSuccess, _onError);
}

注目

ActiveServer から返却されたparam変数にはブラウザ情報が含まれており、それらは auth APIメッセージ内の authData に設定する必要があります。

RBC

3DSリクエスターでブラウザ情報収集処理を完了している場合は、/auth/brw 呼び出し時に browserInfoCollected に設定する必要があります。

デモ用のコードでは、ブラウザ情報はフロントエンドjavascript (3ds-web-adapter)に設定しておりますが、セキュリティ上の観点を考慮すると、本番環境ではバックエンドにこの処理を実装する必要があります。

3ds-web-adapterは成功した応答を処理する為に_onDoAuthSuccess()関数を使用します(ステップ 13)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//3ds-web-adapter.js
function _onDoAuthSuccess(data) {
  console.log('auth returns:', data);

  if (data.transStatus) {
    if (data.transStatus === "C") {
      // 3Dリクエスターはチャレンジフローに移行するか否かを選択できます。
      if (_options.cancelChallenge) {
          if (_options.cancelReason) {
            var sendData = {};
            sendData.threeDSServerTransID = serverTransId;
            sendData.status = _options.cancelReason;
            doPost("/v2/auth/challenge/status", sendData, _onCancelSuccess,
                _onCancelError)
          } else {
            var returnData = _cancelMessage();
            _callbackFn("onAuthResult", returnData);
          }
        } else {
          startChallenge(data);
        }

      } else if (data.transStatus === "D") {
        _startDecoupledAuth(data, getBrwResult);
      else {
        _callbackFn("onAuthResult", data);
      }
    } else {
      _onError(data);
    }
}

返されたtransStatusに基づいて異なるフローを実行します。

注目

transStatusはYCNDUAとです。

  • Y: 認証 / 口座確認に成功
  • C: チャレンジが必要
  • N: 未認証 / 口座未確認
  • U: 認証 / 口座確認を実行できなかった
  • A: 処理の試行が実施された
  • R: 未認証 / 口座未確認または取引拒否

詳細はAPIドキュメントを参照してください。

フリクションレス認証結果

もしtransStatusCまたはDではない場合(つまりフリクションレスの場合)、3ds-web-adapterはフリクションレスフローへ移行し(ステップ 14(F))_callbackFn("onAuthResult", data)を呼び結果を表示します (11行目)。

1
2
3
4
5
6
7
8
9
//process.html
function _callbackFn(type, data) {

  switch (type) {
    case "onAuthResult":
      // "Show results in separate page"を表示する。
      $("#sepButton").removeClass("d-none");
      showResult(data);
      break;

showResult(data)関数はprocess.htmlページ内に結果を表示します:

result shortcut

フリクションレス認証処理はこの時点で終了になります。そして加盟店チェックアウト処理は、認証結果情報を使用して通常のオーソリ処理に移動できます。

情報

認証結果は別のページにも表示されます。これは処理 3で説明されます。

チャレンジ処理の続行

transStatusCの場合、ACSがチャレンジを要求したことを示します。 3DS2認証を継続してチャレンジプロセスに進むか、チャレンジが不要な場合は認証プロセスを終了するかを決定するのは、3DSリクエスター次第です。このデモでは、 options.cancelChallengeパラメーターを使用して、チャレンジフローに関する3DSリクエスターの意思決定を示します。この機能は、BRWテストページで概説されています。

備考

デモの目的で、キャンセルチャレンジプロセスはフロントエンドのjavascript(3ds-web-adapterで実装されています。セキュリティ上の理由から、このプロセスは本番環境ではバックエンドで実装する必要がある場合があります。

3ds-web-adapterは、options.cancelChallengeパラメーターをチェックします。 options.cancelChallenge = trueの場合、3ds-web-adapterはチャレンジをキャンセルします。オプションで、指定されたキャンセルの理由に応じて、 options.cancelReasonを設定してActiveServerに送信することもできます。指定された理由は、3ds-web-adapterによってバックエンドから/auth/challenge/statusに送信されます。 バックエンドがこのリクエストを処理する方法を確認するには、こちらを参照してください。

チャレンジ結果のキャンセル画面は、次のスクリーンショットのようになります。

cancel challenge screen

options.cancelChallenge = trueが存在しない場合(または値がfalseに設定されている場合)、3ds-web-adapterstartChallenge()を呼び出し、チャレンジウィンドウにsrcchallengeUrlに設定したiframeを挿入します(ステップ. 14(C))

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//3ds-web-adapter.js
function startChallenge(data) {

    if (data.challengeUrl) {
      if (_options.threeDSSessionData) {
        data.challengeUrl = appendTDSSessionData(data.challengeUrl);
    }
        challengeResultReady = false;
        _callbackFn("onChallengeStart");
    //iframeを生成
    $('<iframe src="' + data.challengeUrl
        + '" width="100%" height="100%" style="border:0" id="' + "cha_"
        + iframeId
        + '"></iframe>')
    .appendTo(iframeContainer);

    if (data.resultMonUrl) {
      console.log("Start polling for challenge result");
      _doPolling(data.resultMonUrl, getChallengeAuthResult);
    } else {
      console.log(
          "No resultMonUrl provided, challenge timout monitoring is skipped.");
    }

  } else {
    _onError({"Error": "Invalid Challenge Callback Url"});
  }


}

注目

チャレンジシナリオを試したい場合は、こちらのガイドに従ってください。

iframeclass属性がwidth="100%"height="100%"に設定される事が分かります。これはiframeがACSに提供される内容に従ってサイズ変更をする為に必要です。また、リクエスターは、ACSにチャレンジページを特定のサイズで表示するように要求することもできます。この機能の概要は、BRWテストページに記載されています。

iframeが設定されると、次のステップ(ステップ15(C) - 23(C)が自動的に実行されます。チャレンジ画面は、以下のスクリーンショットのようになります。

result screen

そしてカード会員はワンタイムパスワードのような認証データを入力してチャレンジフォームを送信する事が出来ます。ACSは取引とカード会員を認証してチャレンジ結果を返します。

!!! note "注釈" チャレンジiframeを設置するとき、3ds-web-adapterは resultMonUrlとともに_doPolling()関数も追加する必要があります。これは、チャレンジプロセス時にACS側でタイムアウトが発生した場合に、認証結果が確実に取得されるようにするためです。_doPolling()関数と resultMonUrlの詳細については、次のセクションで説明します。

チャレンジフローが終了すると、ActiveServerはコールバックフォームを iframeに返します(ステップ23(C)iframeは、コールバックイベント_onAuthResult3DSリクエスターバックエンドの 3ds-notifyエントリポイント(ステップ24(C))に自動的に転送します。次に、3DSリクエスターは、前回のブラウザー情報収集と3DSメソッドの処理と同様にnotify_3ds_events.htmlページをレンダリングします(ステップ25(C)

チャレンジフローが終了した後、 ActiveServer3DSリクエスターバックエンド内の/3ds-notifyエントリーポイントをiframeを通して呼び出し、_onAuthResultが呼ばれます。3DSリクエスターは以前 (ステップ 19(C))と同様にnotify_3ds_events.htmlページをレンダリングします。3ds-web-adapterは認証結果を取得しそれをprocess.htmlページに表示する為に_onAuthResult()関数を呼び出します。

情報

本番環境ではACSはカード会員から得られた情報から複雑なリスクベースの認証を実行します。同様に、認証メソッド(例えばワンタイムパスワード、生体認証など)がカード会員のイシュアーにより決定され、実行されます。

デカップルド認証処理を続行

transStatusDの場合、カード会員とACSの間でデカップルド認証が実行されます。 ActiveServerは、デカップルド認証が完了すると、ACSから認証結果を取得します。デカップルド認証結果を取得するために、ActiveServer(ステップ13)transStatus = DとともにresultMonUrlを提供します。 3ds-web-adapterresultMonUrlを取得すると、resultMonUrlをポーリングし続けて、デカップルド認証結果の準備ができているかどうかを確認する必要があります(ステップ15(D)

注釈

ポーリング間隔を決定するのは3DSリクエスター次第です。推奨される間隔は2秒毎になります。

transStatusDのときに _startDecoupledAuth()関数を呼び出すことによって行われる結果のポーリング。

1
2
3
4
5
6
7
8
9
//3ds-web-adapter.js
function _startDecoupledAuth(data, authReadyCallback) {
  if (data.resultMonUrl) {
    _callbackFn("onDecoupledAuthStart", data);
    _doPolling(data.resultMonUrl, authReadyCallback)
  } else {
    _onError({"Error": "Invalid Result Mon Url"});
  }
}

_doPolling()関数はGETリクエストをresultMonUrlに送信して、結果の可用性を確認します((ステップ. 16(D)))。resultMonUrlから返された応答(Step.17(D))には、AuthResultNotReadyまたは AuthResultReadyのいずれかのeventが含まれています。AuthResultNotReadyが返されると、ポーリングプロセスは続行されます。 AuthResultReadyが返されると、authReadyCallback関数が呼び出され、ActiveServerから認証結果が取得されます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//3ds-web-adapter.js
function _doPolling(url, authReadyCallback) {
  console.log("call mon url: ", url);
  $.get(url)
  .done(function (data) {
    console.log('returns:', data);

    if (!data.event) {
      _onError({"Error": "Invalid mon url result"});
    }

    if (data.event === "AuthResultNotReady") {
      console.log("AuthResultNotReady, retry in 2 seconds");

      setTimeout(function () {
        _doPolling(url, authReadyCallback)
      }, 2000);
    } else if (data.event === "AuthResultReady") {
      console.log('AuthResultReady');
      authReadyCallback(serverTransId, _callbackFn);
    } else {
      _onError({"Error": "Invalid mon url result event type"});
    }
  })
  .fail(function (error) {
    callbackFn("onError", error.responseJSON);
  });
}

処理3: 認証結果の取得

チャレンジ処理が終了した後(ステップ. 25(C))、デカップルド認証結果を取得可能な場合、(ステップ. 18(D))、もしくはフリクションレス処理結果を別ページに表示する必要がある場合、オーソリ処理に必要な最終認証結果を取得するために、認証結果を要求する必要があります。

なぜ別の認証結果要求が必要なのか?

処理 2の後で利用可能な認証の結果を既に持っているのに、なぜ結果をもう一度要求する必要があるのか不思議に思うかもしれません。

これは、ステップ. 13で認証結果がページに転送されているためです。認証結果ページは、チェックアウトページとは別のページとして表示されるのが一般的です。この場合、3ds-web-adapterは結果を3DSリクエスターまたは結果ページに転送できますが、認証結果はクライアント側コードによって再転送されるため、推奨されるデータフローではありません。一般的に安全ではないと見なされます。

3DSリクエスターのサーバー側には、常に元のソース(ActiveServer)から結果を取得する独自のメカニズムが必要です。3DSリクエスターのクライアント側が認証結果を提供するのではなく、3DSリクエスターのサーバー側が認証結果を取得し結果ページを提供することでデータがより安全であることが保証できます。したがって、このステップで認証結果を再要求する必要があります。

このデモでは、process.html内の処理 2の最後のShow results in separate pageを選択して別のページに結果を表示する事も出来ます。

認証結果を取得し別ページに表示する為に、フロントエンドが必要な事は:

まず、process.htmlページ内でserverTransIdsessionStorage内に保存し、result.htmlページに移動します。

1
2
3
4
5
6
7
8
9
//process.html
function openResultInNewWindow() {
if (serverTransId) {
  var url = '/v2/result';

  sessionStorage.setItem("serverTransId", serverTransId);
  window.open(url, 'newwindow', 'height=800,width=1000');
}
}

v2/result.htmlページ内で、認証結果を取得する為に 3ds-web-adapter内のgetBrwResult()メソッドを呼び出します。getBrwResult()メソッドは認証結果の取得メッセージをバックエンドへ送信します。バックエンドはこのリクエストを受信し、/api/v2/auth/brw/resultメッセージをActiveServerに送信します。バックエンドがどのようにこのリクエストを処理するか確認するには、こちらを 参照してください。コールバック関数showData()はページに結果を表示します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
//result.html
var serverTransId = sessionStorage.getItem("serverTransId");

getBrwResult(serverTransId, showData);

function showData(type, data) {
    var toShow = "<dl class='row'>";
    Object.keys(data).forEach(function (k) {
      toShow = toShow + "<dt class='col-sm-4'>" + k + "</dt>" + "<dd class='col-sm-8'>" + data[k]
          + "</dd>";
    });
    toShow += "</dl>";
    $('#showResult').empty().append(toShow);
    $("#resultCard").removeClass("d-none");
}

新しい結果画面は以下のスクリーンショットのようになります:

result screen

成功

この文書ではフロントエンド統合について説明しました。認証が完了した後、チェックアウト処理は取引ステータス、ECIとCAVVを使用してオーソリ処理を続け、取引を完了出来ます。

次のチャプター

次へボタンを選択し3DSリクエスターの バックエンド実装について確認できます。