Antom, leading provider of tailored payment solutions

Accept payments with EasySafePay (SDK)

Antom EasySafePay is a minimalist payment solution focused on small-amount, high-frequency payment scenarios. With its innovative "bind payment method upon first payment" design and one-click payment feature, it significantly simplifies the payment process. Buyers can choose to pay directly or perform payment method binding during the first transaction, and subsequent payments can be processed instantly without repeated verification.
This solution leverages industry-leading intelligent risk control systems, dynamic polling technology, and payment failure recovery strategies to ensure transaction security while achieving top-tier payment success rates in the industry. It creates a win-win-win scenario for buyer payment experience, merchant conversion rates, and platform ecosystem value.
Web/WAP

User experience

Through simple browser integration, you can quickly enable digital wallet and online banking payment functionalities.
Different payment methods vary in their browser-side user experience. For specific interaction differences, refer to the table below:
​Payment method category
​Payment method
Terminal type
First-time payment
Subsequent payments
Digital wallet
Web
Complete the payment within the payment method app.
Complete the payment on the merchant page.
Online banking
Web
Complete the payment on the payment method page.
Complete the payment on the payment method page.
Digital wallet
WAP
Complete the payment on the merchant page.
Complete the payment on the merchant page.
WAP
Redirect to the payment method app to complete payment.
Complete the payment on the merchant page.
Online banking
WAP
Complete the payment on the merchant page.
Complete the payment on the merchant page.
Digital wallet
In the digital wallet payment scenario, the system will guide the buyer to complete the transaction on the merchant's page or within the payment method app after the buyer confirms the payment. The first payment verification and subsequent simplified payment process are illustrated as follows:
First payment
The first payment requires security authentication. Once authorized, the buyer will be enabled for password-free payments on subsequent transactions.
Web user experience showing the digital wallet first payment flow where buyers complete security authentication to enable password-free payments for subsequent transactions
Subsequent payments
Subsequent payments will be processed automatically upon order submission, without requiring password entry.
Web user experience showing the digital wallet subsequent payment flow where payments are processed automatically without requiring password entry
Online banking
The online banking process is illustrated as follows, including first payment authentication and subsequent simplified payment flows.
First payment
The first payment requires security authentication. Once authorized, the buyer will be enabled for password-free payments on subsequent transactions.
Web user experience showing the online banking first payment flow where buyers complete security authentication to enable password-free payments
Subsequent payments
Subsequent payments will be processed automatically upon order submission, without requiring password entry.
Web user experience showing the online banking subsequent payment flow where payments are processed automatically without password entry

Payment flow

First payment
The first payment flow chart:
Sequence diagram illustrating the EasySafePay first payment flow among Buyer, Merchant Client, Merchant Server, and Antom: the buyer enters the checkout page, the merchant creates a payment session via the createPaymentSession API, the client SDK renders the payment interface and manages redirections, the buyer completes authorization, and the merchant receives asynchronous notifyAuthorization and notifyPayment notifications or queries payment status through the inquiryPayment API
  1. The buyer enters the checkout page.
  2. Create a payment session request.
    After the buyer selects a payment method and submits the order, you can obtain the payment session by calling the createPaymentSession (EasySafePay) API.
  3. Invoke the client SDK.
    Invoke the SDK using a payment session and the SDK will automatically collect payment elements, render the payment interface, handle page redirections, and guide buyers through payment completion based on the specific payment method's characteristics. For detailed interaction differences across payment methods, refer to the User experience table.
  4. Obtain the authorization result.
    When the authorization is successful, Antom sends you the asynchronous notification through the
    notifyAuthorization API.
  5. Obtain the payment result.
    Obtain the payment result using one of the following methods:
    • Asynchronous notification: Specify paymentNotifyUrl in the createPaymentSession (EasySafePay) API to set the address for receiving asynchronous notifications. When the payment is successful or expires, Antom will use notifyPayment to send asynchronous notifications to you.
    • Synchronous inquiry: Call the inquiryPayment API to check the real-time payment status.
Subsequent payments
The subsequent payment flow chart:
Sequence diagram illustrating the EasySafePay subsequent payment flow among Buyer, Merchant Client, Merchant Server, and Antom: the buyer enters the checkout page, the merchant creates a payment session using the previously authorized paymentMethodId via the createPaymentSession API, the client SDK renders the payment interface, the buyer submits the order, and the merchant receives an asynchronous notifyPayment notification or uses the inquiryPayment API to check payment status
  1. The buyer enters the checkout page.
  2. Create a payment session request.
    After the buyer selects a payment method and submits the order, you can obtain the payment session by calling the createPaymentSession (EasySafePay) API.
  3. Invoke the client SDK.
    Invoke the SDK using a payment session and the SDK will automatically collect payment elements, render the payment interface, handle page redirections, and guide buyers through payment completion based on the specific payment method's characteristics. For detailed interaction differences across payment methods, refer to the
    User experience table.
  4. Obtain the payment result.
    Obtain the payment result using one of the following methods:
    • Asynchronous notification: Specify paymentNotifyUrl in the createPaymentSession (EasySafePay) API to set the address for receiving asynchronous notifications. When the payment is successful or expires, Antom will use notifyPayment to send asynchronous notifications to you.
    • Synchronous inquiry: Call the inquiryPayment API to check the real-time payment status.

Integration preparations

Before you start integrating, read the Integration Guide and API Overview documents to understand the integration steps of the server-side API and the precautions for calling the API. Furthermore, ensure that the following prerequisites are met:
  • Obtain a client ID
  • Complete the key configuration
  • Complete the configuration of paymentNotifyUrl to receive the asynchronous notification
  • Integrate the server-side SDK package, install the server-side library, and initialize a request instance. For more details, refer to Server-side SDKs.
  • If you need to conduct joint debugging by connecting the sandbox with the production environment, please contact Antom technical support at least two business days in advance to request configuration. The sandbox environment and production environment require separate configuration.
Refer to Integrate the SDK package for Web/WAP to complete integration preparations.

Integration steps

Start your integration by taking the following steps:
  1. (Optional) Preload the SDK
  2. Create a payment session
  3. Invoke the SDK
  4. Obtain the authorization and payment result

(Optional) Step 1: Preload the SDK
Client-side

Preloading the SDK during the checkout page initialization significantly improves the rendering performance with no negative impact. It is recommended to trigger preloading of the SDK when the buyer selects a payment method.
Follow the code example below to perform the preloading:
Preload SDK
AMSEasyPay.preload();

Step 2: Create a payment session
Server-side

When a buyer selects a payment method provided by Antom, you need to collect essential information including the payment request ID, order amount, payment method, order description, payment redirect page URL, and payment result notification URL.
Call the createPaymentSession (EasySafePay) API to create a payment session and initialize the Antom SDK using the paymentSessionData value returned in the response.
The table below lists the parameter specifications for calling the createPaymentSession (EasySafePay) API during the first and subsequent payments:
Note: For subsequent payments with Express Bank Transfer, simply keep the parameters consistent with the first payment. The buyer can open the Express Bank Transfer webpage and enter the phone number to proceed directly with the payment.
Parameter type
Parameter name
Required
(First-time payment)
Required
(Subsequent payments)
Description
Base parameter
productCode
Yes
Yes
The value is fixed as
AGREEMENT_PAYMENT
in the EasySafePay scenario.
productScene
Yes
Yes
The value is fixed as
EASY_PAY
in the EasySafePay scenario.
paymentRequestId
Yes
Yes
The unique ID assigned by a merchant to identify a payment request.
paymentMethod.paymentMethodType
Yes
Yes
The payment method type that is included in payment method options.
paymentMethod.paymentMethodId
No
Yes
The unique ID that is used to identify a payment method. The value of this parameter is that of accessToken from the notifyAuthorization API.
settlementStrategy
No
No
The settlement strategy for the payment request. If the merchant agreement supports multiple settlement currencies, they must be specified in the API request.
paymentAmount.value
Yes
Yes
The value of the amount as a positive integer in the smallest currency unit.
For details about the smallest currency unit, see Smallest unit of the currency .
paymentAmount.currency
Yes
Yes
The transaction currency, which is a 3-letter currency code that follows the ISO 4217 standard.
paymentSessionExpiryTime
No
No
The specific date and time after which the payment session will expire. The default expiration time is 1 hour after the session creation. For example, if the session is created at 2023-7-27T12:00:01+08:30, the session expiration time is 2023-7-27T13:00:01+08:30.
paymentRedirectUrl
Yes
Yes
The merchant page URL that the user is redirected to after the payment is completed.
The page display according to the server-side result and should not default to a fixed payment success page.
  • If the payment is initiated from a Web or WAP platform, pass the WAP URL.
  • If the payment is initiated from an App, pass the scheme URL.
paymentNotifyUrl
No
No
The URL that is used to receive the payment result notification. it must be an HTTPS URL. This field can be omitted if already configured via Antom Dashboard.
Authorization parameter
agreementInfo.authState
Yes
No
The unique ID generated by the merchant to initiate an EasySafePay authorization.

Order parameter



order.orderAmount
Yes
Yes
The order amount of the merchant that directly provides services or goods to the customer
order.referenceOrderId
Yes
Yes
The unique ID to identify the order on the merchant side.
order.orderDescription
Yes
Yes
Summary description of the order.
order.buyer.referenceBuyerId
No
No
Submit buyer information for risk assessment. Provide at least one of these fields: referenceBuyerId, buyerPhoneNo, or buyerEmail.

order.buyer.
    • buyerPhoneNo
    • buyerEmail
No
No
Buyer's account. Providing relevant payment account information can effectively improve the payment success rate and reduce the risk of buyer attrition. Please refer to the table below for specific format requirements.
The parameter format for the buyer's payment account for each payment method is as follows:
Payment method
Parameter format
It is recommended to prioritize using a mobile phone number:
  • Mobile number:
    • Hong Kong, China: 852-12****78. The phone number must be 8 digits long, excluding the prefix.
    • China: 86-137****5678. The phone number must be 11 digits long, excluding the prefix.
  • Email: xxx@xxx.com
62-8569****7288. The phone number starts with 8 and is no more than 12 digits long, excluding the prefix.
TrueMoney
The buyer is authenticated on the payment method side, and no parameters need to be passed in.userloginId.
During the first-time payment, passing the buyer's payment account will auto-fill the buyer's account on the payment page, eliminating manual input. Below is a comparison of the user experience with and without these fields:
With account parameter passed
Login account input is not required.
User experience showing the merchant checkout page when the buyer's payment account parameter is passed, where the login account input field is pre-filled and manual input is not required
Without account parameter passed
Manual input of login account is required.
User experience showing the merchant checkout page when the buyer's payment account parameter is not passed, requiring manual input of the login account
Below are code examples for first and subsequent payments.
First payment
The following sample code shows how to call the createPaymentSession (EasySafePay) API:
@@PostMapping("/payment/createSession")
public ResponseEntity<ApiResponse> createPaymentSession(@RequestBody PaymentVO payment) {
  AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
  alipayPaymentSessionRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);
  alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.EASY_PAY);

  // replace with paymentRequestId
  String paymentRequestId = UUID.randomUUID().toString();
  alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);

  // convert amount unit(in practice, amount should be calculated on your serverside)
  // For details, please refer to: <a href="https://docs.antom.com/ac/ref/cc">Usage rules of the Amount object</a>
  long amountMinorLong = Money.of(CurrencyUnit.of(payment.currency), new BigDecimal(payment.amountValue)).getAmountMinorLong();

  // set amount
  Amount amount = Amount.builder().currency(payment.currency).value(String.valueOf(amountMinorLong)).build();
  alipayPaymentSessionRequest.setPaymentAmount(amount);

  // set settlement strategy
  // replace with your existing settlement currency
  SettlementStrategy settlementStrategy = SettlementStrategy.builder().settlementCurrency("USD").build();
  alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);

  User loginUser = users.get(payment.getUserId());

  // set buyer info
  Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

  // set paymentMethod
  PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType(payment.paymentMethodType).build();
  if (loginUser.getPaymentMethodTypeAccessToken().containsKey(payment.getPaymentMethodType())) {
      // buyer has authorized
      String accessToken = loginUser.getPaymentMethodTypeAccessToken().get(payment.getPaymentMethodType());
      paymentMethod.setPaymentMethodId(accessToken);
  } else {
      // set agreementInfo
      // replace with your authState
      String authState = UUID.randomUUID().toString();
      AgreementInfo agreementInfo = AgreementInfo.builder().authState(authState).build();
      alipayPaymentSessionRequest.setAgreementInfo(agreementInfo);

      // save the paymentMethodType corresponding to the authState
      authStatePayment.put(authState, payment);

      // The login ID that the user used to register in the payment method client. The login ID can be the user's email address or phone number.
      // Specify this parameter to free users from manually entering their login IDs.
      if(StringUtil.isNotBlank(loginUser.getPhoneNumber()){
          buyer.setBuyerPhoneNo(loginUser.getPhoneNumber());
      }
      if(StringUtil.isNotBlank(loginUser.getEmail() && "ALIPAY_HK".equals(payment.getPaymentMethodType())){
          buyer.setBuyerPhoneNo(loginUser.getPhoneNumber());
      }
  }
  alipayPaymentSessionRequest.setPaymentMethod(paymentMethod);



  // replace with your orderId
  String orderId = UUID.randomUUID().toString();
  // set order info
  Order order = Order.builder().referenceOrderId(orderId)
  .orderDescription("antom sdk testing order").orderAmount(amount).buyer(buyer).build();
  alipayPaymentSessionRequest.setOrder(order);

  // replace with your notify url
  // or configure your notify url here: <a href="https://dashboard.antom.com/global-payments/developers/iNotify">Notification URL</a>
  alipayPaymentSessionRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com/payment/receivePaymentNotify");

  // replace with your redirect URL
  alipayPaymentSessionRequest.setPaymentRedirectUrl(
          "http://localhost:8080/index.html?paymentRequestId=" + paymentRequestId);

  AlipayPaymentSessionResponse alipayPaymentSessionResponse;
  try {
      long startTime = System.currentTimeMillis();
      System.out.println("payment request: " + JSON.toJSONString(alipayPaymentSessionRequest));
      alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
      System.out.println("payment response: " + JSON.toJSONString(alipayPaymentSessionResponse));
      System.out.println("payment request cost time: " + (System.currentTimeMillis() - startTime) + "ms");
  } catch (AlipayApiException e) {
      return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), e));
  }
  return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), alipayPaymentSessionResponse));
}
The following code shows a sample of the request message:
{
"agreementInfo": {
  "authState": "authState001",
  "userLoginId": "userLoginId001"
},
"order": {
  "buyer": {
    "referenceBuyerId": "referenceBuyerId001"
  },
  "orderAmount": {
    "currency": "CNY",
    "value": "100"
  },
  "orderDescription": "orderDescription001",
  "referenceOrderId": "referenceOrderId001"
},
"paymentAmount": {
  "currency": "CNY",
  "value": "100"
},
"paymentMethod": {
  "paymentMethodType": "ALIPAY_CN"
},
"paymentNotifyUrl": "http://debug1688017773824.test.alipay.net:9090/amsdemo/record/notify?env=main_online&paymentMethodType=ALIPAY_CN",
"paymentRedirectUrl": "http://debug1688017773824.test.alipay.net:9090/amsdemo/result",
"paymentRequestId": "paymentRequestId001",
"productCode": "AGREEMENT_PAYMENT",
"productScene": "EASY_PAY",
"settlementStrategy": {
  "settlementCurrency": "USD"
}
}
The following code shows a sample of the response message:
{
  "paymentSessionData": "ZqeGpu7pbMb/I3dNWTTEL3o4w5mXh20j13VnmsE1p3cjK3CVpnMXY7BfQlIvwNqQWtXHEMUo0R5pQwnSyNtxTA==&&SG&&188&&eyJh***",
  "paymentSessionExpiryTime": "2024-09-27T15:57:30+08:00",
  "paymentSessionId": "ZqeGpu7pbMb/I3dNWTTEL3o4w5mXh20j13VnmsE1p3fI21eGbgq240lFVquZsLrM",
  "result": {
      "resultCode": "SUCCESS",
      "resultMessage": "success.",
      "resultStatus": "S"
  }
}
Please take the next step according to the value of the result.resultStatus.
resultStatus
Message
Further actions
S
The payment session is successfully created.
Return the obtained paymentSessionData to the merchant's frontend. For specific operational steps, refer to Step 4.
F
The payment session creation failed.
Check and verify whether the required request parameters (including the header parameters and body parameters) of the current API are correctly passed and valid.
U
The payment session creation failed due to unknown reasons.
Replace the paymentRequestId and authstate value, then retry the API call to resolve the issue. If the problem persists, contact Antom Technical Support.
Note: If you do not receive a response, it may be due to a network timeout. Please retry the API call with a new paymentRequestId and authstate value.
Subsequent payments
The following sample code shows how to call the createPaymentSession (EasySafePay) API:
public static void createPaymentSession() {
AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
alipayPaymentSessionRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);
alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.EASY_PAY);

// replace with your paymentRequestId
String paymentRequestId = UUID.randomUUID().toString();
alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);

// set amount
// you should convert amount unit(in practice, amount should be calculated on your server side)
Amount amount = Amount.builder().currency("HKD").value("98080").build();
alipayPaymentSessionRequest.setPaymentAmount(amount);

//set settlement currency
SettlementStrategy settlementStrategy = new SettlementStrategy();
settlementStrategy.setSettlementCurrency("USD");
alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);

// set paymentMethod
PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("ALIPAY_HK")
.paymentMethodId("28288803001319861727421828000Cv96OFlYoi17100****").build();
alipayPaymentSessionRequest.setPaymentMethod(paymentMethod);

// set buyer info
Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

// replace with your orderId
String orderId = UUID.randomUUID().toString();
// set order Info
Order order = Order.builder().referenceOrderId(orderId).
orderDescription("antom api testing order").orderAmount(amount).buyer(buyer).build();
alipayPaymentSessionRequest.setOrder(order);

// replace with your notify url
alipayPaymentSessionRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com");

// replace with your redirect url
alipayPaymentSessionRequest.setPaymentRedirectUrl("http://www.yourRedirectUrl.com");

AlipayPaymentSessionResponse alipayPaymentSessionResponse;
try {
alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// handle error condition
}
}
The following code shows a sample of the request message:
{
  "order": {
      "buyer": {
          "referenceBuyerId": "yourBuyerId"
      },
      "orderAmount": {
          "currency": "HKD",
          "value": "98080"
      },
      "orderDescription": "antom api testing order",
      "referenceOrderId": "5e445b58-49ad-4552-a36d-d38f311a090d"
  },
  "paymentAmount": {
      "currency": "HKD",
      "value": "98080"
  },
  "paymentMethod": {
      "paymentMethodId": "28288803001319861727421828000Cv96OFlYoi17100****",
      "paymentMethodType": "ALIPAY_HK"
  },
  "paymentNotifyUrl": "http://www.yourNotifyUrl.com",
  "paymentRedirectUrl": "http://www.yourRedirectUrl.com",
  "paymentRequestId": "5810a84e-3a3e-4e47-bbac-9dfe3f2dd2b3",
  "productCode": "AGREEMENT_PAYMENT",
  "productScene": "EASY_PAY",
  "settlementStrategy": {
      "settlementCurrency": "USD"
  }
}
The following code shows a sample of the response message:
 {
"paymentSessionData": "paymentSessionData****",
"paymentSessionExpiryTime": "2023-04-06T03:28:49+08:00",
"paymentSessionId": "paymentSessionId****",
"result": {
  "resultCode": "SUCCESS",
  "resultMessage": "success.",
  "resultStatus": "S"
}
}
Please take the next step according to the value of the result.resultStatus.
resultStatus
Message
Further actions
S
The payment session is successfully created.
Return the obtained paymentSessionData to the merchant's frontend. For specific operational steps, refer to Step 4.
F
The payment session creation failed.
Check and verify whether the required request parameters (including the header parameters and body parameters) of the current API are correctly passed and valid.
U
The payment session creation failed due to unknown reasons.
Replace the paymentRequestId value, then retry the API call to resolve the issue. If the problem persists, contact Antom Technical Support.
Note: If you do not receive a response, it may be due to a network timeout. Please retry the API call with a new paymentRequestId value.
Common questions
Q: Can I use Chinese characters in the value of the request parameters?
A: To avoid incompatibility of a certain payment method, do not use Chinese characters for parameters in the request.
Q: How to set the URL to receive the payment notification?
A: Specify paymentNotifyUrl in the createPaymentSession (EasySafePay) API to receive the asynchronous notification about the payment result (notifyPayment), or configure the receiving URL in Antom Dashboard. If the URL is specified in both the request and Antom Dashboard, the value specified in the request takes precedence.
Q: What is the difference between paymentAmount and orderAmount?
A:
paymentAmount refers to the payment amount, while orderAmount refers to the order amount. The actual charged amount is determined by paymentAmount.
Q: What does paymentSessionExpiryTime specifically refer to in payment requests?
A:
paymentSessionExpiryTime indicates the validity period from successful payment session creation until the buyer submits the payment. After submission, the payment processing timeout is 10 minutes. Therefore, the maximum total duration from session creation to payment completion is 1 hour and 10 minutes.
Q: Which parameters should be prioritized in the response message?
A:
Pay attention to the following key parameters:
  • result.resultStatus: Indicates the result of the API call.
  • paymentSessionData: Encrypted payment session data, which is passed to the frontend for initializing the Antom SDK.
  • paymentSessionExpiryTime: Expiration timestamp of the payment session.

Step 3: Invoke the SDK
Client-side

After obtaining the paymentSessionData value on the merchant server side, the merchant client can invoke the SDK to redirect the checkout page to the payment method authorization page. When the buyer submits a payment request, the SDK will automatically handle encrypted communication, risk control verification, page redirection, and payment instruction execution, enabling an end-to-end payment authorization process.

1. Instantiate the SDK

  1. Use
    AMSEasyPay
    to create the SDK instance. The configuration object includes the following parameters:
Parameter name
Required
Description
environment
Yes
Used to specify the environment information. Valid values are:
  • sandbox
    : Sandbox environment
  • prod
    : Production environment
locale
No
Used to specify the language information. Select the appropriate value based on the region of the payment method. Valid values for this parameter are listed as follows.If a value not in the following list is used, the English is used instead.
  • en_US
    : English
  • in_ID
    : Indonesian
  • ms_MY
    : Malay
  • tl_PH
    : Filipino
  • ko_KR
    : Korean
  • zh_CN
    : Simplified Chinese
  • zh_HK
    : Traditional Chinese
onEventCallback
No
A callback function that returns a specific event code when a payment event occurs during SDK runtime.
Note: After a successful payment, the payment result is not returned by this function by default; instead, the user is redirected to the payment success page you specified. However, when notRedirectAfterComplete is set to
true
and the payment process is completed within the SDK, the system will not perform a redirect after a successful payment but will instead provide an event callback.
The following sample code shows how to instantiate the SDK using npm or CDN:
npm
npm
import { AMSEasyPay } from '@alipay/ams-checkout' // Manage the package

const checkoutApp = new AMSEasyPay({
environment: "sandbox",
locale: "en_US",
onEventCallback: ({code, message})=>{},
});
CDN
CDN
const checkoutApp = new window.AMSEasyPay({
environment: "sandbox",
locale: "en_US",
onEventCallback: ({code, message})=>{},
});
  1. Use
    createComponent
    in the instance object to create a payment component. The parameters involved are as follows:
Parameter name
Required
Description
sessionData
Yes
Create a configuration object using the sessionData parameter: Use the complete data of the value of paymentSessionData obtained in the response of the createPaymentSession (EasySafePay) API as the value of this parameter.
notRedirectAfterComplete
No
Boolean type. Valid values are:
  • false
    : Default value. Indicates that redirection to your page will occur after the payment is completed. The same applies when the value is empty.
  • true
    : Indicates that there will be no redirection. You need to monitor the subsequent process after the payment is completed through client-side event codes.
Note:
  • This parameter applies only to scenarios where the payment is completed within the SDK.
  • The event codes returned by the client-side are only used as a reference for the redirection operation of the client page. For transaction status updates, refer to the results returned by the server's notifyPayment or inquirePayment API.
The following sample code shows how to create the component:
async function create(sessionData) {
await checkoutApp.createComponent({ 
  sessionData: sessionData, 
  notRedirectAfterComplete: false // Set as false by default to indicate that it will redirect to your page after the payment is completed.
});
}
The images below show the rendering effect when the SDK redirects the checkout page to the payment method authorization page:
Web
The image below shows the redirection from the merchant checkout page to the payment method page.
Web user experience showing redirection from the merchant checkout page to the payment method authorization page during the EasySafePay SDK integration
WAP
The image below shows the merchant checkout page launches a half-screen pop-up or redirects to the digital wallet app.
Mobile WAP user experience showing the merchant checkout page launching a half-screen pop-up or redirecting to the digital wallet app for payment authorization

2. Handle SDK callback event codes

Below are the event codes returned by
onEventCallback
and handling recommendations:
Code
Description
Further action
SDK_CALL_URL_SUCCESS
Successfully launched the payment method app or redirected to the merchant page.
No further action is needed.
SDK_LAUNCH_PAYMENT_APP_ERROR
This event code indicates one of the following situations:
  • Failed to invoke the app of the buyer's selected payment method or failed to redirect to the checkout page of the payment method.
  • Failed to redirect to the merchant page.
Check whether the paymentRedirectUrl parameter is correctly passed when calling the createPaymentSession (EasySafePay) API.
Web/WAP scenarios rarely experience redirection exceptions. However, in the event of any exceptions, it is recommended to verify the redirection link. For mobile app scenarios, if frequent redirection exceptions occur, contact Antom Technical Support to troubleshoot redirection or cross-application calling issues.
SDK_PAYMENT_CANCEL
The buyer canceled the payment (the buyer exited the payment page without submitting the order).
You can re-invoke the SDK using paymentSessionData within its validity period; If it has expired, you need to initiate a new createPaymentSession (EasySafePay) request.
SDK_PAYMENT_SUCCESSFUL
Indicates that the payment is successful on the wallet side.
Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result. Suggest redirecting buyers to the payment result page.
Note: This event code is returned only when the payment process is completed within the SDK.
SDK_PAYMENT_FAIL
Indicates that the payment is unsuccessful on the wallet side.
Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result. Suggest redirecting buyers to the payment result page.
Note: This event code is returned only when the payment process is completed within the SDK.
The following sample code shows how to handle the callback function:
// Step 2: Create onEventCallback handler.
function onEventCallback({ code }) {
switch (code) {
  case 'SDK_PAYMENT_CANCEL':
    console.log(
      'The buyer canceled the payment (the buyer exited the payment page without submitting the order). You can re-invoke the SDK using paymentSessionData within its validity period; If it has expired, you need to initiate a new createPaymentSession (EasySafePay) request.'
    );
    break;
  case 'SDK_CALL_URL_SUCCESS':
    console.log('Successfully launched the payment method app or redirected to the merchant page.');
    break;
  case 'SDK_LAUNCH_PAYMENT_APP_ERROR':
    console.log('Failed to redirect to the checkout page of the payment method, or failed to redirect to the merchant page. Check whether the paymentRedirectUrl parameter is correctly passed when calling the createPaymentSession (EasySafePay) request. Web/WAP scenarios rarely experience redirection exceptions. However, in the event of any exceptions, it is recommended to verify the redirection link.');
    break;
  case 'SDK_PAYMENT_SUCCESSFUL':
    console.log('The wallet has successfully processed the payment. Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result. Suggest redirecting buyers to the payment result page.');
    break;
  case 'SDK_PAYMENT_FAIL':
    console.log('The wallet failed to process the payment. Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result. Suggest redirecting buyers to the payment result page.');
    break;
  default:
    console.log(code);
}
};

3. Free SDK component resources

Call the
unmount
method to free SDK component resources in the following situations:
  • When the buyer switches views to exit the checkout page, free the component resources created in the createPaymentSession (EasySafePay) API.
  • When the buyer initiates multiple payments, free the component resources created in the previous createPaymentSession (EasySafePay) API.
  • After obtaining the final payment result, free the component resources.
The following sample code shows how to free components:
// Free SDK component resources
checkoutApp.unmount();
Common questions
Q: Can an
AMSEasyPay
instance execute
createComponent
multiple times?
A: No. If you need to initiate a new payment, you need to create a new
AMSEasyPay
instance.
Q: Are SDK calls required for both first and subsequent payments?
A: Yes.
iOS

User experience

This iOS integration guide is designed to help you quickly integrate the digital wallet and online banking payment functions within the app and easily complete the payment interface rendering.
The user experience of each payment method on the iOS side varies; refer to the table below for specific interaction experiences:
​Payment method category
​Payment method
Terminal type
First-time payment
Subsequent payments
Digital wallet
iOS
Complete the payment on the merchant page.
Complete the payment on the merchant page.
iOS
Redirect to the payment method app to complete payment.
Complete the payment on the merchant page.
Online banking
iOS
Complete the payment on the merchant page.
Complete the payment on the merchant page.
Digital wallet
Below is the user experience for first and subsequent payments using digital wallets.
First payment
Upon the first payment, the buyer can choose to pay immediately or complete the authorization process. After successful authorization, subsequent payments will be processed by the password-free feature.
Pay on the merchant page
Mobile user experience showing the digital wallet first payment flow where buyers complete security authentication to enable password-free payments for subsequent transactions on the merchant page
Pay on the payment method app
Mobile user experience showing the digital wallet first payment flow where buyers complete security authentication to enable password-free payments for subsequent transactions on the payment method app
Subsequent payments
Subsequent payments are processed without requiring a password upon order submission.
Mobile user experience showing digital wallet subsequent payment processed automatically without requiring password entry upon order submission
Online banking
Below is the user experience for first and subsequent payments using online banking payment methods.
First payment
Upon the first payment, the buyer can choose to pay immediately or complete the authorization process. After successful authorization, subsequent payments will be processed by the password-free feature.
Mobile user experience showing the online banking first payment where the buyer completes the authorization process to enable subsequent password-free payments
Subsequent payments
Subsequent payments are processed without requiring a password upon order submission.
Mobile user experience showing the online banking subsequent payment processed automatically without requiring password upon order submission

Payment flow

First payment
The first payment flow chart:
Sequence diagram illustrating the EasySafePay first payment flow among Buyer, Merchant Client, Merchant Server, and Antom: the buyer enters the checkout page, the merchant creates a payment session via the createPaymentSession API, the client SDK renders the payment interface and manages redirections, the buyer completes authorization, and the merchant receives asynchronous notifyAuthorization and notifyPayment notifications or queries payment status through the inquiryPayment API.
  1. The buyer enters the checkout page.
  2. Create a payment session request.
    After the buyer selects a payment method and submits the order, you can obtain the payment session by calling the createPaymentSession (EasySafePay) API.
  3. Invoke the client SDK.
    Invoke the SDK using a payment session and the SDK will automatically collect payment elements, render the payment interface, handle page redirections, and guide buyers through payment completion based on the specific payment method's characteristics. For detailed interaction differences across payment methods, refer to the User experience table.
  4. Obtain the authorization result.
    When the authorization is successful, Antom sends you the asynchronous notification through the
    notifyAuthorization API.
  5. Obtain the payment result.
    Obtain the payment result using one of the following methods:
    • Asynchronous notification: Specify paymentNotifyUrl in the createPaymentSession (EasySafePay) API to set the address for receiving asynchronous notifications. When the payment is successful or expires, Antom will use notifyPayment to send asynchronous notifications to you.
    • Synchronous inquiry: Call the inquiryPayment API to check the real-time payment status.
Subsequent payments
The subsequent payment flow chart:
Sequence diagram illustrating the EasySafePay subsequent payment flow among Buyer, Merchant Client, Merchant Server, and Antom: the buyer enters the checkout page, the merchant creates a payment session using the previously authorized paymentMethodId via the createPaymentSession API, the client SDK renders the payment interface, the buyer submits the order, and the merchant receives an asynchronous notifyPayment notification or uses the inquiryPayment API to check payment status.
  1. The buyer enters the checkout page.
  2. Create a payment session request.
    After the buyer selects a payment method and submits the order, you can obtain the payment session by calling the createPaymentSession (EasySafePay) API.
  3. Invoke the client SDK.
    Invoke the SDK using a payment session and the SDK will automatically collect payment elements, render the payment interface, handle page redirections, and guide buyers through payment completion based on the specific payment method's characteristics. For detailed interaction differences across payment methods, refer to the
    User experience table.
  4. Obtain the payment result.
    Obtain the payment result using one of the following methods:
    • Asynchronous notification: Specify paymentNotifyUrl in the createPaymentSession (EasySafePay) API to set the address for receiving asynchronous notifications. When the payment is successful or expires, Antom will use notifyPayment to send asynchronous notifications to you.
    • Synchronous inquiry: Call the inquiryPayment API to check the real-time payment status.

Integration preparations

Before you start integrating, read the Integration Guide and API Overview documents to understand the integration steps of the server-side API and the precautions for calling the API. Furthermore, ensure that the following prerequisites are met:
  • Obtain a client ID
  • Complete the key configuration
  • Complete the configuration of paymentNotifyUrl to receive the asynchronous notification
  • Integrate the server-side SDK package, install the server-side library, and initialize a request instance. For more details, refer to Server-side SDKs.
  • If you need to conduct joint debugging by connecting the sandbox with the production environment, please contact Antom technical support at least two business days in advance to request configuration. The sandbox environment and production environment require separate configuration.
Refer to Integrate the SDK package for iOS to complete integration preparations.

Integration steps

Start your integration by taking the following steps:
  1. (Optional) Preload the SDK
  2. Create a payment session
  3. Invoke the SDK
  4. Obtain the authorization and payment result

(Optional) Step 1: Preload the SDK
Client-side

Preloading the SDK during the checkout page initialization significantly improves the rendering performance with no negative impact. It is recommended to trigger preloading of the SDK when the buyer selects a payment method.
Follow the code example below to perform the preloading:
Preload SDK
[AMSEasyPay.shared preload];

Step 2: Create a payment session
Server-side

When a buyer selects a payment method provided by Antom, you need to collect essential information including the payment request ID, order amount, payment method, order description, payment redirect page URL, and payment result notification URL.
Call the createPaymentSession (EasySafePay) API to create a payment session and initialize the Antom SDK using the paymentSessionData value returned in the response.
The table below lists the parameter specifications for calling the createPaymentSession (EasySafePay) API during the first and subsequent payments:
Note: For subsequent payments with Express Bank Transfer, simply keep the parameters consistent with the first payment. The buyer can open the Express Bank Transfer webpage and enter the phone number to proceed directly with the payment.
Parameter type
Parameter name
Required
(First-time payment)
Required
(Subsequent payments)
Description
Base parameter
productCode
Yes
Yes
The value is fixed as
AGREEMENT_PAYMENT
in the EasySafePay scenario.
productScene
Yes
Yes
The value is fixed as
EASY_PAY
in the EasySafePay scenario.
paymentRequestId
Yes
Yes
The unique ID assigned by a merchant to identify a payment request.
paymentMethod.paymentMethodType
Yes
Yes
The payment method type that is included in payment method options.
paymentMethod.paymentMethodId
No
Yes
The unique ID that is used to identify a payment method. The value of this parameter is that of accessToken from the notifyAuthorization API.
settlementStrategy
No
No
The settlement strategy for the payment request. If the merchant agreement supports multiple settlement currencies, they must be specified in the API request.
paymentAmount.value
Yes
Yes
The value of the amount as a positive integer in the smallest currency unit.
For details about the smallest currency unit, see Smallest unit of the currency .
paymentAmount.currency
Yes
Yes
The transaction currency, which is a 3-letter currency code that follows the ISO 4217 standard.
paymentSessionExpiryTime
No
No
The specific date and time after which the payment session will expire. The default expiration time is 1 hour after the session creation. For example, if the session is created at 2023-7-27T12:00:01+08:30, the session expiration time is 2023-7-27T13:00:01+08:30.
paymentRedirectUrl
Yes
Yes
The merchant page URL that the user is redirected to after the payment is completed.
The page display according to the server-side result and should not default to a fixed payment success page.
  • If the payment is initiated from a Web or WAP platform, pass the WAP URL.
  • If the payment is initiated from an App, pass the scheme URL.
paymentNotifyUrl
No
No
The URL that is used to receive the payment result notification. it must be an HTTPS URL. This field can be omitted if already configured via Antom Dashboard.
Authorization parameter
agreementInfo.authState
Yes
No
The unique ID generated by the merchant to initiate an EasySafePay authorization.

Order parameter



order.orderAmount
Yes
Yes
The order amount of the merchant that directly provides services or goods to the customer
order.referenceOrderId
Yes
Yes
The unique ID to identify the order on the merchant side.
order.orderDescription
Yes
Yes
Summary description of the order.
order.buyer.referenceBuyerId
No
No
Submit buyer information for risk assessment. Provide at least one of these fields: referenceBuyerId, buyerPhoneNo, or buyerEmail.

order.buyer.
    • buyerPhoneNo
    • buyerEmail
No
No
Buyer's account. Providing relevant payment account information can effectively improve the payment success rate and reduce the risk of buyer attrition. Please refer to the table below for specific format requirements.
The parameter format for the buyer's payment account for each payment method is as follows:
Payment method
Parameter format
It is recommended to prioritize using a mobile phone number:
  • Mobile number:
    • Hong Kong, China: 852-12****78. The phone number must be 8 digits long, excluding the prefix.
    • China: 86-137****5678. The phone number must be 11 digits long, excluding the prefix.
  • Email: xxx@xxx.com
62-8569****7288. The phone number starts with 8 and is no more than 12 digits long, excluding the prefix.
TrueMoney
The buyer is authenticated on the payment method side, and no parameters need to be passed in.userloginId.
During the first-time payment, passing the buyer's payment account will auto-fill the buyer's account on the payment page, eliminating manual input. Below is a comparison of the user experience with and without these fields:
With account parameter passed
Login account input is not required.
User experience showing the merchant checkout page when the buyer's payment account parameter is passed, where the login account input field is pre-filled and manual input is not required
Without account parameter passed
Manual input of login account is required.
User experience showing the merchant checkout page when the buyer's payment account parameter is not passed, requiring manual input of the login account
Below are code examples for first and subsequent payments.
First payment
The following sample code shows how to call the createPaymentSession (EasySafePay) API:
@PostMapping("/payment/createSession")
public ResponseEntity<ApiResponse> createPaymentSession(@RequestBody PaymentVO payment) {
  AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
  alipayPaymentSessionRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);
  alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.EASY_PAY);

  // replace with your paymentRequestId
  String paymentRequestId = UUID.randomUUID().toString();
  alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);

  // convert amount unit(in practice, amount should be calculated on your server side)
  // For details, refer to: <a href="https://docs.antom.com/ac/ref/cc">Usage rules of the Amount object</a>
  long amountMinorLong = Money.of(CurrencyUnit.of(payment.currency), new BigDecimal(payment.amountValue)).getAmountMinorLong();

  // set amount
  Amount amount = Amount.builder().currency(payment.currency).value(String.valueOf(amountMinorLong)).build();
  alipayPaymentSessionRequest.setPaymentAmount(amount);

  // set settlement strategy
  // replace with your existing settlement currency
  SettlementStrategy settlementStrategy = SettlementStrategy.builder().settlementCurrency("USD").build();
  alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);

  User loginUser = users.get(payment.getUserId());

  // set paymentMethod
  PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType(payment.paymentMethodType).build();
  if (loginUser.getPaymentMethodTypeAccessToken().containsKey(payment.getPaymentMethodType())) {
      // buyer has authorized
      String accessToken = loginUser.getPaymentMethodTypeAccessToken().get(payment.getPaymentMethodType());
      paymentMethod.setPaymentMethodId(accessToken);
  } else {
      // set agreementInfo
      // replace with your authState
      String authState = UUID.randomUUID().toString();
      // The login ID that the buyer used to register in the payment method client. The login ID can be the buyer's email address or phone number.
      // Specify this parameter to free buyers from manually entering their login IDs.
      String userLoginId = loginUser.getPhoneNumber();
      AgreementInfo agreementInfo = AgreementInfo.builder().authState(authState).userLoginId(userLoginId).build();
      alipayPaymentSessionRequest.setAgreementInfo(agreementInfo);

      // save the paymentMethodType corresponding to the authState
      authStatePayment.put(authState, payment);
  }
  alipayPaymentSessionRequest.setPaymentMethod(paymentMethod);

  // set buyer info
  Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

  // replace with your orderId
  String orderId = UUID.randomUUID().toString();
  // set order Info
  Order order = Order.builder().referenceOrderId(orderId)
          .orderDescription("antom sdk testing order").orderAmount(amount).buyer(buyer).build();
  alipayPaymentSessionRequest.setOrder(order);

  // replace with your notify url
  // or configure your notify url here: <a href="https://dashboard.antom.com/global-payments/developers/iNotify">Notification URL</a>
  alipayPaymentSessionRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com/payment/receivePaymentNotify");

  // replace with your redirect url
  alipayPaymentSessionRequest.setPaymentRedirectUrl(
          "http://localhost:8080/index.html?paymentRequestId=" + paymentRequestId);

  AlipayPaymentSessionResponse alipayPaymentSessionResponse;
  try {
      long startTime = System.currentTimeMillis();
      System.out.println("payment request: " + JSON.toJSONString(alipayPaymentSessionRequest));
      alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
      System.out.println("payment response: " + JSON.toJSONString(alipayPaymentSessionResponse));
      System.out.println("payment request cost time: " + (System.currentTimeMillis() - startTime) + "ms
");
  } catch (AlipayApiException e) {
      return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), e));
  }
  return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), alipayPaymentSessionResponse));
}
The following code shows a sample of the request message:
{
"agreementInfo": {
  "authState": "authState001",
  "userLoginId": "userLoginId001"
},
"order": {
  "buyer": {
    "referenceBuyerId": "referenceBuyerId001"
  },
  "orderAmount": {
    "currency": "CNY",
    "value": "100"
  },
  "orderDescription": "orderDescription001",
  "referenceOrderId": "referenceOrderId001"
},
"paymentAmount": {
  "currency": "CNY",
  "value": "100"
},
"paymentMethod": {
  "paymentMethodType": "ALIPAY_CN"
},
"paymentNotifyUrl": "http://debug1688017773824.test.alipay.net:9090/amsdemo/record/notify?env=main_online&paymentMethodType=ALIPAY_CN",
"paymentRedirectUrl": "http://debug1688017773824.test.alipay.net:9090/amsdemo/result",
"paymentRequestId": "paymentRequestId001",
"productCode": "AGREEMENT_PAYMENT",
"productScene": "EASY_PAY",
"settlementStrategy": {
  "settlementCurrency": "USD"
}
}
The following code shows a sample of the response message:
{
  "paymentSessionData": "ZqeGpu7pbMb/I3dNWTTEL3o4w5mXh20j13VnmsE1p3cjK3CVpnMXY7BfQlIvwNqQWtXHEMUo0R5pQwnSyNtxTA==&&SG&&188&&eyJh***",
  "paymentSessionExpiryTime": "2024-09-27T15:57:30+08:00",
  "paymentSessionId": "ZqeGpu7pbMb/I3dNWTTEL3o4w5mXh20j13VnmsE1p3fI21eGbgq240lFVquZsLrM",
  "result": {
      "resultCode": "SUCCESS",
      "resultMessage": "success.",
      "resultStatus": "S"
  }
}
Please take the next step according to the value of the result.resultStatus.
resultStatus
Message
Further actions
S
The payment session is successfully created.
Return the obtained paymentSessionData to the merchant's frontend. For specific operational steps, refer to Step 4.
F
The payment session creation failed.
Check and verify whether the required request parameters (including the header parameters and body parameters) of the current API are correctly passed and valid.
U
The payment session creation failed due to unknown reasons.
Replace the paymentRequestId and authstate value, then retry the API call to resolve the issue. If the problem persists, contact Antom Technical Support.
Note: If you do not receive a response, it may be due to a network timeout. Please retry the API call with a new paymentRequestId and authstate value.
Subsequent payments
The following sample code shows how to call the createPaymentSession (EasySafePay) API:
public static void createPaymentSession() {
AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
alipayPaymentSessionRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);
alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.EASY_PAY);

// replace with your paymentRequestId
String paymentRequestId = UUID.randomUUID().toString();
alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);

// set amount
// you should convert amount unit(in practice, amount should be calculated on your server side)
Amount amount = Amount.builder().currency("HKD").value("98080").build();
alipayPaymentSessionRequest.setPaymentAmount(amount);

//set settlement currency
SettlementStrategy settlementStrategy = new SettlementStrategy();
settlementStrategy.setSettlementCurrency("USD");
alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);

// set paymentMethod
PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("ALIPAY_HK")
.paymentMethodId("28288803001319861727421828000Cv96OFlYoi17100****").build();
alipayPaymentSessionRequest.setPaymentMethod(paymentMethod);

// set buyer info
Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

// replace with your orderId
String orderId = UUID.randomUUID().toString();
// set order Info
Order order = Order.builder().referenceOrderId(orderId).
orderDescription("antom api testing order").orderAmount(amount).buyer(buyer).build();
alipayPaymentSessionRequest.setOrder(order);

// replace with your notify url
alipayPaymentSessionRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com");

// replace with your redirect url
alipayPaymentSessionRequest.setPaymentRedirectUrl("http://www.yourRedirectUrl.com");

AlipayPaymentSessionResponse alipayPaymentSessionResponse;
try {
alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// handle error condition
}
}
The following code shows a sample of the request message:
{
  "order": {
      "buyer": {
          "referenceBuyerId": "yourBuyerId"
      },
      "orderAmount": {
          "currency": "HKD",
          "value": "98080"
      },
      "orderDescription": "antom api testing order",
      "referenceOrderId": "5e445b58-49ad-4552-a36d-d38f311a090d"
  },
  "paymentAmount": {
      "currency": "HKD",
      "value": "98080"
  },
  "paymentMethod": {
      "paymentMethodId": "28288803001319861727421828000Cv96OFlYoi17100****",
      "paymentMethodType": "ALIPAY_HK"
  },
  "paymentNotifyUrl": "http://www.yourNotifyUrl.com",
  "paymentRedirectUrl": "http://www.yourRedirectUrl.com",
  "paymentRequestId": "5810a84e-3a3e-4e47-bbac-9dfe3f2dd2b3",
  "productCode": "AGREEMENT_PAYMENT",
  "productScene": "EASY_PAY",
  "settlementStrategy": {
      "settlementCurrency": "USD"
  }
}
The following code shows a sample of the response message:
 {
"paymentSessionData": "paymentSessionData****",
"paymentSessionExpiryTime": "2023-04-06T03:28:49+08:00",
"paymentSessionId": "paymentSessionId****",
"result": {
  "resultCode": "SUCCESS",
  "resultMessage": "success.",
  "resultStatus": "S"
}
}
Please take the next step according to the value of the result.resultStatus.
resultStatus
Message
Further actions
S
The payment session is successfully created.
Return the obtained paymentSessionData to the merchant's frontend. For specific operational steps, refer to Step 4.
F
The payment session creation failed.
Check and verify whether the required request parameters (including the header parameters and body parameters) of the current API are correctly passed and valid.
U
The payment session creation failed due to unknown reasons.
Replace the paymentRequestId value, then retry the API call to resolve the issue. If the problem persists, contact Antom Technical Support.
Note: If you do not receive a response, it may be due to a network timeout. Please retry the API call with a new paymentRequestId value.
Common questions
Q: Can I use Chinese characters in the value of the request parameters?
A: To avoid incompatibility of a certain payment method, do not use Chinese characters for parameters in the request.
Q: How to set the URL to receive the payment notification?
A: Specify paymentNotifyUrl in the createPaymentSession (EasySafePay) API to receive the asynchronous notification about the payment result (notifyPayment), or configure the receiving URL in Antom Dashboard. If the URL is specified in both the request and Antom Dashboard, the value specified in the request takes precedence.
Q: What is the difference between paymentAmount and orderAmount?
A:
paymentAmount refers to the payment amount, while orderAmount refers to the order amount. The actual charged amount is determined by paymentAmount.
Q: What does paymentSessionExpiryTime specifically refer to in payment requests?
A:
paymentSessionExpiryTime indicates the validity period from successful payment session creation until the buyer submits the payment. After submission, the payment processing timeout is 10 minutes. Therefore, the maximum total duration from session creation to payment completion is 1 hour and 10 minutes.
Q: Which parameters should be prioritized in the response message?
A:
Pay attention to the following key parameters:
  • result.resultStatus: Indicates the result of the API call.
  • paymentSessionData: Encrypted payment session data, which is passed to the frontend for initializing the Antom SDK.
  • paymentSessionExpiryTime: Expiration timestamp of the payment session.

Step 3: Invoke the SDK
Client-side

After obtaining the paymentSessionData value on the merchant server side, the merchant client can invoke the SDK to redirect the checkout page to the payment method authorization page. When the buyer submits a payment request, the SDK will automatically handle encrypted communication, risk control verification, page redirection, and payment instruction execution, enabling an end-to-end payment authorization process.

1. Instantiate the SDK

  1. Use
    AMSEasyPayConfiguration
    to create the SDK instance. The configuration object includes the following parameters:
Parameter name
Required
Description
locale
No
Used to specify the language information. Select the appropriate value based on the region of the payment method. Valid values for this parameter are listed as follows. If a value not in the following list is used, English is used instead.
  • en_US
    : English
  • in_ID
    : Indonesian
  • ms_MY
    : Malay
  • tl_PH
    : Filipino
  • ko_KR
    : Korean
  • zh_CN
    : Simplified Chinese
  • zh_HK
    : Traditional Chinese
options
No
Used to specify whether to use the sandbox environment. Valid values are:
  • "sandbox", "true"
    : Sandbox environment
  • "sandbox", "false"
    : Production environment
  • "notRedirectAfterComplete", "false"
    : Optional, Boolean type. The default value is
    false
    , indicates that redirection to your page takes place after the payment is complete. The same applies when the value is empty. When the value is
    true
    , redirection will not take place after the payment is complete. You need to use the customer event code to control the payment and complete the subsequent process.
Note:
  • This parameter applies only to scenarios where the payment is completed within the SDK.
  • The result and event codes returned by the client-side are only used as a reference for the redirection operation of the client page. For transaction status updates, refer to the results returned by the server's notifyPayment or inquirePayment API.
fromScheme
No
In the Alipay scenario, when a buyer completes payment in the Alipay wallet, the system will redirect back to your merchant app according to the
exampleForScheme
configuration.
Note: In the iOS Native environment, Alipay only supports redirecting to the app's launch page specified by componentConfig.fromScheme, rather than the paymentRedirectUrl specified in the createPaymentSession (EasySafePay) API. The specific redirect page needs to be controlled through the event code.
  1. Create an instance of the AMSPaymentProtocol API to process the payment callback result, which includes the following method:
Method
Required
Description
onEventCallback
No
A callback function that monitors payment events on the checkout page, returning eventCode and eventResult. The payment success result will not be returned by this callback function by default. A redirection to the payment success result page that you specified will take place instead. However, when notRedirectAfterComplete is set to
true
, the system will not perform redirection upon payment completion, instead it will provide event callback.
Note: When integrating with Alipay, if you invoke
processOrderWithPaymentResult
, you will receive the payment event codes returned by
onEventCallback
. If you do not invoke
processOrderWithPaymentResult
, payment event codes will not be returned, but you can query the payment result by calling the inquiryPayment API on the server.
The following sample code shows how to instantiate the SDK:
#import <AMSComponent/AMSComponent-Swift.h>


AMSEasyPayConfiguration *componentConfig = [AMSEasyPayConfiguration new];
// Alipay needs to add fromScheme. Note that this address refers to the corresponding APP startup page after the payment is completed.
componentConfig.fromScheme = @"exampleForScheme";

componentConfig.locale = @"en_US";
// Set the sandbox environment. If you leave it empty, the production environment is used by default.
NSDictionary *options = @{@"sandbox": @"true",
                        @"notRedirectAfterComplete": @"false"};
componentConfig.options = options;

[[AMSEasyPay shared] initConfiguration:componentConfig];

// Set the callback to monitor payment events on the checkout page.
[AMSEasyPay shared].paymentDelegate = self;


#pragma AMSPaymentProtocol
- (void)onEventCallback:(NSString *)eventCode eventResult:(AMSEventResult *)eventResult
{
  NSLog(@"eventCode%@ eventResult%@", eventCode, eventResult);
}

The following image shows the rendering effect of the merchant checkout page invoking a half-screen pop-up or redirecting to the digital wallet app:
Mobile user experience showing the merchant checkout page launching a half-screen pop-up or redirecting to the digital wallet app for payment authorization
  1. Use the
    createComponent
    method in the instance object to create a payment component, which includes the following parameter:
Parameter name
Required
Description
sessionData
Yes
Create a configuration object using the sessionData parameter: Use the complete data of the value of paymentSessionData obtained in the response of the createPaymentSession (EasySafePay) API as the value of this parameter.
The sample code is as follows:
[[AMSEasyPay shared] createComponent:sessionData];

2. Handle SDK callback event codes

Below are the event codes returned by
onEventCallback
and handling recommendations:
Type
Code
Description
Further action
Status code
SDK_CALL_URL_SUCCESS
This event code indicates that redirect successfully for the paymentRedirectUrl.
Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.
SDK_PAYMENT_CANCEL
The buyer canceled the payment (the buyer exited the payment page without submitting the order).
You can re-invoke the SDK using paymentSessionData within its validity period; If it has expired, you need to initiate a new createPaymentSession (EasySafePay) API.
SDK_PAYMENT_SUCCESSFUL
Indicates that the wallet has successfully processed the payment.
Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.
Note: For payment solutions not integrated with Alipay, suggest redirecting users to the payment result page.
SDK_PAYMENT_FAIL
Indicates that the wallet failed to process the payment.
Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.
Note: For payment solutions not integrated with Alipay, suggest redirecting users to the payment result page.
SDK_PAYMENT_PROCESSING
(Returned when integrated with Alipay)
Indicates that the payment status of the Alipay walletis unknown.
Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.
SDK_PAYMENT_ERROR
(Returned when integrated with Alipay)
Indicates that the payment processing of the Alipay wallet is abnormal.
Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.
Error code
​
SDK_CREATEPAYMENT_PARAMETER_ERROR
The parameters passed to the
createComponent
method are not correct.
Check if the parameters are correct and re-initialize the component.
SDK_STATUS_ERROR
This event code indicates one of the following situations:
  • You just call
    createComponent
    when it is still in previous payment flow.
  • You just call
    createComponent
    without init.
  • You just call
    createComponent
    when another Popup is active.
Please check the result message, then match the errorsituations.
SDK_INTEGRATION_ERROR
This event code indicates thatsome dependencies of SDK is not exist. Currently there are two scenario:
  • Security SDK is not exist.
  • Open security browser failed.
Please check whether target module has been integrated.
SDK_LAUNCH_PAYMENT_APP_ERROR
This event code indicates one of the following situations:
  • Failed to redirect to the merchant page.
  • Failed to redirect to the 3D verification page.
  • The paymentRedirectUrl parameter was either not passed or incorrectly passed when calling the createPaymentSession (EasySafePay) API.
Check whether the paymentRedirectUrl parameter is correctly passed when calling the createPaymentSession (EasySafePay) API.
If frequent redirection exceptions occur, contact Antom Technical Support to troubleshoot redirection or cross-application calling issues.
The following sample code shows how to handle the callback function:
-(void)onEventCallback:(NSString *)eventCode eventResult:(AMSEventResult *)eventResult {
  if ([[_selectMethod title] isEqualToString:@"ALIPAY_CN"]) {
      if ([eventCode isEqualToString:@"SDK_PAYMENT_CANCEL"]) {
          NSLog(@"The buyer canceled the payment (the buyer exited the payment page without submitting the order). You can re-invoke the SDK using paymentSessionData within its validity period; If it has expired, you need to initiate a new createPaymentSession (EasySafePay) request.");
      } else if ([eventCode isEqualToString:@"SDK_PAYMENT_SUCCESSFUL"]) {
          NSLog(@"The Alipay wallet has successfully processed the payment. Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.");
      } else if ([eventCode isEqualToString:@"SDK_PAYMENT_FAIL"]) {
          NSLog(@"The Alipay wallet failed to process the payment. Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.");
      } else if ([eventCode isEqualToString:@"SDK_PAYMENT_PROCESSING"]) {
          NSLog(@"The payment status of the Alipay wallet is unknown. Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.");
      } else if ([eventCode isEqualToString:@"SDK_PAYMENT_ERROR"]) {
          NSLog(@"The payment processing of the Alipay wallet is abnormal. Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.");
      } else {
          NSLog(@"eventCode%@ eventResult%@", eventCode, eventResult);
      }
  } else {
      // Please note that payment success will not be notified through this callback function, but will instead redirect to the success result page you specified.
      if ([eventCode isEqualToString:@"SDK_PAYMENT_CANCEL"]) {
          NSLog(@"The buyer canceled the payment (the buyer exited the payment page without submitting the order). You can re-invoke the SDK using paymentSessionData within its validity period; If it has expired, you need to initiate a new createPaymentSession (EasySafePay) request.");
      } else if ([eventCode isEqualToString:@"SDK_CALL_URL_SUCCESS"]) {
          NSLog(@"Open wallet app or redirect to the merchant page successfully.");
      } else if ([eventCode isEqualToString:@"SDK_LAUNCH_PAYMENT_APP_ERROR"]) {
          NSLog(@"Open wallet app or redirect to the merchant page failed");
      } else if ([eventCode isEqualToString:@"SDK_CREATEPAYMENT_PARAMETER_ERROR"]) {
          NSLog(@"The input parameter provided is invalid. Please check the value and try again.");
      } else {
          NSLog(@"eventCode%@ eventResult%@", eventCode, eventResult);
      }
  }
}

3. Free SDK component resources

Call the
onDestroy
method to free SDK component resources in the following situations:
In the following scenario, you do not need to call
onDestroy
, and the SDK will automatically free partial resources (for iOS SDK AMSComponents 1.33.0 or above).
  • When the buyer initiates multiple payments, and the parameters in
    initConfiguration
    have not changed. The SDK will automatically free partial resources after the payment is completed to reset to the state before
    createComponent
    was called.
The following sample code shows how to free components:
// Completely free SDK component resources
[[AMSEasyPay shared] onDestroy];
Common questions
Q: Is it mandatory to handle SDK callback events?
A: For Alipay, you must process event codes to display payment results, but this payment method is optional. Callback events can also be used for logging.
​
Q: Can an AMSEasypay instance execute createComponent multiple times?
A: No. You need to create a fresh
AMSEasypay instance to initiate a new payment.
​
Q: Are SDK calls required for both first-time and subsequent payments?
A: Yes.

4. Receive notification from callback function (When integrating Alipay)

When integrating with Alipay, the merchant-client can receive notifications from the callback function. After receiving the callback notification, use the
openURL
method in the AppDelegate file to handle the result returned by Alipay:
  • Use
    canProcessOrderWithPaymentResult()
    to check whether the redirect URL, to redirect from the wallet to the merchant side, is valid.
  • Use
    processOrderWithPaymentResult()
    to handle the redirection from the wallet to the merchant's side.
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
   if ([url.scheme isEqualToString:@"exampleForScheme"]) {
      if ([[AMSEasyPay shared] canProcessOrderWithPaymentResult:url]) {
          [[AMSEasyPay shared] processOrderWithPaymentResult:url];
      }
  }
  return YES;
}
Android

User experience

This Android integration guide is designed to help you quickly integrate the digital wallet and online banking payment functions within the app and easily complete the payment interface rendering.
The user experience of each payment method on the Android side varies; refer to the table below for specific interaction experiences:
​Payment method category
​Payment method
Terminal type
First-time payment
Subsequent payments
Digital wallet
Android
Complete the payment on the merchant page.
Complete the payment on the merchant page.
Android
Redirect to the payment method app to complete payment.
Complete the payment on the merchant page.
Online banking
Android
Complete the payment on the merchant page.
Complete the payment on the merchant page.
Digital wallet
Below is the user experience for first and subsequent payments using digital wallets.
First payment
Upon the first payment, the buyer can choose to pay immediately or complete the authorization process. After successful authorization, subsequent payments will be processed by the password-free feature.
Pay on the merchant page
Mobile user experience showing the digital wallet first payment flow where buyers complete security authentication to enable password-free payments for subsequent transactions on the merchant page
Pay on the payment method app
Mobile user experience showing the digital wallet first payment flow where buyers complete security authentication to enable password-free payments for subsequent transactions on the payment method app
Subsequent payments
Subsequent payments are processed without requiring a password upon order submission.
Mobile user experience showing digital wallet subsequent payment processed automatically without requiring password entry upon order submission
Online banking
Below is the user experience for first and subsequent payments using online banking payment methods.
First payment
Upon the first payment, the buyer can choose to pay immediately or complete the authorization process. After successful authorization, subsequent payments will be processed by the password-free feature.
Mobile user experience showing the online banking first payment where the buyer completes the authorization process to enable subsequent password-free payments
Subsequent payments
Subsequent payments are processed without requiring a password upon order submission.
Mobile user experience showing the online banking subsequent payment processed automatically without requiring password upon order submission

Payment flow

First payment
The first payment flow chart:
Sequence diagram illustrating the EasySafePay first payment flow among Buyer, Merchant Client, Merchant Server, and Antom: the buyer enters the checkout page, the merchant creates a payment session via the createPaymentSession API, the client SDK renders the payment interface and manages redirections, the buyer completes authorization, and the merchant receives asynchronous notifyAuthorization and notifyPayment notifications or queries payment status through the inquiryPayment API.
  1. The buyer enters the checkout page.
  2. Create a payment session request.
    After the buyer selects a payment method and submits the order, you can obtain the payment session by calling the createPaymentSession (EasySafePay) API.
  3. Invoke the client SDK.
    Invoke the SDK using a payment session and the SDK will automatically collect payment elements, render the payment interface, handle page redirections, and guide buyers through payment completion based on the specific payment method's characteristics. For detailed interaction differences across payment methods, refer to the User experience table.
  4. Obtain the authorization result.
    When the authorization is successful, Antom sends you the asynchronous notification through the
    notifyAuthorization API.
  5. Obtain the payment result.
    Obtain the payment result using one of the following methods:
    • Asynchronous notification: Specify paymentNotifyUrl in the createPaymentSession (EasySafePay) API to set the address for receiving asynchronous notifications. When the payment is successful or expires, Antom will use notifyPayment to send asynchronous notifications to you.
    • Synchronous inquiry: Call the inquiryPayment API to check the real-time payment status.
Subsequent payments
The subsequent payment flow chart:
Sequence diagram illustrating the EasySafePay subsequent payment flow among Buyer, Merchant Client, Merchant Server, and Antom: the buyer enters the checkout page, the merchant creates a payment session using the previously authorized paymentMethodId via the createPaymentSession API, the client SDK renders the payment interface, the buyer submits the order, and the merchant receives an asynchronous notifyPayment notification or uses the inquiryPayment API to check payment status.
  1. The buyer enters the checkout page.
  2. Create a payment session request.
    After the buyer selects a payment method and submits the order, you can obtain the payment session by calling the createPaymentSession (EasySafePay) API.
  3. Invoke the client SDK.
    Invoke the SDK using a payment session and the SDK will automatically collect payment elements, render the payment interface, handle page redirections, and guide buyers through payment completion based on the specific payment method's characteristics. For detailed interaction differences across payment methods, refer to the
    User experience table.
  4. Obtain the payment result.
    Obtain the payment result using one of the following methods:
    • Asynchronous notification: Specify paymentNotifyUrl in the createPaymentSession (EasySafePay) API to set the address for receiving asynchronous notifications. When the payment is successful or expires, Antom will use notifyPayment to send asynchronous notifications to you.
    • Synchronous inquiry: Call the inquiryPayment API to check the real-time payment status.

Integration preparations

Before you start integrating, read the Integration Guide and API Overview documents to understand the integration steps of the server-side API and the precautions for calling the API. Furthermore, ensure that the following prerequisites are met:
  • Obtain a client ID
  • Complete the key configuration
  • Complete the configuration of paymentNotifyUrl to receive the asynchronous notification
  • Integrate the server-side SDK package, install the server-side library, and initialize a request instance. For more details, refer to Server-side SDKs.
  • If you need to conduct joint debugging by connecting the sandbox with the production environment, please contact Antom technical support at least two business days in advance to request configuration. The sandbox environment and production environment require separate configuration.
Refer to Integrate the SDK package for Android to complete integration preparations.

Integration steps

Start your integration by taking the following steps:
  1. (Optional) Preload the SDK
  2. Create a payment session
  3. Invoke the SDK
  4. Obtain the authorization and payment result

(Optional) Step 1: Preload the SDK
Client-side

Preloading the SDK during the checkout page initialization significantly improves the rendering performance with no negative impact. It is recommended to trigger preloading of the SDK when the buyer selects a payment method.
Follow the code example below to perform the preloading:
Preload SDK
 AMSEasyPay.preload(getApplicationContext());

Step 2: Create a payment session
Server-side

When a buyer selects a payment method provided by Antom, you need to collect essential information including the payment request ID, order amount, payment method, order description, payment redirect page URL, and payment result notification URL.
Call the createPaymentSession (EasySafePay) API to create a payment session and initialize the Antom SDK using the paymentSessionData value returned in the response.
The table below lists the parameter specifications for calling the createPaymentSession (EasySafePay) API during the first and subsequent payments:
Note: For subsequent payments with Express Bank Transfer, simply keep the parameters consistent with the first payment. The buyer can open the Express Bank Transfer webpage and enter the phone number to proceed directly with the payment.
Parameter type
Parameter name
Required
(First payment)
Required
(Subsequent payments)
Description
Base parameter
productCode
Yes
Yes
The value is fixed as
AGREEMENT_PAYMENT
in the EasySafePay scenario.
productScene
Yes
Yes
The value is fixed as
EASY_PAY
in the EasySafePay scenario.
paymentRequestId
Yes
Yes
The unique ID assigned by a merchant to identify a payment request.
paymentMethod.paymentMethodType
Yes
Yes
The payment method type that is included in payment method options.
paymentMethod.paymentMethodId
No
Yes
The unique ID that is used to identify a payment method. The value of this parameter is that of accessToken from the notifyAuthorization API after the first payment.
settlementStrategy
No
No
The settlement strategy for the payment request. If the merchant agreement supports multiple settlement currencies, they must be specified in the API request.
paymentAmount.value
Yes
Yes
The value of the amount as a positive integer in the smallest currency unit.
For details about the smallest currency unit, see Smallest unit of the currency.
paymentAmount.currency
Yes
Yes
The transaction currency, which is a 3-letter currency code that follows the ISO 4217 standard.
paymentSessionExpiryTime
No
No
The specific date and time after which the payment session will expire. The default expiration time is 1 hour after the session creation. The maximum expiration time cannot exceed 1 hour. For example, if the session is created at 2023-7-27T12:00:01+08:30, the session expiration time is 2023-7-27T13:00:01+08:30.
paymentRedirectUrl
Yes
Yes
The merchant page URL that the buyer is redirected to after the payment is completed.
The page display according to the server-side result and should not default to a fixed payment success page. When the payment is initiated from an app, pass the scheme URL.
paymentNotifyUrl
No
No
The URL that is used to receive the payment result notification. it must be an HTTPS URL. This parameter can be omitted if already configured via Antom Dashboard.
Authorization parameter
agreementInfo.authState
Yes
No
The unique ID generated by the merchant to initiate an EasySafePay authorization. This parameter is only required during the first payment and is not required for subsequent payments.
agreementInfo.userLoginId
No
No
The login ID that the buyer used to register in the payment method client. The login ID can be the buyer's email address or phone number. The specific format requirements are shown in the "Common userLoginId formats" table below. Providing this parameter can effectively increase payment success rates and reduce buyer drop-off risk.

Order parameter



order.orderAmount
Yes
Yes
The order amount of the merchant that directly provides services or goods to the buyer.
order.referenceOrderId
Yes
Yes
The unique ID to identify the order on the merchant side.
order.orderDescription
Yes
Yes
Summary description of the order.
order.buyer
    • referenceBuyerId
    • buyerPhoneNo
    • buyerEmail
Yes
Yes
Submit buyer information for risk assessment. Provide at least one of these parameters: referenceBuyerId, buyerPhoneNo, or buyerEmail.
The parameter format for the buyer's payment account for each payment method is as follows:
Payment method
Parameter format
It is recommended to prioritize using a mobile phone number:
  • Mobile number:
    • Hong Kong, China: 852-12****78. The phone number must be 8 digits long, excluding the prefix.
    • China: 86-137****5678. The phone number must be 11 digits long, excluding the prefix.
  • Email: xxx@xxx.com
62-8569****7288. The phone number starts with 8 and is no more than 12 digits long, excluding the prefix.
TrueMoney
The buyer is authenticated on the payment method side, and no parameters need to be passed in.userloginId.
During the first-time payment, passing the buyer's payment account will auto-fill the buyer's account on the payment page, eliminating manual input. Below is a comparison of the user experience with and without these fields:
With account parameter passed
Login account input is not required.
User experience showing the merchant checkout page when the buyer's payment account parameter is passed, where the login account input field is pre-filled and manual input is not required
Without account parameter passed
Manual input of login account is required.
User experience showing the merchant checkout page when the buyer's payment account parameter is not passed, requiring manual input of the login account
Below are code examples for first and subsequent payments.
First payment
The following sample code shows how to call the createPaymentSession (EasySafePay) API:
@PostMapping("/payment/createSession")
public ResponseEntity<ApiResponse> createPaymentSession(@RequestBody PaymentVO payment) {
  AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
  alipayPaymentSessionRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);
  alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.EASY_PAY);

  // replace with paymentRequestId
  String paymentRequestId = UUID.randomUUID().toString();
  alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);

  // convert amount unit(in practice, amount should be calculated on your serverside)
  // For details, please refer to: <a href="https://docs.antom.com/ac/ref/cc">Usage rules of the Amount object</a>
  long amountMinorLong = Money.of(CurrencyUnit.of(payment.currency), new BigDecimal(payment.amountValue)).getAmountMinorLong();

  // set amount
  Amount amount = Amount.builder().currency(payment.currency).value(String.valueOf(amountMinorLong)).build();
  alipayPaymentSessionRequest.setPaymentAmount(amount);

  // set settlement strategy
  // replace with your existing settlement currency
  SettlementStrategy settlementStrategy = SettlementStrategy.builder().settlementCurrency("USD").build();
  alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);

  User loginUser = users.get(payment.getUserId());

  // set buyer info
  Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

  // set paymentMethod
  PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType(payment.paymentMethodType).build();
  if (loginUser.getPaymentMethodTypeAccessToken().containsKey(payment.getPaymentMethodType())) {
      // buyer has authorized
      String accessToken = loginUser.getPaymentMethodTypeAccessToken().get(payment.getPaymentMethodType());
      paymentMethod.setPaymentMethodId(accessToken);
  } else {
      // set agreementInfo
      // replace with your authState
      String authState = UUID.randomUUID().toString();
      AgreementInfo agreementInfo = AgreementInfo.builder().authState(authState).build();
      alipayPaymentSessionRequest.setAgreementInfo(agreementInfo);

      // save the paymentMethodType corresponding to the authState
      authStatePayment.put(authState, payment);

      // The login ID that the user used to register in the payment method client. The login ID can be the user's email address or phone number.
      // Specify this parameter to free users from manually entering their login IDs.
      if(StringUtil.isNotBlank(loginUser.getPhoneNumber()){
          buyer.setBuyerPhoneNo(loginUser.getPhoneNumber());
      }
      if(StringUtil.isNotBlank(loginUser.getEmail() && "ALIPAY_HK".equals(payment.getPaymentMethodType())){
          buyer.setBuyerPhoneNo(loginUser.getPhoneNumber());
      }
  }
  alipayPaymentSessionRequest.setPaymentMethod(paymentMethod);



  // replace with your orderId
  String orderId = UUID.randomUUID().toString();
  // set order info
  Order order = Order.builder().referenceOrderId(orderId)
  .orderDescription("antom sdk testing order").orderAmount(amount).buyer(buyer).build();
  alipayPaymentSessionRequest.setOrder(order);

  // replace with your notify url
  // or configure your notify url here: <a href="https://dashboard.antom.com/global-payments/developers/iNotify">Notification URL</a>
  alipayPaymentSessionRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com/payment/receivePaymentNotify");

  // replace with your redirect URL
  alipayPaymentSessionRequest.setPaymentRedirectUrl(
          "http://localhost:8080/index.html?paymentRequestId=" + paymentRequestId);

  AlipayPaymentSessionResponse alipayPaymentSessionResponse;
  try {
      long startTime = System.currentTimeMillis();
      System.out.println("payment request: " + JSON.toJSONString(alipayPaymentSessionRequest));
      alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
      System.out.println("payment response: " + JSON.toJSONString(alipayPaymentSessionResponse));
      System.out.println("payment request cost time: " + (System.currentTimeMillis() - startTime) + "ms");
  } catch (AlipayApiException e) {
      return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), e));
  }
  return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), alipayPaymentSessionResponse));
}
The following code shows a sample of the request message:
{
"agreementInfo": {
  "authState": "authState001",
  "userLoginId": "userLoginId001"
},
"order": {
  "buyer": {
    "referenceBuyerId": "referenceBuyerId001"
  },
  "orderAmount": {
    "currency": "CNY",
    "value": "100"
  },
  "orderDescription": "orderDescription001",
  "referenceOrderId": "referenceOrderId001"
},
"paymentAmount": {
  "currency": "CNY",
  "value": "100"
},
"paymentMethod": {
  "paymentMethodType": "ALIPAY_CN"
},
"paymentNotifyUrl": "http://debug1688017773824.test.alipay.net:9090/amsdemo/record/notify?env=main_online&paymentMethodType=ALIPAY_CN",
"paymentRedirectUrl": "http://debug1688017773824.test.alipay.net:9090/amsdemo/result",
"paymentRequestId": "paymentRequestId001",
"productCode": "AGREEMENT_PAYMENT",
"productScene": "EASY_PAY",
"settlementStrategy": {
  "settlementCurrency": "USD"
}
}
The following code shows a sample of the response message:
{
  "paymentSessionData": "ZqeGpu7pbMb/I3dNWTTEL3o4w5mXh20j13VnmsE1p3cjK3CVpnMXY7BfQlIvwNqQWtXHEMUo0R5pQwnSyNtxTA==&&SG&&188&&eyJh***",
  "paymentSessionExpiryTime": "2024-09-27T15:57:30+08:00",
  "paymentSessionId": "ZqeGpu7pbMb/I3dNWTTEL3o4w5mXh20j13VnmsE1p3fI21eGbgq240lFVquZsLrM",
  "result": {
      "resultCode": "SUCCESS",
      "resultMessage": "success.",
      "resultStatus": "S"
  }
}
Please take the next step according to the value of the result.resultStatus.
resultStatus
Message
Further actions
S
The payment session is successfully created.
Return the obtained paymentSessionData to the merchant's frontend. For specific operational steps, refer to Step 4.
F
The payment session creation failed.
Check and verify whether the required request parameters (including the header parameters and body parameters) of the current API are correctly passed and valid.
U
The payment session creation failed due to unknown reasons.
Replace the paymentRequestId and authstate value, then retry the API call to resolve the issue. If the problem persists, contact Antom Technical Support.
Note: If you do not receive a response, it may be due to a network timeout. Please retry the API call with a new paymentRequestId and authstate value.
Subsequent payments
The following sample code shows how to call the createPaymentSession (EasySafePay) API:
public static void createPaymentSession() {
AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
alipayPaymentSessionRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);
alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.EASY_PAY);

// replace with your paymentRequestId
String paymentRequestId = UUID.randomUUID().toString();
alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);

// set amount
// you should convert amount unit(in practice, amount should be calculated on your server side)
Amount amount = Amount.builder().currency("HKD").value("98080").build();
alipayPaymentSessionRequest.setPaymentAmount(amount);

//set settlement currency
SettlementStrategy settlementStrategy = new SettlementStrategy();
settlementStrategy.setSettlementCurrency("USD");
alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);

// set paymentMethod
PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("ALIPAY_HK")
.paymentMethodId("28288803001319861727421828000Cv96OFlYoi17100****").build();
alipayPaymentSessionRequest.setPaymentMethod(paymentMethod);

// set buyer info
Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

// replace with your orderId
String orderId = UUID.randomUUID().toString();
// set order Info
Order order = Order.builder().referenceOrderId(orderId).
orderDescription("antom api testing order").orderAmount(amount).buyer(buyer).build();
alipayPaymentSessionRequest.setOrder(order);

// replace with your notify url
alipayPaymentSessionRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com");

// replace with your redirect url
alipayPaymentSessionRequest.setPaymentRedirectUrl("http://www.yourRedirectUrl.com");

AlipayPaymentSessionResponse alipayPaymentSessionResponse;
try {
alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// handle error condition
}
}
The following code shows a sample of the request message:
{
  "order": {
      "buyer": {
          "referenceBuyerId": "yourBuyerId"
      },
      "orderAmount": {
          "currency": "HKD",
          "value": "98080"
      },
      "orderDescription": "antom api testing order",
      "referenceOrderId": "5e445b58-49ad-4552-a36d-d38f311a090d"
  },
  "paymentAmount": {
      "currency": "HKD",
      "value": "98080"
  },
  "paymentMethod": {
      "paymentMethodId": "28288803001319861727421828000Cv96OFlYoi17100****",
      "paymentMethodType": "ALIPAY_HK"
  },
  "paymentNotifyUrl": "http://www.yourNotifyUrl.com",
  "paymentRedirectUrl": "http://www.yourRedirectUrl.com",
  "paymentRequestId": "5810a84e-3a3e-4e47-bbac-9dfe3f2dd2b3",
  "productCode": "AGREEMENT_PAYMENT",
  "productScene": "EASY_PAY",
  "settlementStrategy": {
      "settlementCurrency": "USD"
  }
}
The following code shows a sample of the response message:
 {
"paymentSessionData": "paymentSessionData****",
"paymentSessionExpiryTime": "2023-04-06T03:28:49+08:00",
"paymentSessionId": "paymentSessionId****",
"result": {
  "resultCode": "SUCCESS",
  "resultMessage": "success.",
  "resultStatus": "S"
}
}
Please take the next step according to the value of the result.resultStatus.
resultStatus
Message
Further actions
S
The payment session is successfully created.
Return the obtained paymentSessionData to the merchant's frontend. For specific operational steps, refer to Step 4.
F
The payment session creation failed.
Check and verify whether the required request parameters (including the header parameters and body parameters) of the current API are correctly passed and valid.
U
The payment session creation failed due to unknown reasons.
Replace the paymentRequestId value, then retry the API call to resolve the issue. If the problem persists, contact Antom Technical Support.
Note: If you do not receive a response, it may be due to a network timeout. Please retry the API call with a new paymentRequestId value.
Common questions
Q: Can I use Chinese characters in the value of the request parameters?
A: To avoid incompatibility of a certain payment method, do not use Chinese characters for parameters in the request.
Q: How to set the URL to receive the payment notification?
A: Specify paymentNotifyUrl in the createPaymentSession (EasySafePay) API to receive the asynchronous notification about the payment result (notifyPayment), or configure the receiving URL in Antom Dashboard. If the URL is specified in both the request and Antom Dashboard, the value specified in the request takes precedence.
Q: What is the difference between paymentAmount and orderAmount?
A:
paymentAmount refers to the payment amount, while orderAmount refers to the order amount. The actual charged amount is determined by paymentAmount.
Q: What does paymentSessionExpiryTime specifically refer to in payment requests?
A:
paymentSessionExpiryTime indicates the validity period from successful payment session creation until the buyer submits the payment. After submission, the payment processing timeout is 10 minutes. Therefore, the maximum total duration from session creation to payment completion is 1 hour and 10 minutes.
Q: Which parameters should be prioritized in the response message?
A:
Pay attention to the following key parameters:
  • result.resultStatus: Indicates the result of the API call.
  • paymentSessionData: Encrypted payment session data, which is passed to the frontend for initializing the Antom SDK.
  • paymentSessionExpiryTime: Expiration timestamp of the payment session.

Step 3: Invoke the SDK
Client-side

After obtaining the paymentSessionData value on the merchant server side, the merchant client can invoke the SDK to redirect the checkout page to the payment method authorization page. When the buyer submits a payment request, the SDK will automatically handle encrypted communication, risk control verification, page redirection, and payment instruction execution, enabling an end-to-end payment authorization process.

1. Instantiate the SDK

  1. Use
    AMSEasyPayConfiguration
    to create the SDK instance. The configuration object includes the following parameters:
Parameter name
Required
Description
setLocale
No
Used to specify the language information. Select the appropriate value based on the region of the payment method. Valid values for this parameter are listed as follows.If a value not in the following list is used, the local language is used instead.
  • "en", "US"
    : English
  • "in", "ID"
    : Indonesian
  • "ms", "MY"
    : Malay
  • "tl", "PH"
    : Filipino
  • "ko", "KR"
    : Korean
  • "zh", "CN"
    : Simplified Chinese
  • "zh", "HK"
    : Traditional Chinese
setOption
No
Used to specify whether to use the sandbox environment, the window alignment mode, and the redirection after the payment is complete. Valid values are:
  • "sandbox", "true"
    : Sandbox environment
  • "sandbox", "false"
    : Production environment
  • "windowGravity","LANDSCAPE_CENTER"
    : Center the window in landscape mode.
  • "windowGravity","LANDSCAPE_RIGHT"
    : Align the window to the right in landscape mode.
  • "notRedirectAfterComplete", "false"
    : Optional, Boolean type. The default value is
    false
    , indicates that redirection to your page takes place after the payment is complete. The same applies when the value is empty. When the value is
    true
    , redirection will not take place after the payment is complete. You need to use the customer event code to control the payment and complete the subsequent process.
Note:
  • This parameter applies only to scenarios where the payment is completed within the SDK.
  • The result and event codes returned by the client-side are only used as a reference for the redirection operation of the client page. For transaction status updates, refer to the results returned by the server's notifyPayment or inquirePayment API.
  1. Create an instance of the setOnCheckoutListener API to handle corresponding events that occur in subsequent processes, which include the following method:
Method
Required
Description
onEventCallback
No
A callback function that monitors payment events on the checkout page, returning eventCode and eventResult. The payment success result will not be returned by this callback function by default. A redirection to the payment success result page that you specified will take place instead. However, when notRedirectAfterComplete is set to
true
, the system will not perform redirection upon payment completion, instead it will provide event callback.
Note: When integrating with Alipay, you will receive the payment event codes returned by
onEventCallback
.
The following sample code shows how to instantiate the SDK:
// Step 1: Create the AMSEasyPayConfiguration type.
AMSEasyPayConfiguration configuration = new AMSEasyPayConfiguration();
configuration.setLocale(new Locale("en", "US"));
// Set the sandbox environment. If you leave it empty, the production environment is used by default.
configuration.setOption("sandbox", "true");
// Set as false by default
configuration.setOption("notRedirectAfterComplete", "false");
// Set the callback to monitor payment events on the checkout page.
configuration.setOnCheckoutListener(new OnCheckoutListener() {
  @Override
  public void onEventCallback(String eventCode, AMSEventResult eventResult) {
      // For eventCode, refer to the respective sample codes or event codes.
      Toast.makeText(activity, "eventCode=" + eventCode + " message=" + message, Toast.LENGTH_SHORT).show();
  }
});

// Instantiate AMSEasyPay.
AMSEasyPay checkout = new AMSEasyPay.Builder(activity, configuration).build();
The following image shows the rendering effect of the merchant checkout page invoking a half-screen pop-up or redirecting to the digital wallet app:
Mobile user experience showing the merchant checkout page launching a half-screen pop-up or redirecting to the digital wallet app for payment authorization
  1. Use the
    createComponent
    method in the instance object to create a payment component, which includes the following parameter:
Parameter name
Required
Description
sessionData
Yes
Create a configuration object using the sessionData parameter: Use the complete data of the value of paymentSessionData obtained in the response of the createPaymentSession (EasySafePay) API as the value of this parameter.
The sample code is as follows:
checkout.createComponent(activity, sessionData);

2. Handle SDK callback event codes

Below are the event codes returned by
onEventCallback
and handling recommendations:
Note: In the Android Native environment, Alipay only supports redirecting to the merchant app's launch page, rather than the paymentRedirectUrl specified in the createPaymentSession (EasySafePay) API. The specific redirect page needs to be controlled through the event code.
Type
Code
Description
Further action
Status code
SDK_CALL_URL_SUCCESS
This event code indicates that redirect successfully for the paymentRedirectUrl.
Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.
SDK_PAYMENT_CANCEL
The buyer canceled the payment (the buyer exited the payment page without submitting the order).
You can re-invoke the SDK usingpaymentSessionDatawithin its validity period; if it has expired, you need to initiate a new createPaymentSession (EasySafePay) API.
SDK_PAYMENT_SUCCESSFUL
Indicates that the wallet has successfully processed the payment.
Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.
Note: For payment solutions not integrated with Alipay, suggest redirecting users to the payment result page.
SDK_PAYMENT_FAIL
Indicates that the wallet failed to process the payment.
Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.
Note: For payment solutions not integrated with Alipay, suggest redirecting users to the payment result page.
SDK_PAYMENT_PROCESSING
(Returned when integrated with Alipay)
Indicates that the payment status of theAlipay walletis unknown.
Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.
SDK_PAYMENT_ERROR
(Returned when integrated with Alipay)
Indicates that the payment processing of the Alipay wallet is abnormal.
Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.
Error code
​
SDK_INTERNAL_ERROR
SDK internal error.
Contact Antom Technical Support.
SDK_CREATEPAYMENT_PARAMETER_ERROR
The parameters passed to the
createComponent
method are not correct.
Check if the parameters are correct and re-initialize the component.
SDK_STATUS_ERROR
This event code indicates one of the following situations:​
  • You just call
    createComponent
    when it is still in previous payment flow.
  • You just call
    createComponent
    without init.
  • You just call
    createComponent
    when another Popup is active.
Please check the result message, then match the error situations.
SDK_INTEGRATION_ERROR
This event code indicates that some dependencies of SDK is not exist. Currently there are two scenario:
  • Security SDK is not exist.
  • Open security browser failed.
Please check whether target module has been integrated.
SDK_LAUNCH_PAYMENT_APP_ERROR
This event code indicates one of the following situations:
  • Failed to invoke the app of the buyer's selected payment method or failed to redirect to the checkout page of the payment method.
  • Failed to redirect to the merchant page.
  • The paymentRedirectUrl parameter is not correctly passed when calling the createPaymentSession (EasySafePay) API.
Check whether the paymentRedirectUrl parameter is correctly passed when calling the createPaymentSession (EasySafePay) API.
If frequent redirection exceptions occur, contact Antom Technical Support to troubleshoot redirection or cross-application calling issues.
The following sample code shows how to handle the callback function:
configuration.setOnCheckoutListener(new OnCheckoutListener() {
          @Override
          public void onEventCallback(String eventCode, AMSEventResult eventResult) {
              if (selectPayment != null && selectPayment.getPaymentMethodCode().equals("ALIPAY_CN")) {
                  switch (eventCode) {
                      case "SDK_PAYMENT_CANCEL":
                          AlertUtils.showAlertWithMessage(MainActivity.this, "The buyer canceled the payment (the buyer exited the payment page without submitting the order). You can re-invoke the SDK using paymentSessionData within its validity period; If it has expired, you need to initiate a new createPaymentSession (EasySafePay) request.");
                          break;
                      case "SDK_PAYMENT_SUCCESSFUL":
                          AlertUtils.showAlertWithMessage(MainActivity.this, "The Alipay wallet has successfully processed the payment. Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.");
                          break;
                      case "SDK_PAYMENT_FAIL":
                          AlertUtils.showAlertWithMessage(MainActivity.this, "The Alipay wallet failed to process the payment. Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.");
                          break;
                      case "SDK_PAYMENT_PROCESSING":
                          AlertUtils.showAlertWithMessage(MainActivity.this, "The payment status of the Alipay wallet is unknown. Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.");
                          break;
                      case "SDK_PAYMENT_ERROR":
                          AlertUtils.showAlertWithMessage(MainActivity.this, "The payment processing of the Alipay wallet is abnormal. Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result.");
                          break;
                      default:
                          AlertUtils.showAlertWithMessage(MainActivity.this, "eventCode=" + eventCode + " message=" + eventResult.getMessage());
                          break;
                  }
              } else {
                  // Please note that payment success will not be notified from this callback function, but rather the page will be redirected to the success result page you specified
                  switch (eventCode) {
                      case "SDK_PAYMENT_CANCEL":
                          AlertUtils.showAlertWithMessage(MainActivity.this, "The buyer canceled the payment (the buyer exited the payment page without submitting the order). You can re-invoke the SDK using paymentSessionData within its validity period; If it has expired, you need to initiate a new createPaymentSession (EasySafePay) request.");
                          break;
                      case "SDK_CALL_URL_SUCCESS":
                          AlertUtils.showAlertWithMessage(MainActivity.this, "Open wallet app or redirect to the merchant page successfully.");
                          break;
                      case "SDK_LAUNCH_PAYMENT_APP_ERROR":
                          AlertUtils.showAlertWithMessage(MainActivity.this, "Open wallet app or redirect to the merchant page failed");
                          break;
                      case "SDK_CREATEPAYMENT_PARAMETER_ERROR":
                          AlertUtils.showAlertWithMessage(MainActivity.this, "The input parameter provided is invalid. Please check the value and try again.");
                          break;
                      default:
                          AlertUtils.showAlertWithMessage(MainActivity.this, "eventCode=" + eventCode + " message=" + eventResult.getMessage());
                          break;
                  }
              }

          }
      });

3. Free SDK component resources

Call the
onDestroy
method to free SDK component resources in the following situations:
In the following scenario, you do not need to call
onDestroy
, and the SDK will automatically free partial resources (for SDK 1.33.0 or above).
  • When the buyer initiates multiple payments, and the parameters in
    AMSEasyPayConfiguration
    have not changed. The SDK will automatically free partial resources after the payment is completed to reset to the state before
    createComponent
    was called.
The following sample code shows how to free components:
// Completely free SDK component resources
checkout.onDestroy();
Common questions
Q: Is it mandatory to handle SDK callback events?
A: For Alipay, you must process event codes to display payment results, but this payment method is optional. Callback events can also be used for logging.
​
Q: Can an AMSEasypay instance execute createComponent multiple times?
A: No. You need to create a fresh
AMSEasypay instance to initiate a new payment.
​
Q: Are SDK calls required for both first-time and subsequent payments?
A: Yes.
WebView

User experience

The following screenshots show the user experience of wallet and bank transfer respectively:
Digital wallet
In the digital wallet payment scenario, the system will guide the buyer to complete the transaction on the merchant's page or within the payment method app after the buyer confirms the payment. The first payment verification and subsequent simplified payment process are illustrated as follows:
First payment
The first payment requires security authentication. Once authorized, the buyer will be enabled for password-free payments on subsequent transactions.
Pay on the merchant page
Mobile user experience showing the digital wallet first payment flow where buyers complete security authentication to enable password-free payments for subsequent transactions on the merchant page
Pay on the payment method app
Mobile user experience showing the digital wallet first payment flow where buyers complete security authentication to enable password-free payments for subsequent transactions on the payment method app
Subsequent payments
Subsequent payments are processed without requiring a password upon order submission.
Mobile user experience showing digital wallet subsequent payment processed automatically without password upon order submission
Online banking
Below is the user experience for first and subsequent payments using online banking payment methods.
First payment
For the first payment, the buyer completes the payment authorization process to enable subsequent password-free payments.
Mobile user experience showing the online banking first payment authorization process where the buyer completes authentication to enable subsequent password-free payments
Subsequent payments
Subsequent payments are processed without requiring a password upon order submission.
Mobile user experience showing the online banking subsequent payment automatically processed without password upon order submission

Payment flow

The following are flow chart for the first payment and subsequent payment:
First payment
Sequence diagram illustrating the EasySafePay first payment flow among Buyer, Merchant Client, Merchant Server, and Antom: the buyer enters the checkout page, the merchant creates a payment session via the createPaymentSession API, the client SDK renders the payment interface and manages redirections, the buyer completes authorization, and the merchant receives asynchronous notifyAuthorization and notifyPayment notifications or queries payment status through the inquiryPayment API
  1. The buyer enters the checkout page.
  2. Preload the Antom SDK when the buyer chooses a payment method.
  3. Create a payment session request.
    After the buyer submits the order, you can obtain the payment session by calling the
    createPaymentSession (EasySafePay) API.
  4. Invoke the client SDK.
    Invoke the SDK using a payment session on the client side and the SDK will automatically collect payment elements, Display the payment page, handle page redirections, and guide buyers through payment completion based on the specific payment method's characteristics.
  5. Obtain the authorization result.
    When the authorization is successful, Antom sends you the asynchronous notification through the
    notifyAuthorization API.
  6. Obtain the payment result.
    Obtain the payment result using one of the following methods:
    • Asynchronous notification: Specify paymentNotifyUrl in the createPaymentSession (EasySafePay) API to set the address for receiving asynchronous notifications. When the payment is successful or expires, Antom will use notifyPayment to send asynchronous notifications to you.
    • Synchronous inquiry: Call the inquiryPayment API to check the real-time payment status.
Subsequent payments
Sequence diagram illustrating the EasySafePay subsequent payment flow among Buyer, Merchant Client, Merchant Server, and Antom: the buyer enters the checkout page, the merchant creates a payment session using the previously authorized paymentMethodId via the createPaymentSession API, the client SDK renders the payment interface, the buyer submits the order, and the merchant receives an asynchronous notifyPayment notification or uses the inquiryPayment API to check payment status
  1. The buyer enters the checkout page.
  2. Preload the Antom SDK when the buyer chooses a payment method.
  3. Create a payment session request.
    After the buyer submits the order, you can obtain the payment session by calling the
    createPaymentSession (EasySafePay) API.
  4. Invoke the client SDK.
    Invoke the SDK using a payment session on the client side and the SDK will automatically collect payment elements, Display the payment page, handle page redirections, and guide buyers through payment completion based on the specific payment method's characteristics.
  5. Obtain the payment result.
    Obtain the payment result using one of the following methods:
    • Asynchronous notification: Specify paymentNotifyUrl in the createPaymentSession (EasySafePay) API to set the address for receiving asynchronous notifications. When the payment is successful or expires, Antom will use notifyPayment to send asynchronous notifications to you.
    • Synchronous inquiry: Call the inquiryPayment API to check the real-time payment status.

Integration preparations

Before you start integrating, read the Integration Guide and API Overview documents to understand the integration steps of the server-side API and the precautions for calling the API. Furthermore, ensure that the following prerequisites are met:
  • Obtain a client ID
  • Complete the key configuration
  • Complete the configuration of paymentNotifyUrl to receive the asynchronous notification
  • Integrate the server-side SDK package, install the server-side library, and initialize a request instance. For more details, refer to Server-side SDKs.
  • If you need to conduct joint debugging by connecting the sandbox with the production environment, please contact Antom technical support at least two business days in advance to request configuration. The sandbox environment and production environment require separate configuration.
Version Requirements
  • iOS:
    • Install Xcode 12 or later.
    • Compatible with iOS 11 or later.
  • Android:
    • Compatible with Android 4.4 (API level 19) or later.
Note: Flutter and React Native (RN) development frameworks are not currently supported.
Refer to Integrate the SDK package for Web/WAP to complete integration preparations.

Integration steps

Start your integration by taking the following steps:
  1. (Optional) Preload the SDK
  2. Create a payment session
  3. Invoke the SDK
  4. Obtain the authorization and payment result

(Optional) Step 1: Preload the SDK
Client-side

Preloading the SDK during the checkout page initialization significantly improves the rendering performance with no negative impact. It is recommended to trigger preloading of the SDK when the buyer selects a payment method.
Follow the code example below to perform the preloading:
AMSEasypay.preload();

Step 2: Create a payment session
Server-side

Call the createPaymentSession (EasySafePay) API to create a payment session and initialize the Antom SDK using the paymentSessionData value returned in the response.
The table below lists the parameter specifications for calling the createPaymentSession (EasySafePay) API during the first and subsequent payments:
Note: For subsequent payments with Express Bank Transfer, simply keep the parameters consistent with the first payment. The buyer can open the Express Bank Transfer webpage and enter the phone number to proceed directly with the payment.
Parameter type
Parameter name
Required
(First-time payment)
Required
(Subsequent payments)
Description
Base parameter
productCode
Yes
Yes
The value is fixed as
AGREEMENT_PAYMENT
in the EasySafePay scenario.
productScene
Yes
Yes
The value is fixed as
EASY_PAY
in the EasySafePay scenario.
paymentRequestId
Yes
Yes
The unique ID assigned by a merchant to identify a payment request.
paymentMethod.paymentMethodType
Yes
Yes
The payment method type that is included in payment method options.
paymentMethod.paymentMethodId
No
Yes
The unique ID that is used to identify a payment method. The value of this parameter is that of accessToken from the notifyAuthorization API.
settlementStrategy
No
No
The settlement strategy for the payment request. If the merchant agreement supports multiple settlement currencies, they must be specified in the API request.
paymentAmount.value
Yes
Yes
The value of the amount as a positive integer in the smallest currency unit.
For details about the smallest currency unit, see Smallest unit of the currency .
paymentAmount.currency
Yes
Yes
The transaction currency, which is a 3-letter currency code that follows the ISO 4217 standard.
paymentSessionExpiryTime
No
No
The specific date and time after which the payment session will expire. The default expiration time is 1 hour after the session creation. For example, if the session is created at 2023-7-27T12:00:01+08:30, the session expiration time is 2023-7-27T13:00:01+08:30.
paymentRedirectUrl
Yes
Yes
The merchant page URL that the user is redirected to after the payment is completed.
The page display according to the server-side result and should not default to a fixed payment success page.
  • If the payment is initiated from a Web or WAP platform, pass the WAP URL.
  • If the payment is initiated from an App, pass the scheme URL.
paymentNotifyUrl
No
No
The URL that is used to receive the payment result notification. it must be an HTTPS URL. This field can be omitted if already configured via Antom Dashboard.
Authorization parameter
agreementInfo.authState
Yes
No
The unique ID generated by the merchant to initiate an EasySafePay authorization.

Order parameter



order.orderAmount
Yes
Yes
The order amount of the merchant that directly provides services or goods to the customer
order.referenceOrderId
Yes
Yes
The unique ID to identify the order on the merchant side.
order.orderDescription
Yes
Yes
Summary description of the order.
order.buyer.referenceBuyerId
No
No
Submit buyer information for risk assessment. Provide at least one of these fields: referenceBuyerId, buyerPhoneNo, or buyerEmail.

order.buyer.
    • buyerPhoneNo
    • buyerEmail
No
No
Buyer's account. Providing relevant payment account information can effectively improve the payment success rate and reduce the risk of buyer attrition. Please refer to the table below for specific format requirements.
The parameter format for the buyer's payment account for each payment method is as follows:
Payment method
Parameter format
It is recommended to prioritize using a mobile phone number:
  • Mobile number:
    • Hong Kong, China: 852-12****78. The phone number must be 8 digits long, excluding the prefix.
    • China: 86-137****5678. The phone number must be 11 digits long, excluding the prefix.
  • Email: xxx@xxx.com
62-8569****7288. The phone number starts with 8 and is no more than 12 digits long, excluding the prefix.
TrueMoney
The buyer is authenticated on the payment method side, and no parameters need to be passed in.userloginId.
Below are code examples for first and subsequent payments.
First payment
The following sample code shows how to call the createPaymentSession (EasySafePay) API:
@PostMapping("/payment/createSession")
public ResponseEntity<ApiResponse> createPaymentSession(@RequestBody PaymentVO payment) {
  AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
  alipayPaymentSessionRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);
  alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.EASY_PAY);

  // replace with your paymentRequestId
  String paymentRequestId = UUID.randomUUID().toString();
  alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);

  // convert amount unit (in practice, amount should be calculated on your serverside)
  // For details, please refer to: <a href="https://docs.antom.com/ac/ref/cc">Usage rules of the Amount object</a>
  long amountMinorLong = Money.of(CurrencyUnit.of(payment.currency), new BigDecimal(payment.amountValue)).getAmountMinorLong();

  // set amount
  Amount amount = Amount.builder().currency(payment.currency).value(String.valueOf(amountMinorLong)).build();
  alipayPaymentSessionRequest.setPaymentAmount(amount);

  // set settlement strategy
  // replace with your existing settlement currency
  SettlementStrategy settlementStrategy = SettlementStrategy.builder().settlementCurrency("USD").build();
  alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);

  User loginUser = users.get(payment.getUserId());

  // set paymentMethod
  PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType(payment.paymentMethodType).build();
  if(loginUser.getPaymentMethodTypeAccessToken().containsKey(payment.getPaymentMethodType())){
      // user has authorized
      String accessToken = loginUser.getPaymentMethodTypeAccessToken().get(payment.getPaymentMethodType());
      paymentMethod.setPaymentMethodId(accessToken);
  }else{
      // set agreementInfo
      // replace with your authState
      String authState = UUID.randomUUID().toString();
      // The login ID that the user used to register in the payment method client. The login ID can be the user's email address or phone number.
      // Specify this parameter to free users from manually entering their login IDs
      String userLoginId = loginUser.getPhoneNumber();
      AgreementInfo agreementInfo = AgreementInfo.builder().authState(authState).userLoginId(userLoginId).build();
      alipayPaymentSessionRequest.setAgreementInfo(agreementInfo);

      // save the paymentMethodType corresponding to the authState
      authStatePayment.put(authState, payment);
  }
  alipayPaymentSessionRequest.setPaymentMethod(paymentMethod);

  // set buyer info
  Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

  // replace with your orderId
  String orderId = UUID.randomUUID().toString();
  // set order info
  Order order = Order.builder().referenceOrderId(orderId).
  orderDescription("antom sdk testing order").orderAmount(amount).buyer(buyer).build();
  alipayPaymentSessionRequest.setOrder(order);

  // replace with your notify url
  // or configure your notify url here: <a href="https://dashboard.antom.com/global-payments/developers/iNotify">Notification URL</a>
  alipayPaymentSessionRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com/payment/receivePaymentNotify");

  // replace with your redirect url
  alipayPaymentSessionRequest.setPaymentRedirectUrl(
          "http://localhost:8080/index.html?paymentRequestId=" + paymentRequestId);

  AlipayPaymentSessionResponse alipayPaymentSessionResponse;
  try {
      long startTime = System.currentTimeMillis();
      System.out.println("payment request: " + JSON.toJSONString(alipayPaymentSessionRequest));
      alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
      System.out.println("payment response: " + JSON.toJSONString(alipayPaymentSessionResponse));
      System.out.println("payment request cost time: " + (System.currentTimeMillis() - startTime) + "ms
");
  } catch (AlipayApiException e) {
      return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), e));
  }
  return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), alipayPaymentSessionResponse));
}
The following code shows a sample of the request message:
{
"agreementInfo": {
  "authState": "authState001",
  "userLoginId": "userLoginId****"
},
"order": {
  "buyer": {
    "referenceBuyerId": "referenceBuyerId****"
  },
  "orderAmount": {
    "currency": "CNY",
    "value": "100"
  },
  "orderDescription": "orderDescription001",
  "referenceOrderId": "referenceOrderId****"
},
"paymentAmount": {
  "currency": "CNY",
  "value": "100"
},
"paymentMethod": {
  "paymentMethodType": "ALIPAY_CN"
},
"paymentNotifyUrl": "http://debug1688017773824.test.alipay.net:9090/amsdemo/record/notify?env=main_online&paymentMethodType=ALIPAY_CN",
"paymentRedirectUrl": "http://debug1688017773824.test.alipay.net:9090/amsdemo/result",
"paymentRequestId": "paymentRequestId****",
"productCode": "AGREEMENT_PAYMENT",
"productScene": "EASY_PAY",
"settlementStrategy": {
  "settlementCurrency": "USD"
}
}
The following code shows a sample of the response message, including the following key parameters:
  • paymentSessionData: Encrypted payment session data. This data is passed to the frontend for invoking the Antom SDK.
  • paymentSessionExpiryTime: Expiration time of the payment session.
{
"paymentSessionData": "paymentSessionData****",
"paymentSessionExpiryTime": "2023-04-06T03:28:49+08:00",
"paymentSessionId": "paymentSessionId****",
"result": {
  "resultCode": "SUCCESS",
  "resultMessage": "success.",
  "resultStatus": "S"
}
}
Please take the next step according to the value of the result.resultStatus.
resultStatus
Message
Further actions
S
The payment session is successfully created.
Return the obtained paymentSessionData to the merchant's frontend.
F
The payment session creation failed.
Check and verify whether the required request parameters (including the header parameters and body parameters) of the current API are correctly passed and valid.
U
The payment session creation failed due to unknown reasons.
Replace the paymentRequestId and authstate value, then retry the API call to resolve the issue. If the problem persists, contact Antom Technical Support.
Note: If you do not receive a response, it may be due to a network timeout. Please retry the API call with a new paymentRequestId and authstate value.
Subsequent payments
The following sample code shows how to call the createPaymentSession (EasySafePay) API:
public static void createPaymentSession() {
  AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
  alipayPaymentSessionRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);
  alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.EASY_PAY);

  // replace with your paymentRequestId
  String paymentRequestId = UUID.randomUUID().toString();
  alipayPaymentSessionRequest.setPaymentRequestId(paymentRequestId);

  // set amount
// you should convert amount unit (in practice, amount should be calculated on your server side)
  Amount amount = Amount.builder().currency("HKD").value("98080").build();
  alipayPaymentSessionRequest.setPaymentAmount(amount);

  // set settlement currency
  SettlementStrategy settlementStrategy = new SettlementStrategy();
  settlementStrategy.setSettlementCurrency("USD");
  alipayPaymentSessionRequest.setSettlementStrategy(settlementStrategy);

  // set paymentMethod
  PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("ALIPAY_HK")
  .paymentMethodId("28288803001319861727421828000Cv96OFlYoi17100****").build();
  alipayPaymentSessionRequest.setPaymentMethod(paymentMethod);

  // set buyer info
  Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

  // replace with your orderId
  String orderId = UUID.randomUUID().toString();
  // set order Info
  Order order = Order.builder().referenceOrderId(orderId).
  orderDescription("antom api testing order").orderAmount(amount).buyer(buyer).build();
  alipayPaymentSessionRequest.setOrder(order);

  // replace with your notify url
  alipayPaymentSessionRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com");

  // replace with your redirect url
  alipayPaymentSessionRequest.setPaymentRedirectUrl("http://www.yourRedirectUrl.com");

  AlipayPaymentSessionResponse alipayPaymentSessionResponse;
  try {
      alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
  } catch (AlipayApiException e) {
      String errorMsg = e.getMessage();
      // handle error condition
  }
}
The following code shows a sample of the request message:
{
"order": {
  "buyer": {
    "referenceBuyerId": "yourBuyerId"
  },
  "orderAmount": {
    "currency": "HKD",
    "value": "98080"
  },
  "orderDescription": "antom api testing order",
  "referenceOrderId": "5e445b58-49ad-4552-a36d-d38f311****"
},
"paymentAmount": {
  "currency": "HKD",
  "value": "98080"
},
"paymentMethod": {
  "paymentMethodId": "28288803001319861727421828000Cv96OFlYoi17100****",
  "paymentMethodType": "ALIPAY_HK"
},
"paymentNotifyUrl": "http://www.yourNotifyUrl.com",
"paymentRedirectUrl": "http://www.yourRedirectUrl.com",
"paymentRequestId": "5810a84e-3a3e-4e47-bbac-9dfe3f2d****",
"productCode": "AGREEMENT_PAYMENT",
"productScene": "EASY_PAY",
"settlementStrategy": {
  "settlementCurrency": "USD"
}
}
The following code shows a sample of the response message, including the following key parameters:
  • paymentSessionData: Encrypted payment session data. This data is passed to the frontend for invoking the Antom SDK.
  • paymentSessionExpiryTime: Expiration time of the payment session.
{
"paymentSessionData": "paymentSessionData****",
"paymentSessionExpiryTime": "2023-04-06T03:28:49+08:00",
"paymentSessionId": "paymentSessionId****",
"result": {
  "resultCode": "SUCCESS",
  "resultMessage": "success.",
  "resultStatus": "S"
}
}
Please take the next step according to the value of the result.resultStatus.
resultStatus
Message
Further actions
S
The payment session is successfully created.
Return the obtained paymentSessionData to the merchant's frontend.
F
The payment session creation failed.
Check and verify whether the required request parameters (including the header parameters and body parameters) of the current API are correctly passed and valid.
U
The payment session creation failed due to unknown reasons.
Replace the paymentRequestId value, then retry the API call to resolve the issue. If the problem persists, contact Antom Technical Support.
Note: If you do not receive a response, it may be due to a network timeout. Please retry the API call with a new paymentRequestId value.
Common questions
Q: Can I use Chinese characters in the value of the request parameters?
A: To avoid incompatibility of a certain payment method, do not use Chinese characters for parameters in the request.
​
Q: How to set the URL to receive the payment notification?
A: Specify paymentNotifyUrl in the createPaymentSession (EasySafePay) API to receive the asynchronous notification about the payment result (notifyPayment), or configure the receiving URL in Antom Dashboard. If the URL is specified in both the request and Antom Dashboard, the value specified in the request takes precedence.
​
Q: What is the difference between paymentAmount and orderAmount?
A:
paymentAmount refers to the payment amount, while orderAmount refers to the order amount. The actual charged amount is determined by paymentAmount.
​
Q: What does paymentSessionExpiryTime specifically refer to in payment requests?
A:
paymentSessionExpiryTime indicates the validity period from successful payment session creation until the buyer submits the payment. After submission, the payment processing timeout is 10 minutes. Therefore, the maximum total duration from session creation to payment completion is 1 hour and 10 minutes.

Step 3: Invoke the SDK
Server-side

After obtaining the paymentSessionData value on the merchant server side, the merchant client can invoke the SDK to redirect the checkout page to the payment method authorization page. When the buyer submits a payment request, the SDK will automatically handle encrypted communication, risk control verification, page redirection, and payment instruction execution, enabling an end-to-end payment authorization process.

1. Instantiate the SDK

  1. Use
    AMSEasyPay
    to create the SDK instance. The configuration object includes the following parameters:
Parameter name
Required
Description
environment
Yes
Used to specify the environment information. Valid values are:
  • sandbox
    : Sandbox environment.
  • prod
    : Production environment.
locale
No
Used to specify the language information. Select the appropriate value based on the region of the payment method. Valid values for this parameter are listed as follows.If a value not in the following list is used, the English is used instead.
  • en_US
    : English
  • in_ID
    : Indonesian
  • ms_MY
    : Malay
  • tl_PH
    : Filipino
  • ko_KR
    : Korean
  • zh_CN
    : Simplified Chinese
  • zh_HK
    : Traditional Chinese
onEventCallback
No
A callback function used to listen for payment events on the checkout page, returning eventCode and eventResult.
During the payment process, set isNativeAppWebview to
true
and additionally monitor the following events:
  • SDK_REDIRECT
    : Triggered when redirecting to a third-party payment page. eventResult.redirectUrls contains the redirection information.
After payment completion:
  • When notRedirectAfterComplete is
    true
    and payment is completed within the SDK, the payment result triggers a callback. Returns
    SDK_PAYMENT_SUCCESSFUL
    for successful payments and
    SDK_PAYMENT_FAIL
    for failed payments. If redirected to a payment method's page, no event code will be returned.
  • When notRedirectAfterComplete is
    false
    , the payment result does not trigger a callback but directly loads your specified result page (the paymentRedirectUrl specified in pay (Checkout Payment) API).
Note: Event codes should only be used for handling frontend navigation. Payment results must be determined based on the server-side payment status.
The following sample code shows how to instantiate the SDK using npm or CDN:
npm
import { AMSEasyPay } from '@alipay/ams-checkout' // manage the package

const checkoutApp = new AMSEasyPay({
environment: "sandbox",
locale: "en_US",
onEventCallback: ({code, message})=>{},
});
CDN
const checkoutApp = new window.AMSEasyPay({
environment: "sandbox",
locale: "en_US",
onEventCallback: ({code, message})=>{},
});
  1. Use
    createComponent
    in the instance object to create a payment component. The parameters involved are as follows:
Parameter name
Required
Description
sessionData
Yes
Create a configuration object using the sessionData parameter: Use the complete data of the value of paymentSessionData obtained in the response of the createPaymentSession (EasySafePay) API as the value of this parameter.
isNativeAppWebview
No
Indicates whether it is an in-app webview. Valid values are:
  • true
    : The merchant integrates the web SDK within an in-app webview.
  • false
    : The merchant integrates the web SDK via an H5 webpage.
notRedirectAfterComplete
No
Boolean type. Valid values are:
  • false
    : Default value. The system will automatically redirect to the merchant's page upon payment completion. The same applies when the value is empty.
  • true
    : The system will not automatically redirect to the merchant's page after payment completion.
    • If the payment is completed within the SDK, the subsequent flow will be monitored through client-side event codes.
    • If the payment is completed by redirecting to the payment method app, the process relies on that payment method's callback capability.
Note:
  • This parameter applies only to scenarios where the payment is completed within the SDK.
  • The event codes returned by the client-side are only used as a reference for the redirection operation of the client page. For transaction status updates, refer to the results returned by the server's notifyPayment or inquirePayment API.
The following sample code shows how to create the component:
async function create(sessionData) {
await checkoutApp.createComponent({ 
  sessionData: sessionData, 
  isNativeAppWebview: true, // Set as false by default to indicate that the merchant integrates the web SDK via an H5 webpage.
  notRedirectAfterComplete: false // Set as false by default to indicate that it will redirect to your page after the payment is completed.
});
}
  1. Listen for event code to handle redirection events.
By monitoring the
SDK_REDIRECT
event code, you can handle the subsequent process. An example code snippet is shown below:
import { AMSEasyPay } from '@alipay/ams-checkout' // Package management

const checkoutApp = new AMSEasyPay({
environment: "sandbox",
locale: "en_US",
onEventCallback: ({code, message, result}) => {
  switch (code) {
    case 'SDK_REDIRECT':
      // Handle redirect logic
      const redirectUrls = result?.redirectUrls || {};
      const jsonString = JSON.stringify(redirectUrls);

      // Check if the current environment's espJSBridge is available
      if (window.espJSBridge) {
          // Call the sdkRedirect method of espJSBridge, passing the redirect information.
          // This approach is for reference; merchants can also use their own native communication methods for data transfer.
          window.espJSBridge.sdkRedirect(jsonString)

          // After data transfer is complete, perform component cleanup
          checkoutApp.unmount();
      }
      
      break;
    default:
      console.log(code);
  }
},
});
  1. Handle redirection events using a WebView container.
Use a WebView container to manage in-app redirection events. The following are sample codes for iOS and Android respectively:
iOS
// Step 1: Create webview container
let url = "https://www.merchantWeb.com"
let webView = WKWebView()
webView.load(URLRequest(url: url))
webView.configuration.userContentController.addUserScript(
  WKUserScript(
      source: "window.espJSBridge = { sdkRedirect: function(message) { window.webkit.messageHandlers.espJSBridge.postMessage(message); } }",
      injectionTime: .atDocumentStart,
      forMainFrameOnly: true
  )
)
webView.configuration.userContentController.add(self, name: "espJSBridge")

// Step 2: Handle redirect event
extension DemoViewController: WKScriptMessageHandler {
  func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
      // Monitor redirect event
      if message.name == "espJSBridge", 
          let bodyString = message.body as? String, 
          let bodyData = bodyString.data(using: .utf8), 
          let body = try? JSONSerialization.jsonObject(with: bodyData, options: []) as? [String: Any] 
      {
          let applinkUrl = body["applinkUrl"] as? String
          let schemeUrl = body["schemeUrl"] as? String
          let normalUrl = body["normalUrl"] as? String
  
          // Redirect to link
          // Attempt to redirect to applinkUrl
          tryRedirect(url: applinkUrl) { [weak self] success in
            // If failed, attempt to redirect to schemeUrl
            if !success {
                  self?.tryRedirect(url: schemeUrl) { [weak self] success in
                      // If failed, attempt to redirect to normalUrl
                      if !success {
                          self?.tryRedirect(url: normalUrl) { _ in }
                      }
                  }
              }
          }
      }
  }
}

func tryRedirect(url: String?, completion: @escaping (Bool) -> Void) {
  guard let url = url, let url = URL(string: url) else {
      completion(false)
      return
  }
  UIApplication.shared.open(url) { success in
      completion(success)
  }
}
Android
// Step 1: Create webview container
WebView webView;
webView = findViewById(R.id.webView);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true); 
webView.addJavascriptInterface(new JSBridgeInterface(this), "espJSBridge");
webView.loadUrl(url);

// Step 2: Handle redirect event
public class JSBridgeInterface {
  private Context mContext;

  public JSBridgeInterface(Context context) {
      mContext = context;
  }

  // Monitor redirect event
  @JavascriptInterface
  public void sdkRedirect(String redirectInfo) {
      JSONObject jsonObject = JSONObject.parseObject(redirectInfo);
      String schemeUrl = jsonObject.getString("schemeUrl");
      String applinkUrl = jsonObject.getString("applinkUrl");
      String normalUrl = jsonObject.getString("normalUrl");

      // Attempt to redirect to schemeUrl
      if (openRedirectionUrl(schemeUrl, true)) {
          return;
      }

      // Attempt to redirect to applinkUrl
      if (openRedirectionUrl(applinkUrl, false)) {
          return;
      }

      // Attempt to redirect to normalUrl
      if (openRedirectionUrl(normalUrl, false)) {
          return;
      }

      showToast(mContext, "Failed to open URL");
  }

  private boolean openRedirectionUrl(String url, boolean isScheme) {
      if (TextUtils.isEmpty(url)) {
          return false;
      }
      try {
          Intent intent = isScheme ? Intent.parseUri(url, Intent.URI_INTENT_SCHEME) : new Intent(Intent.ACTION_VIEW, Uri.parse(url));
          startActivity(mContext, intent, null);
          return true;
      } catch (Exception exception) {
          showToast(mContext, exception.getMessage()); // Display prompt message
          return false;
      }
  }

  private void showToast(Context context, String message) {
      Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
  }
}

2. Handle SDK callback event codes

Below are the event codes returned by
onEventCallback
and handling recommendations:
Code
Description
Further action
SDK_REDIRECT
Triggered when redirection to a third-party payment page (such as Alipay, digital wallet applications, etc.) is required. The eventResult.redirectUrls object returned by this event contains redirect URLs for different environments.
Obtaining redirect URLs from redirectUrls:
  • iOS: Prioritize using applinkUrl, followed by schemeUrl, and finally normalUrl.
  • Android: Prioritize using schemeUrl, followed by applinkUrl, and finally normalUrl.
SDK_CALL_URL_SUCCESS
Successfully launched the payment method app or redirected to the merchant page.
No further action is needed.
SDK_LAUNCH_PAYMENT_APP_ERROR
This event code indicates one of the following situations:
  • Failed to invoke the app of the buyer's selected payment method or failed to redirect to the checkout page of the payment method.
  • Failed to redirect to the merchant page.
Check whether the paymentRedirectUrl parameter is correctly passed when calling the createPaymentSession (EasySafePay) API.
Web/WAP scenarios rarely experience redirection exceptions. However, in the event of any exceptions, it is recommended to verify the redirection link. For mobile app scenarios, if frequent redirection exceptions occur, contact Antom Technical Support to troubleshoot redirection or cross-application calling issues.
SDK_PAYMENT_CANCEL
The buyer canceled the payment (the buyer exited the payment page without submitting the order).
You can re-invoke the SDK using paymentSessionData within its validity period; If it has expired, you need to initiate a new createPaymentSession (EasySafePay) request.
SDK_PAYMENT_SUCCESSFUL
Indicates that the payment is successful on the wallet side.
Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result. Suggest redirecting buyers to the payment result page.
Note: This event code is returned only when the payment process is completed within the SDK.
SDK_PAYMENT_FAIL
Indicates that the payment is unsuccessful on the wallet side.
Please obtain the final payment result from Antom server. You can use the inquiryPayment API or the notifyPayment API to confirm the result. Suggest redirecting buyers to the payment result page.
Note: This event code is returned only when the payment process is completed within the SDK.
The following sample code shows how to handle the callback function:
function onEventCallback({ code, result }) {
switch (code) {
  case 'SDK_REDIRECT':
    // Handle redirect logic
    break;
  case 'SDK_PAYMENT_CANCEL':
    // Within the validity period, paymentSessionData can be used to reinvoke the SDK
    break;
  default:
    break;
}
}

3. Free SDK component resources

Call the
unmount
method to free SDK component resources in the following situations:
  • When the buyer switches views to exit the checkout page, free the component resources created in the createPaymentSession (EasySafePay) API.
  • When the buyer initiates multiple payments, free the component resources created in the previous createPaymentSession (EasySafePay) API.
  • After obtaining the final payment result, free the component resources.
The following sample code shows how to free components:
// Free SDK component resources
checkoutApp.unmount();
Common questions
Q: Is it mandatory to handle SDK callback events?
A: Perform the following operations based on the value of
isNativeAppWebview:
  • When isNativeAppWebview is
    true
    , you need to handle SDK callback events. They are generally categorized into two types:
    • Key callbacks (e.g., payment redirect
      SDK_REDIRECT
      ): Must be handled, otherwise the payment process will be interrupted.
    • Other callbacks: Optional handling. You may use these callback events for logging or tracking purposes.
  • When
    isNativeAppWebview
    is
    false
    , callback handling is optional. You may use the callback events for logging or tracking purposes.
​
Q: Can an AMSEasyPay instance execute createComponent multiple times?
A: No. If you need to initiate a new payment, you need to create a new
AMSEasyPay instance.
​
Q: Are SDK calls required for both first and subsequent payments?
A: Yes.

Step 4: Obtain authorization and payment result
Client-side

For the first payment, you can obtain both the authorization and payment results, while for subsequent payments, only the payment result is available. Below are common scenarios:
Type
Common scenarios
Received asynchronous notification
Suggestions
First payment
The buyer successfully authorized and paid.
Authorization succeeded, payment succeeded.
  • If a payment asynchronous notification is received, advance to the corresponding status.
  • If an authorization success asynchronous notification is received, maintain the buyer-token mapping relationship on the merchant side.
  • If no notification is received by the merchant order closure time, you can call the cancel API to close the order.
The buyer authorized successfully but payment failed (e.g., due to insufficient balance).
Authorization succeeded, payment failed.
The buyer authorization failed (or did not authorize) but payment succeeded.
No authorization asynchronous notification received, payment succeeded.
The buyer authorization failed (or did not authorize) and payment failed (e.g., due to insufficient balance).
No authorization asynchronous notification received, payment failed.
The buyer authorization failed (or did not authorize) and did not submit payment.
No asynchronous notifications received for both authorization and payment.
Subsequent payments
The buyer successfully paid.
Payment succeeded.
  • If a payment asynchronous notification is received, advance to the corresponding status.
  • If no notification is received by the merchant order closure time, you can call the cancel API to close the order.
The buyer payment failed (e.g., due to insufficient balance).
Payment failed.
Obtain the authorization result

Obtain the authorization result

When the authorization is successful during the first payment, Antom sends you the asynchronous notification through the notifyAuthorization API.
  1. Follow the steps below to set the notification webhook URL:
Log in to Antom Dashboard > Developer > Notification URL. Add the notification URL to alipay.ams.authorizations.notify. Refer to Notification URL for detailed steps.
The following code shows a sample of the asynchronous authorization notification request:
{
  "accessToken": "28288803001319861727421828000Cv96OFlYoi17100****",
  "accessTokenExpiryTime": 2145916817000,
  "authState": "36a38e87-0453-495e-ad17-b46553b918da",
  "authorizationNotifyType": "TOKEN_CREATED",
  "userLoginId": "852-91****67",
  "result": {
      "resultCode": "SUCCESS",
      "resultMessage": "success.",
      "resultStatus": "S"
  }
}
Based on the value of result.resultStatus in the authorization result notification request (only
S
is returned), process as follows:
S
: Indicates successful authorization, and the following parameters are returned:
Parameter name
Description
accessToken
The access token that is used to access the corresponding scope of the user resource.
accessTokenExpiryTime
The validity period of the accessToken.
For the specific expiry time, refer to The table of validity period of accessToken. If the accessToken expires, you need to guide the buyer to authorize again.
authState
A unique ID assigned for initiating authorization. This value is used to verify consistency with the authState specified in the createPaymentSession (EasySafePay) request.
authorizationNotifyType
Only
TOKEN_CREATED
will be returned, indicating that the buyer successfully initiated a payment authorization on the merchant's client.
userLoginId
The login ID used by the buyer when registering the payment method. This field has been desensitized. You may store this account for display in subsequent payments.
Note: Not all payment methods return this information.
The table below shows the token validity period for each payment method:
Payment method
Validity period of accessToken
92 years
100 years
100 years
100 years
100 years
TrueMoney
100 years
No accesstoken is returned. The merchant side does not need to maintain an accessToken.
  1. The result notification sent by Antom is signed by Antom, it is recommended that you verify the signature to confirm that the notification was sent by Antom. Refer to the following code example to verify the notification:
@PostMapping("/receiveAuthNotify")
@ResponseBody
public Result receiveAuthNotify(HttpServletRequest request, @RequestBody String notifyBody) {
  // retrieve the required parameters from http request
  String requestUri = request.getRequestURI();
  String requestMethod = request.getMethod();

  // retrieve the required parameters from request header
  String requestTime = request.getHeader("request-time");
  String clientId = request.getHeader("client-id");
  String signature = request.getHeader("signature");

  try {
      // verify the signature of notification
      boolean verifyResult = WebhookTool.checkSignature(requestUri, requestMethod, clientId,
              requestTime, signature, notifyBody, ANTOM_PUBLIC_KEY);
      if (!verifyResult) {
          throw new RuntimeException("Invalid notify signature");
      }

      // deserialize the notification body
      AlipayAuthNotify authNotify = JSON.parseObject(notifyBody,AlipayAuthNotify.class);

      if (authNotify != null && "SUCCESS".equals(authNotify.getResult().getResultCode())
               && "TOKEN_CREATED".equals(authNotify.getAuthorizationNotifyType())) {
          // save buyer's PaymentMethodType corresponding to accessToken
          PaymentVO payment = authStatePayment.get(authNotify.getAuthState());
          User user = users.get(payment.getUserId());
          user.getPaymentMethodTypeAccessToken().put(payment.getPaymentMethodType(), authNotify.getAccessToken());
          return Result.builder().resultCode("SUCCESS").resultMessage("success.").resultStatus(ResultStatusType.S).build();
      }
      // other types of notifications
  } catch (Exception e) {
      return Result.builder().resultCode("FAIL").resultMessage("fail.").resultStatus(ResultStatusType.F).build();
  }

  return Result.builder().resultCode("SYSTEM_ERROR").resultMessage("system error.").resultStatus(ResultStatusType.F).build();
}
  1. After receiving the notification, whether the authorization is successful or not, you are not required to sign the response, but each notification request must be responded to in the format specified below. Otherwise, Antom will resend the asynchronous notification.
{
"result": {
  "resultCode": "SUCCESS",
  "resultStatus": "S",
  "resultMessage": "success"
}
}
Obtain the payment result

Obtain the payment result

After the first or subsequent payment is completed, you can obtain the payment result through one of the following methods:
  • Receive the asynchronous notification: Receive the payment result delivered by the Antom server.
  • Inquire about the result: Call inquiryPayment API to query payment status.
Receive the asynchronous notification
  1. Follow the steps below to set the notification webhook URL:
When the payment reaches a final status of success or failure, Antom sends an asynchronous notification to your configured webhook URL. You can choose one of the following two methods to set up the Webhook URL for receiving notifications:
  • Order-level notification configuration: Specify an independent notification URL for each order through the paymentNotifyUrl parameter in the createPaymentSession (EasySafePay) API request.
  • Merchant-level notification configuration: Log in to Antom Dashboard > Developer > Notification URL and add a notification URL for the alipay.ams.payments.payNotify API. For specific operations, refer to Notification URL.
Note: If you have configured notification URLs through both methods mentioned above, the API settings will take precedence.
The following code shows a sample of the notification request:
{
  "actualPaymentAmount": {
      "currency": "HKD",
      "value": "98080"
  },
  "customsDeclarationAmount": {},
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
      "currency": "HKD",
      "value": "98080"
  },
  "paymentCreateTime": "2024-09-27T00:23:36-07:00",
  "paymentId": "202409271940108001001881E0211235544",
  "paymentRequestId": "bc93d19e-e1f6-4b68-b6b1-3d6ddc2a792a",
  "paymentTime": "2024-09-27T00:23:46-07:00",
  "pspCustomerInfo": {
      "pspCustomerId": "20881221121****",
      "pspName": "ALIPAY_HK"
  },
  "result": {
      "resultCode": "SUCCESS",
      "resultMessage": "success.",
      "resultStatus": "S"
  }
}
The table below displays the possible values returned in the resultStatus parameter of the response. Please follow the corresponding instructions for handling:
result.resultStatus
Message
Suggestion
S
Payment was successful.
The following fields can be obtained from:
  • paymentrequestld: Payment request ID for inquiry, cancellation, and reconciliation.
  • paymentld: Represents the payment order ID generated by Antom for refund and reconciliation.
  • paymentAmount: Indicates the currency and amount of payment.
F
Payment failed.
It is recommended to guide the buyer to place the order again.
  1. The result notification sent by Antom is signed by Antom, it is recommended that you verify the signature to confirm that the notification was sent by Antom. Refer to the following code example to verify the notification:
/**
* receive notify
*
* @param request    request
* @param notifyBody notify body
* @return Result
*/
@PostMapping("/receiveNotify")
@ResponseBody
public Result receiveNotify(HttpServletRequest request, @RequestBody String notifyBody) {
  // retrieve the required parameters from http request
  String requestUri = request.getRequestURI();
  String requestMethod = request.getMethod();

  // retrieve the required parameters from request header
  String requestTime = request.getHeader("request-time");
  String clientId = request.getHeader("client-id");
  String signature = request.getHeader("signature");

  try {
      // verify the signature of notification
      boolean verifyResult = WebhookTool.checkSignature(requestUri, requestMethod, clientId,
                                                        requestTime, signature, notifyBody, ANTOM_PUBLIC_KEY);
      if (!verifyResult) {
          throw new RuntimeException("Invalid notify signature");
      }
      // deserialize the notification body
      JSONObject jsonObject = JSON.parseObject(notifyBody);
      String notifyType = (String)jsonObject.get("notifyType");
      if("PAYMENT_RESULT".equals(notifyType)){
          AlipayPayResultNotify paymentNotify = jsonObject.toJavaObject(AlipayPayResultNotify.class);
          if (paymentNotify != null && "SUCCESS".equals(paymentNotify.getResult().getResultCode())) {
              // handle your own business logic.
              // e.g. The relationship between payment information and buyers is kept in the database.
              System.out.println("receive payment notify: " + JSON.toJSONString(paymentNotify));
              return Result.builder().resultCode("SUCCESS").resultMessage("success.").resultStatus(ResultStatusType.S).build();
          }
      }
      // other types of notifications
  } catch (Exception e) {
      // handle error condition
      return Result.builder().resultCode("FAIL").resultMessage("fail.").resultStatus(ResultStatusType.F).build();
  }
  return Result.builder().resultCode("SYSTEM_ERROR").resultMessage("system error.").resultStatus(ResultStatusType.F).build();
}
  1. After receiving the notification, you are not required to sign the response, but must reply to every notification request in the following standardized format, regardless of whether the payment was successful or not.
{
"result": {
  "resultCode": "SUCCESS",
  "resultStatus": "S",
  "resultMessage": "success"
}
}
Inquire about the payment result
Call the inquiryPayment API to initiate a query on the payment result. The payment status can be checked via polling or scheduled tasks after the payment is initiated.
The following sample code shows how to call the inquiryPayment API:
public static void inquiryPayment() {
  AlipayPayQueryRequest alipayPayQueryRequest = new AlipayPayQueryRequest();

  // replace with your paymentRequestId
  alipayPayQueryRequest.setPaymentRequestId("yourPaymentRequestId");

  AlipayPayQueryResponse alipayPayQueryResponse = null;
  try {
      alipayPayQueryResponse = CLIENT.execute(alipayPayQueryRequest);
  } catch (AlipayApiException e) {
      String errorMsg = e.getMessage();
      // handle error condition
  }
}
The following code shows a sample of the request message:
{
"paymentRequestId": "bc93d19e-e1f6-4b68-b6b1-3d6ddc2a****"
}
The following code shows a sample of the response message:
{
"actualPaymentAmount": {
  "currency": "USD",
  "value": "1"
},
"customsDeclarationAmount": {
  "currency": "CNY",
  "value": "7"
},
"paymentAmount": {
  "currency": "USD",
  "value": "1"
},
"paymentId": "20250305194010800100188690281017336",
"paymentMethodType": "ALIPAY_CN",
"paymentRedirectUrl": "https://checkout.antom.com/checkout-page/pages/payment/index.html?sessionData=%2BCUim8L0KviXagaygm9xBL5jZ%2F75w6gAX1nn8pcuFuGkIsMoHtD6U88YSyMrMJvorbwnBg5uQv8e6pyvIpjDQQ%3D%3D%26%26SG%26%26188%26%26eyJleHRlbmRJbmZvIjoie1wiT1BFTl9NVUxUSV9QQVlNRU5UX0FCSUxJVFlcIjpcInRydWVcIixcImxvY2FsZVwiOlwiZW5fVVNcIixcImRpc3BsYXlBbnRvbUxvZ29cIjpcInRydWVcIn0iLCJwYXltZW50U2Vzc2lvbkNvbmZpZyI6eyJwYXltZW50TWV0aG9kQ2F0ZWdvcnlUeXBlIjoiQUxMIiwicHJvZHVjdFNjZW5lIjoiQ0hFQ0tPVVRfUEFZTUVOVCIsInByb2R1Y3RTY2VuZVZlcnNpb24iOiIxLjAifSwic2VjdXJpdHlDb25maWciOnsiYXBwSWQiOiIiLCJhcHBOYW1lIjoiT25lQWNjb3VudCIsImJpelRva2VuIjoiNlRjZGJyMnJGM3JQWXg0aGtWckhxYnZqIiwiZ2F0ZXdheSI6Imh0dHBzOi8vaW1ncy1zZWEuYWxpcGF5LmNvbS9tZ3cuaHRtIiwiaDVnYXRld2F5IjoiaHR0cHM6Ly9vcGVuLXNlYS1nbG9iYWwuYWxpcGF5LmNvbS9hcGkvb3Blbi9yaXNrX2NsaWVudCIsIndvcmtTcGFjZUlkIjoiIn0sInNraXBSZW5kZXJQYXltZW50TWV0aG9kIjpmYWxzZX0%3D",
"paymentRequestId": "PAYMENT_20250305220039086_AUTO",
"paymentResultCode": "SUCCESS",
"paymentResultMessage": "success.",
"paymentStatus": "SUCCESS",
"paymentTime": "2025-03-05T06:02:34-08:00",
"pspCustomerInfo": {
  "pspName": "ALIPAY_CN"
},
"result": {
  "resultCode": "SUCCESS",
  "resultMessage": "success.",
  "resultStatus": "S"
}
}
The table below displays the possible values returned in the paymentStatus parameter of the response. Please follow the corresponding instructions for handling:
paymentStatus​
Message
Further actions
SUCCESS
Payment was successful.
No further action is required.
FAIL
Payment failed.
Guide the buyer to place a new order.
PROCESSING
Payment is being processed.

CANCELLED
Payment is canceled.

Common questions
Q: When is the payment notification sent?
A: It depends on whether the payment is completed: If the payment is successfully completed, Antom usually sends an asynchronous notification within 3 to 5 seconds.
​
Q: Is there an asynchronous notification sent for authorization failure?
A: No. An asynchronous notification will only be sent if the authorization is successful; there will be no notification returned for authorization failure.
​
Q: Will the asynchronous notification be re-sent?
A: Yes, the asynchronous notification will be re-sent automatically within 24 hours for the following cases:
  • If you didn't receive the asynchronous notification due to network reasons.
  • If you receive an asynchronous notification from Antom, but you didn't make a response to the notification in the sample code format of Process the notification.
The notification can be resent up to 8 times or until a correct response is received to terminate delivery. The sending intervals are as follows: 0 minutes, 2 minutes, 10 minutes, 10 minutes, 1 hour, 2 hours, 6 hours, and 15 hours.
​
Q: Are the authorization notification and payment result notification sent separately, and will the authorization notification always be received before the payment result notification?
A: Due to the uncontrollable nature of network stability, it is possible for the authorization notification to arrive later than the payment result notification.
​
Q: Is authorization result inquiry supported?
A: Currently, calling an interface to query the authorization result is not supported.
​
Q: When responding to an asynchronous notification, do I need to add a digital signature?
A: No. If you receive an asynchronous notification from Antom, you are required to return the response in the sample code format of Process the notification, but you do not need to countersign the response.

After payments

Revoke authorization

After authorization is completed, the buyer can revoke the authorization from either the merchant side or the payment method side. Once revoked, the original authorization token immediately becomes invalid and cannot be used for payments again. For details, refer to Revoke.

Cancel

You can cancel orders through the cancel API within the time window (by D+1 day 00:15 GMT+8). For details, refer to Cancel.

Refund

Refer to Refund to learn about Antom refund rules and operation process.

Reconciliation

After a transaction is completed, use the provided Antom financial reports to perform reconciliation. For settlement rules and reconciliation operations, refer to Reconciliation.

Best practices

Antom provides you with the following best practice solutions. Refer to Best practices for more details.
  • Intelligent risk control service
  • Security expansion package
  • Order query after redirecting to the merchant result page
  • Merchant-initiated transaction cancellation
  • Payment failure retry