Drop in-ApplePay
1. Preparations
ApplePay certificates are uniformly maintained by PayerMax, merchants only need to download the ApplePay certification file and save it in the specified location.
Contact PayerMax technical support to provide the domain names of your official and test environments to complete Apple's domain name certification requirements. Especially note that
127.0.0.1,LAN IP,localhostcan't pull up ApplePay in the test environment.Download the ApplePay authentication file and place it in the specified path
https://[Pending Domain Name Registration]/.well-known/apple-developer-merchantid-domain-association.
Test environment certification documentation: apple-developer-merchantid-domain-association;
Documentation of certification of the production environment: apple-developer-merchantid-domain-association.
- After the merchant has configured the certificate, notify PayerMax to validate the domain certificate and PayerMax will operate the domain certificate validation in the Apple developer backend. If the validation fails, the possible reasons are as follows:
The certificate path is misconfigured;
Your firewall is blocking the Apple Check service, please configure the link page domain to the server whitelist;
You may have already configured a certificate for another MerchantID. In this case, you can use the new domain name, or delete the corresponding domain certificate on the original developer account.
2. API Introduction
2.1 Interface List
| Associated Interaction Sequence | Call Direction | API Type | API PATH |
|---|---|---|---|
| 3.1 Get initialization information for Drop-in component | Merchant -> PayerMax | Backend API | /applyDropinSession |
| 3.4 Create payment, call Drop-in order creation API | Merchant -> PayerMax | Backend API | /orderAndPay |
| 3.4.1 Payment result asynchronous notification | PayerMax -> Merchant | Backend API | /collectResultNotifyUrl |
| 3.4.2 Query payment transaction | Merchant -> PayerMax | Backend API | /orderQuery |
2.2 Environmental Information
Test environment request address:https://
pay-gate-uat.payermax.com/aggregate-pay/api/gateway/<Interface PATH>Integrated Environment:https://
pay-gate.payermax.com/aggregate-pay/api/gateway/<Interface PATH>
2.3 Request header
"headers": {
"Accept": "application/json",
"sign": "Please refer to the signing rules: https://docs-v2.payermax.com/doc-center/developer/config-settings.html", // Required
"Content-Type": "application/json"
}3.Start Integration
3.1 Getting Drop in Initialization Information
The merchant server through the /applyDropinSession API interface, initiates an HTTP POST request to obtain the client token clientKey and the session token sessionKey required for the initialization of the drop in.
/applyDropinSession API Example of an interface request:
{
"version": "1.4",
"keyVersion": "1",
"requestTime": "2025-05-14T16:30:27.174+08:00",
"appId": "test516e8ab74578be8eecd8c4803fbe",
"merchantNo": "TEST010117960578",
"data": {
"country": "MY", # Acquiring country
"currency": "MYR", # Order currency
"totalAmount":"50", # Order amount
"userId": "20220622_00086", # User ID, must be unique
"componentList":["APPLEPAY","CARD"] # Specifies the payment methods available for this order
}
}The actual available payment method types for this order can be specified via the request parameter componentList. Currently, only CARD, APPLEPAY, and GOOGLEPAY are supported. /applyDropinSession API Example of an interface response:
{
"msg": "success",
"code": "APPLY_SUCCESS",
"data": {
"sessionKey": "bf2c47b085e24c299e45dd56fd751a70",
"clientKey": "bbd8d2639a7c4dfd8df7d005294390df"
}
}3.2 Render the Drop in
- Introduce the CDN package on the relevant HTML page.
<script src="https://cdn.payermax.com/dropin/js/pmdropin.min.js"></script>- Embed a
ApplePatbutton display area on the merchant page using adivtag.
<div id="applepay" style="--padding-frame: 0;"></div>- Initialize PayerMax Frames。
Whether the server-side
orderAndPayAPI response is a success or a failure, it must be communicated to the frontend. The Apple Pay pop-up window will only disappear after the frontend callsapplepay.emit('paySuccess'/'payFail').
var applepay = PMdropin.create('applepay', {
// Fill in the clientKey obtained from your server side
clientKey: clientKey,
// Fill in the sessionKey obtained from your server side
sessionKey: sessionKey,
theme: 'light',
// Enable sandbox mode for joint debugging
sandbox: true, //true
});
// Mount the component to the DOM node
applepay.mount('#applepay');
applepay.on('ready', (res) => console.log('[merchant][ready]:', res))
applepay.on('payButtonClick', (res) => {
// Set the component to an uneditable state
applepay.emit('setDisabled', true);
// Initiate component validation and return the payment token
applepay.emit('canMakePayment')
.then(function(response) {
// Relieve the uneditable state
applepay.emit('setDisabled', false);
// Response successfully obtained
if (response.code === 'APPLY_SUCCESS') {
// Obtain the payment token (paymentToken)
var paymentToken = response.data.paymentToken;
console.log("paymentToken:"+paymentToken);
// Proceed with subsequent payment operations. The merchant requests their own server side and constructs the request parameters using "params" on their own.
// The merchant server side calls the payment API (orderAndPay) to initiate the payment.
if(paymentToken){
_postapi('orderAndPay',params).then(res =>{
const code = (res || {}).code
if (code == 'APPLY_SUCCESS') {
+ // After the server side receives the payment success callback, it needs to return the result to the frontend. The frontend calls
+ // applepay.emit('paySuccess') to make the Apple Pay pop-up disappear and display a payment success prompt.
applepay.emit('paySuccess')
} else {
+ applepay.emit('payFail') // The pop-up window will disappear
}
})}
}
})
.catch(function(error) {
// Relieve the uneditable state
applepay.emit('setDisabled', false);
})
})- Obtaining the paymentToken: After the user confirms the payment on the frontend, the frontend
canMakePaymentAPI will receive the following information, which is used for the backend to initiate the payment.
``` js
{
"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 Create Payment
Merchant server: calls the /orderAndPay API interface to initiate the HTTP POST request and create the payment.
/orderAndPay API Example of an interface request:
{
"requestTime": "2025-05-28T03:52:42.591-02:00",
"keyVersion": "1",
"appId": "tested7c863c439a9e29b4519867965a",
"version": "1.4",
"merchantNo": "TEST10116880289",
"data": {
"integrate": "Direct_Payment", # Specifies Direct_Payment under the hosted component mode
"totalAmount": 39.99,
"country": "SA",
"expireTime": "3600",
"paymentDetail": {
# Obtained from the response of the canMakePayment event via the JS SDK emit interface during payment, non-empty
+ "paymentToken": "TEST12637c2c2d942239d9a2661c4ad14f9",
"buyerInfo": {
"clientIp": "176.16.34.144",
"userAgent": "Chrome"
},
# Obtained from the response of the JS SDK create interface during payment, non-empty
+ "sessionKey": "test29632c3643768e3b65ef6a31c9ce" # Non-empty under the hosted component mode
},
"frontCallbackUrl": "[https://front.your.com/pay/index.html](https://front.your.com/pay/index.html)",
"subject": "xx Game",
"outTradeNo": "ov1_da78b1f3c2f9443b966347fc89305fc9",
"notifyUrl": "[https://notify.your.com/pay/paymentWebHookPayerMaxServlet](https://notify.your.com/pay/paymentWebHookPayerMaxServlet)",
"currency": "SAR",
"userId": "1822613953000446",
"terminalType": "WEB"
}
}/orderAndPay API Example of an interface response:
{
"msg": "Success.",
"code": "APPLY_SUCCESS",
"data": {
"outTradeNo": "test_da78b1f3c2f9443b966347fc89305fc9",
"tradeToken": "T2024052805951921811176",
"status": "SUCCESS"
}
}3.4 Get Payment Results
Create Payment/orderAndPay API The data.status of the interface response is not a payment end-state and therefore should not be used by merchants to update payment results directly.
3.4.1 Adoption of notification of payment results
See 链接要更新Get Payment Result Integration - Adoption of Payment Result Notification.
3.4.2 Inquiry via Payment Orders
See 链接要更新Get Payment Result Integration - Inquiry via payment order.
4. ApplePay Frontend API
Use PMdropin.API.
| API | Description | Details |
|---|---|---|
| create | Instantiate a built-in component | Refer 链接要更新 create |
| mount | Mount instantiated component to div tag | Refer**链接要更新** mount |
| on | Listen events | Refer 链接要更新on |
| emit | Trigger events | Refer**链接要更新** emit |
2.1 create
Used to initialize components, please use PMdropin.create(ComponentName, Options).
ComponentName Explanation
| ComponentName | Field Type | Description |
|---|---|---|
| applepay | string | ApplePay Compoment |
Options Explanation
| Options | Required Or Not | Field Type | Default Value |
|---|---|---|---|
| clientKey | Y | String | - |
| sessionKey | Y | String | - |
| sandbox | N | Boolean | false |
| theme | N | String | light |
| payButtonStyle | N | String | - |
2.2 mount
Used to mount initialization component instances, please use PMdropin.mount(Tag).
Tag Explanation
| Tag | Description |
|---|---|
| id | The value of the id element that needs to be mounted, such as PMdropin.mount('#applepay-frame') |
| class | The value of the class element that needs to be mounted, such as PMdropin.mount('.applepay-frame') |
2.3 on
Used to listen to component built-in response events, please use PMdropin.on(Event, CallbackFunction).
Event Explanation
| Tag | Description | Returned Value |
|---|---|---|
| ready | Triggered when the component completes loading | null |
| payButtonClick | Triggered when the ApplePay button is clicked | null |
Example:
PMdropin.on('payButtonClick', function(event) {
// Obtain paymentToken and call 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') {
// After the server side receives the payment success callback, it needs to return the result to the frontend. The frontend calls
// applepay.emit('paySuccess') to make the Apple Pay pop-up disappear and display a payment success prompt.
applepay.emit('paySuccess')
} else {
applepay.emit('payFail')
}
})}else{
applepay.emit('setDisabled', false)
}
})
.catch(err => {
applepay.emit('payFail')
applepay.emit('setDisabled', false)
})
});2.4 emit
Used to call component built-in methods, please use PMdropin.emit(Event, Params).
| Event | Params | Description |
|---|---|---|
| canMakePayment | Object | Get the payment token |
| switchTheme | string | Switch theme |
| setDisabled | Boolean | Set the component available state |
| setpayButtonStyle | string | Set the button style |
2.4.1 emit.canMakePayment
Checks whether the current component status meets the conditions to initiate a payment, and returns the paymentToken after successful validation
PMdropin.emit('canMakePayment', params?)params is an optional parameter. If the merchant server side has already provided complete payment information when calling the /applyDropinSession API, they can directly call PMdropin.emit('canMakePayment') without passing any arguments.
Options Configuration:
| Options | Required | Field Type | Description |
|---|---|---|---|
| totalAmount | No | String | Payment amount, formatted as a pure numeric string (e.g., '1.00'). It is only recommended for scenarios where the amount was not provided when the merchant server side obtained the hosted component initialization information via the /applyDropinSession API. This amount is used solely for display within the Apple Pay payment pop-up window. |
Example:
PMdropin.emit('canMakePayment', {
totalAmount: '1.00'
})Notes:
totalAmountonly accepts valid numeric strings (e.g.,'0.01','99.99'). If an invalid value is passed, the API will return the error codeAMOUNT_INVALID.- If the merchant server side already provided the amount when calling
/applyDropinSession, the amount used when finally submitting the order must match it consistently; otherwise, it may lead to payment failure or risk control interception.- Please ensure that the
totalAmountpassed incanMakePaymentis strictly consistent with the amount used when finally submitting the order; otherwise, it may lead to payment failure or risk control interception.
canMakePayment Response:
| Code | Description |
|---|---|
| APPLY_SUCCESS | Get paymentToken successfully |
| UNKNOWN_ISSUE | Exception information |
| AMOUNT_INVALID | The input amount format is incorrect |
| APPLEPAY_INTERNAL_ERROR | Apple Pay internal error |
4.4.2 emit.switchTheme
- Set the button theme
- Type:
Boolean - Default:
light
| Theme Name | Theme type | Effect Preview |
|---|---|---|
| White | light Default | ![]() |
| Black | dark | ![]() |
2.4.3 emit.setDisabled
- Set the component available state
- Type:
Boolean - Default:
false
// Button disabled state
PMdropin.emit('setDisabled', true)
// Button enabled state
PMdropin.emit('setDisabled', false)1.4.4 emit.setpayButtonStyle
- Set the button style
- Type:
Boolean - Default:
false
// Set the width, height, padding, and border radius of the ApplePay button
PMdropin.emit('payButtonStyle', `width:20rem;height:4rem;border-radius: 4rem;padding:1rem 4rem;`)

