Skip to content

开始集成

环境准备

在开始前,请您确保已完成 设置测试环境 步骤以便继续。

环境信息如下:

测试环境https://p-gate-uat.checus.com/aggregate-pay/api/gateway/<PATH>
正式环境https://pay-gate-hk-prod.checus.com/aggregate-pay/api/gateway/<PATH>

交互流程

关键接口

关联交互时序调用方向接口类型接口名称/方法
1.3 获取前置组件初始化信息商户 -> Checus后端接口/applyDropinSession
1.6 创建并挂载Checus组件商户客户端 -> Checus前置组件JS SDK前端接口PMdropin.create
1.6 创建并挂载Checus组件商户客户端 -> Checus前置组件JS SDK前端接口PMdropin.mount
1.6 创建并挂载Checus组件商户客户端 -> Checus前置组件JS SDK前端接口PMdropin.on
2.2 获取paymentToken商户客户端 -> Checus前置组件JS SDK前端接口PMdropin.emit
3.4 创建支付,调用前置组件下单接口商户 -> Checus后端接口/orderAndPay
4.1 支付结果异步通知Checus -> 商户后端接口/collectResultNotifyUrl
5.1 查询支付交易商户 -> Checus后端接口/orderQuery

卡类支付集成步骤

1. 创建支付会话

调用 前置组件初始化API ,发起POST请求以创建支付。

从返回值获取 clientKeysessionKey,用于前端组件初始化。

json
{
    'Content-Type': 'application/json;charset=utf-8',
    'Accept': 'application/json',
    'sign': <参考:https://docs-v2.checus.com/doc-center/developer/config-settings.html>
};

request.body =
    {
        "version": "1.1",
        "keyVersion": "1",
        "requestTime": <替换>,
        "merchantNo": <替换>,
        "appId": <替换>,
        "data": {
            "country": "MY",
            "currency": "MYR",
            "totalAmount":"50",
            "userId": "20220622_00086",
            "componentList":["APPLEPAY","CARD"]
        }
    }

response={
  "msg": "",
  "code": "APPLY_SUCCESS",
  "data": {
    "sessionKey": "bf2c47b085e24c299e45dd56fd751a70",
    "clientKey": "bbd8d2639a7c4dfd8df7d005294390df"
    }
}

2. 渲染组件

您可下载 Demo示例,替换 clientKeysessionKey 后可以本地打开看到效果。

  • 引入 JS 组件
    js
    <script src="https://dropin.checus.com/dropin/js/pmdropin.min.js"></script>
  • 添加挂载容器
    js
    <div class="frame-card">
      <!-- form will be added here -->
    </div>
  • 初始化组件
    js
    // 初始化卡组件
    const card = PMdropin.create('card', {
      clientKey: "客户端公钥", // 在步骤1中获取到的 data.clientKey
      sessionKey: "会话令牌", // 在步骤1中获取到的 data.sessionKey
      sandbox: false, // 默认是 false,即生产环境
      hideSaveCard: false, //是否隐藏保存卡信息选项,默认是false展示
      hideCardBrands: false, //是否隐藏左上角卡品牌的Logo,默认是false展示
    });
    // 挂载实例
    card.mount('.frame-card'); // 将挂载至匹配到的第一个dom元素上
    // 组件加载完成时机
    card.on('ready', () => {
        // 移除自定义loading
    })
  • 监听表单状态(可选)

状态变更时将实时回调,可以由此决定支付按钮是否可点击。

js
card.on('form-check', (res) => {
  // res.isFormValid 为表单状态 false/true
  // true 表示表单校验通过,可尝试支付;false 表示校验未通过,无法点击支付按钮
  console.log('[dropin][form-check]:', res)
})
  • 获取支付 token 并发起下单

调用支付接口前务必检查是否可支付;可支付时,将获取到 paymentToken, 用于发起支付接口。

js
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') {
            //支付成功,展示支付结果
          } else {
            //支付失败,展示支付结果
          }
    }
      card.emit('setDisabled', false) // ❗️支付接口完成后解冻表单
    }
  })
  .catch(err => {
    card.emit('setDisabled', false) // 发生异常后解冻表单
  })

3. 商户后台下单

发起时机

canMakePayment 返回 APPLY_SUCCESS 后,从中获取 paymentToken,由商户服务端调用 /orderAndPay 接口完成下单。

请求流程

  • 商户前端将 paymentToken 传至商户后端;

  • 商户服务端生成唯一 outTradeNo,向 Checus 发起支付请求;

  • 若返回 redirectUrlstatus=PENDING,前端需跳转该 URL 进行认证(如 3DS);

  • 其他情况下直接返回支付结果。

    下单详细字段请参与 前置组件支付接口

    json
    {
        'Content-Type': 'application/json;charset=utf-8',
        'Accept': 'application/json',
        'sign': <XXX>
    };
    
    {
        "appId": <替换>,
            "version": "1.4",
            "merchantNo": <替换>,
            "requestTime": "2024-06-05T10:46:01.694+08:00",
            "keyVersion": "1",
            "data": {
                    "totalAmount": 77.44,
                    "country": "HK",
                    "expireTime": "7200",
                    "paymentDetail": {
                            "paymentToken": "332e4cc1af1740aeafe9e7df82aeb5a1",
                            "buyerInfo": {
                                    "clientIp": "59.82.59.92",
                                    "userAgent": "Chrome"
                            },
                            "sessionKey": "86409e2c04b44536a484caa5ce3ce0e9"
                    },
                    "frontCallbackUrl": <替换>,
                    "subject": "GoGeal PTE. LTD.",
                    "outTradeNo": <商户订单号,需唯一>,
                    "notifyUrl": <替换>,
                    "currency": "HKD",
                    "userId": "3ff0495692d152be96d84dbc9352dc57",
                    "integrate": "Direct_Payment",
                    "terminalType": "WEB"
            }
    }

卡类前端接口

API 使用说明

前置组件提供了标准的 API 接口供前端调用,核心方法通过 PMdropin.API 调用。

方法描述说明
create初始化组件详见 1.1
mount挂载组件至页面详见 1.2
on监听组件事件详见 1.3
emit触发组件方法详见 1.4

1. create — 初始化组件

js
const card = PMdropin.create('card', options);
  • ComponentName:当前支持 'card'(卡支付)
  • options 参数如下:
参数类型必填默认值描述
clientKeystring-客户端公钥
sessionKeystring-会话令牌
sandboxbooleanfalse是否启用沙盒环境
languagestring'en'显示语言
themestring'light'默认主题
customLocalizationobject-自定义语言包
customThemeobject-自定义样式
grayscalestring'0'页面灰度(0-1)
isRtlbooleanfalse从右至左布局支持
hideSaveCardbooleanfalse是否隐藏“保存卡”选项
hideCardBrandsbooleanfalse是否隐藏卡组织 Logo
hideCardHolderNamebooleanfalse是否隐藏姓名输入框
saveCardCheckedbooleantrue“保存卡”默认是否勾选
ignoreUserCheckedCachebooleanfalse忽略用户勾选缓存

2. mount — 挂载组件

js
card.mount('#card-frame');  // 挂载到指定 DOM 节点

支持使用 idclass 选择器。


3. on — 监听组件事件

js
card.on('ready', () => {
  // 组件加载完成
});

card.on('form-check', (res) => {
  if (res.isFormValid) {
    // 表单校验通过,可启用支付按钮
  }
});
事件名说明
ready组件加载完成
form-check实时返回表单是否校验通过(res.isFormValid = true/false

4. emit — 调用组件方法

常用事件

方法参数说明
canMakePayment-校验表单并获取 paymentToken
setDisabledboolean启用/禁用表单交互
switchLanguagestring切换语言
switchThemestring切换主题
addLocalizationobject添加自定义语言包
addThemeobject添加自定义主题
setRtlboolean启用 RTL 布局
setGrayscalestring设置页面灰度(0-1)

4.1 canMakePayment — 校验表单并获取 paymentToken

js
card.emit('canMakePayment')
  .then(res => {
    if (res.code === 'APPLY_SUCCESS') {
      const paymentToken = res.data.paymentToken;
      // 使用 token 发起后端支付
    }
  })
  .catch(err => {
    console.error('支付失败:', err);
  });

返回结构

json
// 成功
{
  code: 'APPLY_SUCCESS',
  data: {
    paymentToken: 'xxx'
  },
  msg: ''
}

// 失败
{
  code: 'FORM_INVALID',  // 或 UNKNOWN_ISSUE
  msg: 'Invalid params: cvv'
}
返回码说明
APPLY_SUCCESS成功获取 paymentToken
FORM_INVALID表单未通过校验
UNKNOWN_ISSUE其他异常错误

4.2 emit.switchLanguage

参阅 定制化

4.3 emit.switchTheme

参阅定制化

4.4 emit.addLocalization

参阅定制化

4.5 emit.addTheme

参阅定制化

4.6 emit.setDisabled

  • 设置组件可用状态
  • 类型 Boolean
  • 默认:false
js
// 不可编辑状态
PMdropin.emit('setDisabled', true)

// 可编辑状态
PMdropin.emit('setDisabled', false)

4.7 emit.setRtl

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

// 从左到右布局
PMdropin.emit('setRtl', false)

4.8 emit.setGrayscale

  • 设置组件页面灰度
  • 类型: String
  • 默认:0
js
// 设置 0 - 1 灰度值
PMdropin.emit('setGrayscale', '1')

更多配置请参考 卡类定制化

js
// 设置表单为不可编辑状态
card.emit('setDisabled', true);

// 切换语言
card.emit('switchLanguage', 'zh-CN');

// 启用右至左布局
card.emit('setRtl', true);

// 设置页面灰度为 100%
card.emit('setGrayscale', '1');

卡类定制化

通过定制语言和主题样式,您可以更好地适配自身网站的 UI 和用户体验。

1. 语言本地化

1.1 使用预置语言

支持设置 language 参数快速切换语言:

js
PMdropin.create('card', {
  clientKey: '',
  sessionKey: '',
  language: 'zh' // zh: 中文, en: 英文(默认)
});

也可通过如下方式动态切换:

js
PMdropin.emit('switchLanguage', 'zh');

1.2 自定义语言

如预置语言不满足需求,可通过 customLocalization 添加自定义字段:

js
PMdropin.create('card', {
  clientKey: '',
  sessionKey: '',
  customLocalization: {
    // 添加中文示例
    'zh': {
      loading: '加载中',
      loadingFailed: '加载失败',
      refresh: '刷新',
      confirm: '确定',
      cancel: '取消',
      removeCard: '移除卡',
      removeCardTip: '确定移除当前选中卡吗?',
      addNewCard: '使用新卡',
      useSavedCard: '使用已存卡',
      cardnum: '银行卡号',
      cardnumHint: 'XXXX XXXX XXXX XXXX',
      cardnumErrTip: '卡号不正确',
      cardbinErrTip: {
        // {cardOrg} 变量字段,无需翻译
        CARD_NOT_SUPPORT: '不支持{cardOrg},请检查卡号或者更换其他卡重试',
        // {cardType} 变量字段,无需翻译
        CARD_INVALID: '不支持{cardType}的卡类型',
        CARD_NO_INVALID: '请确认卡号输入是否正确',
      },
      expdate: '过期日期',
      expdateHint: '月/年',
      expdateErrTip: '过期日期不正确',
      cvv: 'CVV/CVC',
      cvvHint: '123',
      cvvErrTip: 'CVV/CVC 格式不正确',
      name: '持卡人姓名',
      nameHint: 'XX XX',
      nameErrTip: '姓名格式不正确',
      saveCardInfoTip: '为下次支付保存信息',
      // 以下为新增多语言字段
      // 本地卡额外采集要素
      buyerEmail: '邮箱',
      buyerEmailHint: '',
      buyerEmailErrTip: '格式错误,请复核',
      buyerFullName: '姓名',
      buyerFullNameHint: '',
      buyerFullNameErrTip: '格式错误,请复核',
      buyerFirstName: '名',
      buyerFirstNameHint: '',
      buyerFirstNameErrTip: '格式错误,请复核',
      buyerLastName: '姓',
      buyerLastNameHint: '',
      buyerLastNameErrTip: '格式错误,请复核',
      // 秘鲁 Document(ID)
      dni: 'DNI',
      dniHint: '',
      dniErrTip: '格式错误,请复核',
      // 阿根廷 Document(ID)
      dni_cuit: 'DNI/CUIT',
      dni_cuitHint: '',
      dni_cuitErrTip: '格式错误,请复核',
      // 南非 Document(ID)
      idCard: 'ID',
      idCardHint: '',
      idCardErrTip: '格式错误,请复核',
      // 哥伦比亚 Document(ID)
      cc: 'CC',
      ccHint: '',
      ccErrTip: '格式错误,请复核',
      // 墨西哥 Document(ID)
      curp: 'CURP',
      curpHint: '',
      curpErrTip: '格式错误,请复核',
      // 巴西 Document(ID)
      cpf: 'CPF',
      cpfHint: '',
      cpfErrTip: '格式错误,请复核',
      // 智利/巴拉圭/乌拉圭 Document(ID)
      ci: 'CI',
      ciHint: '',
      ciErrTip: '格式错误,请复核',
      buyerPhoneNo: '手机号码',
      buyerPhoneNoHint: '',
      buyerPhoneNoErrTip: '格式错误,请复核',
      buyerPhoneNoRegion: '手机区号',
      buyerPhoneNoRegionHint: '',
      buyerPhoneNoRegionErrTip: '格式错误,请复核',
    }
  },
  ...
});

动态添加方式:

js
PMdropin.emit('addLocalization', {
  'zh': {
    // 参数如上所示
  }
});

2. 主题样式

2.1 使用预置主题

支持 light(默认)与 dark 两种主题:

js
PMdropin.create('card', {
  clientKey: '',
  sessionKey: '',
  theme: 'dark'
});

动态切换:

js
PMdropin.emit('switchTheme', 'dark');

2.2 自定义主题

可通过 customTheme 自定义 CSS 变量覆盖主题样式:

js
PMdropin.create('card', {
  clientKey: '',
  sessionKey: '',
  customTheme: [
    {
      name: 'red',
      base: 'light',
      style: `:root {
        --color-primary: #e60000;
        --bg-primary: #fff;
        --border-radius-primary: 8px;
        // ... 其他样式
      }`
    }
  ]
});

也可通过动态添加:

js
PMdropin.emit('addTheme', [{ name: 'red', base: 'light', style: '...' }]);

基于 MIT 许可发布