﻿# ApplePay前端接口

## 1. 准备事项

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

1. 联系PayerMax技术支持，提供您的正式环境和测试环境的域名，以完成Apple的域名认证要求。特别注意，在测试环境中，`127.0.0.1`、`局域网IP`、`localhost`都无法拉起ApplePay。

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

  - 测试环境认证文件：[apple-developer-merchantid-domain-association](https://img-cdn-sg.payermax.com/public/20250703-93d02b05-fc2a-4569-b8a0-65887e5453a6apple-developer-merchantid-domain-association)；

  - 生产环境认证文件：[apple-developer-merchantid-domain-association](https://img-cdn-sg.payermax.com/public/20250730-0a4ca772-d0fa-49c3-82d1-ced08252b290apple-developer-merchantid-domain-association).

3. 商户配置好证书后，通知PayerMax验证域名证书，PayerMax将在Apple开发者后台操作域名证书验证。如果验证失败，可能的原因如下：

  - 证书路径配置错误；

  - 您的防火墙拦截了苹果检查服务，请配置[链接页面](https://developer.apple.com/documentation/applepayontheweb/setting-up-your-server)域名至服务器白名单；

  - 可能已经配置过其他MerchantID的证书，此时，可使用新域名，或在原开发者账号上删除对应域名证书。

## 2. API

使用方法 `PMdropin.API`。 

| **API**            | **描述**          | **详情**          |
|---------------------|---------------------|---------------------|
| create | 实例化一个内置组件 |  参阅[create](https://docs.payermax.com/202606-version/receipt/front-end-component/configuration-applepay.md#_1-1-create)      |
|  mount      | 将实例化组件挂载到`div`标签      |  参阅[mount](https://docs.payermax.com/202606-version/receipt/front-end-component/configuration-applepay.md#_1-2-mount)     |
| on           | 监听事件            |  参阅[on](https://docs.payermax.com/202606-version/receipt/front-end-component/configuration-applepay.md#_1-3-on)     |
| emit            | 触发事件            |  参阅[emit](https://docs.payermax.com/202606-version/receipt/front-end-component/configuration-applepay.md#_1-4-emit)      |

### 2.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      |  按钮样式	      |  -      |

### 2.2 mount
用于挂载初始化组件实例，使用方法`PMdropin.mount(Tag)`。

**Tag详解**

| **Tag**            | **描述**          |
|---------------------|---------------------|
| id | 需要挂载的id元素值，如 `PMdropin.mount('#applepay-frame')`|
| class | 需要挂载的class元素值，如 `PMdropin.mount('.applepay-frame')`|

### 2.3 on
用于监听组件内置响应事件，使用方法`PMdropin.on(Event, CallbackFunction)`。

**Event详解**

| **Tag**            | **描述**          | **返回值**          |
|---------------------|---------------------|---------------------|
| ready | 组件加载完成时触发 |`null` |
| payButtonClick | ApplePay按钮被点击时触发| `null`|

示例：

```js [payButtonClick]
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) 
    })
    
});
```

### 2.4 emit
用于调用组件内置方法，使用方法`PMdropin.emit(Event, Params)`。

| **Event**            | **Params**          | **描述**          |
|---------------------|---------------------|---------------------|
| canMakePayment | - |  获取本次支付token      |
| switchTheme | string |  切换主题      |
| setDisabled | Boolean |  设置组件可用状态      |
| setpayButtonStyle | string |  设置按钮样式      |

#### 2.4.1 emit.canMakePayment
检查当前组件状态是否具备发起支付条件，如果校验通过则返回卡标识。

Options配置：

| **Options**            | **是否必填**          | **字段类型**          | **描述**          | **默认值**          |
|---------------------|---------------------|---------------------|---------------------|---------------------|
| totalAmount | N |  String      |  ApplePay支付页面展示金额
数字字符串，最多传入两位小数，如果传入非法值`canMakePayment`响应会抛出异常`AMOUNT_INVALID`
注：该场景仅仅适用于`applyDropinSession`不传金额的场景，如果`applyDropinSession`传入了金额，不要使用该能力，务必确保`canMakePayment`传入的 `totalAmount`和最终支付`orderAndPay`传入的金额保持一致      |  -      |

canMakePayment Response：

| **Code码**            | **描述**          | 
|---------------------|---------------------|
| APPLY_SUCCESS | 成功获取 `paymentToken` |  
| UNKNOWN_ISSUE | 异常信息 | 
| AMOUNT_INVALID | 传入金额格式有误 | 
| APPLEPAY_INTERNAL_ERROR | Apple Pay 内部异常 | 

#### 2.4.2 emit.switchTheme
+ 设置按钮主题
+ 类型： `Boolean`
+ 默认：`light`

| **主题名称**            | **主题编码**          | **效果预览**          |
|---------------------|---------------------|---------------------|
| 白色 | light `默认` |  ![](https://img-cdn-sg.payermax.com/public/20240801-ac3e16a0-6aca-4333-8f2b-431df925b8ee.png)      |
| 黑色 | dark |  ![](https://img-cdn-sg.payermax.com/public/20240801-91bfb336-b33d-484d-a142-2ec5a3d8007d.png)      |

#### 2.4.3 emit.setDisabled
+ 设置组件可用状态
+ 类型 `Boolean`
+ 默认：`false`

```js
// 按钮不可用状态
PMdropin.emit('setDisabled', true)

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

#### 2.4.4 emit.setpayButtonStyle
+ 设置按钮样式
+ 类型： `Boolean`
+ 默认：`false`

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