开始集成 
环境准备 
在开始前,请您确保已完成 设置测试环境 步骤以便继续。
环境信息如下:
| 测试环境 | 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请求以创建支付。
从返回值获取 clientKey 和 sessionKey,用于前端组件初始化。
{
    '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示例,替换
clientKey和sessionKey后可以本地打开看到效果。
- 引入 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 })
- 监听表单状态(可选)
状态变更时将实时回调,可以由此决定支付按钮是否可点击。
card.on('form-check', (res) => {
  // res.isFormValid 为表单状态 false/true
  // true 表示表单校验通过,可尝试支付;false 表示校验未通过,无法点击支付按钮
  console.log('[dropin][form-check]:', res)
})- 获取支付 token 并发起下单
  调用支付接口前务必检查是否可支付;可支付时,将获取到 paymentToken, 用于发起支付接口。
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 发起支付请求;
- 若返回 - redirectUrl且- status=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 — 初始化组件 
const card = PMdropin.create('card', options);- ComponentName:当前支持- 'card'(卡支付)
- options参数如下:
| 参数 | 类型 | 必填 | 默认值 | 描述 | 
|---|---|---|---|---|
| clientKey | string | ✅ | - | 客户端公钥 | 
| sessionKey | string | ✅ | - | 会话令牌 | 
| sandbox | boolean | ❌ | false | 是否启用沙盒环境 | 
| language | string | ❌ | 'en' | 显示语言 | 
| theme | string | ❌ | 'light' | 默认主题 | 
| customLocalization | object | ❌ | - | 自定义语言包 | 
| customTheme | object | ❌ | - | 自定义样式 | 
| grayscale | string | ❌ | '0' | 页面灰度(0-1) | 
| isRtl | boolean | ❌ | false | 从右至左布局支持 | 
| hideSaveCard | boolean | ❌ | false | 是否隐藏“保存卡”选项 | 
| hideCardBrands | boolean | ❌ | false | 是否隐藏卡组织 Logo | 
| hideCardHolderName | boolean | ❌ | false | 是否隐藏姓名输入框 | 
| saveCardChecked | boolean | ❌ | true | “保存卡”默认是否勾选 | 
| ignoreUserCheckedCache | boolean | ❌ | false | 忽略用户勾选缓存 | 
2. mount — 挂载组件 
card.mount('#card-frame');  // 挂载到指定 DOM 节点支持使用 id 或 class 选择器。
3. on — 监听组件事件 
card.on('ready', () => {
  // 组件加载完成
});
card.on('form-check', (res) => {
  if (res.isFormValid) {
    // 表单校验通过,可启用支付按钮
  }
});| 事件名 | 说明 | 
|---|---|
| ready | 组件加载完成 | 
| form-check | 实时返回表单是否校验通过( res.isFormValid = true/false) | 
4. emit — 调用组件方法 
常用事件
| 方法 | 参数 | 说明 | 
|---|---|---|
| canMakePayment | - | 校验表单并获取 paymentToken | 
| setDisabled | boolean | 启用/禁用表单交互 | 
| switchLanguage | string | 切换语言 | 
| switchTheme | string | 切换主题 | 
| addLocalization | object | 添加自定义语言包 | 
| addTheme | object | 添加自定义主题 | 
| setRtl | boolean | 启用 RTL 布局 | 
| setGrayscale | string | 设置页面灰度(0-1) | 
4.1 canMakePayment — 校验表单并获取 paymentToken
card.emit('canMakePayment')
  .then(res => {
    if (res.code === 'APPLY_SUCCESS') {
      const paymentToken = res.data.paymentToken;
      // 使用 token 发起后端支付
    }
  })
  .catch(err => {
    console.error('支付失败:', err);
  });返回结构
// 成功
{
  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
// 不可编辑状态
PMdropin.emit('setDisabled', true)
// 可编辑状态
PMdropin.emit('setDisabled', false)4.7 emit.setRtl
- 设置组件从右到左布局
- 类型: Boolean
- 默认:false
// 从右到左布局
PMdropin.emit('setRtl', true)
// 从左到右布局
PMdropin.emit('setRtl', false)4.8 emit.setGrayscale
- 设置组件页面灰度
- 类型: String
- 默认:0
// 设置 0 - 1 灰度值
PMdropin.emit('setGrayscale', '1')更多配置请参考 卡类定制化
// 设置表单为不可编辑状态
card.emit('setDisabled', true);
// 切换语言
card.emit('switchLanguage', 'zh-CN');
// 启用右至左布局
card.emit('setRtl', true);
// 设置页面灰度为 100%
card.emit('setGrayscale', '1');卡类定制化 
通过定制语言和主题样式,您可以更好地适配自身网站的 UI 和用户体验。
1. 语言本地化 
1.1 使用预置语言
支持设置 language 参数快速切换语言:
PMdropin.create('card', {
  clientKey: '',
  sessionKey: '',
  language: 'zh' // zh: 中文, en: 英文(默认)
});也可通过如下方式动态切换:
PMdropin.emit('switchLanguage', 'zh');1.2 自定义语言
如预置语言不满足需求,可通过 customLocalization 添加自定义字段:
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: '格式错误,请复核',
    }
  },
  ...
});动态添加方式:
PMdropin.emit('addLocalization', {
  'zh': {
    // 参数如上所示
  }
});2. 主题样式 
2.1 使用预置主题
支持 light(默认)与 dark 两种主题:
PMdropin.create('card', {
  clientKey: '',
  sessionKey: '',
  theme: 'dark'
});动态切换:
PMdropin.emit('switchTheme', 'dark');2.2 自定义主题
可通过 customTheme 自定义 CSS 变量覆盖主题样式:
PMdropin.create('card', {
  clientKey: '',
  sessionKey: '',
  customTheme: [
    {
      name: 'red',
      base: 'light',
      style: `:root {
        --color-primary: #e60000;
        --bg-primary: #fff;
        --border-radius-primary: 8px;
        // ... 其他样式
      }`
    }
  ]
});也可通过动态添加:
PMdropin.emit('addTheme', [{ name: 'red', base: 'light', style: '...' }]);