背景:为了符合PCI规范,获得PCI证书,需要将新支付系统信用卡由直连模式调整成iframe模式,不再接触卡信息,直接使用支付渠道的iframe收集卡信息完成支付。

一、页面里引入cko script
<script src="https://cdn.checkout.com/js/framesv2.min.js"></script>
二、根据自己的情况选择要引入的iframe类型
cko在占位的div中插入iframe

1、single iframe(one input field)

<div class="card-frame">
    <!-- form will be added here -->
</div>

single iframe
2、multiple iframes(multiple input fields)

<div class="card-number-frame">
  <!-- card number will be added here -->
</div>
<div class="expiry-date-frame">
  <!-- expiry date will be added here -->
</div>
<div class="cvv-frame">
  <!-- cvv frame will be added here -->
</div>

multiple iframes

三、初始化frames
要展示出输入框需要先用public API key初始化frames
Frames.init("pk_sbox_XXXX");
四、frame可选配置参数
Frames.init({
    publicKey: 'pk_sbox_6ff46046-30af-41d9-bf58-929022d2cd14',
    acceptedPaymentMethods: [ // 需要支持的卡种
        "Visa",
        "Mastercard",
        "American Express",
        "Diners Club",
        "Discover",
        "JCB",
        "Mada",
    ],
    // localization 可以配置为语言,也可以直接配置input的placeholder文案
    // localization: 'EN-GB', 
    localization: {
        cardNumberPlaceholder: '1234 1234 1234 1234',
        expiryMonthPlaceholder: 'MM',
        expiryYearPlaceholder: 'YY',
        cvvPlaceholder: 'CVC',
    },
    debug: true, // 是否显示console messages 
    style: { // 初始化iframe样式
        base: {
            color: '#333',
            fontSize: '14px',
            fontFamily: 'Avenir',
            fontWeight: '400',
            letterSpacing: 'normal',
        },
        autofill: {
            backgroundColor: '#fff',
        },
        hover: {
            color: '#333',
        },
        focus: {
            color: '#333',
        },
        valid: {
            color: '#333',
        },
        invalid: {
            color: '#333',
        },
        placeholder: {
            base: {
                color: '#999',
            }
        },
    },
    ready: function() {
        // Frames注册完成
    },
    frameActivated: function() {
        // 表单渲染完成
    },
    cardBinChanged: function(data) {
        // 修改前8位卡号时触发
        // 返回结果{"bin":"43234533","scheme":"Visa"}
    },
    cardSubmitted: function() {
        // 表单数据提交时触发
    },
    cardValidationChanged: function(data) {
        // 返回结果{"isValid":true,"isElementValid":{"cardNumber":true,"expiryDate":true,"cvv":true,"schemeChoice":true}}
        const valid = Frames.isCardValid(); // 获取卡信息校验结果的方法
        if (valid) {
            Frames.submitCard(); //校验通过,提交卡信息
        }
    },
    cardTokenized: function(data) {
        // Frames.submitCard触发后执行,data内有token等信息
        // 返回结果{"type":"card","token":"tok_kwsesf3cvofu3oh4zrbzpslkjq","expires_on":"2022-10-13T13:31:52Z","expiry_month":12,"expiry_year":2031,"scheme":"Visa","last4":"1111","bin":"411111","card_type":"Credit","issuer":"JPMORGAN CHASE BANK, N.A.","issuer_country":"US","preferred_scheme":""}
    },
    frameBlur: function(data) {
        // 输入框失去焦点事件
        // 返回结果{"element":"card-number"}
    },
    frameFocus: function(data) {
        // 输入框获得焦点事件
        // 返回结果{"element":"card-number"}
    },
    frameValidationChanged: function(data) {
        // 表单有修改时触发,用于更新前端错误信息
        // 返回结果{"element":"card-number","isValid":true,"isEmpty":false,"isFormValid":false,"isFormEmpty":false}
    },
    paymentMethodChanged: function(data) {
        // 修改卡号,当卡有效是触发,用于展示对应币种图片
        // 返回结果{"isValid":false,"paymentMethod":"Visa","isPaymentMethodAccepted":true}
    },
});
iframe样式配置参数:
style配置后,会在iframe中生成对应的css。
五、另一种事件处理程序

除了上述通过configuration options进行事件处理之外,还可以采用绑定事件方式。

Frames.addEventHandler(Frames.Events.EVENT_NAME, handler); 
Frames.removeEventHandler(Frames.Events.EVENT_NAME, handler);
Frames.removeAllEventHandlers(Frames.Events.EVENT_NAME);

举个栗子:

<body>
  <!-- add frames script -->
  <script src="https://cdn.checkout.com/js/framesv2.min.js"></script>

  <form id="payment-form" method="POST" action="https://merchant.com/charge-card">
    <div class="card-frame">
      <!-- form will be added here -->
    </div>
    <!-- add submit button -->
    <button id="pay-button" disabled>
      PAY GBP 24.99
    </button>
  </form>

  <script>
    var payButton = document.getElementById("pay-button");
    var form = document.getElementById("payment-form");

    Frames.init("pk_sbox_6ff46046-30af-41d9-bf58-929022d2cd14");

    Frames.addEventHandler(
      Frames.Events.CARD_VALIDATION_CHANGED,
      function (event) {
        console.log("CARD_VALIDATION_CHANGED: %o", event);

        payButton.disabled = !Frames.isCardValid();
      }
    );

    form.addEventListener("submit", function (event) {
      event.preventDefault();
      Frames.submitCard()
        .then(function (data) {
          Frames.addCardToken(form, data.token);
          form.submit();
        })
        .catch(function (error) {
          // handle error
        });
    });
  </script>
</body>
参考:

JS frames
frames-react


纷橙
13 声望1 粉丝