前置组件 - ApplePay
1. 接入前步骤
ApplePay证书统一由PayerMax维护,商户仅需下载ApplePay认证文件保存在指定位置即可。
联系PayerMax技术支持,提供您的正式环境和测试环境的域名,以完成Apple的域名认证要求。特别注意,在测试环境中,
127.0.0.1、局域网IP、localhost都无法拉起ApplePay,需要放在带有SSL证书的 https 域名下。下载ApplePay认证文件,并放置在指定路径
https://[待注册域名]/.well-known/apple-developer-merchantid-domain-association。
- 商户配置好证书后,通知PayerMax验证域名证书,PayerMax将在Apple开发者后台操作域名证书验证。如果验证失败,可能的原因如下:
- 证书路径配置错误;请确保在公网上可以直接访问到
https://[待注册域名]/.well-known/apple-developer-merchantid-domain-association
- 您的防火墙拦截了苹果检查服务,请配置链接页面域名至服务器白名单;
- 可能已经配置过其他MerchantID的证书,此时,可使用新域名,或在原开发者账号上删除对应域名证书。
2. 接口介绍
2.1 接口列表
| 关联交互时序 | 调用方向 | 接口类型 | 接口PATH |
| 3.1 获取前置组件初始化信息 | 商户 -> PayerMax | 后端接口 | /applyDropinSession |
| 3.3 创建支付,调用前置组件下单接口 | 商户 -> 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
"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。
- /applyDropinSession API 接口请求示例:
{
"version": "1.4",
"keyVersion": "1",
"requestTime": "2025-05-14T16:30:27.174+08:00",
"appId": "test516e8ab74578be8eecd8c4803fbe",
"merchantNo": "TEST010117960578",
"data": {
"country": "MY", # 收单国家
"currency": "MYR", # 订单币种
"totalAmount":"50", # 订单金额
"userId": "20220622_00086", # 用户ID,须保持唯一
"componentList":["APPLEPAY","CARD"] # 指定本次订单支付可用的支付方式
}
}可以通过请求参数componentList指定本次订单实际可用的支付方式类型,当前仅支持CARD、APPLEPAY、GOOGLEPAY。
- /applyDropinSession API 接口响应示例:
{
"msg": "success",
"code": "APPLY_SUCCESS",
"data": {
"sessionKey": "bf2c47b085e24c299e45dd56fd751a70",
"clientKey": "bbd8d2639a7c4dfd8df7d005294390df"
}
}3.2 渲染前置组件
- 在相关 HTML 页面上引入 CDN 包。
<script src="https://cdn.payermax.com/dropin/js/pmdropin.min.js"></script>- 通过过
div标签,在商户页面嵌入一个ApplePay按钮待展示区域。
<div id="applepay" style="--padding-frame: 0;"></div>- 初始化 PayerMax Frames。
服务端orderAndPay接口响应成功或者失败,一定要告诉前端,前端调用applepay.emit('paySuccess'/'payFail'),ApplePay的弹窗才会消失。
var applepay = PMdropin.create('applepay', {
// 填入你在服务端获取到的 clientKey
clientKey: clientKey,
// 填入你在服务端获取到的 sessionKey
sessionKey: sessionKey,
theme: 'light',
// 开启沙盒模式联调
sandbox: true, //true
});
// 将组件挂载到 dom 节点
applepay.mount('#applepay');
applepay.on('ready', (res) => console.log('[merchant][ready]:', res))
applepay.on('payButtonClick', (res) => {
// 将组件设置为不可编辑状态
applepay.emit('setDisabled', true);
// 发起组件校验,并返回卡标识
applepay.emit('canMakePayment')
.then(function(response) {
// 解除不可编辑状态
applepay.emit('setDisabled', false);
// 成功获取到 response
if (response.code === 'APPLY_SUCCESS') {
// 获取卡标识 paymentToken
var paymentToken = response.data.paymentToken;
console.log("paymentToken:"+paymentToken);
// 进行后续支付操作,商户请求自己服务端,自己用params构造请求参数
//商户服务端调用支付接口orderAndPay,发起支付
if(paymentToken){
_postapi('orderAndPay',params).then(res =>{
const code = (res || {}).code
if (code == 'APPLY_SUCCESS') {
+ //服务端接收到支付成功回调后 ,需要将结果返回给前端,前端调用
+ //applepay.emit('paySuccess'),ApplePay弹窗会消失,并提示支付成功
applepay.emit('paySuccess')
} else {
+ applepay.emit('payFail') // 弹窗会消失
}
})}
}
})
.catch(function(error) {
// 解除不可编辑状态
applepay.emit('setDisabled', false);
})
})- 拿到
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"
}
}3.3 创建支付
- 商户服务端:调用/orderAndPay API 接口发起HTTP POST请求,创建支付。
- /orderAndPay API 接口请求示例:
{
"requestTime": "2025-05-28T03:52:42.591-02:00",
"keyVersion": "1",
"appId": "tested7c863c439a9e29b4519867965a",
"version": "1.4",
"merchantNo": "TEST10116880289",
"data": {
"integrate": "Direct_Payment", # 前置组件模式下,指定Direct_Payment
"totalAmount": 39.99,
"country": "SA",
"expireTime": "3600",
"paymentDetail": {
# 支付时,通过JS SDK的emit接口的canMakePayment事件响应获取,非空
+ "paymentToken": "TEST12637c2c2d942239d9a2661c4ad14f9",
"buyerInfo": {
"clientIp": "176.16.34.144",
"userAgent": "Chrome"
},
# 支付时,通过JS SDK的create接口的响应获取,非空
+ "sessionKey": "test29632c3643768e3b65ef6a31c9ce" # 前置组件模式下非空
},
"frontCallbackUrl": "https://front.your.com/pay/index.html",
"subject": "xx Game",
"outTradeNo": "ov1_da78b1f3c2f9443b966347fc89305fc9",
"notifyUrl": "https://notify.your.com/pay/paymentWebHookPayerMaxServlet",
"currency": "SAR",
"userId": "1822613953000446",
"terminalType": "WEB"
}
}- /orderAndPay API 接口响应示例:
{
"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. 前端API接口
使用方法 PMdropin.API。
| API | 描述 | 详情 |
|---|---|---|
| create | 实例化一个内置组件 | 参阅create |
| mount | 将实例化组件挂载到div标签 | 参阅mount |
| on | 监听事件 | 参阅on |
| emit | 触发事件 | 参阅emit |
4.1 create
用于初始化组件,使用方法 PMdropin.create(ComponentName, Options)。
ComponentName详解
| ComponentName | 字段类型 | 描述 |
|---|---|---|
| applepay | string | ApplePay组件 |
Options详解
| Options | 是否必填 | 字段类型 | 描述 | 默认值 |
|---|---|---|---|---|
| clientKey | Y | String | 客户端公钥 | - |
| sessionKey | Y | String | 安全访问令牌 | - |
| sandbox | N | Boolean | 沙盒环境 | false |
| theme | N | String | 主题 | light |
| payButtonStyle | N | String | 按钮样式 | - |
4.2 mount
用于挂载初始化组件实例,使用方法PMdropin.mount(Tag)。
Tag详解
| Tag | 描述 |
|---|---|
| id | 需要挂载的id元素值,如 PMdropin.mount('#applepay-frame') |
| class | 需要挂载的class元素值,如 PMdropin.mount('.applepay-frame') |
4.3 on
用于监听组件内置响应事件,使用方法PMdropin.on(Event, CallbackFunction)。
Event详解
| Tag | 描述 | 返回值 |
|---|---|---|
| ready | 组件加载完成时触发 | null |
| payButtonClick | ApplePay按钮被点击时触发 | null |
示例:
PMdropin.on('payButtonClick', function(event) {
// achieve paymentToken and orderAndPay
applePay.emit('setDisabled', true)
applePay.emit('canMakePayment')
.then(res => {
const paymentToken = res?.data?.paymentToken
if(paymentToken){
_postapi('orderAndPay',params).then(res =>{
const code = (res || {}).code
if (code == 'APPLY_SUCCESS') {
//服务端接收到支付成功回调后 ,需要将结果返回给前端,前端调用
//applepay.emit('paySuccess'),ApplePay弹窗会消失,并提示支付成功
applepay.emit('paySuccess')
} else {
applepay.emit('payFail')
}
})}else{
applePay.emit('setDisabled', false)
}
})
.catch(err => {
applePay.emit('payFail')
applePay.emit('setDisabled', false)
})
});4.4 emit
用于调用组件内置方法,使用方法PMdropin.emit(Event, Params)。
| Event | Params | 描述 |
|---|---|---|
| canMakePayment | Object | 获取本次支付token |
| switchTheme | string | 切换主题 |
| setDisabled | Boolean | 设置组件可用状态 |
| setpayButtonStyle | string | 设置按钮样式 |
4.4.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 | 传入金额格式有误 |
| APPLEPAY_INTERNAL_ERROR | Apple Pay 内部异常 |
4.4.2 emit.switchTheme
- 设置按钮主题
- 类型:
Boolean - 默认:
light
| 主题名称 | 主题编码 | 效果预览 |
|---|---|---|
| 白色 | light 默认 | ![]() |
| 黑色 | dark | ![]() |
4.4.3 emit.setDisabled
- 设置组件可用状态
- 类型
Boolean - 默认:
false
// 按钮不可用状态
PMdropin.emit('setDisabled', true)
// 按钮可用状态
PMdropin.emit('setDisabled', false)4.4.4 emit.setpayButtonStyle
- 设置按钮样式
- 类型:
Boolean - 默认:
false
// 设置ApplePay按钮宽高、内边距、边框弧度
PMdropin.emit('payButtonStyle', `width:20rem;height:4rem;border-radius: 4rem;padding:1rem 4rem;`)

