Antom, leading provider of tailored payment solutions

Accept payments with EasySafePay (API)

Antom EasySafePay is a streamlined payment solution designed for low-value, high-frequency payment scenarios. During the first payment, buyers can either bind their wallet or pay directly. For subsequent payments, they can complete the transaction with a single click, without entering a password.
Powered by an industry-leading intelligent risk control system, dynamic routing technology, and payment failure recovery strategies, this solution ensures transaction security while achieving top-tier payment success rates across the industry. It delivers benefits to buyers, merchants, and the broader platform ecosystem by enhancing the payment experience, improving merchant conversion rates, and increasing ecosystem value.
This article mainly introduces how to integrate the EasySafePay product via API.

User experience

The user experience for each payment method differs between PC and mobile devices. For the specific interaction flows, please refer to the table and user experience diagrams below.
Web
Payment method category
Payment method
Terminal type
First payment
Subsequent payments
Digital wallet
Web
Redirect to the payment method app to complete payment.
Complete the payment on the merchant page.
Online banking
Web
Redirect to the payment method app to complete payment.
Redirect to the payment method app to complete payment.
Below are the user experience diagrams for the two payment categories, digital wallet and online banking, on desktop browsers (Web).
Digital wallet
In the digital wallet scenario, the user experience diagrams for the first payment and subsequent payments are shown below.
First payment
During the first payment, the buyer needs to complete the payment authorization process to enable password-free payments for future transactions.
Subsequent payments
For subsequent payments, if buyer participation is required, the buyer only needs to submit the order to complete the password-free payment. If buyer participation is not required, you can directly initiate the payment request from the backend.
Online banking
The user experience diagram for the online banking scenario is shown below:
First payment
During the first payment, the buyer needs to complete the payment authorization process to enable password-free payments for future transactions.
Subsequent payments
For subsequent payments, if buyer participation is required, the buyer only needs to submit the order to complete the password-free payment. If buyer participation is not required, you can directly initiate the payment request from the backend.
WAP
Payment method category
Payment method
Terminal type
First payment
Subsequent payments
Digital wallet
​
WAP
Complete the payment on the merchant page.
Note: If the buyer turns off the Enable One-Click Payment option, they will be redirected to the payment method provider’s page to complete a one-time payment.
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.
Below are the user experience diagrams for the two payment categories, digital wallet and online banking, on mobile browsers (WAP).
Digital wallet
In the digital wallet scenario, the user experience diagrams for the first payment and subsequent payments are shown below.
First payment
During the first payment, the system guides the buyer to complete the transaction either on the merchant page or on the payment method side. After the buyer completes the authorization, subsequent payments can be made without entering a password.
Pay on the merchant page
Pay on the payment method app
Subsequent payments
For subsequent payments, if buyer participation is required, the buyer only needs to submit the order to complete the password-free payment. If buyer participation is not required, you can directly initiate the payment request from the backend.
Online banking
The user experience diagram for the online banking scenario is shown below:
First payment
During the first payment, the buyer must complete the payment authorization process to enable password-free payments for future transactions.
Subsequent payments
Subsequent payments can be completed without re-linking the account.
App
​Payment method category
Payment method
Terminal type
First payment
Subsequent payments
Digital wallet
​
App
Complete the payment on the merchant page.
Note: If the buyer turns off the Enable One-Click Payment option, they will be redirected to the payment method provider’s page to complete a one-time payment.
Complete the payment on the merchant page.
App
Redirect to the payment method app to complete payment.
Complete the payment on the merchant page.
Online banking
App
Complete the payment on the merchant page.
Complete the payment on the merchant page.
Below are the user experience diagrams for the two payment categories, digital wallet and online banking, on mobile devices (App).
Digital wallet
In the digital wallet scenario, the user experience diagrams for the first payment and subsequent payments are shown below.
First payment
During the first payment, the system will guide the buyer to complete the transaction either on the merchant page or on the payment method side. Once the buyer completes the authorization, subsequent payments can be made without a password.
Pay on the merchant page
Pay on the payment method app
Subsequent payments
For subsequent payments, if buyer participation is required, the buyer only needs to submit the order to complete the password-free payment. If buyer participation is not required, you can directly initiate the payment request from the backend.
Online banking
The user experience diagram for the online banking scenario is shown below:
First payment
During the first payment, the buyer needs to complete the payment authorization process to enable password-free payments for future transactions.
Subsequent payments
Subsequent payments can be completed without re-linking the account.

Payment flow

First payment
  1. The buyer enters the checkout page.
  2. The buyer selects a payment method and submits the payment request.
  3. Create a payment request.
    After the buyer selects a payment method and submits the order, the merchant server initiates the payment request by calling the
    pay (Tokenized Payment) API based on transaction information such as the payment method, amount, currency, and goods.
  4. Process the payment continuation link.
    The merchant client is redirected to the URL returned in the payment request, or launches the relevant application to complete the authorized payment.
  5. Obtain the authorization result.
    When the authorization is successful, Antom sends you an asynchronous notification via the
    notifyAuthorization API.
  6. Obtain the payment result.
    Obtain the payment result using one of the following methods:
    • Asynchronous notification: Specify paymentNotifyUrl in the pay (Tokenized Payment) API to set the address for receiving asynchronous notifications or configure the url for receiving asynchronous notifications in the Antom Dashboard. When the authorization is successful, Antom sends you an asynchronous notification via the notifyPayment API.
    • Synchronous inquiry: Call the inquiryPayment API to check the real-time payment status.
Subsequent payments
  1. The buyer enters the checkout page.
  2. The buyer selects a payment method and submits the payment request.
  3. Create a payment request.
    After obtaining the buyer’s authorization, you can directly call the
    pay (Tokenized Payment) API to initiate the payment.
  4. The buyer completes risk verification.
    If a transaction is identified as risky, the buyer must be redirected to a frontend page to complete verification. If the merchant initiates a subscription charge directly from the backend, no verification page will be displayed.
  1. Obtain the payment result.
    Obtain the payment result using one of the following methods:
    • Asynchronous notification: Specify paymentNotifyUrl in the pay (Tokenized Payment) API to set the address for receiving asynchronous notifications or configure the url for receiving asynchronous notifications in the Antom Dashboard. When the payment is successful or expires, Antom will use notifyPayment API 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 SDK.

Integration steps

Start your integration by taking the following steps:
  1. Create a payment request
  2. Obtain the payment continuation URL
  3. Obtain the authorization and payment result.

Step 1: Create a payment request

After the buyer clicks the payment button, call the pay (Tokenized Payment) API and pass in the order information.
The table below describes the API request parameters for the first payment and subsequent payments.
Note:
  • The integration flow for PayPay Smart Payment is different. For the specific steps, please refer to Accept payments with PayPay Smart Payment.
  • For Express Bank Transfer, the first payment and subsequent payments use the same request parameter format. The buyer only needs to enter their mobile phone number on the payment page to complete the payment.
Parameter type
Parameter name
Required
(First payment)
Required
(Subsequent payment with buyer involvement)
Required
(Subsequent payment with MIT)
Description
​
​
Basic parameter
productCode
Yes
Yes
Yes
The value is fixed as
AGREEMENT_PAYMENT
in the EasySafePay scenario.
paymentRequestId
Yes
Yes
Yes
The unique ID assigned by a merchant to identify a payment request.
paymentMethod.paymentMethodType
Yes
Yes
Yes
A payment method that supports authorization and agreement signing. Refer to Payment method enumeration values for valid values.
paymentMethod.paymentMethodId
N/A
Yes
Yes
Pass in the value of accessToken obtained from the notifyAuthorization API after the first payment.
paymentMethodMetadata.smartPaymentEnabled
No
No
This scenario is not supported.
For the PayPay wallet, this parameter must be specified as
true
.
paymentMethod.paymentMethodMetaData.recurringType
N/A
No
Yes
Specify this parameter when the payment is a merchant-initiated transaction (MIT). Valid values are:
  • SCHEDULED
    : Indicates a recurring automatic debit payment.
  • UNSCHEDULED
    : Indicates an unscheduled automatic debit payment.
If this parameter is empty or not specified, the payment is not an automatic debit, and the payer will participate in the payment process.
settlementStrategy
No
No
No
The settlement strategy for this payment. If your business has multiple settlement currencies configured, you must specify this parameter in the API. If your business has only one settlement currency configured, you do not need to specify it in the API.
paymentAmount.value
Yes
Yes
Yes
The amount value, expressed as a positive integer in the smallest unit of the currency.
paymentExpiryTime
No
No
No
The specific date and time when the payment expires. The default expiration time is 14 minutes.
paymentRedirectUrl
Yes
Yes
No
The merchant-side payment result page should display the result based on the server-side outcome and is not necessarily a success page.
paymentNotifyUrl
No
No
No
The asynchronous notification URL for the payment result. If it is configured on Antom Dashboard, this parameter does not need to be passed. It must be an HTTPS URL.
Environment parameter
​
order.env.terminalType
Yes
Yes
N/A
The terminal type applicable to the merchant service. Valid values include:
  • WEB
    : The client terminal type is a website accessed through a web browser.
  • WAP
    : The client terminal type is an HTML page opened through a mobile browser.
  • APP
    : The client terminal type is a mobile application.
order.env.osType
Yes
Yes
N/A
The operating system type. Valid values are:
  • IOS
    : Indicates that the operating system is Apple iOS.
  • ANDROID
    : Indicates that the operating system is Google Android.
Note: This parameter is required when terminalType is
APP
or
WAP
.
order.env.clientIp
Yes
Yes
N/A
The IP address of the client device.
order.env.deviceId
Yes
Yes
N/A
The unique ID of the device under the user's order.
Authorization parameter
agreementInfo.authState
Yes
N/A
N/A
The unique ID you assign to initiate authorization. This parameter is only passed on the first payment and does not need to be passed on subsequent payments.
Order parameter

​
​
​
​
order.orderAmount
Yes
Yes
Yes
Order amount.
order.referenceOrderId​
Yes
Yes
Yes
Merchant order number.
order.orderDescription​
Yes
Yes
Yes
Merchant order description.
order.buyer.referenceBuyerId
No
No
No
The buyer ID that identifies the buyer.
Note:
  • Specify this parameter when you have risk control requirements. Providing this information helps improve the accuracy of AML and fraud detection, thereby increasing the payment success rate.
  • Pass in either this parameter or buyerEmail or buyerPhoneNo.
order.buyer.buyerEmail
No
No
No
The buyer's email address.
Note:
  • Specify this parameter when you have risk control requirements. Providing this information helps improve the accuracy of AML and fraud detection, thereby increasing the payment success rate.
  • Pass in either this parameter or referenceBuyerId or buyerPhoneNo.
order.buyer.buyerPhoneNo
No
No
No
The buyer’s mobile phone number.
Note:
  • Specify this parameter when you have risk control requirements. Providing this information helps improve the accuracy of AML and fraud detection, thereby increasing the payment success rate.
  • Pass in either this parameter or referenceBuyerId or buyerEmail.
  • For AlipayHK and DANA, after this parameter is passed in, the authorization-and-payment page will be displayed. For the specific format, refer to the table below.
For AlipayHK and DANA, the supported buyerPhoneNo formats are as follows:
Payment method
order.buyer.buyerPhoneNo formats
  • Hong Kong, China: 852-12****78. Note that the total mobile number length must be 8 digits (excluding the 852- prefix).
  • Mainland China: 86-137****5678. Note that the total mobile number length must be 11 digits (excluding the 86- prefix).
62-8569****7288. The mobile number must start with 8 and must not exceed 12 digits in length (excluding the 62- prefix).
During the first payment, passing order.buyer.buyerPhoneNo can automatically prefill the buyer’s payment account on the payment page, eliminating the need for manual entry. Below is a comparison of the user experience with and without this parameter:
Payment method login account is provided
When the payment method account is provided, the buyer enters the authorization payment flow or chooses a one-time payment.
Authorize and pay
When the buyer enables the Enable One-Click Payment option during the first payment, password-free payments are enabled after completing authorization, making subsequent transactions faster and more convenient.
One-time payment
When the buyer disables the Enable One-Click Payment option, the buyer is redirected to the payment method provider’s page to complete a one-time payment.
Payment method login account not provided
If the payment method account is not provided, the page will guide the buyer to the payment method side to complete the authorization.
Below are code examples for first and subsequent payments.
First payment
The following sample code shows how to call the pay (Tokenized Payment) API:
First payment
@PostMapping("/v1/payments/pay")
public ResponseEntity<ApiResponse> pay(@RequestBody PaymentVO payment) {
  AmsPayRequest request = new AmsPayRequest();
  request.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);

  // Replace with your paymentRequestId
  String paymentRequestId = UUID.randomUUID().toString();
  request.setPaymentRequestId(paymentRequestId);

  // Convert the amount unit (in actual use, the amount should be calculated on the server side)
  // For details, refer to: https://docs.antom.com/ac/ref/cc
  long amountMinorLong = Money.of(CurrencyUnit.of(payment.currency),
          new BigDecimal(payment.amountValue)).getAmountMinorLong();

  // Set paymentAmount
  Amount paymentAmount = Amount.builder()
          .currency(payment.currency)
          .value(String.valueOf(amountMinorLong))
          .build();
  request.setPaymentAmount(paymentAmount);

  // Set settlementStrategy
  // Replace with your existing settlement currency
  SettlementStrategy settlementStrategy = SettlementStrategy.builder()
          .settlementCurrency("USD")
          .build();
  request.setSettlementStrategy(settlementStrategy);

  // Set paymentMethod
  PaymentMethod paymentMethod = PaymentMethod.builder()
          .paymentMethodType(payment.paymentMethodType)
          .build();

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

  if (loginUser.getPaymentMethodTypeAccessToken().containsKey(payment.getPaymentMethodType())) {
      // The buyer has already authorized, use the token for recurring payment
      String accessToken = loginUser.getPaymentMethodTypeAccessToken().get(payment.getPaymentMethodType());
      paymentMethod.setPaymentMethodId(accessToken);
  } else {
      // The buyer has not authorized yet, set agreementInfo to start the agreement-signing flow
      String authState = UUID.randomUUID().toString();
      AgreementInfo agreementInfo = AgreementInfo.builder()
              .authState(authState)
              .build();
      request.setAgreementInfo(agreementInfo);

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

  // Set env (environment information for risk control)
  Env env = Env.builder()
          .osType(payment.getOsType())
          .terminalType(payment.getTerminalType())
          .deviceId(payment.getDeviceId())
          .clientIp(payment.getClientIp())
          .deviceTokenId(payment.getDeviceTokenId())
          .build();
  request.setEnv(env);

  // Set goods (product details)
  List<Goods> goodsList = payment.getGoodsList().stream()
          .map(g -> Goods.builder()
                  .referenceGoodsId(g.getReferenceGoodsId())
                  .goodsName(g.getGoodsName())
                  .quantity(g.getQuantity())
                  .price(Amount.builder()
                          .currency(payment.currency)
                          .value(g.getPriceValue())
                          .build())
                  .build())
          .collect(Collectors.toList());

  // Set shipping (shipping information)
  Shipping shipping = Shipping.builder()
          .shippingName(ShippingName.builder()
                  .firstName(payment.getShippingFirstName())
                  .lastName(payment.getShippingLastName())
                  .build())
          .shippingAddress(ShippingAddress.builder()
                  .region(payment.getShippingRegion())
                  .state(payment.getShippingState())
                  .city(payment.getShippingCity())
                  .address1(payment.getShippingAddress1())
                  .address2(payment.getShippingAddress2())
                  .zipCode(payment.getShippingZipCode())
                  .build())
          .shippingCarrier(payment.getShippingCarrier())
          .shippingPhoneNo(payment.getShippingPhoneNo())
          .build();

  // Set buyer (buyer information)
  Buyer buyer = Buyer.builder()
          .referenceBuyerId(loginUser.getReferenceBuyerId())
          .buyerName(BuyerName.builder()
                  .firstName(loginUser.getFirstName())
                  .lastName(loginUser.getLastName())
                  .build())
          .buyerPhoneNo(loginUser.getPhoneNumber())
          .buyerEmail(loginUser.getEmail())
          .build();

  // Replace with your orderId
  String orderId = UUID.randomUUID().toString();

  // Set order (order information, including product details, shipping, and buyer)
  Amount orderAmount = Amount.builder()
          .currency(payment.currency)
          .value(String.valueOf(amountMinorLong))
          .build();
  Order order = Order.builder()
          .referenceOrderId(orderId)
          .orderDescription(payment.getOrderDescription())
          .orderAmount(orderAmount)
          .goods(goodsList)
          .shipping(shipping)
          .buyer(buyer)
          .build();
  request.setOrder(order);

  // Replace with your notification URL
  // Or configure your notification URL: https://dashboard.antom.com/global-payments/developers/iNotify
  request.setPaymentNotifyUrl("https://merchant.com/notify/payment-result");

  // Replace with your redirect URL
  request.setPaymentRedirectUrl(
          "https://merchant.com/payment/result?paymentRequestId=" + paymentRequestId);

  AmsPayResponse amsPayResponse;
  try {
      long startTime = System.currentTimeMillis();
      System.out.println("pay request: " + JSON.toJSONString(request));
      amsPayResponse = CLIENT.execute(request, AmsPayResponse.class);
      System.out.println("pay response: " + JSON.toJSONString(amsPayResponse));
      System.out.println("pay 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(), amsPayResponse));
}
The following code shows a sample of the request message:
{
"order": {
  "orderAmount": {
    "currency": "HKD",
    "value": 100
  },
  "referenceOrderId": "ORD_2024040512345",
  "orderDescription": "iPhone 15 Pro Monthly Subscription",
  "goods": [
    {
      "referenceGoodsId": "G_001",
      "goodsName": "iPhone 15 Pro",
      "quantity": 1,
      "price": {
        "currency": "HKD",
        "value": 100
      }
    }
  ],
  "shipping": {
    "shippingName": {
      "firstName": "John",
      "lastName": "Doe"
    },
    "shippingAddress": {
      "region": "US",
      "state": "CA",
      "city": "San Francisco",
      "address1": "123 Tech Street",
      "address2": "Apt 4B",
      "zipCode": "94107"
    },
    "shippingCarrier": "FedEx",
    "shippingPhoneNo": "+1-415-555-1234"
  },
  "buyer": {
    "referenceBuyerId": "BUYER_88118999",
    "buyerName": {
      "firstName": "John",
      "lastName": "Doe"
    },
    "buyerPhoneNo": "66622222",
    "buyerEmail": "john.doe@example.com"
  }
},
"env": {
  "osType": "IOS",
  "terminalType": "APP",
  "deviceId": "deviceIdxxxxxxx",
  "clientIp": "192.168.111.111",
  "deviceTokenId": "deviceTokenIdxxxxxxxx"
},
"paymentRequestId": "PAYMENT_20251110121228651_AUTO",
"paymentAmount": {
  "currency": "HKD",
  "value": 100
},
"settlementStrategy": {
  "settlementCurrency": "USD"
},
"paymentMethod": {
  "paymentMethodType": "ALIPAY_HK"
},
"paymentNotifyUrl": "https://merchant.com/notify/payment-result",
"paymentRedirectUrl": "https://kademo.intlalipay.cn/melitigo/Test_114.html",
"productCode": "AGREEMENT_PAYMENT",
"agreementInfo":{
  "authState":"sign_no_xxxxx111111x01001"
}
}
The following code shows a sample of the response message:
{
  "actualPaymentAmount": {
      "currency": "HKD",
      "value": "100"
  },
  "normalUrl": "https://checkout.antom.com/easysafepay/1.39.0/pages/api-portal/index.html?paymentMethodCategoryType=WALLET&sessionData=vxA9kkY8yysEoUhFyy%2BEvM17vV72yntAcqJGeMF1PETOU9fJtoSUls3s0vdS1YouYbWEl8gHHEaWPO0Xh%2FT%2BJg%3D%3D%26%26SG%26%26188&locale=en-US&productScene=EASY_PAY&productSceneVersion=2.0",
  "paymentActionForm": "{"method":"GET","paymentActionFormType":"RedirectActionForm","redirectUrl":"https://checkout.antom.com/easysafepay/1.39.0/pages/api-portal/index.html?paymentMethodCategoryType=WALLET&sessionData=vxA9kkY8yysEoUhFyy%2BEvM17vV72yntAcqJGeMF1PETOU9fJtoSUls3s0vdS1YouYbWEl8gHHEaWPO0Xh%2FT%2BJg%3D%3D%26%26SG%26%26188&locale=en-US&productScene=EASY_PAY&productSceneVersion=2.0"}",
  "paymentAmount": {
      "currency": "HKD",
      "value": "100"
  },
  "paymentCreateTime": "2025-11-10T00:35:03-08:00",
  "paymentId": "20251110194010900000188350227845338",
  "paymentRequestId": "PAYMENT_20251110163502455_AUTO",
  "redirectActionForm": {
      "method": "GET",
      "redirectUrl": "https://checkout.antom.com/easysafepay/1.39.0/pages/api-portal/index.html?paymentMethodCategoryType=WALLET&sessionData=vxA9kkY8yysEoUhFyy%2BEvM17vV72yntAcqJGeMF1PETOU9fJtoSUls3s0vdS1YouYbWEl8gHHEaWPO0Xh%2FT%2BJg%3D%3D%26%26SG%26%26188&locale=en-US&productScene=EASY_PAY&productSceneVersion=2.0"
  },
  "result": {
      "resultCode": "PAYMENT_IN_PROCESS",
      "resultMessage": "payment in process",
      "resultStatus": "U"
  }
}
Please take the next step according to the value of the result.resultStatus.
result.resultStatus
Message
Further actions
S
Indicates that the request was successful.
Obtain one or more payment continuation links from applinkUrl, normalUrl, or schemeUrl. For descriptions of the returned URLs, refer to How to properly use the payment continuation URL.
F
Indicates that the request failed.
Close the current transaction, or place the order again after replacing authState and paymentRequestId.
U
Indicates that the request failed for an unknown reason.
  • If the returned result code is
    PAYMENT_IN_PROCESS
    , obtain any one of the links (applinkUrl, normalUrl, or schemeUrl) and open the checkout page. For descriptions of the returned URLs, refer to How to properly use the payment continuation URL.
  • If any other result code is returned, close the current transaction or place the order again after replacing the paymentRequestId.
Note: If you do not receive a response, it may be due to a network timeout. Please close the current transaction or retry the API call with a new paymentRequestId and authstate value.
Subsequent payments
The following sample code shows how to call the pay (Tokenized Payment) API:
Subsequent payments
@PostMapping("/v1/payments/pay")
public ResponseEntity<ApiResponse> pay(@RequestBody PaymentVO payment) {
  AmsPayRequest request = new AmsPayRequest();
  request.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);

  // Replace with your paymentRequestId
  String paymentRequestId = UUID.randomUUID().toString();
  request.setPaymentRequestId(paymentRequestId);

  // Convert the amount unit (in actual use, the amount should be calculated on the server side)
  // For details, refer to: https://docs.antom.com/ac/ref/cc
  long amountMinorLong = Money.of(CurrencyUnit.of(payment.currency),
          new BigDecimal(payment.amountValue)).getAmountMinorLong();

  // Set paymentAmount
  Amount paymentAmount = Amount.builder()
          .currency(payment.currency)
          .value(String.valueOf(amountMinorLong))
          .build();
  request.setPaymentAmount(paymentAmount);

  // Set settlementStrategy
  // Replace with your existing settlement currency
  SettlementStrategy settlementStrategy = SettlementStrategy.builder()
          .settlementCurrency("USD")
          .build();
  request.setSettlementStrategy(settlementStrategy);

  // Set paymentMethod (recurring payment scenario: use the existing paymentMethodId)
  User loginUser = users.get(payment.getUserId());
  String accessToken = loginUser.getPaymentMethodTypeAccessToken().get(payment.getPaymentMethodType());

  PaymentMethodMetadata metadata = PaymentMethodMetadata.builder()
          .recurringType("SCHEDULED")  // Pass SCHEDULED when the user is not involved in the payment; this is not required in user-present scenarios
          .build();
  PaymentMethod paymentMethod = PaymentMethod.builder()
          .paymentMethodType(payment.paymentMethodType)
          .paymentMethodId(accessToken)
          .paymentMethodMetadata(metadata)
          .build();
  request.setPaymentMethod(paymentMethod);

  // Set env (environment information for risk control)
  Env env = Env.builder()
          .osType(payment.getOsType())
          .terminalType(payment.getTerminalType())
          .deviceId(payment.getDeviceId())
          .clientIp(payment.getClientIp())
          .deviceTokenId(payment.getDeviceTokenId())
          .build();
  request.setEnv(env);

  // Set goods (product details)
  List<Goods> goodsList = payment.getGoodsList().stream()
          .map(g -> Goods.builder()
                  .referenceGoodsId(g.getReferenceGoodsId())
                  .goodsName(g.getGoodsName())
                  .quantity(g.getQuantity())
                  .price(Amount.builder()
                          .currency(payment.currency)
                          .value(g.getPriceValue())
                          .build())
                  .build())
          .collect(Collectors.toList());

  // Set shipping (shipping information)
  Shipping shipping = Shipping.builder()
          .shippingAddress(ShippingAddress.builder()
                  .region(payment.getShippingRegion())
                  .state(payment.getShippingState())
                  .city(payment.getShippingCity())
                  .address1(payment.getShippingAddress1())
                  .address2(payment.getShippingAddress2())
                  .zipCode(payment.getShippingZipCode())
                  .build())
          .build();

  // Set buyer (buyer information)
  Buyer buyer = Buyer.builder()
          .referenceBuyerId(payment.getReferenceBuyerId())
          .buyerName(BuyerName.builder()
                  .firstName(payment.getBuyerFirstName())
                  .lastName(payment.getBuyerLastName())
                  .build())
          .buyerPhoneNo(payment.getBuyerPhoneNo())
          .buyerEmail(payment.getBuyerEmail())
          .build();

  // Replace with your orderId
  String orderId = UUID.randomUUID().toString();

  // Set order (order information, including product details, shipping, and buyer)
  Amount orderAmount = Amount.builder()
          .currency(payment.currency)
          .value(String.valueOf(amountMinorLong))
          .build();
  Order order = Order.builder()
          .referenceOrderId(orderId)
          .orderDescription(payment.getOrderDescription())
          .orderAmount(orderAmount)
          .goods(goodsList)
          .shipping(shipping)
          .buyer(buyer)
          .build();
  request.setOrder(order);

  // Replace with your notification URL
  // Or configure your notification URL: https://dashboard.antom.com/global-payments/developers/iNotify
  request.setPaymentNotifyUrl("https://kademo.intlalipay.cn/payments/notifySuccess");

  // Replace with your redirect URL
  request.setPaymentRedirectUrl(
          "https://kademo.intlalipay.cn/melitigo/Test_114.html");

  AmsPayResponse amsPayResponse;
  try {
      long startTime = System.currentTimeMillis();
      System.out.println("pay request: " + JSON.toJSONString(request));
      amsPayResponse = CLIENT.execute(request, AmsPayResponse.class);
      System.out.println("pay response: " + JSON.toJSONString(amsPayResponse));
      System.out.println("pay request cost time: " + (System.currentTimeMillis() - startTime) + "ms");

      // Recurring payment scenario: the payment result is returned synchronously
      // resultStatus=S indicates payment success, and no redirection to the cashier page is required
      if ("S".equals(amsPayResponse.getResult().getResultStatus())) {
          System.out.println("Payment SUCCESS, paymentId: " + amsPayResponse.getPaymentId()
                  + ", paymentTime: " + amsPayResponse.getPaymentTime());
      }
  } catch (AlipayApiException e) {
      return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), e));
  }
  return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), amsPayResponse));
}
The following code shows a sample of the request message:
{
"order": {
  "orderAmount": {
    "currency": "HKD",
    "value": 100
  },
  "referenceOrderId": "ORD_2024040512345",
  "orderDescription": "iPhone 15 Pro Monthly Subscription",
  "goods": [
    {
      "referenceGoodsId": "G_001",
      "goodsName": "iPhone 15 Pro",
      "quantity": 1,
      "price": {
        "currency": "HKD",
        "value": 100
      }
    }
  ],
  "shipping": {
    "shippingAddress": {
      "region": "US",
      "state": "CA",
      "city": "San Francisco",
      "address1": "123 Tech Street",
      "address2": "Apt 4B",
      "zipCode": "94107"
    }
  },
  "buyer": {
    "referenceBuyerId": "BUYER_88118999",
    "buyerName": {
      "firstName": "John",
      "lastName": "Doe"
    },
    "buyerPhoneNo": "66622222",
    "buyerEmail": "john.doe@example.com"
  }
},
"env": {
  "osType": "IOS",
  "terminalType": "APP",
  "deviceId": "deviceIdxxxxxxx",
  "clientIp": "192.168.111.111",
  "deviceTokenId": "deviceTokenIdxxxxxxxx"
},
  "paymentMethod": {
      "paymentMethodType": "ALIPAY_HK",
      "paymentMethodId":"xxxxxxxx",
      "paymentMethodMetadata":{
          "recurringType":"SCHEDULED" //Required when the user is not involved; not required in user-involved scenarios.
      }
  },
  "settlementStrategy": {
      "settlementCurrency": "USD"
  },
  "paymentNotifyUrl": "https://kademo.intlalipay.cn/payments/notifySuccess",
  "paymentRedirectUrl": "https://kademo.intlalipay.cn/melitigo/Test_114.html",
  "paymentRequestId": "PAY_20251110143957765",
  "productCode": "AGREEMENT_PAYMENT"
}
The following code shows a sample of the response message:
{
"actualPaymentAmount": {
	"currency": "HKD",
	"value": "100"
},
"paymentAmount": {
	"currency": "HKD",
	"value": "100"
},
"paymentCreateTime": "2025-11-05T23:03:16-08:00",
"paymentId": "202511061940108001001888********",
"paymentRequestId": "PAYMENT_20251106150314003_AUTO",
"paymentTime": "2025-11-05T23:03:18-08:00",
"pspCustomerInfo": {
	"pspCustomerId": "208812211210000",
	"pspName": "ALIPAY_HK"
},
"result": {
	"resultCode": "SUCCESS",
	"resultMessage": "success.",
	"resultStatus": "S"
}
}
Please take the next step according to the value of the result.resultStatus.
result.resultStatus
Message
Further actions
S
Payment successful.
No further action is needed.
F
Payment failed.
You can handle the response accordingly based on the resultCode.
U
Proceed with the next step based on the returned event code.
  • If the returned event code is
    PAYMENT_IN_PROCESS
    and a redirection link is returned, redirect the user to the payment continuation link normalUrl.
  • If any other event code is returned, actively query the transaction status by polling the inquiryPayment API or wait for notifyPayment to obtain the payment result. It is strongly recommended that you integrate both interfaces so that you can obtain the payment result more quickly and avoid missing the payment result if one of the interfaces encounters an issue.
Note: If you do not receive a response, it may be due to a network timeout. In this case, keep the paymentRequestId unchanged and call the API again to resolve the issue. If the problem persists, please contact Antom technical support.
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 pay (Tokenized Payment) 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.

Step 2: Obtain the payment continuation URL

After obtaining the payment continuation URL returned by Antom, the merchant server passes the address to the front end. The merchant front end redirects to the payment method page.
The following is the sample codes for loading payment continuation URL on the merchant front end:
Web
if (URL != null) {
  window.open(URL, '_blank');
}
WAP
window.location.href = URL;
iOS
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0) {
  [[UIApplication sharedApplication] openURL:[NSURL URLWithString:Url] options:@{} completionHandler:nil];
}else{ 
  [[UIApplication sharedApplication] openURL:[NSURL URLWithString:Url]];
}
Android
try {
  Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(URL));
  intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
  // use the startActivity function to redirect to the wallet app 
  startActivity(intent);
} catch (Exception e) {
  e.printStackTrace();
}
Note: The URLs in the sample code refer to the applinkUrl, schemeUrl, and normalUrl returned in Step 1. For how to use these URLs, see Best practices for configuring the authorization URL.
The figure below shows a sample rendering of the payment method checkout page:
First payment
Subsequent payments
In some scenarios, risk control may require the buyer to complete OTP verification.

Step 3: Obtain the authorization and payment result

Return to the payment result page

After the buyer completes the payment, they will be redirected back to the paymentRedirectUrl specified in the pay (Tokenized Payment) API.
Note: Redirection may not occur in certain scenarios. For example, it may fail due to buyer actions or network issues.

Obtain the authorization and payment result

The first payment returns both the authorization result and the payment result, while subsequent payments return only the payment result. Common scenarios are as follows:
Type
Common scenarios
Asynchronous notification scenarios received
Resolution suggestions
First payment
The buyer successfully completes authorization and payment.
Authorization successful; payment successful.
  • If a payment asynchronous notification is received, proceed with the order according to the corresponding status.
  • If an asynchronous notification of successful authorization is received, ensure to maintain the mapping between the buyer and the token on the merchant side.
  • If no notification is received when the merchant order is closed, you can call the cancel API to close the payment order.
    Note: Calling the cancel API only closes the payment order and does not affect the authorization. If you receive a notification of successful authorization, it is recommended that you proceed with the next step.
The buyer’s authorization is successful, but the payment fails due to insufficient balance or other reasons.
Authorization successful, payment failed.
The buyer has not authorized the payment, or the authorization failed, but the payment was successful.
No asynchronous notification for authorization; payment successful.
The buyer’s authorization failed, and the payment also failed due to insufficient funds or other reasons.
No asynchronous notification for authorization, payment failed.
The buyer has not authorized the payment, or the authorization failed, and no payment has been submitted.
No asynchronous notifications for both authorization and payment.
Subsequent payments
The buyer has successfully paid.
Payment successful.
  • If the payment asynchronous notification is received, proceed with the order according to the corresponding status.
  • If no notification is received when the merchant order is closed, you can call the cancel API to close the order.
The buyer's payment failed due to insufficient funds or other reasons.
Payment failed.
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 nome
Description
accessToken
Payment token returned by Antom for subsequent password-free payments.
Note: Whether a token for password-free payment is returned depends on the capabilities of the payment method or whether the buyer chooses to enable password-free payment. A payment token is not returned for every transaction.
accessTokenExpiryTime
The validity period of the accessToken.
Please refer to the durations listed in the payment token validity period table below. Once the validity period expires, you need to guide the buyer to complete authorization again.
authState
A unique ID assigned when initiating authorization. The value of this parameter is used to verify whether it matches the authState value specified in the pay (Tokenized Payment) request.
authorizationNotifyType
Only
TOKEN_CREATED
is returned, indicating that the buyer has successfully initiated authorization for fast payment on the merchant client.
userLoginId
The login ID used by the buyer when registering for the payment method. This parameter is masked. You can store this account identifier for display in subsequent payments.
Note: Whether userLoginId is returned after authorization depends on the capabilities of the payment method. Therefore, not all payment methods will return this parameter.
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
PayPay Smart Payment
The initial authorization is valid for one year. If a payment is successfully completed within that year, the validity period will be extended by one year from the date of that successful transaction.
100 years
100 years
No accesstoken is returned. The merchant side does not need to manage the token.
  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 the mapping between the buyer’s PaymentMethodType and 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 the first or subsequent payment is completed, you can obtain the payment result through one of the following methods:
{
"result": {
  "resultCode": "SUCCESS",
  "resultStatus": "S",
  "resultMessage": "success"
}
}
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 pay (Tokenized Payment) 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 parameters 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"
}
}
Please process the response based on the value of the paymentStatus parameter. For specific return values, refer to the inquiryPayment API documentation.
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 API 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
  • Order query after redirecting to the merchant result page
  • Merchant-initiated transaction cancellation
  • Payment failure retry