Embedded mode
APO 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 SDK, where the APO Checkout Page is embedded into your product purchase page for buyers to make payment.
User experience
The image shows the user experience where the APO Checkout Page is embedded into the merchant page:
The image shows the user experience for scenarios where certain payment methods redirect to the corresponding payment page within the embedded Checkout Page:
Note:
- Currently, APO embedded CKP is only supported on PC and mobile (H5), but not supported on mobile apps.
- APO embedded CKP is not supported on Apple Pay, integrate APO hosted CKP instead.
Payment flow
The following process shows how to integrate the embedded CKP:
- The buyer places an order in the merchant side.
- Create a payment session request.
When a buyer places an order on the merchant side, you need to call the createPaymentSession API to obtain the paymentSessionData that calls the SDK.
- Invoke the client SDK.
The merchant server uses the paymentSessionData to call the SDK embedded Checkout Page component in the merchant web page, and then the buyer submits the payment in the Checkout Page component, and the SDK will process the payment process.
- Get the payment result.
You can retrieve payment results through asynchronous notifications. Configure the paymentNotifyUrl parameter in the createPaymentSession API to specify the URL to receive asynchronous notifications. APO sends an asynchronous notification through the notifyPayment API when a payment request succeeds or expires.
Notes:
- For transactions paid with cards, Google Pay, or PayPal, APO will send capture results to you via the notifyCapture API. It is recommended to confirm the successful capture result before shipping.
- If the payment method is linked to multiple acquirers, you can configure routing rules on APO Dashboard. Otherwise, APO will use random routing rules.
Integration preparations
- Integrate the APO server-side SDK package, install the server-side library and initialize a request instance. For more details, refer to Server-side SDKs.
- Refer to Integrate the SDK Package for Web/WAP to complete integration preparations, and ensure to use SDK 1.41.0 or above.
Integration steps
Follow these steps to start the integration:
- Create a payment session
- Embed the APO Checkout Page
- Process asynchronous notifications
Step 1: Create a payment session
You can specify the desired payment methods when you activate APO services. For payment method configurations, see Specify a payment method. When the buyer makes a payment, you need to collect key information, such as the payment request ID, order details, payment redirect URL, and payment notification URL. Call the createPaymentSession API to create a payment session and redirect to the APO Checkout Page.
1. Call the createPaymentSession API
The following sample code shows how to call the createPaymentSession API:
public static void createPaymentSession() {
AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.CHECKOUT_PAYMENT);
// set 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 info
Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();
// set goods info
Goods goods = Goods.builder().goodsBrand("Antom Brand").goodsCategory("outdoor goods/bag").goodsName("Classic Woman Bag").goodsQuantity("1")
.goodsSkuName("Black").goodsImageUrl("https://mdn.alipayobjects.com/portal_pdqp4x/afts/file/A*H8M9RrxlArAAAAAAAAAAAAAAAQAAAQ")
.goodsUnitAmount(amount).goodsUrl("https://yourGoodsUrl").referenceGoodsId("yourGoodsId").build();
// set order info
Order order = Order.builder().referenceOrderId(orderId)
.orderDescription("antom ckp testing order").orderAmount(amount).buyer(buyer).goods(Stream.of(goods).collect(Collectors.toList())).build();
alipayPaymentSessionRequest.setOrder(order);
// replace with your notify url
// or configure your notify url here: <a href="https://dashboard.antom.com/global-payments/developers/iNotify">Notification URL</a>
alipayPaymentSessionRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com/payment/receiveNotify");
// replace with your redirect url
alipayPaymentSessionRequest.setPaymentRedirectUrl(
"http://localhost:8080/index.html?paymentRequestId=" + paymentRequestId);
AlipayPaymentSessionResponse alipayPaymentSessionResponse;
try {
System.out.println("paymentSession request: " + JSON.toJSONString(alipayPaymentSessionRequest));
alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
System.out.println("paymentSession response: " + JSON.toJSONString(alipayPaymentSessionResponse));
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// handle error condition
}
}
2. Create a payment session
If your payment methods include card payments, buyer information from the merchant side must be provided in the payment session parameters. For details, please refer to Card payments.
Creating a payment session includes the following parameters:
Field Type | Field Name | Whether required | Description |
Base fields | productCode | Yes | The value of this field in this scenario is fixed as CASHIER_PAYMENT . |
productScene | Yes | The value of this field in this scenario is fixed as CHECKOUT_PAYMENT . | |
paymentRequestId | Yes | The unique ID assigned by a merchant to identify a payment request. | |
paymentAmount | Yes | The payment amount that the merchant requests to receive in the order currency. The amount to charge is a positive integer in the smallest currency unit, e.g., CNY in fen and KRW in won. | |
paymentRedirectUrl | Yes | The merchant page URL that the buyer is redirected to after the payment is completed. The display bases on server-side results, not fixes as a result page. It must be an HTTPS URL. | |
paymentNotifyUrl | No | The URL that is used to receive the payment result notification. You can set the URL to receive the notification via API or on APO Dashboard. If the notification URL is set on APO Dashboard, you do not need to pass this parameter through the API. The URL must be in HTTPS. | |
settlementStrategy | No | This field is only applicable when the acquirer is Antom. The settlement strategy for the payment request. Specify the settlementCurrency parameter in the API if you signed up for multiple settlement currencies. | |
locale | No | Language tag specified for the Checkout Page. If the provided language is not supported, the default language setting of the browser will be used, which is usually English. | |
Order fields | order.orderAmount | Yes | Order amount. |
order.referenceOrderId | Yes | Order ID. | |
order.orderDescription | Yes | Order description. |
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.
The following shows the sample code of a request:
{
"order": {
"buyer": {
"referenceBuyerId": "yourBuyerId"
},
"goods": [
{
"goodsBrand": "Antom Brand",
"goodsCategory": "outdoor goods/bag",
"goodsImageUrl": "https://mdn.alipayobjects.com/portal_pdqp4x/afts/file/A*H8M9RrxlArAAAAAAAAAAAAAAAQAAAQ",
"goodsName": "Classic Woman Bag",
"goodsQuantity": "1",
"goodsSkuName": "Black",
"goodsUnitAmount": {
"currency": "SGD",
"value": "6000"
},
"goodsUrl": "https://yourGoodsUrl",
"referenceGoodsId": "yourGoodsId"
}
],
"orderAmount": {
"currency": "SGD",
"value": "6000"
},
"orderDescription": "antom ckp testing order",
"referenceOrderId": "c3df9b82-ff67-424b-880b-06c3615****"
},
"paymentAmount": {
"currency": "SGD",
"value": "6000"
},
"paymentFactor":{
"isAuthorization":true
},
"paymentNotifyUrl": "http://www.yourNotifyUrl.com/payment/receiveNotify",
"paymentRedirectUrl": "http://localhost:8080/index.html?paymentRequestId=597795b7-c812-4132-bd7d-c55914ee****",
"paymentRequestId": "597795b7-c812-4132-bd7d-c55914ee****",
"productCode": "CASHIER_PAYMENT",
"productScene": "CHECKOUT_PAYMENT"
}
The following shows the sample code of a response, which contains the following parameters:
- paymentSessionData: The encrypted payment session data. Pass the data to your 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 (In APO embedded CKP scenario, this field can be ignored.).
{
"normalUrl": "https://checkout.antom.com/checkout-page/pages/payment/index.html?sessionData=1iwX2rH5kXnUGT5372d0kHD7PwcgPmRSMgAsvKs8hqRkqobbtWbep59PU2eO5w72h%2B%2XXXX",
"paymentSessionData": "1iwX2rH5kXnUGT5372d0kHD7PwcgPmRSMgAsvKs8hqRkqobbtWbep59PU2eO5w72h+/c278B+P+nDVNzrQySQQ==&&SG&&188&&eyJleHRlbmRJbmZvIjoie1wiT1BFTl9NVUxUSXXXX",
"paymentSessionExpiryTime": "2025-03-19T16:21:06+08:00",
"paymentSessionId": "1iwX2rH5kXnUGT5372d0kHD7PwcgPmRSMgAsvKs8hqSln4WiVZXXXX",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}
The table shows the possible values that the result.resultStatus field in the request message may return. Please handle the result according to the guidances:
result.resultStatus | Message | Further actions |
S | Indicates that payment session creation succeeded. | The merchant server can use paymentSessionData to call the SDK. |
U | Indicates that payment session creation failed for unknown reasons. |
Change the paymentRequestId and call the API again to resolve the issue. Please contact APO technical support if the problem persists. |
F | Indicates that the payment session creation failed. | Check and verify whether the current API required request fields (including header fields and body fields) are correctly passed and valid.
|
Note: If you did not receive a response message, it might be due to a network timeout. Change the paymentRequestId and call the API again to resolve the issue.
Step 2: Embed APO Checkout Page
The SDK is a component used to handle the payment process. To collect information and switch between applications based on the payment method specified in the createPaymentSession API, you need to use the paymentSessionDataobtained from the creation of the payment session to initialize the SDK, seamlessly embedding the APO Checkout Page into the web payment interface. Once the buyer submits a payment request on this page, the SDK will automatically perform encrypted communication, risk verification, and payment instruction processing, achieving end-to-end payment closed-loop management.
1. Instantiate the SDK
Use AMSCheckoutPage
to create an SDK instance. The configuration object includes the following parameters:
Parameter Name | Required | Description |
environment | Yes | It is used to pass in environmental information. Valid values are:
|
onEventCallback | Optional | A callback function returns a specific event code when a payment event happens during SDK runtime, like payment result or a form submission error. For further information, refer to SDK References. |
The following sample code shows how to instantiate the SDK:
npm:
import { AMSCheckoutPage } from '@alipay/ams-checkout' // Package manager
const checkoutApp = new AMSCheckoutPage({
environment: "sandbox",
onEventCallback: ({code, message}) => {},
});
cdn:
// Under CDN method: Use window.AMSCheckoutPage to instantiate
const checkoutApp = new AMSCheckoutPage({
environment: "sandbox",
onEventCallback: ({code, message}) => {},
});
2. Invoke the SDK
When the buyer places an order and redirects to the APO Checkout Page, you need to create the SDK and instantiate it with a payment session.
Create a DOM node
On your checkout page, create a DOM node to embed the APO Checkout Page component.
<div class="content">
<div class="checkout-container" id="ckp-embed-wrapper"></div>
</div>
Create the component
Use the mountComponent
function in the instance object to create the APO Checkout Page component:
Parameter Name | Required | Description |
sessionData | Yes | Create a configuration object using the sessionData parameter. Pass the complete paymentSessionData parameter obtained in the createPaymentSession API response to the sessionData parameter. |
async function create(sessionData) {
await checkoutApp.mountComponent({
sessionData: sessionData,
},'#ckp-embed-wrapper');
}
Destroy the component
Call the unmount
method to free SDK component resources in the following situations:
- When the buyer switches views away from the checkout page, free the component resources created in createPaymentSession.
- When the buyer initiates multiple payments, free the previously created component resources in createPaymentSession.
- Free the component resources after obtaining the final payment result codes.
// Free SDK component resources
checkoutApp.unmount();
3. Process payment results
The payment result will be returned by the onEventCallback
function. You need to customize the processing flow you want for each payment result through the data in the result of onEventCallback
. The payment result here is only for front-end display, and the final order status is subject to the server side.
The following are the possible event codes of the payment result returned by onEventCallback
:
Event Code | Message | Further actions |
SDK_PAYMENT_SUCCESSFUL | Payment is successful. | It is recommended to redirect the buyer to the payment result page. |
SDK_PAYMENT_FAIL | Payment failed. | It is recommended that you check the value of paymentResultCode in the |
SDK_PAYMENT_CLICK_BACK_TO_MERCHANT | Event that is triggered when the buyer clicks the Back to merchant control on the results page. | It is recommended to redirect the buyer to the payment result page. |
SDK_PAYMENT_CANCEL | The buyer exits the payment page without submitting the order. | The SDK can be reinvoked with paymentSessionData within the validity period; if it has expired, paymentSessionData needs to be requested again. |
The following sample code shows how to process onEventCallback
:
function onEventCallback({ code, result }) {
switch (code) {
case 'SDK_PAYMENT_SUCCESSFUL':
// Payment was successful. Redirect buyers to the payment result page.
break;
case 'SDK_PAYMENT_FAIL':
console.log('Check the payment result data', result);
// Payment failed. Guide buyers to retry the payment based on the provided information.
break;
case 'SDK_PAYMENT_CANCEL':
// Guide buyers to retry the payment.
break;
case 'SDK_PAYMENT_CLICK_BACK_TO_MERCHANT':
// User click the Back to merchant button. Redirect buyers to the payment result page.
break;
default:
break;
}
}
The image shows the rendered merchant page embedded with the APO Checkout Page:
Step 3: Process asynchronous notifications
1. Set the webhook URL to receive notifications
You can choose one of following two methods to set the webhook URL to receive notifications:
- If each of your order has a unique notification URL, we recommend to set the webhook URL in each individual request. You can pass the asynchronous notification receiving URL for the specific order through the paymentNotifyUrl field in the createPaymentSession API.
- If all your orders share a unified notification URL, you can set the webhook URL on APO Dashboard through Developer > Notification Address.
APM payment
When a payment succeeds or fails, APO sends an asynchronous notification (notifyPayment) to the address that you specified in the createPaymentSession API via the paymentNotifyUrl parameter. After receiving the notifications from APO, you need to return response according to Return a receipt acknowledgement message. It is recommended to save the information on acquirers (acquirerInfo), refer to Order number management for specific reasons.
APO allows you to specify the URL in the createPaymentSession API via the paymentNotifyUrl parameter. If the address of each payment is the same, you can also configure the address on APO Dashboard.
The following is the notification request sample code:
{
"acquirerInfo": {
"acquirerMerchantId": "21********99147",
"acquirerName": "ALIPAY",
"acquirerResultCode": "SUCCESS",
"acquirerResultMessage": "success",
"acquirerTransactionId": "2025061819********0188540299977984",
"referenceRequestId": "PAYMENT_20250618100222331_****"
},
"customsDeclarationAmount": {
"currency": "CNY",
"value": "10"
},
"notifyType": "PAYMENT_RESULT",
"paymentAmount": {
"currency": "CNY",
"value": "10"
},
"paymentCreateTime": "2025-06-17T19:02:31-07:00",
"paymentId": "2025061819********0188540299977984",
"paymentMethodType": "ALIPAY_CN",
"paymentRequestId": "PAYMENT_20250618100222331_****",
"paymentResultInfo": {
},
"paymentTime": "2025-06-17T19:02:50-07:00",
"pspCustomerInfo": {
"pspCustomerId": "20*******9879519",
"pspName": "ALIPAY_CN"
},
"pspPaymentId": "2025061*********11432765638",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}
The table shows the possible values that the result.resultStatus field in the request message may return. Please handle the result according to the guidances:
result.resultStatus | Message | Further actions |
| Indicates that the payment is successful. | You can advance the order status, and use the information in the following fields for after-payment processes:
|
| Indicates that the payment failed. | Please guide the buyer to place a new order. |
Common Questions
Q: When will the notification be sent?
A: The sending time of asynchronous notifications varies in different scenarios.
- If the payment is successfully completed, APO will usually send you an asynchronous notification within 3 to 5 seconds. For some payment methods like OTC, the notification might take a bit longer.
- If the buyer does not submit a payment, when the payment session times out, APO does not send an asynchronous notification.
Note: The default payment session expiry time is 1 hour. The time it takes to close an order varies for different payment methods, Antom' default payment session expiry time is 14 minutes while PayEasy and Konbini are 7 days.
Q: When will the buyer receive the timeout notification after submiting a payment?
A: If the buyer selects a payment method within the payment session expiry time, the maximum delay is the payment method timeout plus the payment session expiry time. For example, if the payment session expiry time is 1 hour and the buyer selects bank transfer at the 59 minute but does not complete the payment, the timeout notification will be sent to you after 59 minutes + 48 hours. (depending on the specific payment methods).
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 APO, but you didn't make a response to the notification in the Sample code format.
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: What are the key parameters in the notification that I need to use?
A: Pay attention to the following key parameters:
- result: indicates the payment result of the order.
- paymentRequestId: indicates the payment request number you generated for consult, cancel, and reconciliation.
- paymentId: indicates the payment order number generated by APO, used for refund and reconciliation.
- paymentAmount: indicates the payment amount.
- paymentMethodTpye: indicates the payment method type that is included in payment method options.
- acquirerInfo: indicates the information about the acquirers.
Q: There are two types of asynchronous notifications. Which one should be used as the basis for shipment?
A: When you receive a notification where the value of notifyType is
PAYMENT_RESULT
, you should first check whether the value of paymentMethodType isCARD
/GOOGLEPAY
/PAYPAL
. If it is notCARD
/GOOGLEPAY
/PAYPAL
, you can decide whether to proceed with shipment based on the result of this notification. If the value of paymentMethodType isCARD
/GOOGLEPAY
/PAYPAL
, you need to wait for a notification where the value of notifyType isCAPTURE_RESULT
before making the decision to ship.
2. Verify asynchronous notifications
If you receive an asynchronous notification from APO, you are required to return the response in the Sample code format, but you do not need to countersign the response.
You need to verify the signature of the payment notification sent by APO.
/**
* 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 users 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();
}
}else if("CAPTURE_RESULT".equals(notifyType)){
AlipayCaptureResultNotify captureNotify = jsonObject.toJavaObject(AlipayCaptureResultNotify.class);
if (captureNotify != null && "SUCCESS".equals(captureNotify.getResult().getResultCode())) {
// handle your own business logic.
System.out.println("receive capture notify: " + JSON.toJSONString(captureNotify));
return Result.builder().resultCode("SUCCESS").resultMessage("success.").resultStatus(ResultStatusType.S).build();
}
}
} 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();
}
You do not need to countersign the response of the result notification. However, you must respond to each notification request in the following fixed format, regardless of whether the payment is successful or not.
{
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "success"
}
}
After payments
Inquire payments
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
}
}
It is recommended to save the information on acquirers (acquirerInfo), refer to Order number management for specific reasons. The following code shows an example of a response:
{
"acquirerInfo": {
"acquirerMerchantId": "76476400001****",
"acquirerName": "2C2P",
"acquirerTransactionId": "823c1fe4-1168-4abc-9687-c42f3269****",
"referenceRequestId": "202504301903130001032028917****"
},
"acquirerReferenceNo": "202504301903130001032028917****",
"paymentAmount": {
"currency": "USD",
"value": "110"
},
"paymentCreateTime": "2025-04-30T00:16:12-07:00",
"paymentId": "2025043019401089010011132026330****",
"paymentMethodType": "MIXEDCARD",
"paymentRequestId": "PAYMENT_20250430151543077_****",
"paymentResultCode": "SUCCESS",
"paymentResultInfo": {
"avsResultRaw": "",
"cardBin": "53**32",
"cardBrand": "MASTERCARD",
"cardNo": "************1310",
"cardholderName": "*******",
"cvvResultRaw": "",
"expiryMonth": "**",
"expiryYear": "**",
"fingerprint": "2684e4fa13af655191************0aff65851486d4f575183f46",
"funding": "CREDIT",
"issuerName": "CHINA MERCHANTS BANK",
"issuingCountry": "CN",
"lastFour": "1310",
"threeDSResult": {
"cavv": "",
"eci": "00",
"threeDSType": "INTERNAL",
"xid": ""
}
},
"paymentResultMessage": "success.",
"paymentStatus": "SUCCESS",
"paymentTime": "2025-04-30T00:16:14-07:00",
"transactions": [
{
"acquirerInfo": {
"acquirerMerchantId": "76476400001****",
"acquirerName": "2C2P",
"referenceRequestId": "202504301903130101032028917****"
},
"transactionAmount": {
"currency": "USD",
"value": "110"
},
"transactionId": "2025043019401089010011132026318****",
"transactionRequestId": "PAYMENT_20250430151543077_****",
"transactionResult": {
"resultCode": "SUCCESS",
"resultMessage": "success",
"resultStatus": "S"
},
"transactionStatus": "SUCCESS",
"transactionTime": "2025-04-30T00:16:15-07:00",
"transactionType": "CAPTURE"
}
],
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}
The values of the paymentMethodType and transactions.transactionType fields in the response represent different status. The following outlines the returned values in respective scenarios:
If the value of paymentMethodType is not CARD
, APPLEPAY
, or GOOGLEPAY
, you need to handle the transaction based on the value of paymentStatus. The returned values include:
SUCCESS
: indicated that the payment is successful.FAIL
: indicated that the payment failed.
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.
Refund
To learn about APO refund rules and how to initiate a refund for a successful transaction, see Refund for more information.
Dispute
When a buyer chooses to pay with a card, a dispute may occur. To learn more, see Dispute.
Reconciliation
After the transaction is completed, use the financial reports provided by APO for reconciliation. For more information on how to reconcile and the settlement rules of APO, please refer to Reconciliation.
Payment method features
Card payments
If your payment method includes card payments, the buyer's information from the merchant side must be passed in the payment session parameters. In the order.buyer field, at least one of the following parameters must be provided: referenceBuyerId, buyerPhoneNo, or buyerEmail. If the buyer's information is not provided, when the buyer selects the card payment method and submits the payment, an error will occur on the page, resulting in the inability to complete the payment process.
{
"order": {
...
"buyer": {
"referenceBuyerId": "88888888",
"buyerEmail": "gaga@test.com",
"buyerPhoneNo": "18888888888"
}
},
...
}
Activate 3D Secure 2
To learn more about 3D Secure 2, see 3D Secure 2 authentication.
- You can conduct your risk assessment, and specify the value of availablePaymentMethod.paymentMethodMetaData.is3DSAuthentication as
TRUE
through the createPaymentSession API. In this case, APO designates the payment as 3D-authenticated and passes it to the corresponding acquirer. - If you do not specify the availablePaymentMethod.paymentMethodMetaData.is3DSAuthentication parameter or specify the value as
FALSE
, APO designates the payment as non-3D-authenticated and passes it to the corresponding acquirer. However, the final decision will be based on the acquirer's processing.
{
...
"availablePaymentMethod": {
"paymentMethodMetaData": {
"is3DSAuthentication": true
}
},
...
}
When a transaction passes 3DS authentication, the corresponding 3DS information will be included in the asynchronous notification. You can check the information in the paymentResultInfo.threeDSResult field.
{
"acquirerInfo": {
"acquirerMerchantId": "219117000551****",
"acquirerName": "ALIPAY",
"acquirerResultCode": "SUCCESS",
"acquirerResultMessage": "success",
"acquirerTransactionId": "2025043019401080010019178029053****",
"referenceRequestId": "PAYMENT_20250430155835598_****"
},
"notifyType": "PAYMENT_RESULT",
"paymentAmount": {
"currency": "GBP",
"value": "100"
},
"paymentCreateTime": "2025-04-30T00:59:08-07:00",
"paymentId": "2025043019401080010019178029053****",
"paymentMethodType": "CARD",
"paymentRequestId": "PAYMENT_20250430155835598_****",
"paymentResultInfo": {
"avsResultRaw": "U",
"cardBin": "53**32",
"cardBrand": "MASTERCARD",
"cardCategory": "CONSUMER",
"cardNo": "************1310",
"cardholderName": "*******",
"cvvResultRaw": "U",
"expiryMonth": "**",
"expiryYear": "**",
"funding": "CREDIT",
"issuingCountry": "CN",
"lastFour": "1310",
"paymentMethodRegion": "GLOBAL",
"threeDSResult": {
"cavv": "kAPDv**********+btfgoJhBG+N",
"eci": "02",
"threeDSOffered": true,
"threeDSVersion": "2.2.0"
}
},
"paymentTime": "2025-04-30T00:59:28-07:00",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}
APM payments
Przelewy24
When the buyer selects Przelewy24 as the payment method, you can optimize the email input experience:
Pass the availablePaymentMethod.paymentMethodMetaData.payerEmail field in the createPaymentSession API. The APO Checkout Page will automatically pre-fill the email address in the payment options, eliminating the need for manual input by the buyer.
The sample code:
{
...
"availablePaymentMethod": {
"paymentMethodMetaData": {
"payerEmail": "123221321@test.com",
}
},
...
}
When the buyer selects Przelewy24 to pay, APO Chechout page will pre-fill the email address:
Mercado Pago
When the buyer selects to pay with Mercado Pago, the following parameters may be involved:
Acquirer | Payment method | Payment elements | Payment element parameter name | Best practice |
Antom | Mercado Pago (Brazil) | The CPF number | paymentMethodMetaData.cpf | Guide the buyer to enter the CPF number on the merchant page and manually open the Mercado Pago app to complete the payment. |
Antom | Mercado Pago (Brazil, Mexico, Chile, and Peru) | The buyer's email address. | paymentMethodMetaData.payerEmail | Guide the buyer to enter the email address on the merchant page and manually open the Mercado Pago app to complete the payment. |
Use the following methods to optimize the input experience:
- Pass the availablePaymentMethod.paymentMethodMetaData.payerEmail field in the createPaymentSession API. The APO Checkout Page will automatically pre-fill the email address in the payment options, eliminating the need for manual input by the buyer.
- Pass the availablePaymentMethod.paymentMethodMetaData.cpf field in the createPaymentSession API. The APO Checkout Page will automatically pre-fill the CPF number, eliminating the need for manual input by the buyer.
The sample code:
{
...
"availablePaymentMethod": {
"paymentMethodMetaData": {
"payerEmail": "123221321@test.com",
}
},
...
}
When the buyer selects Mercado Pago to pay, APO Chechout page will pre-fill the email address:
Additional content
Specify a payment method
You can modify the parameters in the createPaymentSession API to specify the display of payment methods on Checkout Page, the order of the payment method list, and the display of quick payments.
Note: If you need to enable the payment method, please contact APO Technical Support.
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.
How to enable
You can pass payment methods through API parameters or configure them on APO Dashboard through Checkout page > Payment method. If you pass parameters through the API, the API values take priority.
Pass through API parameters | |
Specify and filter the display of payment methods | copy
|
Sort the payment methods | copy
|
Display quick payments | copy
|
APO tokenization
If the buyer pays with a card, the Checkout Page can allow the buyer to save their card information during the first payment using APO Tokenization. For subsequent payments, the buyer will not need to re-enter the card details, and the Checkout Page will display the buyer's tokenized masked card number for payment.
You can help the buyer complete tokenized payments by saving and passing the buyer's card token information, the user experience is as follows:
Benefits
- Allow buyers to store their payment method information for a faster checkout experience in future transactions.
- Storing payment method information allows the display of detailed payment method information, which helps boost buyers' trust during payment.
- Data shows that using cardToken during payment helps achieve a higher payment success rate.
- The usage of cardToken has no restrictions on any acquirers and can be used with any acquirers that you have activated.
How to enable
You can use the following steps to complete tokenized payments:
- To display the card-vaulting button, specify the value of the availablePaymentMethod.paymentMethodMetaData.tokenizeMode field as
ASKFORCONSENT
through the createPaymentSession API, the card-vaulting button can be displayed in the card payment option on the APO Checkout Page.
{
...
"availablePaymentMethod": {
"paymentMethodMetaData": {
"tokenizeMode": "ASKFORCONSENT"
}
}
}
- To vault the card after the first payment, when the buyer saves their bank card information on your page, make sure to associate it with the buyer information and save the corresponding card information on your server. (Retrieve the value of cardToken from the paymentResultInfo field in the notifyPayment API.)
{
"acquirerInfo": {
"acquirerMerchantId": "219117000551****",
"acquirerName": "ALIPAY",
"acquirerResultCode": "SUCCESS",
"acquirerResultMessage": "success",
"acquirerTransactionId": "2025043019401080010019178029053****",
"referenceRequestId": "PAYMENT_20250430155835598_****"
},
"notifyType": "PAYMENT_RESULT",
"paymentAmount": {
"currency": "GBP",
"value": "100"
},
"paymentCreateTime": "2025-04-30T00:59:08-07:00",
"paymentId": "2025043019401080010019178029053****",
"paymentMethodType": "CARD",
"paymentRequestId": "PAYMENT_20250430155835598_****",
"paymentResultInfo": {
"avsResultRaw": "U",
"cardBin": "53**32",
"cardBrand": "MASTERCARD",
"cardCategory": "CONSUMER",
"cardNo": "************1310",
"cardToken": "ALIPAY5ITT+wDZhYuE1f********************vJ5BksK4yWCloE4MwfmN48sP1+rSPQ==",
"cardholderName": "*******",
"cvvResultRaw": "U",
"expiryMonth": "**",
"expiryYear": "**",
"funding": "CREDIT",
"issuingCountry": "CN",
"lastFour": "1310",
"networkTransactionId": "MCGQ120DH****",
"paymentMethodRegion": "GLOBAL",
"threeDSResult": {
"cavv": "kAPDv**********+btfgoJhBG+N",
"eci": "02",
"threeDSOffered": true,
"threeDSVersion": "2.2.0"
}
},
"paymentTime": "2025-04-30T00:59:28-07:00",
"result": {
"resultCode": "SUCCESS",
"resultMessage": "success.",
"resultStatus": "S"
}
}
- To use the card token in subsequent payments, when the buyer has a saved bank card, you need to pass the card token information through the createPaymentSession API. This is to display the buyer's saved card information on the APO Checkout Page, allowing the buyer to use it to complete payments.
The sample code below shows the createPaymentSession API initiates a request using the card token when the buyer uses a saved bank card to make payment.
{
...
"savedPaymentMethods": [
{
"paymentMethodType": "CARD",
"paymentMethodId": "ALIPAYEfG2DFbGx2Eh739qU+VMnCPEe7MfRKfMfC5k7k/IFASWpAh/vCxHV3dPYpbkGz1iyWCloE4MwfmN48sP8+rS****"
}
]
}