Skip to content

前置组件 - CARD

1. 交互流程

%%{init: {
  'theme': 'base',
  'themeVariables': {
    'primaryColor': '#e6f0ff',
    'primaryTextColor': '#333',
    'primaryBorderColor': '#5b9bd5',
    'lineColor': '#888',
    'actorMargin': 40,
    'noteBkgColor': '#0056b3',
    'noteTextColor': '#ffffff',
    'noteBorderColor': '#004a99'
  }
}}%%
sequenceDiagram
    participant User as 用户
    participant Page as 商户页面
    participant Component as PayerMax
前置组件 participant MServer as 商户服务端 participant PMServer as PayerMax服务器 participant Channel as 支付渠道
钱包/银行等 %% 1. 初始化阶段 User->>Page: 1.1 选择商品下单 Page->>MServer: 1.2 发送订单信息
如:收单国家、订单币种等 MServer->>PMServer: 1.3 获取前置组件初始化信息
clientKey和sessionKey PMServer-->>MServer: 1.4 返回结果
clientKey和sessionKey MServer-->>Page: 1.5 返回结果
含clientKey和sessionKey Page->>Component: 1.6 创建并挂载PayerMax组件 %% 2. 获取 Token 阶段 User->>Page: 2.1 用户输入支付信息 Page->>Component: 2.2 获取paymentToken Component->>PMServer: 2.3 获取paymentToken PMServer-->>Component: 2.4 返回结果
含paymentToken Component-->>Page: 返回paymentToken %% 3. 提交订单与支付 User->>Page: 3.1 确认支付 Page->>Component: 3.2 提交支付
含paymentToken Component->>MServer: 3.3 提交订单
含paymentToken MServer->>PMServer: 3.4 创建支付
调用前置组件下单接口 PMServer->>Channel: 3.5 支付请求 PMServer-->>MServer: 3.6 返回结果 MServer-->>Component: 3.7 返回结果 Component-->>Page: 3.8 返回结果 %% 4. 获取支付结果 (逻辑框) rect rgb(235, 245, 255) Note over MServer, PMServer: 获取支付结果 Note over MServer, PMServer: 通过支付结果通知 PMServer->>MServer: 4.1 支付结果异步通知 MServer->>MServer: 4.2 更新支付结果 MServer-->>PMServer: 4.3 返回响应 Note over MServer, PMServer: 通过支付订单查询 MServer->>PMServer: 5.1 查询支付交易单 PMServer-->>MServer: 5.2 交易详情,含支付结果 MServer->>MServer: 5.3 更新支付结果 end

2. 接口介绍

2.1 接口列表

关联交互时序调用方向接口类型接口PATH
3.1 获取前置组件初始化信息商户 -> PayerMax后端接口/applyDropinSession
3.4 创建支付,调用前置组件下单接口商户 -> PayerMax后端接口/orderAndPay
3.4.1 支付结果异步通知PayerMax -> 商户后端接口/collectResultNotifyUrl
3.4.2 查询支付交易商户 -> PayerMax后端接口/orderQuery

2.2 环境信息

  • 测试环境:https:// pay-gate-uat.payermax.com/aggregate-pay/api/gateway/ <接口PATH>

  • 集成环境:https:// pay-gate.payermax.com/aggregate-pay/api/gateway/ <接口PATH>

2.3 请求header

js
"headers": {
        "Accept": "application/json",
        "sign": "请参考签名规则:https://docs-v2.payermax.com/doc-center/developer/config-settings.html",//必须
        "Content-Type": "application/json"
}

3.开始集成

3.1 获取前置组件初始化信息

商户服务端通过/applyDropinSession API 接口,发起HTTP POST请求,获取前置组件初始化所需的客户端令牌clientKey和会话令牌sessionKey

json
{
    "requestTime": "2024-11-20T01:56:36.753-02:00",
    "keyVersion": "1",
    "data": {
            "country":"US",
            "currency": "USD",
            "totalAmount": "19.99",
            "componentList": ["CARD","APPLEPAY"],
            "userId": "1447410849000200"
    },
    "appId": "381ded7c863c439a9e29b4519867965a",
    "version": "1.1",
    "merchantNo": ""
}
json
{
    "msg": "",
    "code": "APPLY_SUCCESS",
    "data": {
            "sessionKey": "964bffa7c9eb4951bd5ba11a2691e5ed",
            "notSupportedComponent": [],
            "clientKey": "8eef820ecbd443b7a608c2e0863750eb"
    }
}

3.2 渲染前置组件

  1. 在相关 HTML 页面上引入 CDN 包。
html
<script src="https://cdn.payermax.com/dropin/js/pmdropin.min.js"></script>
  1. 通过过div标签,在商户页面嵌入一个card待展示区域。
html
<div class="frame-card">  
    <!-- 表单内容 -->
</div>
  1. 初始化 PayerMax Frames。
js
// 初始化卡组件
const card = PMdropin.create('card', {
  clientKey: "客户端公钥", // 在步骤3.1中获取到的 data.clientKey
  sessionKey: "会话令牌", // 在步骤3.1中获取到的 data.sessionKey
  sandbox: false, // 默认是 false,即生产环境
  hideSaveCard: false, //是否隐藏保存卡信息选项,默认是false展示
  hideCardBrands: false, //是否隐藏左上角卡品牌的Logo,默认是false展示
});
// 挂载实例
card.mount('.frame-card'); // 将挂载至匹配到的第一个dom元素上
// 组件加载完成时机
card.on('ready', () => {
    // 移除自定义loading               
})
  1. 监听表单填写状态,动态设置支付按钮(可选)。通过表单监听事件,可实时监控用户填写信息的合法性,以此动态设定 支付 按钮是否可点击。
js
card.on('form-check', (res) => {
  // res.isFormValid 为表单状态。取值是false/true
  // true 表示表单校验通过,可支付;false 表示校验未通过,不可支付,无法点击支付按钮。
  console.log('[dropin][form-check]:', res)
})
  1. 用户点击支付按钮,商户提交支付到PayerMax服务端
js
//用户点击支付按钮,提交支付
function goPay(){
    card.emit('setDisabled', true) // 点击支付按钮后冻结表单,防止重复提交支付过程
    card.emit('canMakePayment')
      .then(res => {
        if (res.code === 'APPLY_SUCCESS') {
          const paymentToken = res.data.paymentToken // 支付token,支付接口使用
          // 发起支付接口
          // 商户自己请求后端接口进行下单, 
          // 商户自己用params构造请求参数,需要带上paymentToken
            _postapi('orderAndPay',params).then(res =>{
              const code = (res || {}).code
              //商户将支付结果返回到前端
              if (code == 'APPLY_SUCCESS') {  
                  if(res.threeDSUrl){ 
                //使用PayerMax组件内弹窗完成3ds;也可以将threeDSUrl新开浏览器tab页打开完成3ds
                    handle3DS(threeDSUrl)
                }
                //支付成功,展示支付结果
              }  else {
                  //支付失败,展示失败结果
              }
        }
          card.emit('setDisabled', false) // 支付接口完成后解冻表单
        }
      })
      .catch(err => {
        card.emit('setDisabled', false) // 发生异常后解冻表单
      })
}

// orderAndPay后若获取到返回的url(即为threeDSUrl)就使用handle3DS方法唤起弹窗
function handle3DS(threeDSUrl) {
  card.create3DSPopup({
    url: threeDSUrl,
    // width/height 不传则按设备与视口自动计算;也可显式传入如 '80%'、'400px' 等
  })
  .then(res => {
    if (res.code === '3DS_PROCESSED') {
      // 3DS 流程完成,继续支付流程。
      console.log('3DS 流程完成', res.data);
      // 此处商户需要维持现有逻辑,商户侧应该主动查询支付结果 继续商户侧后续的交互
      proceedPayment(res.data);
    }
  })
  .catch(err => {
    if (err.code === 'USER_CANCEL') {
      // 商户也可不做处理,但是应允许用户继续点击支付按钮
      showMessage('您已关闭认证窗口');
    } else {
      showMessage('认证出现异常,请重试');
    }
  });
}
  1. 当用户在前端确认支付后,前端canMakePayment接口会返回paymentToken,用作后端发起支付。

前端返回数据结构如下:

json
{
    "msg": "",
    "code": "APPLY_SUCCESS",
    "data": {
        "paymentToken": "CPT771e98494eff41f1a03a715ebab69cc9",
        "cardOrg": "VISA",
        "maskCardNumber": "444433****1111",
        "cardExpirationMonth": "12",
        "cardType": "CREDIT",
        "cardExpirationYear": "26",
        "cardHolderFullName": "Jemy Cheung",
        "agreementAccepted": true,
        "cardBinNo": "444433",
        "cardIssuingCountry": "US"
    }
}

3.3 创建支付

  1. 商户服务端:调用/orderAndPay API 接口发起HTTP POST请求,创建支付。

/orderAndPay API 接口请求示例:

diff
{
    "requestTime": "2024-11-20T01:56:45.802-02:00",
    "keyVersion": "1.5", 
    "data": {
        "currency": "USD",
        "country": "US",
        "totalAmount": 19.99,      
        "expireTime": "3600",
        "paymentDetail": {
+           "paymentToken": "dbe78b7dd4fa4b668bacfdcc7153821d", // 用户输入卡信息后点击支付会回调前端paymentDetail
            "buyerInfo": {
                "clientIp": "146.75.136.237",
                "userAgent": "Chrome"
            },
+           "sessionKey": "abf62fdcf9c4408cb73117db6e740713"
        },
        "frontCallbackUrl": "https://",
        "subject": "xxx Game HK Limited",
        "outTradeNo": "ov1_5b89ced71d764ed9994e6882d88082f7",
        "notifyUrl": "https://",
        "userId": "1447410849000200",
        "integrate": "Direct_Payment",
        "terminalType": "WEB"
    },
    "appId": "381ded7c863c439a9e29b4519867965a",
    "version": "1.4",
    "merchantNo": "P04010116880289"
}

WARNING

注意:返回中可能存在data.redirectUrl,这时请返回给前端引导用户完成3ds认证。

json
{
    "msg": "Success.",
    "code": "APPLY_SUCCESS",
    "data": {
        "outTradeNo": "test_da78b1f3c2f9443b966347fc89305fc9",
        "tradeToken": "T2024052805951921811176",
        "status": "SUCCESS"
    }
}

3.4 获取支付结果

创建支付/orderAndPay API 接口响应的data.status并非支付终态,因此,商户不应直接使用其更新支付结果。

3.4.1 通过支付结果通知

请查看支付结果-通过支付结果通知

3.4.2 通过支付订单查询

请查看支付结果-通过支付订单查询

4.卡支付前端接口

4.1 API

使用方法 PMdropin.API

API描述详情
create实例化一个内置组件参阅create
mount将实例化组件挂载到div标签参阅mount
on监听事件参阅on
emit触发事件参阅emit

4.1.1 create

用于初始化组件,使用方法 PMdropin.create(ComponentName, Options)

ComponentName详解

ComponentName字段类型描述
cardstring卡组件

Options详解

Options是否必填字段类型描述默认值
clientKeyYString客户端公钥-
sessionKeyYString安全访问令牌-
sandboxNBoolean沙盒环境false
languageNString语言en
themeNString主题light
customLocalizationNObject自定义语言-
customThemeNObject自定义主题-
grayscaleNString页面灰度'0'
isRtlNBoolean从右到左false
hideSaveCardNBoolean隐藏Save保存false
hideCardBrandsNBoolean隐藏头部卡组织LOGOfalse
hideCardHolderNameNBoolean隐藏卡姓名false
saveCardCheckedNBoolean保存卡信息的checkbox是否选中
true - 勾选
false - 不勾选
注:当hideSaveCard = false时,该字段生效
true
ignoreUserCheckedCacheNBoolean是否忽略用户勾选缓存
false - 默认不忽略
true - 忽略
注:当hideSaveCard = false时,该字段生效
false
hideRecommendAccountNBoolean是否隐藏推荐卡模块
false
openTermsInCurrentPageNBoolean是否在当前页面打开协议弹框
false
termsPopupConfigNObject协议弹框配置
注:当openTermsInCurrentPage = true时,该字段生效
-
>>showMaskNBoolean是否展示遮罩层
true
>>closeOnClickMaskNBoolean点击遮罩是否关闭弹框
true

4.1.2 mount

用于挂载初始化组件实例,使用方法PMdropin.mount(Tag)

Tag详解

Tag描述
id需要挂载的id元素值,如 PMdropin.mount('#card-frame')
class需要挂载的class元素值,如 PMdropin.mount('.card-frame')

4.1.3 on

用于监听组件内置响应事件,使用方法PMdropin.on(Event, CallbackFunction)

Event详解

Tag描述返回值
ready组件加载完成时触发null
form-check实时监听卡组件校验状态参阅下方 Event Response
load组件加载完成时触发Object
- type:组件类型card/applepay/googlepay
- code:响应码 SUCCESS 表示加载成功,其余枚举表示加载失败
- msg:响应 message

示例:

js
PMdropin.on('form-check', function(event) {
  if (event.isFormValid) {
    // 表单校验通过
  }
});

4.1.4 create3DSPopup

用于在组件内弹窗打开3DS认证页面

**语言设置说明:**SDK会会自动从实例配置中获取语言,无需在create3DSPopup中单独传入

入参说明:

参数类型必填默认值说明
urlstring-3DS 认证页面 URL(从 orderandpay 接口获取)
showMaskbooleantrue是否显示背景遮罩
widthstring响应式计算弹框宽度,不传则按设备/视口自动计算
heightstring响应式计算弹框高度,不传则按设备/视口自动计算

返回:

CODE说明处理建议
3DS_PROCESSED3DS 流程已处理继续后续支付流程,通过接口查询最终认证结果
USER_CANCEL用户关闭弹框提示用户已关闭,可重试
INVALID_PARAMS调用入参不合法根据 err.msg 检查入参(如 url 必填且非空、类型正确等),修正后重试

4.1.5 emit

用于调用组件内置方法,使用方法PMdropin.emit(Event, Params)

EventParams描述
canMakePayment-获取卡标识
switchLanguagestring切换语言
switchThemestring切换主题
addLocalizationObject添加自定义语言
addThemeObject添加自定义主题
setDisabledBoolean设置组件可用状态
setRtlBoolean设置组件从右到左布局
setGrayscalestring设置组件页面灰度
1. emit.canMakePayment

检查当前组件状态是否具备发起支付条件,如果校验通过则返回卡标识。

js
// 示例
PMdropin.emit('canMakePayment')
  .then(function(response) {
    // 验证成功
    if (response.code === 'APPLY_SUCCESS') {
      // 获取 paymentToken 
      var paymentToken = response.data.paymentToken
      // 进行后续支付操作
    }
  })
  .catch(function(error) {
    // 捕获内部异常错误
    console.log(error);
  })

canMakePayment Response:

js
// 接口成功示例
{
  code: 'APPLY_SUCCESS',
  data: {
    // 卡标识
    paymentToken: 'xxx'
  },
  msg: ''
}

// 接口失败示例
{
  code: 'FORM_INVALID',
  msg: 'Invalid params: cvv'
}
CODE码描述
APPLY_SUCCESS成功获取 paymentToken
FORM_INVALID表单校验失败
UNKNOWN_ISSUE异常信息
2. emit.switchLanguage
3. emit.switchTheme
4. emit.addLocalization
5. emit.addTheme
6. emit.setDisabled
  • 设置组件可用状态
  • 类型 Boolean
  • 默认:false
js
// 不可编辑状态
PMdropin.emit('setDisabled', true)

// 可编辑状态
PMdropin.emit('setDisabled', false)
7. emit.setRtl
  • 设置组件从右到左布局
  • 类型: Boolean
  • 默认:false
js
// 从右到左布局
PMdropin.emit('setRtl', true)

// 从左到右布局
PMdropin.emit('setRtl', false)
8. emit.setGrayscale
  • 设置组件页面灰度
  • 类型: String
  • 默认:0
js
// 设置 0 - 1 灰度值
PMdropin.emit('setGrayscale', '1')

此页面的内容有帮助吗?

感谢您帮助改进 PayerMax 产品文档!

Last updated:

Released under the MIT License.