Hosted recurring payments

Antom Checkout Page (CKP) is a user-friendly, low-code payment solution that simplifies global transactions. Supporting a wide range of payment methods, CKP meets the needs of different markets and business scenarios. With minimal setup, you can quickly create a professional, feature-rich checkout page that offers buyers a smooth and convenient payment experience while significantly improving payment integration efficiency and driving business growth.
This guide shows you how to integrate CKP through an API, where your buyers are redirected to the Antom Checkout Page to make payment without the need for additional page configurations.

User experience

The following illustrates the user experience for first-time subscription and subsequent payments when integrating the Checkout Page:
First-time subscription
Subsequent deductions

Payment flow

The process for subscription payments using hosted CKP includes the following steps:
Card payments, Google Pay, and Apple Pay
APMs

Subscription lifecycle

The following images illustrate the subscription lifecycle for different payment methods:
Card payments, Google Pay, and Apple Pay
APMs

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.

Integration Steps

Follow these steps to start the integration:
  1. Create a payment session
  2. Redirect to Antom Checkout Page
  3. Notify authorization/payment result
  4. (Optional) Capture and obtain the capture result
  5. Obtain subscription notifications

Step 1: Create a payment session
Server-side

You can call the createPaymentSession (One-time Payments) API and pass in the order information. After creating the payment session, you will be redirected to the Antom Checkout Page.
Creating a payment session includes the following parameters:
The above parameters are the basic parameters for creating a payment session. For complete and additional requirements for specific payment methods, please refer to createPaymentSession (One-time Payments).
The following sample code shows how to call the createPaymentSession (One-time Payments) API:
public static void createPaymentSession() {
  AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
  alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
  alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.CHECKOUT_PAYMENT);

  // Set subscription information
  SubscriptionInfo subscriptionInfo = new SubscriptionInfo();
  subscriptionInfo.setSubscriptionDescription("TEST_SUBSCRIPTION");
  DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");
  subscriptionInfo.setSubscriptionStartTime(ZonedDateTime.now().format(formatter));
  subscriptionInfo.setSubscriptionEndTime(ZonedDateTime.now().plusYears(1).format(formatter));
  subscriptionInfo.setSubscriptionNotifyUrl("https://your.example.com/subscriptionNotify");

  // Set subscription period rule
  PeriodRule periodRule = new PeriodRule();
  periodRule.setPeriodType("YEAR");
  periodRule.setPeriodCount(1);
  subscriptionInfo.setPeriodRule(periodRule);
  alipayPaymentSessionRequest.setSubscriptionInfo(subscriptionInfo);

  // Set payment amount
  Amount amount = Amount.builder()
          .currency("SGD")
          .value("6000")
          .build();
  alipayPaymentSessionRequest.setPaymentAmount(amount);

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

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

  // Set buyer information
  Buyer buyer = Buyer.builder()
          .referenceBuyerId("yourBuyerId")
          .build();

  // Set order information
  Order order = Order.builder()
          .referenceOrderId(orderId)
          .orderDescription("antom ckp testing order")
          .orderAmount(amount)
          .buyer(buyer)
          .build();
  alipayPaymentSessionRequest.setOrder(order);

  // Set available payment method
  AvailablePaymentMethod availablePaymentMethod = new AvailablePaymentMethod();
  HashMap<String, Object> methodData = new HashMap<>();
  methodData.put("is3DSAuthentication", true);
  List<PaymentMethodTypeItem> paymentMethodTypeList = new ArrayList<>();
  PaymentMethodTypeItem paymentMethodTypeItem = new PaymentMethodTypeItem();
  paymentMethodTypeItem.setPaymentMethodType("CARD");
  availablePaymentMethod.setPaymentMethodTypeList(paymentMethodTypeList);
  availablePaymentMethod.setPaymentMethodMetaData(methodData);
  alipayPaymentSessionRequest.setAvailablePaymentMethod(availablePaymentMethod);


  // Set environment information
  Env env = Env.builder()
          .terminalType(TerminalType.WEB)
          .clientIp("1.2.3.4")
          .build();
  alipayPaymentSessionRequest.setEnv(env);

  // Replace with your notification URL
  // Or configure your notification URL here: https://dashboard.antom.com/global-payments/developers/iNotify
  alipayPaymentSessionRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com/payment/receiveNotify");

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

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

  // Replace with your clientId
  alipayPaymentSessionRequest.setClientId(clientId);

  AlipayPaymentSessionResponse alipayPaymentSessionResponse;
  try {
      alipayPaymentSessionResponse = defaultAlipayClient.execute(alipayPaymentSessionRequest);
  } catch (AlipayApiException e) {
      String errorMsg = e.getMessage();
      // Handle error condition
  }
}
The following shows the sample code of a request:
{
  "env": {
      "clientIp": "1.*.*.*",
      "terminalType": "WEB"
  },
  "order": {
      "buyer": {
          "referenceBuyerId": "yourBuyerId"
      },
      "orderAmount": {
          "currency": "SGD",
          "value": "6000"
      },
      "orderDescription": "antom ckp testing order",
      "referenceOrderId": "9aec4249-1934-4294-8c30-1993a157da5f"
  },
  "paymentAmount": {
      "currency": "SGD",
      "value": "6000"
  },

  "availablePaymentMethod": {
      "paymentMethodMetaData": {
          "is3DSAuthentication": true
      },
      "paymentMethodTypeList": []
  },
  "paymentNotifyUrl": "http://www.yourNotifyUrl.com/payment/receiveNotify",
  "paymentRedirectUrl": "http://www.yourRedirectUrl.com/payment/redirect",
  "paymentRequestId": "601e5c9e-78b3-455e-84bb-ee41f88c6c07",
  "productCode": "CASHIER_PAYMENT",
  "productScene": "CHECKOUT_PAYMENT",
  "settlementStrategy": {
      "settlementCurrency": "USD"
  },
  "subscriptionInfo": {
      "periodRule": {
          "periodCount": 1,
          "periodType": "YEAR"
      },
      "subscriptionDescription": "TEST_SUBSCRIPTION",
      "subscriptionEndTime": "2027-03-12T10:38:54+08:00",
      "subscriptionNotifyUrl": "https://your.example.com/subscription/notify",
      "subscriptionStartTime": "2026-03-12T10:38:54+08:00"
  }
}
The following shows the sample code of a response, which contains the following parameters:
  • paymentSessionData: Payment session data to be returned to the front end.
  • paymentSessionExpiryTime: The specific date and time after which the payment session will expire.
  • normalUrl: The URL used to redirect to the Checkout Page.
{
  "normalUrl": "https://checkout.antom.com/checkout-page/pages/payment/index.html?sessionData=cwnCzs7PcMfU03oKT1F%2BPHrpJmhr5k%2FF8nAcL4GP4PIin2bG4nFyF0NmqIOyf8Lt7Rh1%2BmgE27Csjx3Xhr8lkA%3D%3D%26%26SG%26%26188%26%26eyJlbGlnaWJsZUVhc3lQYXlNYXJrZXRpbmciOmZhbHNlLCJleHRlbmRJbmZvIjoie1wiT1BFTl9NVUxUSV9QQVlNRU5UX0FCSUxJVFlcIjpcInRydWVcIixcImRpc3BsYXlBbnRvbUxvZ29cIjpcInRydWVcIn0iLCJuZWVkQWNjb3VudENvbmZpcm1QYWdlIjpmYWxzZSwicGF5bWVudFNlc3Npb25Db25maWciOnsicGF5bWVudE1ldGhvZENhdGVnb3J5VHlwZSI6IkFMTCIsInByb2R1Y3RTY2VuZSI6IkNIRUNLT1VUX1BBWU1FTlQiLCJwcm9kdWN0U2NlbmVWZXJzaW9uIjoiMS4wIn0sInNlY3VyaXR5Q29uZmlnIjp7ImFwcElkIjoiIiwiYXBwTmFtZSI6Ik9uZUFjY291bnQiLCJiaXpUb2tlbiI6IjZUY2RicjJyRjNyUFl4NGhrVnJIcWJ2aiIsImdhdGV3YXkiOiJodHRwczovL2ltZ3Mtc2VhLmFsaXBheS5jb20vbWd3Lmh0bSIsImg1Z2F0ZXdheSI6Imh0dHBzOi8vb3Blbi1zZWEtZ2xvYmFsLmFsaXBheS5jb20vYXBpL29wZW4vcmlza19jbGllbnQiLCJ3b3JrU3BhY2VJZCI6IiJ9LCJza2lwUmV******GF5bWVudE1ldGhvZCI6ZmFsc2V9&shadow=true",
  "paymentSessionData": "4dChA3EBSSxaN9XOjRZ0zN3C8l8x******RPDA5O+7TYW/kJ9tR76f**********vPiEEUII0uZciWVbjNIpxElA==&&SG&&188&&eyJlbGlnaWJsZUVhc3lQYXlNYXJrZXRpbmciOmZhbHNlLCJleHRlbmRJbmZvIjoie1wiT1BFTl9NVUxUSV9QQVlNRU5UX0FCSUxJVFlcIjpcInRydWVcIixcImRpc3BsYXlMYXlvdXRcIjpcIkxFRlRfT1JERVJfQU5EX1JJR0hUX1BBWU1FTlRcIixcInRoZW1lVHlwZVwiOlwiQ1VTVE9NSVpFXCIsXCJkaXNwbGF5QW50b21Mb2dvXCI6XCJmYWxzZVwifSIsIm5lZWRBY2NvdW50Q29uZmlybVBhZ2UiOmZhbHNlLCJwYXltZW50U2Vzc2lvbkNvbmZpZyI6eyJwYXltZW50TWV0aG9kQ2F0ZWdvcnlUeXBlIjoiQUxMIiwicHJvZHVjdFNjZW5lIjoiQ0hFQ0tPVVRfUEFZTUVOVCIsInByb2R1Y3RTY2VuZVZlcnNpb24iOiIxLjAifSwic2VjdXJpdHlDb25maWciOnsiYXBwSWQiOiIiLCJhcHBOYW1lIjoiT25lQWNjb3VudCIsImJpelRva2VuIjoiNlRjZGJyMnJGM3JQWXg0aGtWckhxYnZqIiwiZ2F0ZXdheSI6Imh0dHBzOi8vaW1ncy1zZWEuYWxpcGF5LmNvbS9tZ3cuaHRtIiwiaDVnYXRld2F5IjoiaHR0cHM6Ly9vcGVuLXNlYS1nbG9iYWwuYWxpcGF5LmNvbS9hcGkvb3Blbi9yaXNrX2NsaWVudCIsIndvcmtTcGFjZUlkIjoiIn0sInNraXBSZW5kZXJQYXltZW50TWV0aG9kIjpmYWxzZX0=",
  "paymentSessionExpiryTime": "2026-03-12T11:38:59+08:00",
  "paymentSessionId": "4dChA3EBSSxaN9XOjRZ0zN3C8l8x*********DA5O+7S4zYs/gYmYI0w5X1FgRTmT",
  "result": {
      "resultCode": "SUCCESS",
      "resultMessage": "success.",
      "resultStatus": "S"
  }
}
The table shows the possible values that the result.resultStatus parameter in the request message may return. Please handle the result according to the guidances:
Note: If you did not receive a response message, it might be due to a network timeout. Please change the paymentRequestId and call the API again to resolve the issue.

Step 2: Redirect to Antom Checkout Page (normalUrl)
Client-side

After the merchant server obtains the Checkout Page URL (normalUrl) returned by Antom, it passes this URL to the front end, and the merchant front end redirects to the Antom Checkout Page.
The following is a sample code for loading normalUrl on the merchant front end:
Web
WAP
The image below shows the page rendering effect of the redirected Antom Checkout Page:
Screenshot of rendered Antom Checkout Page (CKP) showing the subscription payment interface

3D Secure authentication page

The initial transaction requires buyer participation for identity authentication, which ensures the security of subsequent recurring charges without the buyer's presence. The 3D Secure (3DS) authentication requirements for the initial transaction are as follows:
Common questions

Q: What are the considerations for passing the paymentRedirectUrl parameter?
A: It is set to an HTTPS address by default. Additionally, special characters in the URL must be encoded; otherwise, payment exceptions may occur.

Q: How is the payment result page displayed?
A: You need to specify the paymentRedirectUrl parameter in the createPaymentSession (One-time Payments) API to provide an HTTPS address. This address is used to display the payment result on the merchant side. In both success and failure scenarios, there may be options to redirect back to the merchant page from the payment method side. Therefore, avoid hardcoding the paymentRedirectUrl as a "subscription creation success page". Instead, dynamically display content based on the server-side response to prevent buyer confusion.

Q: Does redirecting to the merchant result page indicate successful subscription creation?
A: Redirecting to the merchant page alone cannot confirm successful subscription creation. The following three scenarios should be considered:
  • After successful payment, the buyer may fail to redirect to the merchant page due to network issues.
  • Even if the buyer does not complete the payment, they may still redirect to the merchant page using options provided by the payment method side.
  • Even if the buyer completes the payment, the subscription may not activate due to failed capture.

Step 3: Notify authorization or payment result
Server-side

During the payment processing flow, Antom will send you respective result notifications based on the specific payment method type.
  • For card payments, Google Pay, and Apple Pay transactions, Antom sends authorization result notifications to inform you whether the authorization was successful. A capture request is only triggered after a successful authorization. Please use the capture result as the basis for shipping goods.
  • For APM scenarios, Antom sends payment result notifications when a payment either succeeds or fails.
Card payments, Google Pay, and Apple Pay
APMs

(Optional) Step 4: Capture and obtain the capture result
Server-side

Note
  • Card payments require capture. Capture can only be initiated with successful authorized payments.
  • Certain APMs, such as Apple Pay, Google Pay, and Pay by bank, require capture. Capture can only be initiated with successful authorized payments.
If payment is successful, Antom will automatically initiate capture for you, while you can also initiate capture manually. Antom will subsequently send you the capture result via the notifyCapture (One-time Payments) API. You may also proactively query the capture result. You should decide whether to ship goods based on the capture result. For specific operations, refer to Capture.

Step 5: Obtain subscription notifications
Server-side

Once a subscription is activated, Antom will send the following notifications to you:

First-time subscription Notifications

Antom will send the following event notifications via HTTPS to the webhook URL configured in the API or the Antom Dashboard:
Subscription status notifications
Current deduction result notifications
Common questions

Q: Will Antom resend asynchronous notifications?
A: Yes. Notifications will be automatically resent within 24 hours under these circumstances:
  • If asynchronous notifications are not received due to network issues.
  • If you receive an asynchronous notification from Antom but fail to respond in the format of Return a receipt acknowledgment message.
Notifications can be resent up to 8 times, or until a correct response is received to stop delivery. Intervals are: 0 minute, 2 minutes, 10 minutes, 10 minutes, 1 hour, 2 hours, 6 hours, 15 hours.

Q: Is signature verification required for payment result notifications?
A: Yes. Antom will send a guaranteed callback request to you for signature verification. Please note that when assembling the message to be verified, it must be processed according to the standard format:
<http-method> <http-uri> <client-id>.<request-time>.<request-body>
. Specifically, for the
<request-body>
, the value must be taken directly rather than by parsing the JSON and reassembling.

Q: If the initial payment fails, does the subscription become active?
A: No. If the initial payment for subscription creation fails, the subscription will not be activated. Antom will send a status notification via webhook with subscriptionStatus set to
TERMINATED
, indicating failed subscription creation.

Q: What is the default expiry time for a subscription order creation?
A:
  • For APM payment types, the default subscription expiryTime is 80 minutes.
  • For Card/ApplePay/GooglePay, the default subscription expiry time is 7 days.
You can also specify the expiry time through the subscriptionExpiryTime field.

Subscription renewal notifications

After the subscription is created and activated successfully, Antom will automatically initiate renewal deductions based on your configured subscription rules and send corresponding payment result notifications via webhook to achieve periodic deductions. The timing and rules for triggering renewal payments are as follows:
  • Trigger time: Renewal deductions are triggered automatically 24 hours before the start of the next subscription cycle. You can determine the next deduction time by subtracting 24 hours from the periodEndTime parameter in the previous period's payment result notification.
  • Cycle rules: The renewal cycle and deduction frequency follow the periodRule set during subscription, such as daily, monthly, quarterly, or yearly deductions.
Card payments, Google Pay, and Apple Pay
APMs
Common questions

Q: Will a failed payment deduction terminate the subscription?
A: If the initial payment for creating a subscription fails, the subscription will not be activated; if the subscription is already active but a subsequent recurring payment fails (e.g., due to insufficient balance), the subscription status remains active; if the subscription is not manually canceled, Antom will continue to attempt recurring payments in the next cycle.

Q: Will a failed payment deduction trigger a notification, and will retries be attempted?
A: A failed payment deduction will trigger a deduction failure notification. For card payments, Google Pay, and Apple Pay subscriptions, Antom does not initiate retries. For APM subscriptions, Antom will perform multiple retries. If you wish to implement their own retry mechanism, please contact Antom Technical Support for customized solutions.

Q: If the initial payment date is at the end of a month, such as February 28, March 31, or April 30, how is the next payment date determined?
A: The subscription cycle logic is that the next deduction trggers based on the selected date. If the next cycle does not have the selected date, the system adjusts to the last day of that month. For example:
  • First cycle: Jan 28; Second cycle: Feb 28; Third cycle: Mar 28; Fourth cycle: Apr 28.
  • First cycle: Jan 31; Second cycle: Feb 28; Third cycle: Mar 31; Fourth cycle: Apr 30.
  • First cycle: Jan 30; Second cycle: Feb 28; Third cycle: Mar 30; Fourth cycle: Apr 30.

Q: How are subsequent recurring deductions associated with the initial subscription contract?
A: For recurring payment notifications, you can use the subscriptionRequestId or subscriptionId in the notification request to link to the initial subscription contract. For recurring payments of card payments, Google Pay, and Apple Pay, Antom additionally sends authorization result notifications and capture result notifications. The two kinds of notifications can be linked to the recurring payment notification via the paymentId and ultimately associated with the initial contract's subscriptionId.

After subscription

After completing the subscription, you can perform the following actions:

Inquire subscription information
Server-side

After your subscription is confirmed, you can query the following subscription information:

Inquire payments
Server-side

In addition to obtaining the buyer's payment result through the asynchronous notification, you can retrieve the corresponding payment result through the inquiry payments service. You can call the inquiryPayment API and use the paymentRequestId from the payment session to check the payment status.
The following 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 an example of a response:
{
"actualPaymentAmount": {
  "currency": "USD",
  "value": "1"
},
"customsDeclarationAmount": {
  "currency": "CNY",
  "value": "7"
},
"paymentAmount": {
  "currency": "USD",
  "value": "1"
},
"paymentId": "2025030519401080****8690281017336",
"paymentMethodType": "ALIPAY_CN",
"paymentRedirectUrl": "https://checkout.antom.com/checkout-page/pages/payment/index.html?sessionData=REDACTED_SESSION_DATA",
"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 shows the possible values of paymentStatus returned in the response:
Note: When inquiring about the transaction, if the buyer does not submit the order, the
ORDER_NOT_EXIST
error code will be returned. This error is not returned if the order is submitted.

Subscription trial
Server-side

Antom provides a subscription trial feature that allows buyers to experience a product or service for a limited time at no cost or at a discounted rate before officially purchasing a subscription plan. For more details, please refer to the Subscription trial.

Subscription cancellation
Server-side

The subscription cancellation feature allows buyers to cancel their current subscription at any time when they no longer need to use the associated service. For more details, please refer to the Subscription cancellation.

Cancel
Server-side

For orders that have been successfully paid, if the buyer requests to cancel the order or refund on the same day, you can use Antom's cancel transaction capability to cancel or unfreeze the order status. Additionally, for orders that have not yet completed payment, you can also directly cancel them. For detailed integration solutions, please refer to Cancel.

Refund
Server-side

For orders that have been successfully paid, if you need to initiate a refund to the buyer, Antom offers the following two methods:
  • Your operation staff can manually process the refund directly on the Antom Dashboard.
  • You can initiate a refund by integrating with the refund API.
Antom's refund capabilities include:
  • Support for full refunds.
  • Support for partial multiple refunds, with the total amount of multiple refunds not exceeding the captured amount.
For detailed integration solutions, please refer to Refund.

Dispute
Server-side

When a buyer chooses to pay with a card, a dispute may occur. To learn more, see Dispute.

Reconciliation
Server-side

After the transaction is completed, use the financial reports provided by Antom for reconciliation. For more information on how to reconcile and the settlement rules of Antom, please refer to Reconciliation.

Additonal content

Specify a payment method

You can specify payment methods on Antom Dashboard through Payments > Checkout page> Payment methods. You can also pass the parameters in the createPaymentSession (One-time Payments) API to specify the display of payment methods on Checkout Page, the order of the payment method list, and the display of quick payments. For specific steps, refer to Specify a payment method.
Note: If you pass parameters through the API, the API values take priority.
This feature offers you the following benefits:
  • Filter local payment methods based on your business region.
  • Sort your preferred payment methods.
  • Display the mainstream quick payments, such as Alipay, Apple Pay, and Google Pay.