前置组件 - GooglePay
1. 接口介绍
1.1 接口列表
| 关联交互时序 | 调用方向 | 接口类型 | 接口PATH |
| 2.1 获取前置组件初始化信息 | 商户 -> PayerMax | 后端接口 | /applyDropinSession |
| 2.3 创建支付,调用前置组件下单接口 | 商户 -> PayerMax | 后端接口 | /orderAndPay |
| 2.4.1 支付结果异步通知 | PayerMax -> 商户 | 后端接口 | /collectResultNotifyUrl |
| 2.4.2 查询支付交易 | 商户 -> PayerMax | 后端接口 | /orderQuery |
1.2 环境信息
测试环境:https://
pay-gate-uat.payermax.com/aggregate-pay/api/gateway/<接口PATH>集成环境:https://
pay-gate.payermax.com/aggregate-pay/api/gateway/<接口PATH>
1.3 请求header
"headers": {
"Accept": "application/json",
"sign": "请参考签名规则:https://docs-v2.payermax.com/doc-center/developer/config-settings.html",//必须
"Content-Type": "application/json"
}2.开始集成
2.1 获取前置组件初始化信息
商户服务端通过/applyDropinSession API 接口,发起HTTP POST请求,获取前置组件初始化所需的客户端令牌clientKey和会话令牌sessionKey。
- /applyDropinSession API 接口请求示例:
{
"requestTime": "2024-11-20T01:56:36.753-02:00",
"keyVersion": "1",
"data": {
"country":"US",
"currency": "USD",
"totalAmount": "19.99",
"componentList": ["CARD","GOOGLEPAY"],
"userId": "1447410849000200"
},
"appId": "381ded7c863c439a9e29b4519867965a",
"version": "1.1",
"merchantNo": ""
}- /applyDropinSession API 接口响应示例:
{
"msg": "",
"code": "APPLY_SUCCESS",
"data": {
"sessionKey": "964bffa7c9eb4951bd5ba11a2691e5ed",
"notSupportedComponent": [],
"clientKey": "8eef820ecbd443b7a608c2e0863750eb"
}
}2.2 渲染前置组件
- 在相关 HTML 页面上引入 CDN 包。
<script src="https://cdn.payermax.com/dropin/js/pmdropin.min.js"></script>- 通过过
div标签,在商户页面嵌入一个ApplePay按钮待展示区域。
<div class="frame-googlepay">
<!-- 表单内容 -->
</div>- 初始化 PayerMax Frames,将GooglePay进行挂载。
const googlePay = PMdropin.create('googlepay', {
clientKey: "8eef820ecbd443b7a608c2e0863750eb",
sessionKey: "0fdde7eda5fe4cc28ca8fdc759e28dc1",
sandbox: true,
payButtonConfig: {
buttonRadius: "12",
buttonColor: "white",
buttonType: "order",
buttonLocale: "en",
width: "240px",
height: "40px"
}
});
//按钮挂载
googlePay.mount('.frame-googlepay');- 监听按钮状态,用户走完GoolePay认证流程,前端拿到
paymentToken,服务端发起支付并返回redirectUrl到前端引导用户完成3DS认证
googlePay.on('ready', () => {
console.log('组件初始化完成');
})
googlePay.on('load', (res = {}) => {
const { code, msg } = res || {};
if (code === "SUCCESS") {
console.log('[merchant][load]success:', res)
} else {
console.log('[merchant][load]fail:', res)
}
})
googlePay.on('payButtonClick', (res) => {
googlePay.emit('setDisabled', true);
googlePay.emit('canMakePayment')
.then(paymentRes => {
console.log('canMakePayment')
if (paymentRes.code === 'APPLY_SUCCESS') {
const paymentToken = paymentRes?.data?.paymentToken;
console.log('paymentToken:', paymentToken)
// ⚠️ 发起支付接口
// 商户自己请求后端接口进行下单,
// 商户自己用params构造请求参数,需要带上paymentToken
const params = { // 添加params定义
token: paymentToken,
};
_postapi('orderAndPay', params)
.then(apiRes => {
const code = (apiRes || {}).code;
if (code === 'APPLY_SUCCESS') {
if(apiRes.threeDSUrl){
handle3DS(threeDSUrl)
//使用PayerMax组件内弹窗完成3ds;也可以将threeDSUrl新开浏览器tab页打开完成3ds
}
googlePay.emit('paySuccess');//支付成功,googlePay控件消失
} else {
googlePay.emit('payFail');//支付失败,googlePay控件消失
}
googlePay.emit('setDisabled', false);// ⚠️ 支付接口完成后解冻表单
})
.catch(err => {
console.error('API请求失败:', err);
googlePay.emit('setDisabled', false);// 发生异常后解冻表单
});
}
})
.catch(err => {
console.error('支付能力检测失败:', err);
googlePay.emit('setDisabled', false);
});
});
// orderAndPay后若获取到返回的url(即为threeDSUrl)就使用handle3DS方法唤起弹窗
function handle3DS(threeDSUrl) {
googlePay.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('认证出现异常,请重试');
}
});
}- 拿到
paymentToken,当用户在前端确认支付后,前端canMakePayment接口会返回以下信息,用作后端发起支付。
{
"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"
}
}2.3 创建支付
- 商户服务端:调用/orderAndPay API 接口发起HTTP POST请求,创建支付。
- /orderAndPay API 接口请求示例:
{
"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"
}- /orderAndPay API 接口响应示例:
{
"msg": "Success.",
"code": "APPLY_SUCCESS",
"data": {
"outTradeNo": "test_da78b1f3c2f9443b966347fc89305fc9",
"tradeToken": "T2024052805951921811176",
"status": "SUCCESS"
}
}2.4 获取支付结果
创建支付/orderAndPay API 接口响应的data.status并非支付终态,因此,商户不应直接使用其更新支付结果。
2.4.1 通过支付结果通知
请查看支付结果-通过支付结果通知。
2.4.2 通过支付订单查询
请查看支付结果-通过支付订单查询。
3. API
使用方法 PMdropin.API。
| API | 描述 | 详情 |
|---|---|---|
| create | 实例化一个内置组件 | 参阅create |
| mount | 将实例化组件挂载到div标签 | 参阅mount |
| on | 监听事件 | 参阅on |
| emit | 触发事件 | 参阅emit |
3.1 create
用于初始化组件,使用方法 PMdropin.create(ComponentName, Options)。
ComponentName详解
| ComponentName | 字段类型 | 描述 |
|---|---|---|
| googlepay | string | GooglePay组件 |
Options详解
| Options | 是否必填 | 字段类型 | 描述 | 默认值 |
|---|---|---|---|---|
| clientKey | Y | String | 客户端公钥 | - |
| sessionKey | Y | String | 安全访问令牌 | - |
| sandbox | N | Boolean | 沙盒环境 | false |
| payButtonConfig | N | Object | 按钮样式 | '{buttonRadius: "12",buttonColor: "default",buttonType: "plain",buttonLocale: "en",width: "240px",height: "40px"}' |
3.2 mount
用于挂载初始化组件实例,使用方法PMdropin.mount(Tag)。
Tag详解
| Tag | 描述 |
|---|---|
| id | 需要挂载的id元素值,如 PMdropin.mount('#googlepay-frame') |
| class | 需要挂载的class元素值,如 PMdropin.mount('.googlepay-frame') |
3.3 on
用于监听组件内置响应事件,使用方法PMdropin.on(Event, CallbackFunction)。
Event详解
| Tag | 描述 | 返回值 |
|---|---|---|
| ready | 组件加载完成时触发 | null |
| payButtonClick | GooglePay按钮被点击时触发 | null |
3.4 create3DSPopup
用于在组件内弹窗打开3DS认证页面
语言设置说明: SDK会会自动从实例配置中获取语言,无需在create3DSPopup中单独传入
入参说明:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| url | string | 是 | - | 3DS 认证页面 URL(从 orderandpay 接口获取) |
| showMask | boolean | 否 | true | 是否显示背景遮罩 |
| width | string | 否 | 响应式计算 | 弹框宽度,不传则按设备/视口自动计算 |
| height | string | 否 | 响应式计算 | 弹框高度,不传则按设备/视口自动计算 |
返回:
| CODE | 说明 | 处理建议 |
|---|---|---|
3DS_PROCESSED | 3DS 流程已处理 | 继续后续支付流程,通过接口查询最终认证结果 |
USER_CANCEL | 用户关闭弹框 | 提示用户已关闭,可重试 |
INVALID_PARAMS | 调用入参不合法 | 根据 err.msg 检查入参(如 url 必填且非空、类型正确等),修正后重试 |
3.5 emit
用于调用组件内置方法,使用方法PMdropin.emit(Event, Params)。
| Event | Params | 描述 |
|---|---|---|
| canMakePayment | Object | 获取本次支付token |
| switchTheme | string | 切换主题 |
| setDisabled | Boolean | 设置组件可用状态 |
| setpayButtonConfig | Object | 设置按钮样式 |
3.5.1 emit.canMakePayment
- 检查当前组件状态是否具备发起支付条件,校验通过后返回
paymentToken。
PMdropin.emit('canMakePayment', params?)params为可选参数。若商户服务端在调用/applyDropinSession接口时已传入完整支付信息,可直接调用PMdropin.emit('canMakePayment')而无需传参。
- Options配置: | Options | 是否必填 | 字段类型 | 描述 | | :--- | :---: | :---: | :--- | | totalAmount | N | String | 支付金额,格式为纯数字字符串(如 '1.00')。仅推荐在商户服务端通过
/applyDropinSession接口获取前置组件初始化信息时未传入金额的场景下使用,该金额仅用于展示在 Apple Pay 支付弹窗中。 |
示例:
PMdropin.emit('canMakePayment', {
totalAmount: '1.00'
})说明:
totalAmount仅接受合法的数字字符串(如'0.01'、'99.99')。传入非法值时,接口将返回错误码AMOUNT_INVALID。- 若商户服务端在调用
/applyDropinSession时已传入金额,则最终提交订单时的金额必须与其保持一致,否则可能导致支付失败或风控拦截。- 请确保
canMakePayment中传入的totalAmount与最终提交订单时的金额严格一致,否则可能导致支付失败或风控拦截。
canMakePayment Response:
| Code码 | 描述 |
|---|---|
| APPLY_SUCCESS | 成功获取 paymentToken |
| UNKNOWN_ISSUE | 异常信息 |
| AMOUNT_INVALID | 传入金额格式有误 |
3.5.2 emit.setDisabled
- 设置组件可用状态
- 类型
Boolean - 默认:
false
// 按钮不可用状态
PMdropin.emit('setDisabled', true)
// 按钮可用状态
PMdropin.emit('setDisabled', false)3.5.3 emit.setpayButtonConfig
- 设置按钮样式
- 类型:
Object - 默认:
{
buttonRadius: "12", // 设置googlepay按钮边框弧度 String
buttonColor: 'default', // 设置按钮颜色 "default"/"white"/ "black"
buttonType: 'plain',
buttonLocale: 'en',
width:"240px",
height:"40px",
}4. 内部字段说明
| 字段 | 默认值 | 类型 | 枚举值 | 功能说明 |
| width | "240px" | String | / | 设置googlepay按钮宽 |
| height | "40px" | String | / | 设置googlepay按钮高 |
| buttonRadius | "12" | String | / | 设置googlepay按钮边框弧度 String |
| buttonColor | 'default' | String | 'default'/'white'/ 'black' | 设置按钮颜色 |
| buttonType | 'plain' | String | "plain","buy","book","checkout","donate","order","pay","subscribe" | 设置按钮类型 同GooglePay官方。自定义按钮预览demo |
| buttonLocale | 'en' | String | 'en'/'ja'/'zh'/... 国际语种编码 | 设置按钮上文案的多语言,同GooglePay官方,需指定类型才支持,如"checkout"、"donate"等 |
5. 颜色展示
| 入参 | 效果预览 |
| default | ![]() |
| white | ![]() |
| black | ![]() |
6. buttonType展示
| 入参 | 效果预览 |
| "plain" | ![]() |
| "buy" | ![]() |
| "book" | ![]() |
| "checkout" | ![]() |
| "donate" | ![]() |
| "order" | ![]() |
| "pay" | ![]() |
| "subscribe" | ![]() |
7. buttonLocale展示
| 入参 | 效果预览 | 说明 |
| "ja" | ![]() ![]() | Japanese |
| "bg" | ![]() ![]() | Bulgarian |















