Skip to content

前置组件 - 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

json
"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

js
{
    "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": ""
}
json
{
    "msg": "",
    "code": "APPLY_SUCCESS",
    "data": {
            "sessionKey": "964bffa7c9eb4951bd5ba11a2691e5ed",
            "notSupportedComponent": [],
            "clientKey": "8eef820ecbd443b7a608c2e0863750eb"
    }
}

2.2 渲染前置组件

  1. 在相关 HTML 页面上引入 CDN 包。
html
<script src="https://cdn.payermax.com/dropin/js/pmdropin.min.js"></script>
  1. 通过过div标签,在商户页面嵌入一个ApplePay按钮待展示区域。
html
<div class="frame-googlepay">  
    <!-- 表单内容 -->
</div>
  1. 初始化 PayerMax Frames,将GooglePay进行挂载。
js
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');
  1. 监听按钮状态,用户走完GoolePay认证流程,前端拿到paymentToken,服务端发起支付并返回redirectUrl到前端引导用户完成3DS认证
SQL
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('认证出现异常,请重试');
    }
  });
}
  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"
    }
}

2.3 创建支付

  1. 商户服务端:调用/orderAndPay API 接口发起HTTP POST请求,创建支付。
diff
{
        "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"
}
json
{
    "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字段类型描述
googlepaystringGooglePay组件

Options详解

Options是否必填字段类型描述默认值
clientKeyYString客户端公钥-
sessionKeyYString安全访问令牌-
sandboxNBoolean沙盒环境false
payButtonConfigNObject按钮样式'{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
payButtonClickGooglePay按钮被点击时触发null

3.4 create3DSPopup

用于在组件内弹窗打开3DS认证页面

语言设置说明: SDK会会自动从实例配置中获取语言,无需在create3DSPopup中单独传入

入参说明:

参数类型必填默认值说明
urlstring-3DS 认证页面 URL(从 orderandpay 接口获取)
showMaskbooleantrue是否显示背景遮罩
widthstring响应式计算弹框宽度,不传则按设备/视口自动计算
heightstring响应式计算弹框高度,不传则按设备/视口自动计算

返回:

CODE说明处理建议
3DS_PROCESSED3DS 流程已处理继续后续支付流程,通过接口查询最终认证结果
USER_CANCEL用户关闭弹框提示用户已关闭,可重试
INVALID_PARAMS调用入参不合法根据 err.msg 检查入参(如 url 必填且非空、类型正确等),修正后重试

3.5 emit

用于调用组件内置方法,使用方法PMdropin.emit(Event, Params)

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

3.5.1 emit.canMakePayment

  1. 检查当前组件状态是否具备发起支付条件,校验通过后返回paymentToken
js
PMdropin.emit('canMakePayment', params?)

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

  1. Options配置: | Options | 是否必填 | 字段类型 | 描述 | | :--- | :---: | :---: | :--- | | totalAmount | N | String | 支付金额,格式为纯数字字符串(如 '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传入金额格式有误

3.5.2 emit.setDisabled

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

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

3.5.3 emit.setpayButtonConfig

  • 设置按钮样式
  • 类型: Object
  • 默认:
Go
{
  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

此页面的内容有帮助吗?

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

Last updated:

Released under the MIT License.