# Embedded mode

> Follow the guide to integrate the embedded mode of Antom Checkout Page (CKP).

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 SDK, where the Antom Checkout Page is embedded into your product purchase page for buyers to make payment.

## User experience

#### Tab: PC

The image shows the user experience where the Antom Checkout Page is embedded into the merchant page: 

![User experience on PC where the Antom Checkout Page is embedded into the merchant page](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/150742e5-16e2-434c-b8d8-399beacd1d5b.png)

The image shows the user experience for scenarios where certain payment methods redirect to the corresponding payment page within the embedded Checkout Page:

![User experience on PC for scenarios where certain payment methods redirect to the corresponding payment page within the embedded Checkout Page](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/e91e1ff7-a614-4a23-899f-e5c0e861cf17.png)

#### Tab: Mobile

The image shows the user experience where the Antom Checkout Page is embedded into the merchant page:

![User experience on mobile where the Antom Checkout Page is embedded into the merchant page](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/d6eb5a5e-155e-40ab-bacb-d42ff17d22bb.png)

The image shows the user experience for scenarios where certain payment methods redirect to the corresponding payment page within the embedded Checkout Page:

![User experience on mobile for scenarios where certain payment methods redirect to the corresponding payment page within the embedded Checkout Page](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/51174775-e90c-473a-b0b8-a87e156ac7bd.png)

> **Note**: Currently, embedded CKP is only supported on PC and mobile (H5), but not supported on mobile apps.

## Payment flow

The following process shows how to integrate the embedded CKP:

![Antom Checkout Page embedded mode payment flow showing the integration flow across buyer, merchant client, merchant server and Antom](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2026/png/60c3b949-ab02-49ba-b4c7-f028238d8860.png)

1.  **The buyer places an order in the merchant side.**
2.  **Create** **a payment session** **request.**
    When a buyer places an order on the merchant side, you need to call the [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API to obtain the _paymentSessionData_ that calls the SDK_._
3.  **Invoke the client SDK.
    **The merchant 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.
4.  **Get the payment result.**You can retrieve payment results through asynchronous notifications. Configure the _paymentNotifyUrl_ parameter in the [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API to specify the URL to receive asynchronous notifications. Antom sends an asynchronous notification through the **[notifyPayment](https://docs.antom.com/docs/ac/ams/paymentrn_online.md)** API when a payment request succeeds or expires.

> **Note**: For card payments, [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md), and [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md), an authorized-capture model is used. Steps 1 to 4 only complete the authorization stage-where the buyer completes payment using a card and the funds are temporarily frozen. To transfer the funds to your account, you must complete the capture step. A successful capture result should be used as the basis for shipping goods.

5.  **Obtain the capture result.**
    By default, Antom automatically handles fund capture on your behalf. You can also manually capture funds by calling the [**capture (One-time Payments)**](https://docs.antom.com/ac/ams/capture.md) API. The capture result can be obtained through one of the following methods:

-   Asynchronous notification: Specify _paymentNotifyUrl_ in the [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API or configure on [Antom Dashboard](https://dashboard.alipay.com/global-payments/account/login?goto=https%3A%2F%2Fdashboard.alipay.com%2Fglobal-payments%2Fhome) to set the address for receiving asynchronous notifications. Upon capture completion, Antom will send you asynchronous notifications via the [**notifyCapture (One-time Payments)**](https://docs.antom.com/ac/ams/notify_capture.md) API.
-   Synchronous inquiry: Call the [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md) API to check the payment status.

## Integration preparations

Before you start integrating, read the [Integration Guide](https://docs.antom.com/integration_guide_en.md) and [API Overview](https://docs.antom.com/ac/ams/api_fund.md) 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](https://docs.antom.com/ac/sdks/server_sdks.md).
-   Refer to [Integrate the SDK package for Web/WAP](https://docs.antom.com/ac/sdks/web.md) to complete integration preparations, and ensure to use SDK 1.41.0 or above.

## Integration steps

Follow these steps to start the integration:

1.  Create a payment session
2.  Embed the Antom Checkout Page
3.  Process asynchronous notifications
4.  Obtain the capture result

### Step 1: Create a payment session Server-side

Buyers can select a payment method provided by Antom when making payments. For payment method configurations, see [Specify a payment method](#9qw4o). 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 (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API to create a payment session and redirect to the Antom Checkout Page.

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](#Ts0fB).

Creating a payment session includes the following parameters:

| **Field type** | **Field name** | **Required** | **Description** |
| --- | --- | --- | --- |
| Basic parameters | _productCode_ | Yes | The value of this field in this scenario is fixed as `CASHIER_PAYMENT`. |
| Basic parameters | _productScene_ | Yes | The value of this field in this scenario is fixed as `CHECKOUT_PAYMENT`. |
| Basic parameters | _paymentRequestId_ | Yes | The unique ID assigned by a merchant to identify a payment request. |
| Basic parameters | _paymentAmount_ | Yes | The payment amount that the merchant requests to receive in the order currency. |
| Basic parameters | _paymentRedirectUrl_ | Yes | The merchant page URL that the buyer is redirected to after the payment is completed. |
| Basic parameters | _paymentNotifyUrl_ | No | The URL that is used to receive the payment result notification. You can also set the URL to receive the result notification on [Antom Dashboard](https://dashboard.alipay.com/global-payments/account/login?goto=https%3A%2F%2Fdashboard.alipay.com%2Fglobal-payments%2Fhome). |
| Basic parameters | _settlementStrategy_ | No | The settlement strategy for the payment request. Specify the _settlementCurrency_ parameter in the API if you signed up for multiple settlement currencies. |
| Basic parameters | _locale_ | No | Language tag specified for the Checkout Page. If this field is empty or set to automatic, the default language setting of the browser will be used, which is usually English. |
| Basic parameters | _paymentFactor.captureMode_ | No | Indicates the method for capturing funds after the user authorizes the payment. Valid values are: - `AUTOMATIC`: indicates that Antom automatically captures the funds after the authorization. The same applies when the value is empty or you do not pass in this parameter. - `MANUAL`: indicates that you manually capture the funds by calling the [**capture (One-time Payments)**](https://docs.antom.com/ac/ams/capture.md) API. |
| Order parameters | _order.goods_ | No | Goods information in the order. If you use this parameter to pass goods information in the API, you must specify the following parameters: - _referenceGoodsId_: The unique ID to identify the goods. - _goodsName_: Goods name. - _goodsUnitAmount_: Price of goods. - _goodsQuantity_: Quantity of goods. |
| Order parameters | _order.orderAmount_ | Yes | The order amount on the merchant side for the services or products provided to the buyer. This parameter is used to display the buyer’s consumption record or payment result page. It includes the following parameters: - _currency_: The transaction currency that is specified in the contract. A 3-letter currency code that follows the [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) standard. - _value_: The amount to charge as a positive integer in the smallest currency unit. > **Note**: If goods information is specified, the value of _order.orderAmount.value_ must exactly match the total amount calculated from the goods details. Otherwise, the API will return a parameter validation error. Calculation logic: Σ(_goods\[i\].goodsUnitAmount.value_ × _goods\[i\].goodsQuantity_) = _order.orderAmount.value_ |
| Order parameters | _order.referenceOrderId_ | Yes | The unique ID to identify the order on the merchant side. |
| Order parameters | _order.orderDescription_ | Yes | Summary description of the order on the merchant side. |

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)**](https://docs.antom.com/ac/ams/session_cashier.md).

The following sample code shows how to call the [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API:

```java
public static void createPaymentSession() {
    AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
    alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
    alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.CHECKOUT_PAYMENT);

    // 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();

    // convert amount unit(in practice, amount should be calculated on your serverside)
    // For details, please refer to: <a href="https://docs.antom.com/ac/ref/cc">Usage rules of the Amount object</a>
    Amount goodAmount = Amount.builder().currency("SGD").value("3000").build();

    // set goods info
    // note that goods.referenceGoodsId, good.referenceGoodsId, and goods.goodsName are required
    Goods goods = Goods.builder().goodsBrand("Antom Brand").goodsCategory("outdoor goods/bag").goodsName("Classic Woman Bag").goodsQuantity("2")
            .goodsSkuName("Black").goodsImageUrl("https://mdn.alipayobjects.com/portal_pdqp4x/afts/file/A*H8M9RrxlArAAAAAAAAAAAAAAAQAAAQ")
            .goodsUnitAmount(goodAmount).goodsUrl("https://yourGoodsUrl").referenceGoodsId("yourGoodsId").build();

    // set amount
    // amount.value equals goodsAmount.value * goods.goodsQuantity
    // for the currencies supported by payment methods, please refer to: <a href="https://docs.antom.com/ac/pm/supported_pm">Supported payment methods</a>
    Amount amount = Amount.builder().currency("SGD").value("6000").build();
    alipayPaymentSessionRequest.setPaymentAmount(amount);

    // set order info
    // note that order.orderAmount, order.referenceOrderId, and order.orderDescription are required
    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(JSON.toJSONString(alipayPaymentSessionRequest));
        alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
    } catch (AlipayApiException e) {
        String errorMsg = e.getMessage();
        // handle error condition
    }
}
```

The following shows the sample code of a request: 

```json
{
  "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-06c3615b46ea"
  },
  "paymentAmount": {
    "currency": "SGD",
    "value": "6000"
  },
  "paymentNotifyUrl": "http://www.yourNotifyUrl.com/payment/receiveNotify",
  "paymentRedirectUrl": "http://localhost:8080/index.html?paymentRequestId=597795b7-c812-4132-bd7d-c55914eefdcb",
  "paymentRequestId": "597795b7-c812-4132-bd7d-c55914eefdcb",
  "productCode": "CASHIER_PAYMENT",
  "productScene": "CHECKOUT_PAYMENT"
}
```

The following shows the sample code of a response, which contains the following parameters:

-   _pa__ymentSessionData_: 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 Antom embedded CKP scenario, this field can be ignored.).

```json
{
    "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. | Please change the _paymentRequestId_ and call the API again to resolve the issue. Please contact Antom technical support if the problem persists. |
| `F` | Indicates that the payment session creation failed. | Please 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. Please change the _paymentRequestId_ and call the API again to resolve the issue.

### Step 2: Embed Antom Checkout Page Client-side

The Antom SDK is a component used for handling payment processes. You initiate the SDK by creating a payment session to collect information and switch between apps based on the payment method specified in the [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API.

#### 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: - `sandbox`: Sandbox environment - `prod`: Production environment |
| _onEventCallback_ | No | 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](https://docs.antom.com/ac/sdks/ref.md). |

The following sample code shows how to instantiate the SDK:

```json
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 Antom 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 Antom Checkout Page component. 

```json
<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 Antom 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 (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API response to the _sessionData_ parameter. |

```json
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 (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md).
-   When the buyer initiates multiple payments, free the previously created component resources in [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md).
-   Free the component resources after obtaining the final payment result codes.

```json
// Free SDK component resources
checkoutApp.unmount();
```

#### 3\. Process payment results

The payment result will be returned by `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 `onEventCallback` result data for details. Guide buyers to retry the payment based on the provided information. |
| `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`:

```json
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's page embedded with the Antom Checkout Page:

![The rendered merchant's page embedded with the Antom Checkout Page showing the payment method selection interface with available payment options and order details](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/56e29924-781b-42a4-9e33-6f8eb4993dd4.png)

### Step 3: Process asynchronous notifications Server-side

#### 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 orders 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 (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API.
-   If all your orders share a unified notification URL, you can set the webhook URL on [Antom Dashboard](https://dashboard.alipay.com/global-payments/developers/iNotify) through **Developer > Notification Address**. For detailed steps, refer to [Notification URL](https://docs.antom.com/ac/merchant_service/notification.md).

#### Tab: APM payment

When a payment succeeds or fails, Antom sends an asynchronous notification ([**notifyPayment**](https://docs.antom.com/docs/ac/ams/paymentrn_online.md)) to the address that you specified in the [**createPaymentSession (One-time Payments)**](https://docs.antom.com/docs/ac/ams/session_cashier.md) API via the _paymentNotifyUrl_ parameter. After receiving the notifications from Antom, you need to return response according to [Return a receipt acknowledgement message](https://docs.antom.com/docs/ac/cashierpay/notifications.md#vQK5A).

Antom allows you to specify the URL in the [**createPaymentSession (One-time Payments)**](https://docs.antom.com/docs/ac/ams/session_cashier.md) API via the _paymentNotifyUrl_ parameter. If the address of each payment is the same, you can also configure the address on Antom Dashboard.

The following is the notification request sample code:

-   _paymentRequestId:_ indicats the payment request ID for consult, cancellation, and reconciliation.
-   _paymentId:_ indicates the payment ID aligned by Antom for refunds and reconciliation.
-   _paymentAmount_: indicates the payment amount.
-   _paymentMethodType_: indicates the payment method used by the buyer.

```json
{
  "actualPaymentAmount": {
    "currency": "KRW",
    "value": "100"
  },
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
    "currency": "KRW",
    "value": "100"
  },
  "paymentCreateTime": "2024-04-19T01:10:49-07:00",
  "paymentId": "20240419194010800100188350218317930",
  "paymentRequestId": "amsdmpay_yuqian_fyf_0b3bd5e9-14bd-4cea-b288-091d9c6862ed",
  "paymentResultInfo": {},
  "paymentTime": "2024-04-19T01:12:14-07:00",
  "pspCustomerInfo": {
    "pspCustomerId": "a070c0d1b89af442c6aa01886f0183de812a5d3d4fe15c771145b2b844a9dd67",
    "pspName": "TOSSPAY"
  },
  "paymentMethodType": "TOSSPAY",
  "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 the payment is successful. | You can advance the order status. |
| `F` | Indicates that the payment failed. | Please guide the buyer to place a new order. |

#### Tab: Card payment

**Authorization asynchronous notification**

When a payment authorization succeeds or fails, Antom sends an asynchronous notification ([**notifyPayment**](https://docs.antom.com/docs/ac/ams/paymentrn_online.md)) to the address that you specified in the [**createPaymentSession (One-time Payments)**](https://docs.antom.com/docs/ac/ams/session_cashier.md) API via the _paymentNotifyUrl_ parameter. After receiving the notifications from Antom, you need to return response according to [Return a receipt acknowledgement message](https://docs.antom.com/docs/ac/cashierpay/notifications.md#vQK5A).

Antom allows you to specify the URL in the [**createPaymentSession (One-time Payments)**](https://docs.antom.com/docs/ac/ams/session_cashier.md) API via the _paymentNotifyUrl_ parameter. If the address of each payment is the same, you can also configure the address on Antom Dashboard.

The following is the authorization asynchronous notification request sample code:

```json
{
    "actualPaymentAmount": {
        "currency": "USD",
        "value": "1"
    },
    "cardInfo": {
        "avsResultRaw": "U",
        "cardBrand": "MASTERCARD",
        "cardNo": "************1876",
        "cvvResultRaw": "Y",
        "funding": "CREDIT",
        "issuingCountry": "CN",
        "networkTransactionId": "MEB88D1C91119",
        "paymentMethodRegion": "GLOBAL",
        "threeDSResult": {
            "cavv": "",
            "eci": ""
        }
    },
    "notifyType": "PAYMENT_RESULT",
    "paymentAmount": {
        "currency": "USD",
        "value": "1"
    },
    "paymentCreateTime": "2024-11-18T23:51:51-08:00",
    "paymentId": "20241119194010800100188200260012929",
    "paymentMethodType": "CARD",
    "paymentRequestId": "PAYMENT_20241119155126620_AUTO",
    "paymentResultInfo": {
        "avsResultRaw": "U",
        "cardBrand": "MASTERCARD",
        "cardNo": "************1876",
        "cvvResultRaw": "Y",
        "funding": "CREDIT",
        "issuingCountry": "CN",
        "networkTransactionId": "MEB88D1C91119",
        "paymentMethodRegion": "GLOBAL",
        "threeDSResult": {
            "cavv": "",
            "eci": ""
        }
    },
    "paymentTime": "2024-11-18T23:51:55-08:00",
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}
```

**Capture asynchronous notification**

After completing payment authorization, Antom automatically process capture. When completing capture, Antom sends an asynchronous notification ([**notifyPayment**](https://docs.antom.com/docs/ac/ams/paymentrn_online.md)) to the address that you specified in the [**createPaymentSession (One-time Payments)**](https://docs.antom.com/docs/ac/ams/session_cashier.md) API via the _paymentNotifyUrl_ parameter. After receiving the notifications from Antom, you need to return response according to [Return a receipt acknowledgement message](https://docs.antom.com/docs/ac/cashierpay/notifications.md#vQK5A).

Antom allows you to specify the URL in the [**createPaymentSession (One-time Payments)**](https://docs.antom.com/docs/ac/ams/session_cashier.md) API via the _paymentNotifyUrl_ parameter. If the address of each payment is the same, you can also configure the address on Antom Dashboard.

The following is the capture asynchronous notification request sample code:

```json
{
    "captureAmount": {
        "currency": "USD",
        "value": "1"
    },
    "captureId": "20241119194010807000188200261316896",
    "captureRequestId": "PAYMENT_20241119155126620_AUTO",
    "captureTime": "2024-11-18T23:51:58-08:00",
    "notifyType": "CAPTURE_RESULT",
    "paymentId": "20241119194010800100188200260012929",
    "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 the capture is successful. | You can advance the order status. |
| `F` | Indicates that the capture failed. | Please contact Antom technical support. |

> **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, Antom will usually send you an asynchronous notification within 3 to 5 seconds. For some payment methods like cash payment, the notification might take a bit longer.
> -   If the buyer does not submit a payment, when the payment session times out, Antom does not send an asynchronous notification.
> -   If the buyer submits a payment but the final payment is not completed:
>
> -   When the last order is closed, if the payment session is still valid, Antom will send asynchronous notifications when the payment session expires.
> -   When the last order is closed, if the payment session expired, Antom will send an asynchronous notification when the last order is closed.
>
> **Note**: The default payment session expiry time is 1 hour. The time it takes to close an order varies for different payment methods, the default is 14 minutes.
>
> **Q: Will the asynchronous notification be re-sent?**
>
> A: Yes, the asynchronous notification will be re-sent automatically within 24 hours for the following cases:
>
> -   If you didn't receive the asynchronous notification due to network reasons.
> -   If you receive an asynchronous notification from Antom, but you didn't make a response to the notification in the [Sample code](https://docs.antom.com/ac/cashierpay/notifications.md#vQK5A) 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 Antom, used for refund and reconciliation.
> -   _paymentAmount_: indicates the payment amount.
> -   _paymentMethodType_: indicates the payment method type that is included in payment method options. 
>
> **Q: There are two types of asynchronous notifications. Which one should be used as the basis for shipment?**
>
> A: When you receives a `PAYMENT_RESULT` _notifyType_ notification, you should first check whether the _paymentMethodType_ is `CARD`. If it is not `CARD`, you can decide whether to proceed with shipment based on the result of this notification. If it is `CARD`, you need to wait for a notification of `CAPTURE_RESULT` type before making the decision to ship.

#### 2\. Verify asynchronous notifications

If you receive an asynchronous notification from Antom, you are required to return the response in the [Sample code](https://docs.antom.com/ac/cashierpay/notifications.md#vQK5A) format, but you do not need to countersign the response.

You need to verify the signature of the payment notification sent by Antom.

```java
/**
     * 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) {
        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 sign the response for the notification result. However, you must respond to each notification request in the following fixed format, regardless of whether the payment is successful or not. 

```json
{
    "result": {
        "resultCode": "SUCCESS",
        "resultStatus": "S",
        "resultMessage": "success"
    }
}
```

### Step 4: Obtain the capture result Server-sideFor card paymentsApple Pay/Google Pay

If payment is successful, Antom will automatically initiate capture for you, while you can also initiate capture manually. After capture, you can obtain the capture result either via asynchronous notification or active query. You should decide whether to ship goods based on the capture result. For specific operations, refer to [Capture](https://docs.antom.com/ac/cashierpay/capture.md).

## After payments

### 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 inquire payments service. You can call the [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md) API and use the _paymentRequestId_ from the payment session to check the payment status. 

The following code shows how to call the [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md) API: 

```json
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:

```json
{
    "actualPaymentAmount": {
        "currency": "USD",
        "value": "1"
    },
    "customsDeclarationAmount": {
        "currency": "CNY",
        "value": "7"
    },
    "paymentAmount": {
        "currency": "USD",
        "value": "1"
    },
    "paymentId": "20250305194010800100188690281017336",
    "paymentMethodType": "ALIPAY_CN",
    "paymentRedirectUrl": "https://checkout.antom.com/checkout-page/pages/payment/index.html?sessionData=%2BCUim8L0KviXagaygm9xBL5jZ%2F75w6gAX1nn8pcuFuGkIsMoHtD6U88YSyMrMJvorbwnBg5uQv8e6pyvIpjDQQ%3D%3D%26%26SG%26%26188%26%26eyJleHRlbmRJbmZvIjoie1wiT1BFTl9NVUxUSV9QQVlNRU5UX0FCSUxJVFlcIjpcInRydWVcIixcImxvY2FsZVwiOlwiZW5fVVNcIixcImRpc3BsYXlBbnRvbUxvZ29cIjpcInRydWVcIn0iLCJwYXltZW50U2Vzc2lvbkNvbmZpZyI6eyJwYXltZW50TWV0aG9kQ2F0ZWdvcnlUeXBlIjoiQUxMIiwicHJvZHVjdFNjZW5lIjoiQ0hFQ0tPVVRfUEFZTUVOVCIsInByb2R1Y3RTY2VuZVZlcnNpb24iOiIxLjAifSwic2VjdXJpdHlDb25maWciOnsiYXBwSWQiOiIiLCJhcHBOYW1lIjoiT25lQWNjb3VudCIsImJpelRva2VuIjoiNlRjZGJyMnJGM3JQWXg0aGtWckhxYnZqIiwiZ2F0ZXdheSI6Imh0dHBzOi8vaW1ncy1zZWEuYWxpcGF5LmNvbS9tZ3cuaHRtIiwiaDVnYXRld2F5IjoiaHR0cHM6Ly9vcGVuLXNlYS1nbG9iYWwuYWxpcGF5LmNvbS9hcGkvb3Blbi9yaXNrX2NsaWVudCIsIndvcmtTcGFjZUlkIjoiIn0sInNraXBSZW5kZXJQYXltZW50TWV0aG9kIjpmYWxzZX0%3D",
    "paymentRequestId": "PAYMENT_20250305220039086_AUTO",
    "paymentResultCode": "SUCCESS",
    "paymentResultMessage": "success.",
    "paymentStatus": "SUCCESS",
    "paymentTime": "2025-03-05T06:02:34-08:00",
    "pspCustomerInfo": {
        "pspName": "ALIPAY_CN"
    },
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}
```

Please handle the result based on the value of the _paymentStatus_ parameter in the response. For specific return values, refer to the [API documentation](https://docs.antom.com/ac/ams/paymentri_online.md#Responseparameters-paymentStatus).

> **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 Server-side

To learn about Antom refund rules and how to initiate a refund for a successful transaction, see [Refund](https://docs.antom.com/ac/cashierpay/refund.md) for more information.

### Dispute Server-side

When a buyer chooses to pay with a card, a dispute may occur. To learn more, see [Dispute resolution](https://docs.antom.com/ac/dispute/dispute_resolution.md).

### 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](https://docs.antom.com/ac/cashierpay/reconcile.md).

## Payment method features

### Card payments

If your payment method includes cards, 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. 

```json
{
    "order": {
        ...
        "buyer": {
            "referenceBuyerId": "88888888",
            "buyerEmail": "gaga@test.com",
            "buyerPhoneNo": "18888888888"
        }
    },
...
}
```

#### Activate 3D Secure 2

For more information, refer to [3D Secure 2](https://docs.antom.com/ac/pm/3ds.md).

### 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 (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API. The Antom Checkout Page will automatically pre-fill the email address in the payment options, eliminating the need for manual input by the buyer.

#### Tab: Pass the payerEmail field

The sample code: 

```json
{
  ...
    "availablePaymentMethod": {
        "paymentMethodMetaData": {
            "payerEmail": "123221321@test.com",
        }
    },
  ...
}
```

When the buyer selects Przelewy24 to pay, Antom Chechout page will pre-fill the email address:

![Antom Checkout Page showing Przelewy24 payment method with pre-filled buyer email address if the payerEmail field is passed in the createPaymentSession API](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/1742368584062-882d2b99-fa5a-4358-b7e8-07afeaefc6c2.png)

#### Tab: The payerEmail field is not provided

The sample code: 

```json
{
  ...
    "availablePaymentMethod": {
        "paymentMethodMetaData": {
        }
    },
  ...
}
```

When the buyer selects Przelewy24 to pay, Antom checkout page will display the input box for buyers to enter the email address:

![Antom Checkout Page showing Przelewy24 payment method with empty email input box for buyer to enter their email address when the payerEmail field is not passed in the createPaymentSession API](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/1742368564520-9ee82d4b-e154-41d1-bd4e-c16459bce4d5.png)

#### Mercado Pago

When the buyer selects Mercado Pago as the payment method, you can optimize the input experience using the following methods:

-   Pass the _availablePaymentMethod.paymentMethodMetaData.payerEmail_ field in the [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API. The Antom 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 (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API. The Antom Checkout Page will automatically pre-fill the CPF number, eliminating the need for manual input by the buyer.

#### Tab: Pass the payerEmail field

The sample code:

```json
{
  ...
    "availablePaymentMethod": {
        "paymentMethodMetaData": {
            "payerEmail": "123221321@test.com",
        }
    },
  ...
}
```

When the buyer selects Mercado Pago to pay, Antom Chechout page will pre-fill the email address:

![Antom Checkout Page showing Mercado Pago payment method with pre-filled buyer email address if the payerEmail field is passed in the createPaymentSession API](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/1746694800391-aed3b970-9f7e-4627-9726-30c9551c146b.png)

#### Tab: Pass the payerEmail and CPF field

The sample code:

```json
{
  ...
    "availablePaymentMethod": {
        "paymentMethodMetaData": {
            "payerEmail": "123221321@test.com",
            "cpf":"2132321312",
        }
    },
  ...
}
```

When the buyer selects Mercado Pago (Brazil) to pay, Antom Chechout page will pre-fill the email address and CPF number:

![Antom Checkout Page showing Mercado Pago (Brazil) payment method with pre-filled buyer email address and CPF number if the payerEmail and the CPF fields are passed in the createPaymentSession API](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/1746694278380-700705ce-612f-4f08-9d95-829486d6ff28.png)

#### Tab: The payerEmail field is not provided

The sample code:

```json
{
  ...
    "availablePaymentMethod": {
        "paymentMethodMetaData": {
        }
    },
  ...
}
```

When the buyer selects Mercado Pago to pay, Antom checkout page will display the input box for buyers to enter the email address:

![Antom Checkout Page showing Mercado Pago payment method with empty email input box for buyer to enter their email address when the payerEmail field is not passed in the createPaymentSession API](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/1746694843181-b5ae08c7-9ed7-41d0-b46c-a2393dc99ffd.png)

## Additional content

### Antom Tokenization

With Antom Tokenization, you can allow buyers to save their card information during the first payment, saving them from needing to re-enter the information in subsequent transactions. This helps avoid payment failures caused by incorrect card details. For details, please refer to [Antom Tokenization](https://docs.antom.com/ac/pm/tokenization.md).

### Specify a payment method

You can specify payment methods on [Antom Dashboard](https://dashboard.alipay.com/global-payments/account/login?goto=https%3A%2F%2Fdashboard.alipay.com%2Fglobal-payments%2Fhome) through **Payments > Checkout page** **\> Payment methods**. You can also pass the parameters in the [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) 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 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](https://docs.antom.com/ac/antomop/alipay_cn.md), [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md), and [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md).

To specify the payment method, pass the following parameters in the _availablePaymentMethod_ parameter of the [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API:

| **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| _paymentMethodTypeList_ | No | List of payment methods available to the buyer. The list includes the following parameters: - _paymentMethodType_: The type of payment method included in the payment option. See [Enumeration values of payment methods](https://docs.antom.com/ac/pm/enumeration_values.md) for valid values. - _paymentMethodOrder_: The priority order you set for payment methods, represented by sequence numbers. The smaller the number, the higher the priority. If no sequence is set, Antom's default sorting will be used. - _expressCheckout_: Indicates whether the payment method selected by you is displayed as a quick payment method. Currently, only `ALIPAY_CN`, `APPLEPAY`, and `GOOGLEPAY` can be configured as quick payments. Valid values are: - `true`: The payment method is displayed as quick payment. - `false`: The payment method is not displayed as quick payment. |

The following is a sample code for specifying the payment method:

```json
{ ...
  "availablePaymentMethod": {
    "paymentMethodTypeList": [
      {
        "paymentMethodType": "ALIPAY_CN",
        "expressCheckout": true,
        "paymentMethodOrder": "0"
      },
      {
        "paymentMethodType": "TNG",
        "expressCheckout": false,
        "paymentMethodOrder": "1"
      }
    ]
  }
}
```