Subscription payment is a recurring automatic payment solution that enables merchants to collect payments periodically. With a one-time authorization, buyers can link their payment accounts to enjoy continuous subscription services, while supporting dynamic adjustments to subscription configurations (such as modifying cycle/amount, canceling renewal, or terminating services, etc.). The entire process is both efficient and secure.
The following figures demonstrate the user experience of paying with Google Pay: You can choose one of the following two decryption methods to decrypt the obtained paymentToken, and the corresponding payment processes differ.
- Hosted decryption: Antom manages certificates and performs decryption on your behalf, so you do not need to be PCI-qualified.
- Merchant decryption: You manage your own certificates and perform decryption operations yourself, and this mode requires that you are PCI-qualified.
Note: For more information about PCI DSS compliance requirements, see PCI DSS standard. The following illustrates the payment flow of accepting recurring payments with Google Pay: The following illustrates the payment flow for the initial subscription payment process using Antom-decrypted paymentToken:
The following illustrates the payment flow for the subsequent periodic deductions process using Antom-decrypted paymentToken:
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.
Follow these steps to start the integration:
- Obtain paymentToken
- Create a subscription payment request
- (Optional) Redirect to the 3DS authentication page
- Obtain the authorization result
- Capture and recieve the capture notification
- Recieve subscription notifications
Step 1: Obtain paymentToken
After you obtain paymentToken, you can choose the Antom-hosted decryption method to decrypt the token and call the pay (One-time Payments) API to initiate an authorized payment request. Step 2: Create a subscription payment request
Server-side
After you integrate the Google Pay SDK, use Antom's configuration in Google Pay to interact.
Below is the acquirer information of Antom for Google Pay: The following is a sample code of the interaction:
const tokenizationSpecification = {
type: 'PAYMENT_GATEWAY',
parameters: {
'gateway': "alipayintl",
'gatewayMerchantId': "2188XXXXXXXX"//The merchant id for merchant onboarding in the Antom (PROD/SANDBOX) environment.
}
};
private static JSONObject getGatewayTokenizationSpecification() throws JSONException {
return new JSONObject() {{
put("type", "PAYMENT_GATEWAY");
put("parameters", new JSONObject() {{
put("gateway", "alipayintl");
put("gatewayMerchantId", "2188XXXXXXXX"); //商户在 Antom 入驻相应环境(PROD/SANBOX)的 merchant id
}});
}};
}
After you obtain paymentToken and have Antom decrypt it, initiate the payment using Antom’s card authorization payment capability. You can pass the decrypted paymentToken through the paymentMethod.paymentMethodMetaData.googlePayConfiguration parameter in the pay (One-time Payments) API. public static void payByGooglePayServer2Server() {
AlipayPayRequest alipayPayRequest = new AlipayPayRequest();
alipayPayRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
// Replace with your paymentRequestId
String paymentRequestId = UUID.randomUUID().toString();
alipayPayRequest.setPaymentRequestId(paymentRequestId);
// Set subscription information
SubscriptionInfo subscriptionInfo = new SubscriptionInfo();
subscriptionInfo.setSubscriptionDescription("Subscription test");
LocalDateTime localNow = LocalDateTime.now();
OffsetDateTime offsetDateTime = localNow.atOffset(ZoneOffset.of("+08:00"));
String startTime = offsetDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
subscriptionInfo.setSubscriptionStartTime(startTime);
subscriptionInfo.setSubscriptionNotifyUrl("https://www.yourDomain.com/subscription/notify");
PeriodRule periodRule = new PeriodRule();
periodRule.setPeriodType("MONTH");
periodRule.setPeriodCount(1);
subscriptionInfo.setPeriodRule(periodRule);
alipayPayRequest.setSubscriptionInfo(subscriptionInfo);
// Set payment amount
Amount amount = Amount.builder().currency("SGD").value("4200").build();
alipayPayRequest.setPaymentAmount(amount);
// Set settlement strategy
SettlementStrategy settlementStrategy = SettlementStrategy.builder().settlementCurrency("SGD").build();
alipayPayRequest.setSettlementStrategy(settlementStrategy);
// Set payment method
PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("GOOGLEPAY").build();
alipayPayRequest.setPaymentMethod(paymentMethod);
// Set Google Pay related parameters -- delegated decryption
Map<String, String> googlePayToken = new HashMap<>();
googlePayToken.put("googlePayToken", "googlePay token");
Map<String, Object> paymentMethodMetaData = new HashMap<>();
paymentMethodMetaData.put("googlePayConfiguration", googlePayToken);
paymentMethodMetaData.put("is3DSAuthentication", false);
paymentMethod.setPaymentMethodMetaData(paymentMethodMetaData);
// 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 testing order").orderAmount(amount).buyer(buyer).build();
alipayPayRequest.setOrder(order);
// Set environment information
Env env = Env.builder().terminalType(TerminalType.WEB).clientIp("1.2.3.4").build();
alipayPayRequest.setEnv(env);
// Set authorization capture mode
PaymentFactor paymentFactor = PaymentFactor.builder().isAuthorization(true).build();
alipayPayRequest.setPaymentFactor(paymentFactor);
// Replace with your notification URL
alipayPayRequest.setPaymentNotifyUrl("https://www.yourNotifyUrl.com");
// Replace with your redirect URL
alipayPayRequest.setPaymentRedirectUrl("https://www.yourMerchantWeb.com");
// Pay
AlipayPayResponse alipayPayResponse = null;
try {
alipayPayResponse = CLIENT.execute(alipayPayRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// Handle error case
}
}
The following shows the sample code of a request:
{
"env": {
"clientIp": "1.2.3.4",
"terminalType": "WEB"
},
"order": {
"buyer": {
"referenceBuyerId": "yourBuyerId"
},
"orderAmount": {
"currency": "SGD",
"value": "4200"
},
"orderDescription": "antom testing order",
"referenceOrderId": "2a7772b2-4eae-43cf-8f1a-07c8dec3739f"
},
"paymentAmount": {
"currency": "SGD",
"value": "4200"
},
"paymentFactor": {
"isAuthorization": true
},
"paymentMethod": {
"paymentMethodMetaData": {
"is3DSAuthentication": true,
"googlePayConfiguration": {
"googlePayToken": "{\"signature\":"MEQCIB1/pqJy8Z7565NKYN8Mx+Rl57M0xVPOKAnuLdSpm/RaAiAH8t+q+aJA9KAOXXnyFVU13qJ2J4Uuhu2iggNd6hgJnw\u003d\u003d","intermediateSigningKey":{"signedKey":"{\"keyValue\":\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKWkTmXgqxeLpsCa4POKjunH+b4aIdKOr37TJAn1a0x8gduKJy8UJSCoDUqqKASHYmQoWA8TDr+Gq0Ie8pA9LoA\\u003d\\u003d\",\"keyExpiration\":\"1774047508238\"}","signatures":["MEUCIQDa+BMhD7nmJq2xaf6uJnV+2fx8B4s1XGaJXF/zG4w9pQIgIdDlhrBarzgbuWSmYpiemS92jy9zxK3UJguJsfaPWrQ\u003d"]},"protocolVersion":"ECv2","signedMessage":"{\"encryptedMessage\":\"DMJ8HqrPreS67BYJseOLUlox42ZFpgmbv/wU5a1JMS0KdawwC7JmDrvm57Ysot3VxmG0jZwVd54Ru78Z22j5lGd8W145sgI30gIWgRHT1ru9yt/lTdLuJExNeNUGGjrSUPBHinGy4sOILFWGRilNtuQaftt0NHnuPEEUUb1GdN/8+J5RNxNLXFI7AFlaC5tCrDshLsh3K1pzLSVK024B5Q+LbZxaWeiOygZ7OJqWzpFuUg6i2GOdXEOW8hrNv2dUHa7Jn07+G2xVa++5YT8dMpbOQ+bUn6MiH95+k3Ppl8ipFx2e2KKhMH8VoF5vRQIppCrCrJm6f/IRoZwh7x4785d73oLtoFMk6MPSFnw46s8PJ+jBDOQhhvFzzXwr+0tZbrqNtXui3PHSVt86ED+axRpuUog5ePzaSJQ+AVdSxQwCxT19avooAZPHjw9jT4U9Eo18BFIAQSaxtgNhaAJltaZdOKxZ+EYiWOnEZDs3BZCrWtgfiRKA5PD0gJAFl+fEet1JwH/HSmHFOSvBt4csIe1s8KpUeubnoZMrBSPAZDfjNvhrSzHaKHpFi3WLi6DSP4pyHiHNg/LZRI4L5CpWQnEk/Dxu19A\\u003d\",\"ephemeralPublicKey\":\"BJbQqCHVXHkg/3vioDJAQNoNQMClUmmsjTJ9loy5+IacdR7Qb28Z2t8L6IlO3jgZvx6RFvD9ikR2zQWAa4RzYYQ\\u003d\",\"tag\":\"gAbroVixfH3Ayet2BVsuJ608Sw45u1HigVMiIRlif9k\\u003d\"}"}"
}
},
"paymentMethodType": "GOOGLEPAY"
},
"paymentNotifyUrl": "https://www.yourNotifyUrl.com",
"paymentRedirectUrl": "https://www.yourMerchantWeb.com",
"paymentRequestId": "713c6f16-fca5-4507-8291-beea32dc470b",
"productCode": "CASHIER_PAYMENT",
"settlementStrategy": {
"settlementCurrency": "SGD"
},
"subscriptionInfo": {
"periodRule": {
"periodCount": 1,
"periodType": "MONTH"
},
"subscriptionDescription": "Subscription test",
"subscriptionNotifyUrl": "https://www.yourDomain.com/subscription/notify",
"subscriptionStartTime": "2026-03-13T14:42:55.062+08:00"
}
}
The following shows the sample code of a response:
{
"normalUrl": "https://iexpfront-sea.alipay.com/authorise3d?merchantId=1887SjzZ56b1lvObJWQTaqG4PhACjUGncnl0Sihzg8en5I%3D&ddcId=m47qH0MLK7A7yJNVdjLYJMrfAGZ7ZPgbv5TmV3FoZ4U%3D&pass=lt%5E1&needDDC=Y&from=iexpcore",
"paymentActionForm": {
"method": "POST",
"parameters": {
"Bin": "4***11",
"JWT": "eyJraWQiOiJDQVJESU5BTF9KV1RfYWxpcGF5IiwiY3R5IjoiQ****QUxfSldUX2FsaXBheSIsImFsZyI6IkhTMjU2In0.eyJPcmdVbml0SWQiOiI1ZDVmMTA2MjRiNzkyYTFhZTBkN2Y3MTEiLCJSZWZlcmVuY2VJZCI6Ijk2OTQ2ZWQ0LTRiZDEtNDBkOS05Y2I2LTQ4NjExMjlhZDVkYyIsIlJldHVyblVybCI6Imh0dHBzOi8vb3Blbi1uYS5hbGlwYXkuY29tL2FwaS9vcGVuL3VybF9jYWxsYmFja19nZXQvY2FyZGluYWwvY2FyZGluYWwwMDcuaHRtP3NpZ25EYXRhPWpKa1IlMkZQdnYweldCeEZvJTJCOUtXM1B5TFZDM2h4WHpkUEVVQWpHRmszQjR0anJ4eW5LTHRKJTJGR3pMekZFR1RYSEVhcWlJd05Jb2xqTW0xUEw2MlllYVFFZUU4S2pYeVNCUUt0M01iMVBNbEo0dXolMkY2WHllSW5UJTJCZW92QWJXSDclMkJDc0V1RmtqckdwOHpQYmJkMDA1M0IlMkYlMkZhcXc3VEN5RklXQXdWOGkxcyUyQjE5R1pzTXJKZGpoRkk4NVc5RjVvWTBJclZrQTlsRSUyRk5VZ1p6c3N0VGtSVFFVYjl0azJTbmM5WGJBZ096JTJCek5MNkc3UlhTeURNanNtZ0pqR0pWdjVDWUpFR3htaSUyRjVWMk5MRlBRZ3Nrd1RPSEdCVlVMY1VGM1RUaXhHM0JnbjlsdXlDU0hvbnN1RHY5M0Q3bnhXZ3gzS2JsSloxY1hVbGxaU2Q4V2Q2bVU5VGZiZyUzRCUzRCZpblNlcmlhbE5vPTIwMjYwMzEzODkwMzEzNDEwMDAxSjM3NDMyNTc3MjQmb3V0T3JkZXJObz0yMDI2MDMxMzg5MDMxMzQxMDAwMUozNzQzMjU3NzI0IiwiZXhwIjoxNzczMzg1MDc4LCJpYXQiOjE3NzMzODQxNzgsImlzcyI6IjVkNWZkZGU4Y2NlZjc2MWFkOGI4MmI2OCIsImp0aSI6IjIwMjYwMzEzODkwMzEzNDEwMDAxSjM3NDMyNTc3MjQifQ.hBMn31v0ntxmMhDjqnYByylVufj7EjUyZj55WPivQu4",
"DDCFlag": "Y"
},
"paymentActionFormType": "RedirectActionForm",
"redirectUrl": "https://iexpfront-sea.alipay.com/authorise3d?merchantId=1887SjzZ56b1lvObJWQTaqG4PhACjUGncnl0Sihzg8en5I%3D&ddcId=m47qH0MLK7A7yJNVdjLYJMrfAGZ7ZPgbv5TmV3FoZ4U%3D&pass=lt%5E1&needDDC=Y&from=iexpcore"
},
"paymentAmount": {
"currency": "SGD",
"value": "4200"
},
"paymentCreateTime": "2026-03-12T23:42:56-07:00",
"paymentId": "2026031319401****1001881J0284139383",
"paymentRequestId": "713c6f16-fca5-4507-8291-beea32dc****",
"paymentResultInfo": {
"cardBrand": "VISA",
"cardNo": "************1111",
"credentialTypeUsed": "PAN",
"threeDSResult": {}
},
"redirectActionForm": {
"method": "POST",
"parameters": {
"Bin": "411111",
"JWT": "eyJraWQiOiJDQVJESU5BTF9KV1RfYWxpcGF5IiwiY3R5I*****SRElOQUxfSldUX2FsaXBheSIsImFsZyI6IkhTMjU2In0.eyJPcmdVbml0SWQiOiI1ZDVmMTA2MjRiNzkyYTFhZTBkN2Y3MTEiLCJSZWZlcmVuY2VJZCI6Ijk2OTQ2ZWQ0LTRiZDEtNDBkOS05Y2I2LTQ4NjExMjlhZDVkYyIsIlJldHVyblVybCI6Imh0dHBzOi8vb3Blbi1uYS5hbGlwYXkuY29tL2FwaS9vcGVuL3VybF9jYWxsYmFja19nZXQvY2FyZGluYWwvY2FyZGluYWwwMDcuaHRtP3NpZ25EYXRhPWpKa1IlMkZQdnYweldCeEZvJTJCOUtXM1B5TFZDM2h4WHpkUEVVQWpHRmszQjR0anJ4eW5LTHRKJTJGR3pMekZFR1RYSEVhcWlJd05Jb2xqTW0xUEw2MlllYVFFZUU4S2pYeVNCUUt0M01iMVBNbEo0dXolMkY2WHllSW5UJTJCZW92QWJXSDclMkJDc0V1RmtqckdwOHpQYmJkMDA1M0IlMkYlMkZhcXc3VEN5RklXQXdWOGkxcyUyQjE5R1pzTXJKZGpoRkk4NVc5RjVvWTBJclZrQTlsRSUyRk5VZ1p6c3N0VGtSVFFVYjl0azJTbmM5WGJBZ096JTJCek5MNkc3UlhTeURNanNtZ0pqR0pWdjVDWUpFR3htaSUyRjVWMk5MRlBRZ3Nrd1RPSEdCVlVMY1VGM1RUaXhHM0JnbjlsdXlDU0hvbnN1RHY5M0Q3bnhXZ3gzS2JsSloxY1hVbGxaU2Q4V2Q2bVU5VGZiZyUzRCUzRCZpblNlcmlhbE5vPTIwMjYwMzEzODkwMzEzNDEwMDAxSjM3NDMyNTc3MjQmb3V0T3JkZXJObz0yMDI2MDMxMzg5MDMxMzQxMDAwMUozNzQzMjU3NzI0IiwiZXhwIjoxNzczMzg1MDc4LCJpYXQiOjE3NzMzODQxNzgsImlzcyI6IjVkNWZkZGU4Y2NlZjc2MWFkOGI4MmI2OCIsImp0aSI6IjIwMjYwMzEzODkwMzEzNDEwMDAxSjM3NDMyNTc3MjQifQ.hBMn31v0ntxmMhDjqnYByylVufj7EjUyZj55WPivQu4",
"DDCFlag": "Y"
},
"redirectUrl": "https://iexpfront-sea.alipay.com/authorise3d?merchantId=1887SjzZ56b1lvObJWQTaqG4PhACjUGncnl0Sihzg8en5I%3D&ddcId=m47qH0MLK7A7yJNVdjLYJMrfAGZ7ZPgb****V3FoZ4U%3D&pass=lt%5E1&needDDC=Y&from=iexpcore"
},
"result": {
"resultCode": "PAYMENT_IN_PROCESS",
"resultMessage": "payment in process",
"resultStatus": "U"
}
}
The following illustrates the payment flow for the subsequent periodic deductions process using merchant-decrypted paymentToken:
The following illustrates the payment flow for the subsequent periodic deductions process using merchant-decrypted paymentToken:
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.
Follow these steps to start the integration:
- Obtain paymentToken
- Create a subscription payment request
- (Optional) Redirect to the 3DS authentication page
- Obtain the authorization result
- Capture and recieve the capture notification
- Recieve subscription notifications
Step 1: Obtain paymentToken
After you obtain paymentToken, you can choose the merchant decryption method to decrypt the token and call the pay (One-time Payments) API to initiate an authorized payment request. Step 2: Create a subscription payment request
Server-side
After integrating the Google Pay SDK, you can obtain the paymentToken through Direct tokenization. For details, please refer to Payment data encryption for merchants. After obtaining the paymentToken and completing the decryption, please pass the corresponding parameters according to the card transaction authentication scenario (PAN_ONLY
or CRYPTOGRAM_3DS
) in the decryption result, and call the pay (One-time Payments) API to initiate an authorization payment request. Note: Using this mode requires that you are PCI-qualified and you have uploaded the PCI proof to the Google Pay backend. The following code demonstrates the retrieved Google Pay message, covering two card transaction authentication scenarios: PAN_ONLY
and CRYPTOGRAM_3DS
: PAN_ONLY
: This authentication method is associated with payment cards stored in the buyer's Google account. In this scenario, the decrypted card information obtained is FPAN.CRYPTOGRAM_3DS
: This authentication method is associated with cards stored as tokens on Android devices. In this scenario, the decrypted card information obtained is DPAN.
"paymentMethod": "CARD",
"paymentMethodDetails": {
"authMethod": "PAN_ONLY",
"pan": "1111222233334444",
"expirationMonth": 10,
"expirationYear": 2020
}, "gatewayMerchantId": "some-merchant-id", "messageId": "some-message-id",
"messageExpiration": "1577862000000"
}
When the card transaction authentication scenario in the decryption result is PAN_ONLY
(that is, when the card information type obtained after decryption is FPAN), the key Google Pay parameters in the request are listed below: public static void payByGooglePayServer2Server() {
AlipayPayRequest alipayPayRequest = new AlipayPayRequest();
alipayPayRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
// Replace with your paymentRequestId
String paymentRequestId = UUID.randomUUID().toString();
alipayPayRequest.setPaymentRequestId(paymentRequestId);
// Set subscription information
SubscriptionInfo subscriptionInfo = new SubscriptionInfo();
subscriptionInfo.setSubscriptionDescription("Subscription test");
LocalDateTime localNow = LocalDateTime.now();
OffsetDateTime offsetDateTime = localNow.atOffset(ZoneOffset.of("+08:00"));
String startTime = offsetDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
subscriptionInfo.setSubscriptionStartTime(startTime);
subscriptionInfo.setSubscriptionNotifyUrl("https://www.yourDomain.com/subscription/notify");
PeriodRule periodRule = new PeriodRule();
periodRule.setPeriodType("MONTH");
periodRule.setPeriodCount(1);
subscriptionInfo.setPeriodRule(periodRule);
alipayPayRequest.setSubscriptionInfo(subscriptionInfo);
// Set payment amount
Amount amount = Amount.builder().currency("SGD").value("4200").build();
alipayPayRequest.setPaymentAmount(amount);
// Set settlement strategy
SettlementStrategy settlementStrategy = SettlementStrategy.builder().settlementCurrency("SGD").build();
alipayPayRequest.setSettlementStrategy(settlementStrategy);
// Set payment method - PAN_ONLY scenario
PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("GOOGLEPAY").build();
alipayPayRequest.setPaymentMethod(paymentMethod);
// Set Google Pay related parameters -- merchant decryption
Map<String, Object> paymentMethodMetaData = new HashMap<>();
paymentMethodMetaData.put("cardNo", "4054695723100768");
paymentMethodMetaData.put("cvv", "123");
paymentMethodMetaData.put("expiryMonth", "12");
paymentMethodMetaData.put("expiryYear", "99");
paymentMethodMetaData.put("tokenizeMode", false);
paymentMethodMetaData.put("is3DSAuthentication", true);
paymentMethod.setPaymentMethodMetaData(paymentMethodMetaData);
// 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 testing order").orderAmount(amount).buyer(buyer).build();
alipayPayRequest.setOrder(order);
// Set device environment information
Env env = Env.builder().terminalType(TerminalType.WEB).clientIp("1.2.3.4").build();
alipayPayRequest.setEnv(env);
// Set authorization capture mode
PaymentFactor paymentFactor = PaymentFactor.builder().isAuthorization(true).build();
alipayPayRequest.setPaymentFactor(paymentFactor);
// Replace with your notification URL
alipayPayRequest.setPaymentNotifyUrl("https://www.yourNotifyUrl.com");
// Replace with your redirect URL
alipayPayRequest.setPaymentRedirectUrl("https://www.yourMerchantWeb.com");
// Execute payment
AlipayPayResponse alipayPayResponse = null;
try {
alipayPayResponse = CLIENT.execute(alipayPayRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// Handle error case
}
}
The following shows the sample code of a request:
{
"env": {
"clientIp": "1.2.3.4",
"terminalType": "WEB"
},
"order": {
"buyer": {
"referenceBuyerId": "yourBuyerId"
},
"orderAmount": {
"currency": "SGD",
"value": "4200"
},
"orderDescription": "antom testing order",
"referenceOrderId": "daa64b56-0850-4d08-a322-370ac8fa6891"
},
"paymentAmount": {
"currency": "SGD",
"value": "4200"
},
"paymentFactor": {
"isAuthorization": true
},
"paymentMethod": {
"paymentMethodMetaData": {
"cvv": "123",
"is3DSAuthentication": true,
"expiryMonth": "12",
"expiryYear": "99",
"cardNo": "4054695723100768",
"tokenizeMode": false
},
"paymentMethodType": "GOOGLEPAY"
},
"paymentNotifyUrl": "https://www.yourNotifyUrl.com",
"paymentRedirectUrl": "https://www.yourMerchantWeb.com",
"paymentRequestId": "a1513804-d4ab-4dc8-9ec5-775e3aeb6587",
"productCode": "CASHIER_PAYMENT",
"settlementStrategy": {
"settlementCurrency": "SGD"
},
"subscriptionInfo": {
"periodRule": {
"periodCount": 1,
"periodType": "MONTH"
},
"subscriptionDescription": "Subscription test",
"subscriptionNotifyUrl": "https://www.yourDomain.com/subscription/notify",
"subscriptionStartTime": "2026-03-13T15:29:13.475+08:00"
}
}
The following shows the sample code of a response:
{
"normalUrl": "https://iexpfront-sea.alipay.com/authorise3d?merchantId=1887SjzZ56b1lvObJWQTaqG4PhACjUGncnl0Sihzg8en5I%3D&ddcId=m47qH0MLK7A7yJNVdjLYJBM4I4E%2B6F%2****8QutUHkz0%3D&pass=lt%5E1&needDDC=Y&from=iexpcore",
"paymentActionForm": "{"method":"POST","parameters":"{\"JWT\":\"eyJraWQiOiJDQVJESU5BTF9KV1RfYWxpcGF5IiwiY3R5IjoiQ0FSRElOQUxfSldUX2FsaXBheSIsImFsZyI6IkhTMjU2In0.eyJPcmdVbml0SWQiOiI1ZD*****2MjRiNzkyYTFhZTBkN2Y3MTEiLCJSZWZlcmVuY2VJZCI6ImEzMTFmNTE4LTY2ZjQtNGQzMC1hMmFhLTI2ZWU0YmI5NjMzMSIsIlJldHVyblVybCI6Imh0dHBzOi8vb3Blbi1uYS5hbGlwYXkuY29tL2FwaS9vcGVuL3VybF9jYWxsYmFja19nZXQvY2FyZGluYWwvY2FyZGluYWwwMDcuaHRtP3NpZ25EYXRhPUdGWUhkWUl2VFBjZE9sJTJCdUl5emk3VG5RbHYwWlNaWG5jaVlOM3NQb0JCUXMlMkZLMXZhdThaVTJwR1hHUVRNVndieVFOV3V5OElMV0p6b2dIdExzbFJ0U3BhYVNUbGpsY3doQ1pRTnNaM2U3JTJGcVVMZFBUNElEYUJvQ1pkTERFTkFiS0NFd3pzQSUyQjF1UFk1dU1neE5zRmt4dSUyQkhXZVpSaldDekplRVNGVUtqMUMwNyUyRkpleGVTZmltRDBEN1dvemJKdmlud2pObjZ5bko3RGVuVTl1a2NRSXlkeFNSJTJGJTJCUWc4TTNUMGNHMFZuWkdXN2xUZ25OcExEd0ZHUlZlJTJCWlFSM2xpQTEyUkE2TjZjTmo1VTVpM0VpUk8yNHRRczVWWmJOTyUyRkFDdHZBWmxmR0hjbXdldyUyQmNBQ0doR3gyNjI0emplNmZGOGZZY1djbGJJYVNkckxJazMzWlElM0QlM0QmaW5TZXJpYWxObz0yMDI2MDMxMzg5MDMxMzQxMDAwMkoyNTQzNjY1OTAzJm91dE9yZGVyTm89MjAyNjAzMTM4OTAzMTM0MTAwMDJKMjU0MzY2NTkwMyIsImV4cCI6MTc3MzM4Nzg1NiwiaWF0IjoxNzczMzg2OTU2LCJpc3MiOiI1ZDVmZGRlOGNjZWY3NjFhZDhiODJiNjgiLCJqdGkiOiIyMDI2MDMxMzg5MDMxMzQxMDAwMkoyNTQzNjY1OTAzIn0.6ZPZv8AflJ10Nwpjj22WTXKrG6J6ldthzJiGcEHrYwg\",\"Bin\":\"405469\",\"DDCFlag\":\"Y\"}","paymentActionFormType":"RedirectActionForm","redirectUrl":"https://iexpfront-sea.alipay.com/authorise3d?merchantId=1887SjzZ56b1lvObJWQTaqG4PhACjUGncnl0Sihzg8en5I%3D&ddcId=m47qH0MLK7A7yJNVdjLYJBM4I4E%2B6F%2BWD98QutUHkz0%3D&pass=lt%5E1&needDDC=Y&from=iexpcore"}",
"paymentAmount": {
"currency": "SGD",
"value": "4200"
},
"paymentCreateTime": "2026-03-13T00:29:15-07:00",
"paymentId": "202603131940108001001882J0282278120",
"paymentRequestId": "a1513804-d4ab-4dc8-9ec5-775e3aeb6587",
"paymentResultInfo": {
"cardBrand": "VISA",
"cardNo": "************0768",
"credentialTypeUsed": "PAN",
"threeDSResult": {
}
},
"paymentTime": "2026-03-13T00:29:16-07:00",
"redirectActionForm": {
"method": "POST",
"parameters": "{"JWT":"eyJraWQiOiJDQVJESU5BTF9KV1RfYWxpcGF5IiwiY3R5IjoiQ0FSRElOQUxfSldUX2FsaXBheSIsImFsZyI6IkhTMjU2In0.eyJPcmdVbml0SWQiOiI1ZDVmMTA2MjRiNzkyYTFhZTBkN2Y3MTEiLCJSZWZlcmVuY2VJZCI6Im****FmNTE4LTY2ZjQtNGQzMC1hMmFhLTI2ZWU0YmI5NjMzMSIsIlJldHVyblVybCI6Imh0dHBzOi8vb3Blbi1uYS5hbGlwYXkuY29tL2FwaS9vcGVuL3VybF9jYWxsYmFja19nZXQvY2FyZGluYWwvY2FyZGluYWwwMDcuaHRtP3NpZ25EYXRhPUdGWUhkWUl2VFBjZE9sJTJCdUl5emk3VG5RbHYwWlNaWG5jaVlOM3NQb0JCUXMlMkZLMXZhdThaVTJwR1hHUVRNVndieVFOV3V5OElMV0p6b2dIdExzbFJ0U3BhYVNUbGpsY3doQ1pRTnNaM2U3JTJGcVVMZFBUNElEYUJvQ1pkTERFTkFiS0NFd3pzQSUyQjF1UFk1dU1neE5zRmt4dSUyQkhXZVpSaldDekplRVNGVUtqMUMwNyUyRkpleGVTZmltRDBEN1dvemJKdmlud2pObjZ5bko3RGVuVTl1a2NRSXlkeFNSJTJGJTJCUWc4TTNUMGNHMFZuWkdXN2xUZ25OcExEd0ZHUlZlJTJCWlFSM2xpQTEyUkE2TjZjTmo1VTVpM0VpUk8yNHRRczVWWmJOTyUyRkFDdHZBWmxmR0hjbXdldyUyQmNBQ0doR3gyNjI0emplNmZGOGZZY1djbGJJYVNkckxJazMzWlElM0QlM0QmaW5TZXJpYWxObz0yMDI2MDMxMzg5MDMxMzQxMDAwMkoyNTQzNjY1OTAzJm91dE9yZGVyTm89MjAyNjAzMTM4OTAzMTM0MTAwMDJKMjU0MzY2NTkwMyIsImV4cCI6MTc3MzM4Nzg1NiwiaWF0IjoxNzczMzg2OTU2LCJpc3MiOiI1ZDVmZGRlOGNjZWY3NjFhZDhiODJiNjgiLCJqdGkiOiIyMDI2MDMxMzg5MDMxMzQxMDAwMkoyNTQzNjY1OTAzIn0.6ZPZv8AflJ10Nwpjj22WTXKrG6J6ldthzJiGcEHrYwg","Bin":"405469","DDCFlag":"Y"}",
"redirectUrl": "https://iexpfront-sea.alipay.com/authorise3d?merchantId=1887SjzZ56b1lvObJWQTaqG4PhACjUGncnl0Sihzg8en5I%3D&ddcId=m47qH0MLK7A7yJNVdjLYJBM4I4E%2B6F%2BWD98Qu****0%3D&pass=lt%5E1&needDDC=Y&from=iexpcore"
},
"result": {
"resultCode": "PAYMENT_IN_PROCESS",
"resultMessage": "payment in process",
"resultStatus": "U"
}
}
{
"paymentMethod": "CARD",
"paymentMethodDetails": {
"authMethod": "CRYPTOGRAM_3DS",
"pan": "1111222233334444",
"expirationMonth": 10,
"expirationYear": 2020,
"cryptogram": "AAAAAA...",
"eciIndicator": "eci indicator"
},
"messageId": "some-message-id",
"messageExpiration": "1577862000000"
}
When the card transaction authentication scenario in the decryption result is CRYPTOGRAM_3DS
(that is, when the card information type obtained after decryption is DPAN), the key Google Pay parameters in the request are listed below: public static void payByGooglePayServer2Server() {
AlipayPayRequest alipayPayRequest = new AlipayPayRequest();
alipayPayRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
// Replace with your paymentRequestId
String paymentRequestId = UUID.randomUUID().toString();
alipayPayRequest.setPaymentRequestId(paymentRequestId);
// Set subscription information
SubscriptionInfo subscriptionInfo = new SubscriptionInfo();
subscriptionInfo.setSubscriptionDescription("Subscription test");
LocalDateTime localNow = LocalDateTime.now();
OffsetDateTime offsetDateTime = localNow.atOffset(ZoneOffset.of("+08:00"));
String startTime = offsetDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
subscriptionInfo.setSubscriptionStartTime(startTime);
subscriptionInfo.setSubscriptionNotifyUrl("https://www.yourDomain.com/subscription/notify");
PeriodRule periodRule = new PeriodRule();
periodRule.setPeriodType("MONTH");
periodRule.setPeriodCount(1);
subscriptionInfo.setPeriodRule(periodRule);
alipayPayRequest.setSubscriptionInfo(subscriptionInfo);
// Set payment amount
Amount amount = Amount.builder().currency("SGD").value("4200").build();
alipayPayRequest.setPaymentAmount(amount);
// Set settlement strategy
SettlementStrategy settlementStrategy = SettlementStrategy.builder().settlementCurrency("SGD").build();
alipayPayRequest.setSettlementStrategy(settlementStrategy);
// Set payment method - CRYPTOGRAM_3DS scenario
PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("GOOGLEPAY").build();
alipayPayRequest.setPaymentMethod(paymentMethod);
// Set MpiData information -- CRYPTOGRAM_3DS scenario
Map<String, Object> paymentMethodMetaData = new HashMap<>();
paymentMethodMetaData.put("cardNo", "4054695723100768");
paymentMethodMetaData.put("cvv", "123");
paymentMethodMetaData.put("expiryMonth", "12");
paymentMethodMetaData.put("expiryYear", "99");
MpiData mapiDate = new MpiData();
mapiDate.setCavv("googlePay cryptogram");
mapiDate.setEci("eci indicator");
paymentMethodMetaData.put("mpiData", mapiDate);
paymentMethod.setPaymentMethodMetaData(paymentMethodMetaData);
// 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 testing order").orderAmount(amount).buyer(buyer).build();
alipayPayRequest.setOrder(order);
// Set environment information
Env env = Env.builder().terminalType(TerminalType.WEB).clientIp("1.2.3.4").build();
alipayPayRequest.setEnv(env);
// Set authorization capture mode
PaymentFactor paymentFactor = PaymentFactor.builder().isAuthorization(true).build();
alipayPayRequest.setPaymentFactor(paymentFactor);
// Replace with your notification URL
alipayPayRequest.setPaymentNotifyUrl("https://www.yourNotifyUrl.com");
// Replace with your redirect URL
alipayPayRequest.setPaymentRedirectUrl("https://www.yourMerchantWeb.com");
// Execute payment
AlipayPayResponse alipayPayResponse = null;
try {
alipayPayResponse = CLIENT.execute(alipayPayRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
System.out.println("支付失败: " + errorMsg);
// Handle error case
}
}
The following shows the sample code of a request:
{
"env": {
"clientIp": "1.2.3.4",
"terminalType": "WEB"
},
"order": {
"buyer": {
"referenceBuyerId": "yourBuyerId"
},
"orderAmount": {
"currency": "SGD",
"value": "4200"
},
"orderDescription": "antom testing order",
"referenceOrderId": "b2ad9478-2eec-4aee-8403-13432ca66a38"
},
"paymentAmount": {
"currency": "SGD",
"value": "4200"
},
"paymentFactor": {
"isAuthorization": true
},
"paymentMethod": {
"paymentMethodMetaData": {
"cvv": "123",
"expiryMonth": "12",
"expiryYear": "99",
"cardNo": "4054695723100768",
"mpiData": {
"cavv": "googlePay cryptogram",
"eci": "eci indicator"
}
},
"paymentMethodType": "GOOGLEPAY"
},
"paymentNotifyUrl": "https://www.yourNotifyUrl.com",
"paymentRedirectUrl": "https://www.yourMerchantWeb.com",
"paymentRequestId": "383bc587-0a45-479c-8e2a-ef719c0e9b93",
"productCode": "CASHIER_PAYMENT",
"settlementStrategy": {
"settlementCurrency": "SGD"
},
"subscriptionInfo": {
"periodRule": {
"periodCount": 1,
"periodType": "MONTH"
},
"subscriptionDescription": "Subscription test",
"subscriptionNotifyUrl": "https://www.yourDomain.com/subscription/notify",
"subscriptionStartTime": "2026-03-13T15:47:56.201+08:00"
}
}
The following shows a sample code of a response:
{
"authExpiryTime": "2026-03-20T00:47:59-07:00",
"paymentAmount": {
"currency": "SGD",
"value": "4200"
},
"paymentCreateTime": "2026-03-13T00:47:58-07:00",
"paymentId": "20260313194010****001884C0282432224",
"paymentRequestId": "383bc587-0a45-479c-8e2a-ef719c0e****",
"paymentResultInfo": {
"avsResultRaw": "I",
"cardBrand": "VISA",
"cardNo": "************0768",
"credentialTypeUsed": "PAN",
"cvvResultRaw": "P",
"networkTransactionId": "2026031389031****004C9843804231",
"threeDSResult": {
"cavv": "",
"eci": ""
}
},
"paymentTime": "2026-03-13T00:47:59-07:00",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}
(Optional) Step 3: Redirect to the 3DS authentication page
Client-side
Note: In the Google Pay scenario, when Antom hosts decryption of paymentToken or you decrypt paymentToken yourself and the received information is FPAN, the returned normalUrl is the 3DS authentication page. Step 4: Obtain the authorization result
Server-side
Step 5: Capture and recieve the capture notification
Server-side
Note:
- Only successful authorized payments will trigger capture.
- Shipping desicion should be based on the capture result.
After successful authorization, Antom will automatically initiate capture for you, or you can choose to initiate capture manually. Meanwhile, Antom will send the capture result notification to you via the notifyCapture (One-time Payments) API, or you can proactively query to obtain the capture result. Shipping of goods should be based on the capture result. For detailed steps, refer to Capture. Step 6: Recieve subscription notifications
Server-side
After the subscription takes effect, Antom will send the following notifications:
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:
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. For successful payments, if the buyer requests cancellation or a refund on the same day, you can use Antom’s cancellation capability to cancel the order or release funds. Orders not yet completed can also be cancelled directly. For details, refer to Cancel. To learn about Antom refund rules and how to initiate a refund for a successful transaction, see Refund for more information. 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, refer to Reconciliation.