﻿# Integration Process

![](https://img-cdn-sg.payermax.com/public/20250306-da597675-98cc-456e-b3e3-7121bd572542.jpg)

### 1. Implementation Process

Before integration: You need to provide an https domain name to payermax configuration (two domain names for the official environment and the test environment) for ApplePay to initiate payment.

::: danger Special Reminder:
During the test, `127.0.0.1`, `LAN`, and `localhost` will be all failed to pull up ApplePay.

:::

(a) Merchants provide their test environment and production environment domain names to PayerMax;

(b) PayerMax will generate certificates corresponding to each domain name for merchants;

(c) The merchant adds the certificate file apple-developer-merchantid-domain-association to the ./well-known path;

::: warning Note:
Please note the certificate configuration path.
:::

![](https://img-cdn-sg.payermax.com/public/20240524-9f7ef725-cee1-4292-9926-782900278249.jpg)

(4) After the merchant configures the certificate, it notifies PayerMax to verify the domain name certificate, and PayerMax will perform domain name certificate verification in the Apple developer backend.

::: warning If verification fails:
  1. The certificate path may be configured incorrectly: `Please check again whether the path is correct;`

  2. Maybe the domain name firewall blocks the Apple check service: Please configure the domain name of [the link page](https://developer.apple.com/documentation/apple_pay_on_the_web/setting_up_your_server#3179116) to the server whitelist, please refer to the screenshot below;

  3. You may have configured certificates for other MerchantIDs: `You can use a new domain name, or delete the corresponding domain name certificate on the original developer account.`
:::

![](https://img-cdn-sg.payermax.com/public/20240524-7664a72c-3658-4c63-a671-0540e1b95de6.png)

#### 1.1 Get clientKey and sessionKey

For detailed interface information, please refer: [API](https://docs.payermax.com/api.html?docName=New%20Version&docVer=v1.0&docLang=cn#/paths/aggregate-pay-api-gateway-applyDropinSession/post).

(a) Request API; the API environment and request URL are as follows:

| API Environment | Request URL                                                                    |
| --------------- | ------------------------------------------------------------------------------ |
| Test            | https://pay-gate-uat.payermax.com/aggregate-pay/api/gateway/applyDropinSession |
| Live            | https://pay-gate.payermax.com/aggregate-pay/api/gateway/applyDropinSession     |

(b) Get clientKey and sessionKey from the return value.

Request Header Example:

```json
{
    'Content-Type': 'application/json;charset=utf-8',
    'Accept': 'application/json',
    'sign': <Refer: https://docs-v2.payermax.comen/202506-version/developer/config-settings.html>
};
```

Request Body Example:

```json
request.body = 
    {
        "version": "1.1",
        "keyVersion": "1",
        "requestTime": <To be replaced>, 
        "merchantNo": <To be replaced>,
        "appId": <To be replaced>, 
        "data": {
            "country": "MY", 
            "currency": "MYR", 
            "totalAmount":"50",
            "userId": "20220622_00086",
            "componentList":["APPLEPAY","CARD"] 
        }
    }

response={
  "msg": "",
  "code": "APPLY_SUCCESS", 
  "data": {
    "sessionKey": "bf2c47b085e24c299e45dd56fd751a70",
    "clientKey": "bbd8d2639a7c4dfd8df7d005294390df" 
    }
}
```

#### 1.2 Rendering Components

+ **Front-end Example**

Download the [Demo](https://img-cdn-sg.payermax.com/public/20240801-a9cce221-531b-4bad-9b53-9ce7720a269c.zip), after replacing clientKey and sessionKey, you need to deploy it on a domain with an ApplePay certificate and open it to see the effect.

+ **Front-end Integration Steps**

(a) Introduce the CDN package on the relevant HTML page;

```html

```

(b) Embed an iframe via a div tag;

```html

  

```

(c) Initialize PayerMax Frames；

```js
// Initialize the card component
const applePay = PMdropin.create('applepay', {
  clientKey: "Client Public Key", // data.clientKey obtained in Step 1.1
  sessionKey: "Session Key", // data.sessionKey obtained in Step 1.1 
  sandbox: true, // The default value is false, which means production environment
  theme: 'dark',// Theme, the default value is light
});
// Mounting an instance
applePay.mount('.frame-applepay'); // Will be mounted on the first matched DOM element
// Component loading completed
applePay.on('ready', () => {
    // Except for custom loading               
})
```

(d) Listen for applePay button clicks and get paymentToken;

::: warning Note:
Get `paymentToken`, used to initiate the payment interface.
:::

```js
applePay.on('payButtonClick', (res) => {
  applePay.emit('setDisabled', true) // Freeze the form to prevent repeated button clicks
  applePay.emit('canMakePayment')
    .then(res => {
      if (res.code === 'APPLY_SUCCESS') {
        const paymentToken = res?.data?.paymentToken // Payment token, used for payment API
        // ❗️Initiate payment API
        // Merchants request the backend interface to place orders
        // Merchants use params to construct request parameters, and paymentToken is required
          _postapi('orderAndPay',params).then(res =>{
            const code = (res || {}).code
            // The merchant returns the payment result to the front end
            if (code == 'APPLY_SUCCESS') {     
              applepay.emit('paySuccess')// Payment is successful, ApplePay control disappears
            } else {
              applepay.emit('payFail')// Payment failed, ApplePay control disappeared
            }
        applePay.emit('setDisabled', false) // ❗️Unfreeze the form after the payment interface is completed
      } 
    })
    .catch(err => {
      applePay.emit('setDisabled', false) // Unfreeze the form after an exception occurs
    })
})
```

(e) Initiate payment. For details, please refer to 1.3 Server-side Initiated Payment.

#### 1.3 Place order on merchant backend 

+ **Order Timing**

Please call card.emit('canMakePayment') on the front end and initiate an order request when response.code is 'APPLY_SUCCESS'. At this point, you can get the paymentToken from the canMakePayment method and use it as an input parameter in the subsequent order placement interface.

+ **Order Steps**

(a) The merchant frontend initiates an order to the merchant backend, passing in the paymentToken obtained by the canMakePayment method.

(b) The merchant server generates an order number (outTradeNo) and then initiates a payment request to the PayerMax server;

(c) Process the PayerMax response result.

+ **Response Processing**

The server will return the payment result after placing an order. After processing the payment result, it needs to respond to the front end. The front end calls applepay.emit('paySuccess') or applepay.emit('payFail') according to the response result.

+ **API Environment and Request URL**

| API Environment | Request URL                                                             |
| --------------- | ----------------------------------------------------------------------- |
| Test            | https://pay-gate-uat.payermax.com/aggregate-pay/api/gateway/orderAndPay |
| Prod            | https://pay-gate.payermax.com/aggregate-pay/api/gateway/orderAndPay     |

Request Header Example:

For the value of the sign field, please refer: [[Config Settings and Signature Rules](https://docs.payermax.com/en/202606-version/developer/config-settings.md)].

```json
{
    'Content-Type': 'application/json;charset=utf-8',
    'Accept': 'application/json',
    'sign': <XXX>
};
```

Request Body Example:

For detailed fields for order placement API, please refer: [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).

```json
{
    "appId": "<To be replaced>",
	"version": "1.4",
	"merchantNo": "<To be replaced>",
	"requestTime": "2024-06-05T10:46:01.694+08:00",
	"keyVersion": "1",
	"data": {
		"totalAmount": 77.44,
		"country": "HK",
		"expireTime": "7200",
		"paymentDetail": {
			"paymentToken": "332e4cc1af1740aeafe9e7df82aeb5a1",
			"buyerInfo": {
				"clientIp": "59.82.59.92",
				"userAgent": "Safari"
			},
			"sessionKey": "86409e2c04b44536a484caa5ce3ce0e9"
		},
		"frontCallbackUrl": "<To be replaced>",
		"subject": "<To be replaced>",
		"outTradeNo": "1003052024060510454400707",
		"notifyUrl": "<To be replaced>",
		"currency": "HKD",
		"userId": "3ff0495692d152be96d84dbc9352dc57",
		"integrate": "Direct_Payment",// Fixed value
		"terminalType": "WEB"
	}
}
```
### 2. Other customization

For details on the front-end API, please refer: [[ApplePay Frontend API](https://docs.payermax.com/en/202606-version/receipt/front-end-component/configuration-applepay.md)].
