Skip to content

前置组件 - ApplePay

1. 接入前步骤

ApplePay证书统一由PayerMax维护,商户仅需下载ApplePay认证文件保存在指定位置即可。

  1. 联系PayerMax技术支持,提供您的正式环境和测试环境的域名,以完成Apple的域名认证要求。特别注意,在测试环境中,127.0.0.1局域网IPlocalhost都无法拉起ApplePay,需要放在带有SSL证书的 https 域名下。

  2. 下载ApplePay认证文件,并放置在指定路径https://[待注册域名]/.well-known/apple-developer-merchantid-domain-association

  1. 商户配置好证书后,通知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

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

js
{
        "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指定本次订单实际可用的支付方式类型,当前仅支持CARDAPPLEPAYGOOGLEPAY

json
{
  "msg": "success",
  "code": "APPLY_SUCCESS", 
  "data": {
    "sessionKey": "bf2c47b085e24c299e45dd56fd751a70",
    "clientKey": "bbd8d2639a7c4dfd8df7d005294390df" 
    }
}

3.2 渲染前置组件

  1. 在相关 HTML 页面上引入 CDN 包。
html
<script src="https://cdn.payermax.com/dropin/js/pmdropin.min.js"></script>
  1. 通过过div标签,在商户页面嵌入一个ApplePay按钮待展示区域。
html
<div id="applepay" style="--padding-frame: 0;"></div>
  1. 初始化 PayerMax Frames。

服务端orderAndPay接口响应成功或者失败,一定要告诉前端,前端调用applepay.emit('paySuccess'/'payFail'),ApplePay的弹窗才会消失。

diff
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);
    })
})
  1. 拿到paymentToken 当用户在前端确认支付后,前端 canMakePayment 接口会拿到以下信息,用作后端发起支付。
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请求,创建支付。
diff
{
    "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"
    }
}
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. 前端API接口

使用方法 PMdropin.API

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

4.1 create

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

ComponentName详解

ComponentName字段类型描述
applepaystringApplePay组件

Options详解

Options是否必填字段类型描述默认值
clientKeyYString客户端公钥-
sessionKeyYString安全访问令牌-
sandboxNBoolean沙盒环境false
themeNString主题light
payButtonStyleNString按钮样式-

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
payButtonClickApplePay按钮被点击时触发null

示例:

js
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)

EventParams描述
canMakePaymentObject获取本次支付token
switchThemestring切换主题
setDisabledBoolean设置组件可用状态
setpayButtonStylestring设置按钮样式

4.4.1 emit.canMakePayment

检查当前组件状态是否具备发起支付条件,校验通过后返回paymentToken

js
PMdropin.emit('canMakePayment', params?)

params 为可选参数。若商户服务端在调用 /applyDropinSession 接口时已传入完整支付信息,可直接调用PMdropin.emit('canMakePayment')而无需传参。

Options配置:

Options是否必填字段类型描述
totalAmountNString支付金额,格式为纯数字字符串(如 '1.00')。仅推荐在商户服务端通过 /applyDropinSession 接口获取前置组件初始化信息时未传入金额的场景下使用,该金额仅用于展示在 Apple Pay 支付弹窗中。

示例:

js
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_ERRORApple Pay 内部异常

4.4.2 emit.switchTheme

  • 设置按钮主题
  • 类型: Boolean
  • 默认:light
主题名称主题编码效果预览
白色light 默认
黑色dark

4.4.3 emit.setDisabled

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

// 按钮可用状态
PMdropin.emit('setDisabled', false)

4.4.4 emit.setpayButtonStyle

  • 设置按钮样式
  • 类型: Boolean
  • 默认:false
js
// 设置ApplePay按钮宽高、内边距、边框弧度
PMdropin.emit('payButtonStyle', `width:20rem;height:4rem;border-radius: 4rem;padding:1rem 4rem;`)

此页面的内容有帮助吗?

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

Last updated:

Released under the MIT License.