﻿# Auth-Capture 前置组件支付集成

::: tip  
该文档介绍前置组件集成模式的集成流程。
:::

PayerMax通过预先构建的前端UI组件，其可以根据用户选择的不同支付方式，动态展示相应的支付信息输入表单。同时，商户也可以定制化组件的语言、样式等特性。

## 1. 集成准备

+ [注册开发者中心账号](https://docs.payermax.com/202606-version/developer/integration-guide.md#_3-2-注册成为开发者)；

+ [上传测试商户公钥](https://docs.payermax.com/202606-version/developer/integration-guide.md#_3-4-1-配置测试环境的密钥信息)，获取平台公钥、AppID、测试商户号等集成信息；

+ [配置回调地址（WebHook）](https://docs.payermax.com/202606-version/developer/integration-guide.md#_3-4-2-配置测试环境的回调地址)，包括支付结果回调地址、退款结果回调地址等；

+ [设置测试环境服务器IP白名单](https://docs.payermax.com/202606-version/developer/integration-guide.md#_3-5-设置测试环境的服务器ip白名单)；

+ [配置并开通相应支付方式](https://docs.payermax.com/202606-version/developer/integration-guide.md#_3-6-开通集成的支付方式)；

+ [查看不同环境的请求地址](https://docs.payermax.com/202606-version/developer/integration-guide.md#_2-环境信息)；

+ [理解请求报文加签和验签的原理](https://docs.payermax.com/202606-version/developer/config-settings.md)，用于生成每次HTTP请求Header的`sign`签名字符串。

## 2. 交互流程

```mermaid
%%{init: {
  'theme': 'base',
  'themeVariables': {
    'primaryColor': '#e6f0ff',
    'primaryTextColor': '#333',
    'primaryBorderColor': '#5b9bd5',
    'lineColor': '#888',
    'actorMargin': 40,
    'noteBkgColor': '#0056b3',
    'noteTextColor': '#ffffff',
    'noteBorderColor': '#004a99'
  }
}}%%
sequenceDiagram
    participant User as 用户
    participant Page as 商户页面
    participant Component as PayerMax
前置组件
    participant MServer as 商户服务端
    participant PMServer as PayerMax服务器
    participant Channel as 支付渠道
钱包/银行等

    %% 1. 初始化阶段
    User->>Page: 1.1 选择商品下单
    Page->>MServer: 1.2 发送订单信息
如：收单国家、订单币种等
    MServer->>PMServer: 1.3 获取前置组件初始化信息
clientKey和sessionKey
    PMServer-->>MServer: 1.4 返回结果
clientKey和sessionKey
    MServer-->>Page: 1.5 返回结果
含clientKey和sessionKey
    Page->>Component: 1.6 创建并挂载PayerMax组件

    %% 2. 获取 Token 阶段
    User->>Page: 2.1 用户输入支付信息
    Page->>Component: 2.2 获取paymentToken
    Component->>PMServer: 2.3 获取paymentToken
    PMServer-->>Component: 2.4 返回结果
含paymentToken
    Component-->>Page: 返回paymentToken

    %% 3. 提交订单与支付
    User->>Page: 3.1 确认支付
    Page->>Component: 3.2 提交支付
含paymentToken
    Component->>MServer: 3.3 提交订单
含paymentToken
    MServer->>PMServer: 3.4 创建支付
调用前置组件下单接口
    PMServer->>Channel: 3.5 支付请求
    PMServer-->>MServer: 3.6 返回结果
    MServer-->>Component: 3.7 返回结果
    Component-->>Page: 3.8 返回结果

    %% 4. 获取支付结果 (逻辑框)
    rect rgb(235, 245, 255)
        Note over MServer, PMServer: 获取支付结果
        
        Note over MServer, PMServer: 通过支付结果通知
        PMServer->>MServer: 4.1 支付结果异步通知
        MServer->>MServer: 4.2 更新支付结果
        MServer-->>PMServer: 4.3 返回响应

        Note over MServer, PMServer: 通过支付订单查询
        MServer->>PMServer: 5.1 查询支付交易单
        PMServer-->>MServer: 5.2 交易详情，含支付结果
        MServer->>MServer: 5.3 更新支付结果
    end
```

## 3. 接口列表

| 关联交互时序                       | 调用方向             | 接口类型   | 接口PATH                                                                                                                                                                      |
| ---------------------------------- | -------------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1.3 获取前置组件初始化信息         | `商户` -> `PayerMax` | `后端接口` | [/applyDropinSession](https://docs.payermax.com/api.html?docName=New%20Version&docVer=v1.0&docLang=cn#/paths/aggregate-pay-api-gateway-applyDropinSession/post.html)          |
| 3.4 创建支付，调用前置组件下单接口 | `商户` -> `PayerMax` | `后端接口` | [/orderAndPay](https://docs.payermax.com/api.html?docName=New%20Version&docVer=v1.0&docLang=cn#/paths/aggregate-pay-api-gateway-orderAndPay(for-drop-dont-copy-me)/post.html) |
| 4.1 支付结果异步通知               | `PayerMax` -> `商户` | `后端接口` | [/collectResultNotifyUrl](https://docs.payermax.com/api.html?docName=New%20Version&docVer=v1.0&docLang=cn#/paths/collectResultNotifyUrl/post.html)                            |
| 5.1 查询支付交易                   | `商户` -> `PayerMax` | `后端接口` | [/orderQuery](https://docs.payermax.com/api.html?docName=New%20Version&docVer=v1.0&docLang=cn#/paths/aggregate-pay-api-gateway-orderQuery/post.html)                          |

## 4. 环境信息

- **测试环境**：https:// `pay-gate-uat.payermax.com`/aggregate-pay/api/gateway/ `<接口PATH>`

- **集成环境**：https:// `pay-gate.payermax.com`/aggregate-pay/api/gateway/ `<接口PATH>`

## 5. 集成步骤

### 5.1 获取前置组件初始化信息

商户服务端通过[/applyDropinSession API](https://docs.payermax.com/api.html?docName=New%20Version&docVer=v1.0&docLang=cn#/paths/aggregate-pay-api-gateway-applyDropinSession/post.html) 接口，发起HTTP POST请求，获取前置组件初始化所需的客户端令牌`clientKey`和会话令牌`sessionKey`。

**关键参数**：

| 字段名称            | 字段类型 | 是否必填 | 描述                                                   |
| ------------------- | -------- | -------- | ------------------------------------------------------ |
| `captureMode`       | `string` | `否`     | 请款模式：`MANUAL`                                     |
| `authorizationType` | `string` | `否`     | 授权类型：`PRE_AUTH`，`FINAL_AUTH`；默认为`FINAL_AUTH` |

[/applyDropinSession API](https://docs.payermax.com/api.html?docName=New%20Version&docVer=v1.0&docLang=cn#/paths/aggregate-pay-api-gateway-applyDropinSession/post.html) 接口请求示例：

``` js
curl --request POST \
  --url https://pay-gate-uat.payermax.com/aggregate-pay/api/gateway/applyDropinSession \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'sign: FPFVT3o227JrFRbqu19boZCpVVTF9KznxyRawUmxpfXilHV/0yK46haPhAjNu1hPUMy7Vw/ILXhfzffNm4Fj0apWknlTY9OJxnSoQxS9BTFtc61tn5yV1q69x/kkBl82/qwg+XTJ4fOzy7Mar3VaC1E2PlDA6RkkKBUyNE6RYgsdB+Su7an4+4HVTNAnoe74WyvBgxTLMNg28igBTdqxaO3w/UBY6ObVp7vkqkQGdL1Y+HgmMYaAVwrM3+ALWGId0sJ+YqTY4WJ+0xCRGhaSnybiIjZsQEYyID68WNUfuavDLDsEhaMm/HfQvf5p0R1Ltovp3wwJnEbQcjY458iX5A==' \
  --data '{
        "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`指定本次订单实际可用的支付方式，取值必须是商户已经签约的支付方式。商户可通过[**商户平台（MMC）**](https://mmc.payermax.com/#/login)查询已签约的支付方式，或者咨询PayerMax技术支持。

[/applyDropinSession API](https://docs.payermax.com/api.html?docName=New%20Version&docVer=v1.0&docLang=cn#/paths/aggregate-pay-api-gateway-applyDropinSession/post.html) 接口响应示例：

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

### 5.2 渲染前置组件

1. 在相关 HTML 页面上引入 CDN 包。

``` html

```

2. 通过过`div`标签，在商户页面嵌入一个`iframes`。

``` html
  
    

```

3. 初始化 PayerMax Frames。

``` js
// 初始化卡组件
const card = PMdropin.create('card', {
  clientKey: "客户端公钥", // 在步骤1.1中获取到的 data.clientKey
  sessionKey: "会话令牌", // 在步骤1.1中获取到的 data.sessionKey
  sandbox: false, // 默认是 false，即生产环境
  hideSaveCard: false, //是否隐藏保存卡信息选项，默认是false展示
  hideCardBrands: false, //是否隐藏左上角卡品牌的Logo，默认是false展示
});
// 挂载实例
card.mount('.frame-card'); // 将挂载至匹配到的第一个dom元素上
// 组件加载完成时机
card.on('ready', () => {
    // 移除自定义loading               
})
```

4. 监听表单填写状态，动态设置支付按钮（可选）。通过表单监听事件，可实时监控用户填写信息的合法性，以此动态设定 **支付** 按钮是否可点击。

``` js
card.on('form-check', (res) => {
  // res.isFormValid 为表单状态。取值是false/true
  // true 表示表单校验通过，可支付；false 表示校验未通过，不可支付，无法点击支付按钮。
  console.log('[dropin][form-check]:', res)
})
```

下载完整的[前端组件集成DEMO示例](https://img-cdn-sg.payermax.com/public/20250703-85aff055-dea2-4851-87c9-acd1a439c94f.zip)，替换`sessionKey`和`clientKey`后，可本地运行并查看前置组件集成样例。

### 5.3 创建支付

1. 商户客户端：用户点击发起支付，检查是否可支付，并获取`paymentToken`。

``` js
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) // 发生异常后解冻表单
  })
```

2. 商户服务端：调用[/orderAndPay API](https://docs.payermax.com/api.html?docName=New%20Version&docVer=v1.0&docLang=cn#/paths/aggregate-pay-api-gateway-orderAndPay(for-drop-dont-copy-me)/post.html) 接口发起HTTP POST请求，创建支付。

::: warning 注意：
创建支付后，商户可以通过接口入参`expireTime`指定单笔支付的支付关单时间，单位是秒，取值须大于1800（30分钟）且小于86400（24小时）。如果传入值小于1800，则系统默认重置为最小值30min；如果传入值小于86400，则系统默认重置为最大值86400。
如果商户不指定，则具体的关单时间，根据使用的支付方式会有所不同。
:::

[/orderAndPay API](https://docs.payermax.com/api.html?docName=New%20Version&docVer=v1.0&docLang=cn#/paths/aggregate-pay-api-gateway-orderAndPay(for-drop-dont-copy-me)/post.html) 接口请求示例：

**关键参数**：

| 字段名称            | 字段类型 | 是否必填 | 描述                                                   |
| ------------------- | -------- | -------- | ------------------------------------------------------ |
| `captureMode`       | `string` | `否`     | 请款模式：`MANUAL`，`AUTOMATIC`；默认为`AUTOMATIC`     |
| `authorizationType` | `string` | `否`     | 授权类型：`PRE_AUTH`，`FINAL_AUTH`；默认为`FINAL_AUTH` |

``` js
curl --request POST \
  --url 'https://pay-gate-uat.payermax.com/aggregate-pay/api/gateway/orderAndPay' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'sign: FPFVT3o227JrFRbqu19boZCpVVTF9KznxyRawUmxpfXilHV/0yK46haPhAjNu1hPUMy7Vw/ILXhfzffNm4Fj0apWknlTY9OJxnSoQxS9BTFtc61tn5yV1q69x/kkBl82/qwg+XTJ4fOzy7Mar3VaC1E2PlDA6RkkKBUyNE6RYgsdB+Su7an4+4HVTNAnoe74WyvBgxTLMNg28igBTdqxaO3w/UBY6ObVp7vkqkQGdL1Y+HgmMYaAVwrM3+ALWGId0sJ+YqTY4WJ+0xCRGhaSnybiIjZsQEYyID68WNUfuavDLDsEhaMm/HfQvf5p0R1Ltovp3wwJnEbQcjY458iX5A==' \
  --data '{
    "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": "River Game HK Limited",
        "outTradeNo": "ov1_da78b1f3c2f9443b966347fc89305fc9",
        "notifyUrl": "https://notify.your.com/pay/paymentWebHookPayerMaxServlet",
        "currency": "SAR",
        "userId": "1822613953000446",
        "terminalType": "WEB"
    }
}'
```

[/orderAndPay API](https://docs.payermax.com/api.html?docName=New%20Version&docVer=v1.0&docLang=cn#/paths/aggregate-pay-api-gateway-orderAndPay(for-drop-dont-copy-me)/post.htlm) 接口响应示例：

``` json
{
    "msg": "Success.",
    "code": "APPLY_SUCCESS",
    "data": {
        "outTradeNo": "test_da78b1f3c2f9443b966347fc89305fc9",
        "tradeToken": "T2024052805951921811176",
        "status": "SUCCESS"
    }
}
``` 

### 5.4 获取支付结果

[创建支付/orderAndPay API](https://docs.payermax.com/api.html?docName=New%20Version&docVer=v1.0&docLang=cn#/paths/aggregate-pay-api-gateway-orderAndPay/post.html) 接口响应的`data.status`并非支付终态，因此，商户不应直接使用其更新支付结果。

#### 5.4.1 支付结果通知

请查看[支付结果-支付结果通知](https://docs.payermax.com/202606-version/acquiring/start-integration/related-capabilities-integration/payment-result.md#_3-1-支付结果通知)。

#### 5.4.2 支付结果查询

请查看[支付结果-支付结果查询](https://docs.payermax.com/202606-version/acquiring/start-integration/related-capabilities-integration/payment-result.md#_3-2-支付结果查询)。

## 6. 测试上线

在商户完成上述集成步骤后，可以发起实际支付请求进行初步测试验证，具体步骤请查看[集成测试-发起测试](https://docs.payermax.com/202606-version/acquiring/integration-testing-and-troubleshooting/start-a-test.md)。

在测试通过后，最终发布上线前，须联系PayerMax技术支持，提交测试的订单信息，以便于PayerMax检查请求日志和数据，确认您已经正确集成相关能力，具体步骤请查看[集成测试-发起验收](https://docs.payermax.com/202606-version/acquiring/start-integration/golive-confirmation.md)。

验收通过后，商户可以[配置生产环境的集成信息](https://docs.payermax.com/202606-version/developer/integration-guide.md#_7-3-配置生产环境的集成信息)，并准备开量事宜。

另外，在**收单产品集成**下有PayerMax支持的各类支付方式的集成文档，其中包含每种支付方式的测试上线说明。

## 7. 错误排除

测试或验收过程中的响应错误，可以查看[错误排查-错误码](https://docs.payermax.com/202606-version/acquiring/integration-testing-and-troubleshooting/troubleshooting/error-code.md)。同时，在[常见问题](https://docs.payermax.com/202606-version/appendix/faq/collection/cashier-direct-api.md)中，总结列举各类常见的问题及其处理方式。

您还可以直接联系PayerMax技术支持团队，咨询集成、测试、验收过程中的任何问题。
