背景:为了符合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>
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>
三、初始化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>