跳转到内容

常见问题

3DS 集成模式对接指引

3DS method 样例(result.action=IdentifyShopper)

Post 参数

threeDSMethodData: Base64url encode

image.png

3DS Method 允许 ACS 在收到 AReq 报文前收集额外的浏览器信息,以帮助交易风险评估。ACS 可以选择性使用 3DS Method。

如 EMVCo 3DS 规范所述,3DS 请求者应在持卡人浏览器中渲染一个隐藏的 HTML iframe,并通过 HTTP POST 向 ACS 3DS Method URL 发送一个名为 threeDSMethodData 的 JSON 对象的表单。

3DS 请求方在指定时间内(例如 5 秒)接收到由 ACS 发送的 3DS 方法设备收集完成请求后,应将 threeDSCompInd 设置为“Y”。如果在规定时间内未收到请求,则应在超过制定时间后将 threeDSCompInd 设置为“N”。该字段的状态需要在 AReq 消息请求中发送。

3DS 设备信息收集的结果不会影响后续的 AReq 流程。

样例报文

创建一个隐藏的 iframe 并向 ACS 发 3DS 请求,每 500 毫秒监控一次响应。如果 ACS 在 500ms 内无响应,则跳过 3DS,执行 AReq。

html
<html>
  <head>
    <script type="text/javascript" src="jquery.min.js"></script>
    <script type="text/javascript">
      $(document).ready(function() {
                  // If 3ds method URL is empty,
                  // 3ds requestor can pass 3DS method processing and threeDSCompInd=U
                  var threeDSCompInd = "${threeDSCompInd}";
                  if (threeDSCompInd == "U") {
                      submitForm1(threeDSCompInd);
                      return;
                  }
                  // send 3DS Method request in iframe
                  var iframe = $("#3dsmethod");
                  var formContent = ""
                      .concat("<form name='form2' id='form2'
                          action = '${threeDSMethodUrl}'
                          method = 'post' > ")
                          .concat(" <input type='hidden' name='threeDSMethodData'
                              id = 'threeDSMethodData'
                              value = '${threeDSMethodData}' / > ")
                              .concat("</form>"); iframe.contents().find('body').html(formContent); iframe.contents().find('#form2').submit();
                              // monitor 3DS Method response
                              var t1 = window.setInterval(function() {
                                  console.log('monitor method result.');
                                  console.log($("#3dsmethod").attr("src"));
                                  if ($("#3dsmethod").contents().find('#threeDSCompInd').val() == "Y") {
                                      console.log('monitor method result GOTTEN.');
                                      window.clearInterval(t1);
                                      window.clearTimeout(t2);
                                      threeDSCompInd = "Y";
                                      submitForm1(threeDSCompInd);
                                  }
                              }, 500);
                              // if reach timeout setting, set threeDSCompInd = N and go next step
                              var t2 = window.setTimeout(function() {
                                  console.log('monitor timeout.');
                                  if (threeDSCompInd != "Y")
                                      threeDSCompInd = "N";
                                  window.clearInterval(t1);
                                  window.clearTimeout(t2);
                                  submitForm1(threeDSCompInd);
                              }, 5 * 1000);
                          });
                  //next step
                  function submitForm1(threeDSCompInd) {
                      console.log('before form1 submited, threeDSCompInd =',
                          threeDSCompInd);
                      $("#threeDSCompInd").val(threeDSCompInd);
                      $("#form1").submit();
                  }
    </script>
  </head>

  <body>
    <div>
      <form id="form1" name="form1" action="${next step URL}" method="post">
        <input type="hidden" name="threedsIntegratorOid" id="threedsIntegratorOid" value="${threedsIntegratorOid}" />
        <input type="hidden" name="threeDSCompInd" id="threeDSCompInd" value="" />
      </form>
    </div>
    <div id="iframe_3dsmethod">
      <iframe
        id="3dsmethod"
        src="about:blank"
        allow="geolocation"
        frameborder="0"
        allowfullscreen="true"
        style="width: 100%; height: 0vh; position: relative; border-width:
0px"
      >
      </iframe>
    </div>
  </body>
</html>

Post Creq 样例(result.action=ChallengeShopper)

Post 参数

creq: Base64url encode

threeDSSessionData: ACS 在 CRes 消息 POST 中向 3DS 请求者返回 3DS 请求者会话数据。可用于适应 3DS 请求者系统处理会话信息的不同方法。

Acs URL 样例

https://{host}:8050/acs-auth-web/challenge/brw/V/210/1/123/creq

ACS 请求

(creq): eyJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiI4OGVmNGIyNC1iOWRkLTQ0YTAtOTk2Yi1jYTYxMDcyYTFjOTIiLCJhY3NUcmFuc0lEIjoiMTE4ZDNiNjEtYjU5Ny00Nzg2LTg1ZWMtNzA0Mzc3ZDhjMWU4IiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjAyIn0=

image.png

浏览器挑战将在持卡人的浏览器中进行,ACS 将在浏览器挑战窗口中向持卡人展示标准化的挑战界面。

为获得更好的用户体验,3DS 请求者可在持卡人浏览器中创建一个 HTML iframe 以进行挑战,并在收到 CRes 信息后通过刷新页面和删除 HTML iframe 关闭挑战窗口。

样例报文

生成一个 HTTP 请求持卡人浏览器到 ACS 挑战页面。

html
<html>
  <head>
    <script type="text/javascript" src="jquery.min.js"></script>
    <script type="text/javascript">
      $(document).ready(function () {
        $('#form1').submit();
      });
    </script>
  </head>

  <body>
    <div>
      <form id="form1" name="form1" action="${acsURL}" method="post">
        <input type="hidden" name="creq" value="${creq}" />
        <input type="hidden" name="threeDSSessionData" value="${threeDSSessionData}" />
      </form>
    </div>
  </body>
</html>

ACS 应答: 显示类似页面

image.png

3DS 集成模式结果判断方式

3DS 集成模式发卡行回调类型判断

可以通过回调 body 的参数来区分是 IdentifyShopper 还是 ChallengeShopper 的回调。

  • IdentifyShopper 的发卡行回调中参数名称是 threeDSMethodData
  • ChallengeShopper 的发卡行回调中参数名称是 cres