# Payment Element integration

> Follow the guide to integrate Antom Payment Element to build a seamless payment experience.

 Antom Payment Element is a payment component integrated via SDK, designed to provide a seamless payment experience and help increase conversion rates. For different client types, Antom offers the following solutions:

 - Web/WAP: Web Element for browser and mobile web environments
- App (Android & iOS): Mobile Element designed for merchants' native mobile applications

 The capabilities supported by Payment Element on each platform are shown in the table below:

 | **Feature** | **Description** | **Web/WAP** | **Android** | **iOS** |
| --- | --- | --- | --- | --- |
| Payment Element-rendered payment method list | You can use the default payment method list rendered by Payment Element on the checkout page. You can also   [specify payment methods](#L9xOX)   to flexibly control which payment methods are displayed. | ✔️ | ✔️ | ✔️ |
| Merchant-rendered payment methods (single-payment-method integration) | You can   [specify individual payment methods](#L9xOX)   according to your business needs to display a customized payment method list. > **[INFO]** **Note**    : For   [certain payment methods](#Ygtd4X)   (e.g., card payments), you need to embed the payment details component rendered by Payment Element. | ✔️ | ✔️ | ✔️ |
| Embedded experience | The payment form is directly embedded on your merchant page, delivering a seamless integration experience. | ✔️ | ❌ | ❌ |
| Pop-up experience | The buyer completes payment in a separate pop-up window after clicking, offering simple integration and secure experience. | ❌ | ✔️ | ✔️ |
| [Appearance customization](https://docs.antom.com/ac/cashierpay/appearance.md) | Use the     *appearance*     parameter to customize the visual style and layout of the payment interface, including theme selection, layout configuration, and CSS styling. | ✔️ | ✔️ | ✔️ |
| Custom p   ayment button | ​   You can customize the payment button. When the buyer clicks your custom payment button, you need to call the   `[submitPayment()](https://docs.antom.com/ac/sdks/web_submitPayment.md)`   method to submit payment. | ✔️ | ❌ | ❌ |

<!-- ToggleTab query="platform" -->

**Tab: Web/WAP**

# User experience {#BEWwv}

<!-- TabGroup -->

**Tab: Web**

The following figures demonstrate the user experience of using Payment Element in different scenarios:

<!-- TabGroup -->

**Tab: Payment Element-rendered payment method list**

The following figure shows templates with embedded Payment Element-rendered payment method list:

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/654fb40d-fe90-4ae5-af47-d0d83fc3d93d.png) If you use the Payment Element-rendered payment method list, all supported payment methods will be displayed on the checkout page by default. The following figures illustrate the user experience for different payment methods:

<!-- TabGroup -->

**Tab: Scan to pay**

Payment Element displays a QR code for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/61b582ba-39c9-4718-b6b3-6b850f78307c.png)

**Tab: Redirect to payment page**

Payment Element redirects to the payment method page for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/7ca32450-68cd-474d-9d26-b645f6c98ef5.png)

**Tab: New card payment**

Payment Element displays the card detail collection page for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/5dfc12e9-e7d1-4a44-98b9-cb5475f5d707.png)

**Tab: Stored card payments**

Payment Element handles the stored card payment scenario.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/fcb26e34-236b-454e-bcf0-c1a28eb63d52.png)

<!-- /TabGroup -->

**Tab: Merchant-rendered payment method list**

The following figure shows templates of merchant-rendered payment method list:

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/f47c4812-dbc9-4c16-abda-b4c09b794db0.png) If you render the payment methods by specifying them yourself, the following figures demonstrate the user experience for different payment methods:

<!-- TabGroup -->

**Tab: Scan to pay**

Payment Element displays a QR code for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2026/png/c00c1697-c29e-416a-92aa-5c746b6128d2.png)

**Tab: Redirect to payment page**

Payment Element redirects to the payment method page for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/dadc71af-863e-4fe8-9697-f6e03c5fd12a.png)

**Tab: New card payment**

Payment Element displays the card detail collection page for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/6a1f3fa8-3b2e-4e10-9c37-610db8f7eb74.png)

<!-- /TabGroup -->

<!-- /TabGroup -->

**Tab: WAP**

The following figures demonstrate the user experience of using Payment Element in different scenarios:

<!-- TabGroup -->

**Tab: Payment Element-rendered payment method list**

The following figure shows templates with embedded Payment Element-rendered payment method list:

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/c95557ec-7912-471e-b64c-0c3e049bf886.png)

 If you use the Payment Element-rendered payment method list, all supported payment methods will be displayed on the checkout page by default. The following figures illustrate the user experience for different payment methods:

<!-- TabGroup -->

**Tab: Scan to pay**

Payment Element displays a QR code for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/49216072-a2d0-45d4-81b4-69087444d810.png)

**Tab: Redirect to payment page**

Payment Element redirects to the payment method page for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/42c96cfe-dd03-463f-9c01-7dfdff4808ed.png)

**Tab: New card payment**

Payment Element displays the card detail collection page for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/f7016b1a-57d9-46bb-a0ec-7b7af2f4be7c.png)

**Tab: Stored card payments**

Payment Element handles the stored card payment scenario.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/67d151b4-08db-4f75-9831-4c407077f195.png)

<!-- /TabGroup -->

**Tab: Merchant-rendered payment method list**

The following figure shows templates of merchant-rendered payment method list:

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/fa1dc44d-2bb0-44f8-89b2-0adcde44178b.png) If you render the payment methods by specifying them yourself, the following figures demonstrate the user experience for different payment methods:

<!-- TabGroup -->

**Tab: Scan to pay**

Payment Element displays a QR code for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/80081db0-5cc9-4865-bb47-79b7a6cf1414.png)

**Tab: Redirect to payment page**

Payment Element redirects to the payment method page for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/0b6a633a-cfa7-40a9-a135-93580cf3df07.png)

**Tab: New card payment**

Payment Element displays the card detail collection page for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/22162520-4054-4881-971f-ff4288b006f9.png)

<!-- /TabGroup -->

<!-- /TabGroup -->

<!-- /TabGroup -->

# Order lifecycle {#iYCQo}

 Learn about the lifecycle of different payment methods:

<!-- TabGroup -->

**Tab: APM Payments**

For APM payments, such as  [Alipay](https://docs.antom.com/ac/antomop/alipay_cn.md)  and  [Touch'n Go eWallet](https://docs.antom.com/ac/antomop/touchngo.md) , funds are transferred directly to your account once the payment is initiated and completed by the buyer. You can  [cancel](#Otb6j)  or  [refund](#kg4oU)  the order within the allowable period.

   ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/6da32eae-f8c2-495f-a6ce-c8a4f7b27c2e.png)

**Tab: Card payments, Apple Pay, Google Pay**

For card payments,  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)  , and   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md) , the order lifecycle includes the following stages:

 1. Authorization: After the buyer completes the payment using a card, the funds are temporarily frozen. You can   [cancel](#Otb6j)   the order during the allowable period from when the order is placed until authorization is completed.
2. Capture   : You can manually capture the frozen funds to transfer them to your account, or let Antom automatically handle capture for you. For details, refer to   [Capture](https://docs.antom.com/ac/cashierpay/capture.md)  . After capture, you can initiate a   [refund](#kg4oU)   within the allowable period if needed.
3. Chargeback: You may submit a chargeback defense based on the specific situation. For more information, refer to   [Dispute](#AoEw6)  .

   ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/abc1f3bf-4223-4ed2-adc3-35862da1bfeb.png)

<!-- /TabGroup -->

# Payment flow {#nigJF}

 The following flow illustrates how to integrate One-time Payments using Payment Element:

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/047938a8-2ce8-4fe3-a919-c2d7d7e343a3.png) 1. **The buyer lands on the checkout page and submits payment.**
2. **Create a payment session request.**  
   You can obtain the payment session by calling the   [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)        API.
3. **Invoke Payment Element.**  
   On the client side, invoke Payment Element using the payment session. You can choose to use the Payment Element-rendered payment method list, or render the payment methods by specifying them yourself. Payment Element will handle information processing, collect payment details, perform redirects, manage app invocations, display QR codes, and conduct validations based on the features of the selected payment method. After the payment is completed, depending on your configuration and the payment method features, you need to handle redirections based on the result returned by the   `submitPayment().then()`   method, or the system will automatically return to your result page.
4. **Confirm the payment result.**  
   Obtain the payment result by using one of the following two 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. When the payment is successful or expires, Antom will use   [**notifyPayment**](https://docs.antom.com/ac/ams/paymentrn_online.md)   to send asynchronous notifications to you.
  - Synchronous inquiry: Call the   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   API to check the payment status.

 > **[INFO]** **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 mode 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. **Initiate capture and obtain the 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 capture status.

# Integration preparations {#hKAW}

 Before you start integrating, read   [Integration guide](https://docs.antom.com/integration_guide_en.md)   and   [API overview](https://docs.antom.com/ac/ams/api_fund.md)   to understand the integration steps of the server-side API and the precautions for calling the API. Furthermore, ensure the following prerequisites are met:

 - Obtained your 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)  .
- Integrate the client-side SDK package by following the steps detailed in   [Integrate the SDK package for Web/WAP](https://docs.antom.com/ac/sdks/web.md)  , and ensure to use the latest SDK version or no lower than 1.46.0.

# Integration steps {#n1t0Y}

 Start your integration by taking the following steps:

 1. Create a payment session
2. Invoke Payment Element
3. Obtain    the payment result
4. Capture

## Step 1: Create a payment session   **[Server-side]** {#KuWal}

 Call the      [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)      API with order information to create a payment session and obtain the     *paymentSessionData*     required to invoke Payment Element. You can choose to either    render the payment methods by specifying them yourself    or    use the Payment Element-rendered payment method list   . Pass the corresponding parameters when calling the      [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)      API:

 - Render the payment methods by yourself:    When rendering the payment method list yourself, you must pass the parameters for specifying payment methods listed in the table below. Note that for   [certain payment methods](#Ygtd4X)   (e.g., card payments), you need to embed the payment details component rendered by Payment Element. The optimal timing for calling the      [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)      API when offering card payment options is as follows:

   - If Payment Element needs to collect payment details: Call the      [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)      API after the buyer selects the payment method, and pass the card payment parameters listed in the table.
  - If Payment Element does not need to collect payment details: Call the      [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)      API after the buyer selects the payment method and submits payment.

 - When using the Payment    Element-rendered    payment method list, you only need to pass the basic parameters listed in the table below. Payment Element renders all supported payment methods on the checkout page by default, but you can [specify payment methods](#L9xOX) to display only the options you need.

   | **Type** | **Parameter name** | **Required** | **Description** |
| --- | --- | --- | --- |
| Basic parameters | *productCode* | Yes | For Payment Element, the value is fixed as      `CASHIER_PAYMENT`  . |
| *productScene* | Yes | For Payment Element, the value is fixed as      `ELEMENT_PAYMENT`  . |  |
| *paymentRequestId* | Yes | The unique ID assigned by the merchant to identify a payment request. |  |
| *paymentAmount* | Yes | The payment amount that the merchant requests to receive in the order currency. |  |
| *paymentRedirectUrl* | Yes | The merchant page URL that the buyer is redirected to after the payment is completed. |  |
| *paymentNotifyUrl* | No | The payment result notification URL, which can be passed in through the API or set as a fixed value through Antom Dashboard. If both are set, the value in the API takes precedence. |  |
| *settlementStrategy* | Yes | The settlement strategy for the payment request. |  |
| *order.referenceOrderId* | Yes | The unique ID to identify the order on the merchant side. |  |
| *order.orderDescription* | Yes | Summary description of the order. |  |
| *env.terminalType* | No | Terminal type of which the merchant service applies to. Valid values are: - `WEB`  : The client-side terminal type is a website, which is opened via a PC browser. - `WAP`  : The client-side terminal type is an H5 page, which is opened via a mobile browser. - `APP`  : The client-side terminal type is a mobile application.   > **[INFO]** **Note**    : This parameter is required for  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)   and   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md) . |  |
| *env.osType* | No | The operating system type from which the buyer initiated the transaction. Valid values: - `IOS`  : Apple's iOS. - `ANDROID`  : Google's Android.   > **[INFO]** **Note**    : Specify this parameter when     *env.terminalType*     is   `WAP`   or   `APP`  . |  |
| *env.clientIp* | No | The IP address of the client device. > **[INFO]** **Note**    : This parameter is required for card payments,  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)   and   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md)  scenarios. |  |
| Card payment parameters (Refer to   [Card payment features](#abqU1)  ) | *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.buyer* | Yes | Buyer information. At least one of the following must be provided: - *order.buyer.referenceBuyerId* - *order.buyer.buyerPhoneNo* - *order.buyer.buyerEmail* |  |
| *availablePaymentMethod.paymentMethodMetaData.is3DSAuthentication* | No | Determine whether to set the transaction authentication type to 3DS based on risk and dispute history. Valid values are: - `true`  : indicates that the transaction authentication type is 3DS authentication. - `false`  : indicates that the transaction authentication type is Non-3DS authentication. Default if empty or not provided. |  |
| *availablePaymentMethod.paymentMethodMetaData.tokenizeMode* | No | The tokenize mode. Indicates whether card information needs to be stored. When you opt to   [store card details](https://docs.antom.com/ac/cashierpay/tokenization.md)  , the actual information is replaced with a unique and secure token that can be used for future payments. Valid values are: - `ENABLED`  : indicates that you obtain card binding authorization and want to store card information for future payments. - `DISABLED`  : indicates that you don’t need to store card information. The same applies when the value is empty or you do not specify this parameter. - `ASKFORCONSENT`  : indicates that you present a button on the page, allowing the buyer to choose whether or not they want to store the card information. |  |
| *availablePaymentMethod.paymentMethodMetaData.isCardOnFile* | No | Indicates whether the card used in this transaction has been   [previously processed and stored](https://docs.antom.com/ac/cashierpay/cof.md)   by the merchant. Valid values are: - `true`  : The card used in the transaction has been previously processed and stored by the merchant. Set to   `true`   for stored card payments. - `false`  : Default. The card is new and has not been used previously on the merchant side. |  |
| *savedPaymentMethods.paymentMethodId* | No | Used for stored card payments.    The value of this parameter is that of     *cardToken*     obtained from the new card payment. |  |
| Parameters for specifying payment methods (Refer to   [Specify payment methods](#L9xOX)  ) | *availablePaymentMethod.paymentMethodTypeList.paymentMethodType* | No | Used to specify payment methods. You can specify one or multiple payment methods. Refer to   [Enumeration values of payment methods](https://docs.antom.com/ac/pm/enumeration_values.md)   for valid values. |
| *availablePaymentMethod.paymentMethodTypeList.paymentMethodOrder* | No | Set the priority order of payment methods. |  |

 The above parameters are the basic parameters for creating a payment session, for full parameters and additional requirements for certain payment methods 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
  @PostMapping("/payment/createSession")
    public ResponseEntity<ApiResponse> createPaymentSession(@RequestBody PaymentVO payment) {
        AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
        alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
        alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.ELEMENT_PAYMENT);

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

        // 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>
        long amountMinorLong = Money.of(CurrencyUnit.of(payment.currency), new BigDecimal(payment.amountValue)).getAmountMinorLong();

        // set amount
        Amount amount = Amount.builder().currency(payment.currency).value(String.valueOf(amountMinorLong)).build();
        alipayPaymentSessionRequest.setPaymentAmount(amount);

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

        // set buyer info
        Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

        // replace with your orderId
        String orderId = UUID.randomUUID().toString();
        // set order Info
        Order order = Order.builder().referenceOrderId(orderId).
                orderDescription("antom sdk testing order").orderAmount(amount).buyer(buyer).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/receivePaymentNotify");

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

        AlipayPaymentSessionResponse alipayPaymentSessionResponse;
        try {
            long startTime = System.currentTimeMillis();
            System.out.println("payment request: " + JSON.toJSONString(alipayPaymentSessionRequest));
            alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
            System.out.println("payment response: " + JSON.toJSONString(alipayPaymentSessionResponse));
            System.out.println("payment request cost time: " + (System.currentTimeMillis() - startTime) + "ms\n");
        } catch (AlipayApiException e) {
            return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), e));
        }
        return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), alipayPaymentSessionResponse));
    }
```

<!-- TabGroup -->

**Tab: Merchant-rendered payment method list**

If you render the payment method list yourself, you must integrate by specifying individual payment methods. The following code shows a sample of the request message:

   ```json
{
   "env": {
        "terminalType": "WAP",
        "clientIp": "***.***.***.***", // The buyer's IP adress
        "osType": "IOS"
 },
  "order": {
    "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
    "orderAmount": {
      "currency": "HKD",
      "value": "300"
    },
    "orderDescription": "AMSDM_GIFT",
    "referenceOrderId": "PAYMENT_2025*********138_AUTO"
  },
  "paymentAmount": {
    "currency": "HKD",
    "value": "300"
  },
  "settlementStrategy": {
    "settlementCurrency": "USD"
  },
  "availablePaymentMethod": {
    "paymentMethodTypeList": [
      {
        "paymentMethodType": "ALIPAY_CN" // Specify payment method
      }
    ]
  },
  "paymentNotifyUrl": "https://www.*********.com",
  "paymentRedirectUrl": "https://www.*********u.com",
  "paymentRequestId": "PAYMENT_2025*********201_AUTO",
  "productCode": "CASHIER_PAYMENT",
  "productScene": "ELEMENT_PAYMENT"
}
```

**Tab: Payment Element-rendered payment method list**

If you use Payment Element-rendered payment method list, Payment Element will display all supported payment methods by default. The following code shows a sample of the request message:

   ```json
{
   "env": {
        "terminalType": "WAP",
        "clientIp": "***.***.***.***", // The buyer's IP adress
        "osType": "IOS"
 },
    "order": {
      "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
        "orderAmount": {
            "currency": "HKD",
            "value": "300"
        },
        "orderDescription": "AMSDM_GIFT",
        "referenceOrderId": "PAYMENT_2025*********138_AUTO"
    },
    "paymentAmount": {
        "currency": "HKD",
        "value": "300"
    },
    "settlementStrategy": {
        "settlementCurrency": "USD"
    },
    "paymentNotifyUrl": "https://www.*********.com",
    "paymentRedirectUrl": "https://www.*********.com",
    "paymentRequestId": "PAYMENT_2025*********201_AUTO",
    "productCode": "CASHIER_PAYMENT",
    "productScene": "ELEMENT_PAYMENT"
}
```

<!-- /TabGroup -->
   The following code shows a sample of the response, which contains the following parameters:

 - *result.resultStatus*    : The result of the   [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)   API call.
- *paymentSessionData*    : The payment session data to be returned to the client.
- *paymentSessionExpiryTime*    : The expiration time of the payment session.

   ```json
 {
  "paymentSessionData": "gpZy************fQ==",
  "paymentSessionExpiryTime": "2023-04-06T03:28:49+08:00",
  "paymentSessionId": "paymentSessionId****",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
```

 The table below shows the possible values of     *result.resultStatus*     in the response. Please handle the result according to the guidance provided:

   | ***result.resultStatus*** | **Message** | **Further action** |
| --- | --- | --- |
| `S` | The payment session was successfully created, and     *paymentSessionData*     is returned. | Proceed to the next steps. |
| `U` | Unknown error. | Please use a new          *paymentRequestId*     and call the API again. If the issue persists, contact Antom Technical Support. |
| `F` | Failed to create the payment session. | Please check and verify whether the current API required request fields (including header fields and body fields) are correctly passed and valid. |

 > **[INFO]** **Note**    : If no response is received, it may indicate a network timeout. Please use a new     *paymentRequestId*     and call the API again. If the issue persists, contact Antom Technical Support.

 > **[INFO]** **Common questions**
>
>  **Q: Can I use Chinese characters in the value of the request parameters?**
>
>  A: To avoid incompatibility of certain payment methods, do not use Chinese characters for fields in the request.
>
>  ​
>
>  **Q: How to set the address to receive payment notification?**
>
>  A: Specify     *paymentNotifyUrl*     in the      [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)      API to receive the asynchronous notification about the payment result (  [**notifyPayment**](https://docs.antom.com/docs/ac/ams/paymentrn_online.md)  ), or configure the receiving URL in Antom Dashboard. If the URL is specified in both the request and Antom Dashboard, the value specified in the request takes precedence.
>
>  ​
>
>  **Q: Does the returned**       ***paymentSessionData***       **require processing before passing it to the client?**
>
>  A: Do not process or modify     *paymentSessionData*     in any way, as this may cause the Payment Element invocation to fail.

## Step 2: Invoke Payment Element   **[Client-side]** {#FWfpW}

 Use     *paymentSessionData*     to invoke Payment Element on your client. After the buyer clicks to submit payment, Payment Element will handle the entire flow based on the selected payment method, including displaying QR codes, redirecting to payment pages, performing 3DS authentication, and returning to the merchant’s result page.

 Depending on the rendering method you chose in Step 1 (merchant-rendered or Payment Element-rendered payment method list), the following table compares how to invoke Payment Element in different scenarios:

 | **Method** | **Integration steps** |  |
| --- | --- | --- |
| Merchant-rendered payment method list       (Single payment method integration) | Payment Element collects payment details   ​ | 1. Call the   `[mount()](https://docs.antom.com/ac/sdks/web_mount.md)`   method to embed the payment details component rendered by Payment Element. 2. After the buyer clicks your custom payment button, call the   `[submitPayment()](https://docs.antom.com/ac/sdks/web_submitPayment.md)`   method to submit payment. |
| Payment Element does not collect payment details   ​ | Call the   `[mount()](https://docs.antom.com/ac/sdks/web_mount.md)`   method without embedding the payment details component. After the buyer clicks your custom payment button, call the   `[submitPayment()](https://docs.antom.com/ac/sdks/web_submitPayment.md)`   method to submit payment directly. |  |
| Payment Element-rendered payment method list | 1. Call the   `[mount()](https://docs.antom.com/ac/sdks/web_mount.md)`   method to embed the Payment Element-rendered payment method list. 2. After the buyer clicks your custom payment button, call the   `[submitPayment()](https://docs.antom.com/ac/sdks/web_submitPayment.md)`   method to submit payment. |  |

 1. After obtaining     *paymentSessionData*     from the server, use the   `[AMSElement](https://docs.antom.com/ac/sdks/web_AMSElement.md)`   class to create a Payment Element instance. The following sample code how to instantiate the SDK using CDN or npm:

<!-- TabGroup -->

**Tab: CDN**

```javascript
// Get the browser language
let language = navigator.language || navigator.userLanguage;
language = language.replace("-", "_"); // Replace "-" with "_"

// Create Payment Element instance
const elementPayment = new window.AMSElement({
  environment: "sandbox",
  locale: "en_US",
  sessionData:sessionData
})
```

**Tab: npm**

```javascript
import { AMSElement, ThemeType, PaymentElementLayout } from '@alipay/ams-checkout' // Package management

// Get the browser language
let language = navigator.language || navigator.userLanguage;
language = language.replace("-", "_"); // Replace "-" with "_"

// Create Payment Element instance
const elementPayment = new AMSElement({
  environment: "sandbox",
  locale: "en_US",
  sessionData:sessionData
})
```

<!-- /TabGroup -->
   2. Use the   `[mount()](https://docs.antom.com/ac/sdks/web_mount.md)`   method from the instance object to create the payment component, and embed the component into the specified view if needed. Before calling the   `[mount()](https://docs.antom.com/ac/sdks/web_mount.md)`   method, you may add a     *loading*     indicator and close it when handling the callback in the   `.then()`   method. If the callback result contains error information, determine the specific error type via     *error?.code*    , and refer to the   [callback function event codes](https://docs.antom.com/ac/sdks/ref.md#M3TUS)   for detailed error causes and handling suggestions. If no error information is present, the   `[mount()](https://docs.antom.com/ac/sdks/web_mount.md)`   method rendering was successful.

 > **[INFO]** **Note**    :
>
>  - If you need to embed the payment details collection component (see   [Payment methods requiring embedding](#Ygtd4X)   for details), it is recommended that the container for the payment element have a minimum width of 375 px and no height restriction, allowing the Payment Element to automatically expand the container height.
> - The different configuration of     *notRedirectAfterComplete*     in the   `[mount()](https://docs.antom.com/ac/sdks/web_mount.md)`   method handles the redirection of the merchant page differently. For details, refer to   [Redirect to the merchant page](https://docs.antom.com/ac/sdks/web_mount.md#gxPhN)  .

 The following sample code shows how to create a payment component using the      `[mount()](https://docs.antom.com/ac/sdks/web_mount.md)`      method:

 ```javascript
let loading = false;

// Customize appearance
const appearance = {
  theme: "default",
  layout: { type: "Accordion" },
  variables: {},
};

// Set external container loading state before calling mount
loading = true;

// Embed into the document.querySelector("#payment-element") node
elementPayment.mount(
  {
    type: 'payment',
    appearance: appearance,
    notRedirectAfterComplete: false,
  },
  '#payment-element',
).then(({ error }) => {
  // Manually turn off external container loading state
  loading = false;

  // Handle error information, process exceptions based on error.code
  if (error && error?.code) {
    // PARAM_INVALID: SDK parameter exception, recommend checking integration code
    // UI_STATE_ERROR: mount call timing exception, recommend checking integration code
    console.log(error.message);
  
    if(error?.code === 'INITIALIZE_API_TIMEOUT') {
    // Payment information query API timeout causing checkout rendering failure, recommend guiding user to retry
  
    } else if(error?.code === 'INITIALIZE_WEB_TIMEOUT'){
      // Checkout static resource loading timeout, recommend guiding user to retry
  
    } ...
    return;
  }
  // mount rendering successful, no handling needed
})
```

 3. After the buyer clicks your custom payment button, call the   `[submitPayment()](https://docs.antom.com/ac/sdks/web_submitPayment.md)`  method to submit payment.
   Before calling the   `[submitPayment()](https://docs.antom.com/ac/sdks/web_submitPayment.md)`   method, you may add a     *loading*     indicator and close it when handling the callback in the   `.then()`   method. It is recommended to display the *loading* state after the buyer clicks the payment button to prevent repeated submissions within a short period. After receiving the payment result returned by Payment Element, guide the buyer to either retry the payment or redirect to the payment result page based on the actual outcome.

   - If the callback result contains error information, you can simplify integration based on the     *status*     value. Refer to the sample code below for specific operations. You may also refer to     *error?.code*     for specific exception handling and refer to   [callback function event codes](https://docs.antom.com/ac/sdks/ref.md#heMi7)   for detailed error causes and handling suggestions.
  - If no error information exists, proceed with subsequent operations based on the     *status*     value.

 ```javascript
let loading = false;

loading = true;
// When the buyer clicks the payment button:
elementPayment.submitPayment().then(({ error, status, userCanceled3D }) => {
  // Manually turn off the external container's loading state
  loading = false;

  if (error) { // Handle error information first
    const { code, message } = error;

    if (userCanceled3D) {
      // Buyer actively closed the 3D popup, recommend polling results from the server
    }

    if (status === 'PROCESSING') {
      // Status unknown due to network exception or channel instability. Recommend polling results from the server
    } else {
      // FAIL - Failure
      // Form validation failed, Payment Element has prompted the buyer, recommend ignoring
      if (code === 'FORM_INVALID') {
        return;
      }

      toast(message);

      // Or customize experience based on code granularity
      if (code ){
        // xxx
      }
    }
    return;
  }

  if (status === 'SUCCESS') {
    // SUCCESS - Success. In some scenarios Payment Element will show a toast prompt, recommend directly redirecting to the result page

  } else if(status === 'CANCELLED'){
    // Order has been cancelled, can be ignored if not applicable to this scenario

  } else {
    // You can add monitoring
  }
})

```

### Unmount Payment Element {#gn3NV8}

 Call the   `[destroy()](https://docs.antom.com/ac/sdks/web_destroy.md)`   method to release the resources occupied by the Payment Element component:

   ```typescript
elementPayment.destroy();
```

   > **[INFO]** **Common questions**
>
>  **Q: Can I integrate the Web Element using Webview in PC or mobile applications?**
>
>  A: Currently not supported.

## Step 3: Obtain the payment result   **[Server-side]** {#MxqX3}

 After the buyer completes the payment or the payment times out, Antom will send the corresponding payment results to you through server interaction. You can obtain the payment results using one of the following methods:

 - Receive asynchronous notifications from Antom
- Inquire about the payment result

<!-- TabGroup -->

**Tab: Receive asynchronous notifications**

**1\. Configure the webhook URL to receive asynchronous notifications**

 When a payment succeeds or fails, Antom will send an asynchronous notification to the webhook URL you set. You can choose one of the following two methods to configure the webhook URL for receiving notifications (if both are set, the URL specified in the request takes precedence):

 - If each of your orders has a unique notification URL, it is recommended to set the webhook URL in each request. You can pass the asynchronous notification receiving URL for the specific order through     *paymentNotifyUrl*     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 URL**    . For detailed steps, refer to   [Notification URL](https://docs.antom.com/ac/merchant_service/notification.md)  .

 The following code shows a sample of the asynchronous notification request:

<!-- TabGroup -->

**Tab: Card payments, Apple Pay, Google Pay**

```json
{
  "actualPaymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "cardInfo": {
    "avsResultRaw": "A",
    "cardBrand": "MASTERCARD",
    "cardNo": "****************",
    "cardToken":"exxxxe",
    "cvvResultRaw": "Y",
    "funding": "DEBIT",
    "issuingCountry": "US",
    "networkTransactionId": "XXXXX",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "paymentMethodType": "CARD",
  "paymentCreateTime": "2024-01-01T00:00:00+08:00",
  "paymentId": "20240101123456789XXXX",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultInfo": {
    "avsResultRaw": "A",
    "cardBrand": "MASTERCARD",
    "cardNo": "****************",
    "cardToken":"exxxxe", // store cardToken for future card payments
    "cvvResultRaw": "Y",
    "funding": "DEBIT",
    "issuingCountry": "US",
    "networkTransactionId": "XXXXX",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "paymentTime": "2024-01-01T00:01:00+08:00",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
```

   The following table shows the possible values of     *result.resultStatus*     in the notification request of payment result. Please handle the result according to the guidance provided:

   | ***result.resultStatus*** | **Message** | **Further action** |
| --- | --- | --- |
| `S` | Authorization    was successful. | You may proceed to initiate a capture. |
| `F` | Authorization    failed. | Please use a new     *paymentRequestId*        and initiate the payment again. |

**Tab: APM payments**

```json
{
    "actualPaymentAmount": {
        "currency": "HKD",
        "value": "100"
    },
    "notifyType": "PAYMENT_RESULT",
    "paymentAmount": {
        "currency": "HKD",
        "value": "100"
    },
    "paymentCreateTime": "2025-02-04T22:11:19-08:00",
    "paymentId": "20240101123456789XXXX",
    "paymentMethodType": "ALIPAY_HK",
    "paymentRequestId": "paymentRequestId01",
    "paymentResultInfo": {

    },
    "paymentTime": "2025-02-04T22:14:25-08:00",
    "pspCustomerInfo": {
        "pspCustomerId": "216022003753XXXX",
        "pspName": "ALIPAY_HK"
    },
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}
```

   The following table shows the possible values of     *result.resultStatus*     in the notification request of payment result. Please handle the result according to the guidance provided:

 | ***result.resultStatus*** | **Message** | **Further action** |
| --- | --- | --- |
| `S` | Payment was successful. | **​**    You may proceed to ship the goods. |
| `F` | Payment failed. | Please use a new     *paymentRequestId*        and initiate the payment again. |

<!-- /TabGroup -->
 **2\. Verify the asynchronous notification**

 When 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
import javax.servlet.http.HttpServletRequest;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.alipay.global.api.model.Result;
import com.alipay.global.api.model.ResultStatusType;
import com.alipay.global.api.response.AlipayResponse;
import com.alipay.global.api.tools.WebhookTool;

@RestController
public class PaymentNotifyHandleBySDK {

    /**
     * alipay public key, used to verify signature
     */
    private static final String SERVER_PUBLIC_KEY = "";
  
    /**
     * payment result notify processor
     * using <a href="https://spring.io">Spring Framework</a>
     *
     * @param request    HttpServletRequest
     * @param notifyBody notify body
     * @return
     */
    @PostMapping("/payNotify")
    public Object payNotifyHandler(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");

        Result result;
        AlipayResponse response = new AlipayResponse();

        try {
            // verify the signature of notification
            boolean verifyResult = WebhookTool.checkSignature(requestUri, requestMethod, clientId, requestTime, signature, notifyBody, SERVER_PUBLIC_KEY);
            if (!verifyResult) {
                throw new RuntimeException("Invalid notify signature");
            }

            // deserialize the notification body
  
            // update the order status with notify result

            // respond the server that the notification is received
            result = new Result("SUCCESS", "success", ResultStatusType.S);

        } catch (Exception e) {
            String errorMsg = e.getMessage();
            // handle error condition
            result = new Result("ERROR", errorMsg, ResultStatusType.F);
        }
        response.setResult(result);
        return ResponseEntity.ok().body(response);
    }

}
```

   Whether the payment is successful or not, each notification request must be responded to in the format specified below. Otherwise, Antom will resend the asynchronous notification.

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

   > **[INFO]** **Common questions**
>
>  **Q: When will the notification be sent?**
>
>  A: It depends on whether the payment is completed:
>
>  - If the payment is successfully completed, Antom will 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 payment is not completed, Antom needs to close the order first before sending an asynchronous notification. The time it takes for different payment methods to close the order varies, usually defaulting to 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 did not respond 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: When responding to an asynchronous notification, do I need to add a digital signature?**
>
>  A: 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.
>
>  ​
>
>  **Q: What key parameters do I need to use in the notification?**  
>    A: Please note the following key parameters:
>
>  - *result*    : For APM payments, it represents the final payment result. For  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)  ,   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md) , and card payments, it only represents the authorization result, and further capture is required.
> - *paymentRequestId*    : The payment request ID used for inquiries, cancellations, and reconciliation.
> - *paymentId*    : The payment order ID generated by Antom, used for refunds and reconciliation.
> - *paymentAmount*    : The payment amount.

**Tab: Inquire about the result**

You can also inquire about the payment result by calling the   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   API using     *paymentRequestId*     from the payment request,    regardless of whether it is an APM payment, card payment,  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)  , or   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md) .

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

 ```java
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 sample code shows a request message:

   ```json
{
  "paymentRequestId": "paymentRequestId01"
}
```

   The following sample code shows a response message:

<!-- TabGroup -->

**Tab: APM payments**

```json
{
  "actualPaymentAmount": {
    "currency": "THB",
    "value": "299"
  },
  "paymentAmount": {
    "currency": "THB",
    "value": "299"
  },
  "paymentId": "20240101123456789XXXX",
  "paymentMethodType": "TRUEMONEY",
  "paymentRedirectUrl": "https://kademo.intlalipay.cn/melitigo/Test_114.html",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultCode": "SUCCESS",
  "paymentResultMessage": "success.",
  "paymentStatus": "SUCCESS",
  "paymentMethodType": "TRUEMONEY",
  "paymentTime": "2025-02-17T08:06:43-08:00",
  "pspCustomerInfo": {
    "pspName": "TRUEMONEY"
  },
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
```

**Tab: Card payments, Apple Pay, Google Pay**

```json
{
    "actualPaymentAmount": {
        "currency": "USD",
        "value": "5000"
    },
    "authExpiryTime": "2024-12-17T21:56:56-08:00",
    "cardInfo": {
        "cardBrand": "VISA",
        "funding": "CREDIT",
        "issuingCountry": "US"
    },
    "paymentAmount": {
        "currency": "USD",
        "value": "5000"
    },
    "paymentId": "20240101123456789XXXX",
    "paymentMethodType": "CARD",
    "paymentRedirectUrl": "http://gol.alipay.net:8080/amsdemo/result?paymentRequestId=amsdmpay_yanfei_wzh_20240111_191505_666",
    "paymentRequestId": "paymentRequestId01",
    "paymentResultCode": "SUCCESS",
    "paymentResultInfo": {
        "avsResultRaw": "M",
        "cardBrand": "VISA",
        "cardNo": "************9954",
        "cvvResultRaw": "U",
        "funding": "CREDIT",
        "issuingCountry": "US",
        "networkTransactionId": "123qwe456rew",
        "paymentMethodRegion": "GLOBAL",
        "threeDSResult": {
            "cavv": "",
            "eci": ""
        }
    },
    "paymentResultMessage": "success.",
    "paymentStatus": "SUCCESS",
    "paymentTime": "2024-12-10T21:56:57-08:00",
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}
```

<!-- /TabGroup -->
   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)  .

 > **[INFO]** **Common questions**
>
>  **Q: What key parameters should I pay attention to when using the**       [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)       **API to check the payment or authorization status?**
>
>  A: Please note the following key parameters:
>
>  - *result*    :    Only indicates the result of the API call. For APM payments, the final payment result should be determined based on     *paymentStatus*     (  `SUCCESS`  /  `FAIL`  /  `PROCESSING`  ). For card payments,  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)  , and   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md) ,     *paymentStatus*     only represents the authorization result, and the decision to ship goods should rely on the capture result.
> - *paymentAmount*    : Used to verify the payment amount.
> - *paymentId*    : The payment order ID generated by Antom, used for refunds and reconciliation.
>
>  ​
>
>  **Q: How often should I call the inquiryPayment API?**
>
>  A: Call the   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   API constantly with an interval of 2 seconds until the final payment result is obtained or an asynchronous payment result notification is received.

<!-- /TabGroup -->

## Step 4: Capture   **[Server-side]** **[For card payments/Apple Pay/Google Pay only]** {#qu0V5}

 Antom provides both automatic and manual capture methods. You can choose based on your business needs. After initiating capture, you can obtain the result via asynchronous notification or active inquiry. For specific operations, refer to   [Capture](https://docs.antom.com/ac/cashierpay/capture.md)  .

**Tab: iOS**

# User experience {#2BEWwv}

 The following figures demonstrate the user experience of using Payment Element in different scenarios:

<!-- TabGroup -->

**Tab: Payment Element-rendered payment method list**

The following figure shows templates for invoking the Payment Element-rendered payment method list in a pop-up:

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/83d1a1b7-e30b-40cc-8b72-bb350ba3c395.png) If you use the Payment Element-rendered payment method list, all supported payment methods will be displayed on the checkout page by default. The following figures illustrate the user experience for different payment methods:

<!-- TabGroup -->

**Tab: Scan to pay**

Payment Element displays a QR code for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/4e0fd2d7-196e-4f0c-a424-35fd36883389.png)

**Tab: Redirect to payment page**

Payment Element redirects to the payment method page for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/fa7d21a7-3bc9-4bb1-a334-5910f5c4cfad.png)

**Tab: New card payment**

Payment Element displays the card detail collection page for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/054517ec-1b96-4e8b-a43d-0f8ebec53401.png)

**Tab: Stored card payments**

Payment Element handles the stored card payment scenario.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/48da6b02-d667-43af-9f45-ba17a6141a42.png)

<!-- /TabGroup -->

**Tab: Merchant-rendered payment method list**

The following figure shows templates of merchant-rendered payment method list:

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/fe5b70f9-c2c0-41b6-8b76-c22ea5f5efbf.png) If you render the payment methods by specifying them yourself, the following figures demonstrate the user experience for different payment methods:

<!-- TabGroup -->

**Tab: Scan to pay**

Payment Element displays a QR code for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/5c280a88-d3fb-48d2-8fb7-0e9833d7d99d.png)

**Tab: Redirect to payment page**

Payment Element redirects to the payment method page for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/34b1d2d5-2952-4c18-8941-67167652babf.png)

**Tab: New card payment**

Payment Element displays the card detail collection page for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/7846ecfc-3a15-4175-a3d6-a4ccb31dfbf8.png)

<!-- /TabGroup -->

<!-- /TabGroup -->

# Order lifecycle {#2iYCQo}

 Learn about the lifecycle of different payment methods:

<!-- TabGroup -->

**Tab: APM Payments**

For APM payments, such as  [Alipay](https://docs.antom.com/ac/antomop/alipay_cn.md)  and  [Touch'n Go eWallet](https://docs.antom.com/ac/antomop/touchngo.md) , funds are transferred directly to your account once the payment is initiated and completed by the buyer. You can  [cancel](#Otb6j)  or  [refund](#kg4oU)  the order within the allowable period.

   ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/6da32eae-f8c2-495f-a6ce-c8a4f7b27c2e.png)

**Tab: Card payments, Apple Pay, Google Pay**

For card payments,  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)  , and   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md) , the order lifecycle includes the following stages:

 1. Authorization: After the buyer completes the payment using a card, the funds are temporarily frozen. You can   [cancel](#Otb6j)   the order during the allowable period from when the order is placed until authorization is completed.
2. Capture   : You can manually capture the frozen funds to transfer them to your account, or let Antom automatically handle capture for you. For details, refer to   [Capture](https://docs.antom.com/ac/cashierpay/capture.md)  . After capture, you can initiate a   [refund](#kg4oU)   within the allowable period if needed.
3. Chargeback: You may submit a chargeback defense based on the specific situation. For more information, refer to   [Dispute](#AoEw6)  .

   ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/abc1f3bf-4223-4ed2-adc3-35862da1bfeb.png)

<!-- /TabGroup -->

# Payment flow {#n2igJF}

 The following flow illustrates how to integrate One-time Payments using Payment Element:

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/47f3836c-03c0-452f-b3e2-c4217016ba8d.png) 1. **The buyer lands on the checkout page and submits payment.**
2. **Create a payment session request.**  
   You can obtain the payment session by calling the   [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)        API.
3. **Invoke Payment Element.**  
   On the client side, invoke Payment Element using the payment session. You can choose to use the Payment Element-rendered payment method list, or render the payment methods by specifying them yourself. Payment Element will handle information processing, collect payment details, perform redirects, manage app invocations, display QR codes, and conduct validations based on the features of the selected payment method. After the payment is completed, depending on your configuration and the payment method features, you need to handle redirections based on the result returned by the   `onSubmitPayCallback:`   method, or the system will automatically return to your result page.
4. **Confirm the payment result.**  
   Obtain the payment result by using one of the following two 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. When the payment is successful or expires, Antom will use   [**notifyPayment**](https://docs.antom.com/ac/ams/paymentrn_online.md)   to send asynchronous notifications to you.
  - Synchronous inquiry: Call the   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   API to check the payment status.

 > **[INFO]** **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 mode 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. **Initiate capture and obtain the 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 capture status.

# Integration preparations {#22KAW}

 Before you start integrating, read   [Integration guide](https://docs.antom.com/integration_guide_en.md)   and   [API overview](https://docs.antom.com/ac/ams/api_fund.md)   to understand the integration steps of the server-side API and the precautions for calling the API. Furthermore, ensure the following prerequisites are met:

 - Obtained your 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)  .
- Integrate the client-side SDK package by following the steps detailed in   [Integrate the SDK package for iOS](https://docs.antom.com/ac/sdks/ios.md)  , and ensure to use the latest SDK version or no lower than 1.46.0.

# Integration steps {#n22t0Y}

 Start your integration by taking the following steps:

 1. (Optional) Preload the SDK
2. Create a payment session
3. Invoke Payment Element
4. Obtain    the payment result
5. Capture

## (Optional) Step 1: Preload the SDK   **[Client-side]** {#c33hKYz}

 Before creating a payment session, it is highly recommended that you preload the SDK to improve the rendering speed of the checkout page, reducing the waiting time for buyers during the payment. Follow the code example below to perform the preloading:

 ```objectivec
[AMSPaymentElement.shared preload];
```

## Step 2: Create a payment session   **[Server-side]** {#K22uWal}

 Call the      [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)      API with order information to create a payment session and obtain the     *paymentSessionData*     required to invoke Payment Element. You can choose to either render the payment methods by specifying them yourself or use the Payment Element-rendered payment method list. It is recommended that you create a payment session after the buyer clicks the payment button. Depending on the method you selected for rendering the payment method list at the checkout page, pass the corresponding parameters when calling the   [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)      API.

 - Render the payment methods by yourself:    When rendering the payment method list yourself, you must pass the parameters for specifying payment methods listed in the table below. If Payment Element needs to collect payment details, pass the card payment parameters listed in the table below.

 - When using the Payment    Element-rendered    payment method list, you only need to pass the basic parameters listed in the table below. Payment Element renders all supported payment methods on the checkout page by default, but you can [specify payment methods](#L9xOX) to display only the options you need.

   | **Type** | **Parameter name** | **Required** | **Description** |
| --- | --- | --- | --- |
| Basic parameters | *productCode* | Yes | For Payment Element, the value is fixed as      `CASHIER_PAYMENT`  . |
| *productScene* | Yes | For Payment Element, the value is fixed as      `ELEMENT_PAYMENT`  . |  |
| *paymentRequestId* | Yes | The unique ID assigned by the merchant to identify a payment request. |  |
| *paymentAmount* | Yes | The payment amount that the merchant requests to receive in the order currency. |  |
| *paymentRedirectUrl* | Yes | The merchant page URL that the buyer is redirected to after the payment is completed. |  |
| *paymentNotifyUrl* | No | The payment result notification URL, which can be passed in through the API or set as a fixed value through Antom Dashboard. If both are set, the value in the API takes precedence. |  |
| *settlementStrategy* | Yes | The settlement strategy for the payment request. |  |
| *order.referenceOrderId* | Yes | The unique ID to identify the order on the merchant side. |  |
| *order.orderDescription* | Yes | Summary description of the order. |  |
| *env.terminalType* | No | Terminal type of which the merchant service applies to. Valid values are: - `WEB`  : The client-side terminal type is a website, which is opened via a PC browser. - `WAP`  : The client-side terminal type is an H5 page, which is opened via a mobile browser. - `APP`  : The client-side terminal type is a mobile application.   > **[INFO]** **Note**    : This parameter is required for  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)   and   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md) . |  |
| *env.osType* | No | The operating system type from which the buyer initiated the transaction. Valid values: - `IOS`  : Apple's iOS. - `ANDROID`  : Google's Android.   > **[INFO]** **Note**    : Specify this parameter when     *env.terminalType*     is   `WAP`   or   `APP`  . |  |
| *env.clientIp* | No | The IP address of the client device. > **[INFO]** **Note**    : This parameter is required for card payments,  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)   and   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md)  scenarios. |  |
| Card payment parameters (Refer to   [Card payment features](#abqU1)  ) | *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.buyer* | Yes | Buyer information. At least one of the following must be provided: - *order.buyer.referenceBuyerId* - *order.buyer.buyerPhoneNo* - *order.buyer.buyerEmail* |  |
| *availablePaymentMethod.paymentMethodMetaData.is3DSAuthentication* | No | Determine whether to set the transaction authentication type to 3DS based on risk and dispute history. Valid values are: - `true`  : indicates that the transaction authentication type is 3DS authentication. - `false`  : indicates that the transaction authentication type is Non-3DS authentication. Default if empty or not provided. |  |
| *availablePaymentMethod.paymentMethodMetaData.tokenizeMode* | No | The tokenize mode. Indicates whether card information needs to be stored. When you opt to   [store card details](https://docs.antom.com/ac/cashierpay/tokenization.md)  , the actual information is replaced with a unique and secure token that can be used for future payments. Valid values are: - `ENABLED`  : indicates that you obtain card binding authorization and want to store card information for future payments. - `DISABLED`  : indicates that you don’t need to store card information. The same applies when the value is empty or you do not specify this parameter. - `ASKFORCONSENT`  : indicates that you present a button on the page, allowing the buyer to choose whether or not they want to store the card information. |  |
| *availablePaymentMethod.paymentMethodMetaData.isCardOnFile* | No | Indicates whether the card used in this transaction has been   [previously processed and stored](https://docs.antom.com/ac/cashierpay/cof.md)   by the merchant. Valid values are: - `true`  : The card used in the transaction has been previously processed and stored by the merchant. Set to   `true`   for stored card payments. - `false`  : Default. The card is new and has not been used previously on the merchant side. |  |
| *savedPaymentMethods.paymentMethodId* | No | Used for stored card payments.    The value of this parameter is that of     *cardToken*     obtained from the new card payment. |  |
| Parameters for specifying payment methods (Refer to   [Specify payment methods](#L9xOX)  ) | *availablePaymentMethod.paymentMethodTypeList.paymentMethodType* | No | Used to specify payment methods. You can specify one or multiple payment methods. Refer to   [Enumeration values of payment methods](https://docs.antom.com/ac/pm/enumeration_values.md)   for valid values. |
| *availablePaymentMethod.paymentMethodTypeList.paymentMethodOrder* | No | Set the priority order of payment methods. |  |
| *availablePaymentMethod.paymentMethodTypeList.expressCheckout* | No | Specifies whether to enable the express checkout option for a payment method. Currently, only   `ALIPAY_CN`  ,   `APPLEPAY`   and   `GOOGLEPAY`  can be set as express checkout methods. Valid values are: - `true`  : Enables express checkout for this payment method. - `false`  : Disables express checkout for this payment method.   > **[INFO]** **Note**    : This parameter is currently supported only on Android and iOS. |  |

 The above parameters are the basic parameters for creating a payment session, for full parameters and additional requirements for certain payment methods 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
  @PostMapping("/payment/createSession")
    public ResponseEntity<ApiResponse> createPaymentSession(@RequestBody PaymentVO payment) {
        AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
        alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
        alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.ELEMENT_PAYMENT);

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

        // 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>
        long amountMinorLong = Money.of(CurrencyUnit.of(payment.currency), new BigDecimal(payment.amountValue)).getAmountMinorLong();

        // set amount
        Amount amount = Amount.builder().currency(payment.currency).value(String.valueOf(amountMinorLong)).build();
        alipayPaymentSessionRequest.setPaymentAmount(amount);

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

        // set buyer info
        Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

        // replace with your orderId
        String orderId = UUID.randomUUID().toString();
        // set order Info
        Order order = Order.builder().referenceOrderId(orderId).
                orderDescription("antom sdk testing order").orderAmount(amount).buyer(buyer).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/receivePaymentNotify");

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

        AlipayPaymentSessionResponse alipayPaymentSessionResponse;
        try {
            long startTime = System.currentTimeMillis();
            System.out.println("payment request: " + JSON.toJSONString(alipayPaymentSessionRequest));
            alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
            System.out.println("payment response: " + JSON.toJSONString(alipayPaymentSessionResponse));
            System.out.println("payment request cost time: " + (System.currentTimeMillis() - startTime) + "ms\n");
        } catch (AlipayApiException e) {
            return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), e));
        }
        return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), alipayPaymentSessionResponse));
    }
```

<!-- TabGroup -->

**Tab: Merchant-rendered payment method list**

If you render the payment method list yourself, you must integrate by specifying individual payment methods. The following code shows a sample of the request message:

   ```json
{
   "env": {
        "terminalType": "APP",
        "clientIp": "***.***.***.***", // The buyer's IP adress
        "osType": "IOS"
 },
  "order": {
    "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
    "orderAmount": {
      "currency": "HKD",
      "value": "300"
    },
    "orderDescription": "AMSDM_GIFT",
    "referenceOrderId": "PAYMENT_2025*********138_AUTO"
  },
  "paymentAmount": {
    "currency": "HKD",
    "value": "300"
  },
  "settlementStrategy": {
    "settlementCurrency": "USD"
  },
  "availablePaymentMethod": {
    "paymentMethodTypeList": [
      {
        "paymentMethodType": "ALIPAY_CN" // Specify payment method
      }
    ]
  },
  "paymentNotifyUrl": "https://www.*********.com",
  "paymentRedirectUrl": "https://www.*********u.com",
  "paymentRequestId": "PAYMENT_2025*********201_AUTO",
  "productCode": "CASHIER_PAYMENT",
  "productScene": "ELEMENT_PAYMENT"
}
```

**Tab: Payment Element-rendered payment method list**

If you use Payment Element-rendered payment method list, Payment Element will display all supported payment methods by default. The following code shows a sample of the request message:

   ```json
{
   "env": {
        "terminalType": "APP",
        "clientIp": "***.***.***.***", // The buyer's IP adress
        "osType": "IOS"
 },
    "order": {
      "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
        "orderAmount": {
            "currency": "HKD",
            "value": "300"
        },
        "orderDescription": "AMSDM_GIFT",
        "referenceOrderId": "PAYMENT_2025*********138_AUTO"
    },
    "paymentAmount": {
        "currency": "HKD",
        "value": "300"
    },
    "settlementStrategy": {
        "settlementCurrency": "USD"
    },
    "paymentNotifyUrl": "https://www.*********.com",
    "paymentRedirectUrl": "https://www.*********.com",
    "paymentRequestId": "PAYMENT_2025*********201_AUTO",
    "productCode": "CASHIER_PAYMENT",
    "productScene": "ELEMENT_PAYMENT"
}
```

<!-- /TabGroup -->
   The following code shows a sample of the response, which contains the following parameters:

 - *result.resultStatus*    :    The result of the   [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)   API call.
- *paymentSessionData*    : The payment session data to be returned to the client.
- *paymentSessionExpiryTime*    : The expiration time of the payment session.

   ```json
 {
  "paymentSessionData": "gpZy************fQ==",
  "paymentSessionExpiryTime": "2023-04-06T03:28:49+08:00",
  "paymentSessionId": "paymentSessionId****",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
```

 The table below shows the possible values of     *result.resultStatus*     in the response. Please handle the result according to the guidance provided:

   | ***result.resultStatus*** | **Message** | **Further action** |
| --- | --- | --- |
| `S` | The payment session was successfully created, and     *paymentSessionData*     is returned. | Proceed to the next steps. |
| `U` | Unknown error. | Please use a new          *paymentRequestId*     and call the API again. If the issue persists, contact Antom Technical Support. |
| `F` | Failed to create the payment session. | Please check and verify whether the current API required request fields (including header fields and body fields) are correctly passed and valid. |

 > **[INFO]** **Note**    : If no response is received, it may indicate a network timeout. Please use a new     *paymentRequestId*     and call the API again. If the issue persists, contact Antom Technical Support.

 > **[INFO]** **Common questions**
>
>  **Q: Can I use Chinese characters in the value of the request parameters?**
>
>  A: To avoid incompatibility of certain payment methods, do not use Chinese characters for fields in the request.
>
>  ​
>
>  **Q: How to set the address to receive payment notification?**
>
>  A: Specify     *paymentNotifyUrl*     in the      [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)      API to receive the asynchronous notification about the payment result (  [**notifyPayment**](https://docs.antom.com/docs/ac/ams/paymentrn_online.md)  ), or configure the receiving URL in Antom Dashboard. If the URL is specified in both the request and Antom Dashboard, the value specified in the request takes precedence.
>
>  ​
>
>  **Q: Does the returned**       ***paymentSessionData***       **require processing before passing it to the client?**
>
>  A: Do not process or modify     *paymentSessionData*     in any way, as this may cause the Payment Element invocation to fail.

## Step 3: Invoke Payment Element   **[Client-side]** {#3WfpW}

 Use     *paymentSessionData*     to invoke Payment Element on your client. After the buyer clicks to submit payment, Payment Element will handle the entire flow based on the selected payment method, including displaying QR codes, redirecting to payment pages, performing 3DS authentication, and returning to the merchant’s result page.

 1. After obtaining     *paymentSessionData*     from the server, use the   `AMSPaymentElement`   class to create a Payment Element instance.

   1. Creating the   `AMSPaymentElementConfiguration`   object includes the following parameters:

 | **Parameter name** | **Required** | **Type** | **Description** |
| --- | --- | --- | --- |
| *locale* | No | String | Used to pass in language information. Pass the corresponding value based on the region of the payment method. Valid values are listed as follows. If other values are passed, English is used by default: - `en_US`  : Default value.    English - `pt_BR`  : Portuguese (Brazil) - `pt_PT`  : Portuguese - `es_ES`  : Spanish - `ko_KR`  : Korean - `zh_CN`  : Simplified Chinese - `zh_HK`  : Traditional Chinese - `ms_MY`  : Malay - `in_ID`  : Indonesian - `th_TH`  : Thai - `vi_VN`  : Vietnamese - `tl_PH`  : Filipino - `it_IT`  : Italian - `de_DE`  : German - `fr_FR`  : French - `nl_NL`  : Dutch - `ja_JP`  : Japanese - `ro`  : Romanian - `pl_PL`  : Polish - `ar_SA`  : Arabic - `tr_TR`  : Turkish - `hi_IN`  : Hindi |
| *options* | No | Dictionary | Used to specify whether to use the default loading mode and sandbox environment. Valid values are: - `"sandbox", "true"`  ：Sandbox environment. - `"sandbox", "false"`  ：Default value. Production environment. - `"showLoading", "true"`  ：   Default value   . The default loading mode is used. - `"showLoading", "false"`  ：The default loading mode is not used.. - `"notRedirectAfterComplete"`  ：Optional. Boolean type. Used to set whether to redirect back to your page after payment completion. Valid values are:     - `false`  ：Default value. Redirects to your page after successful payment completion. The same applies if the value is empty.   - `true`  ：No redirection after payment completion. You need to manually control the subsequent payment flow based on client-side event codes.   > **[INFO]** **Note**    : The payment result event codes returned on the client-side are for reference only in page navigation. Transaction status updates must be based on the results returned by the server-side   [**notifyPayment**](https://docs.antom.com/ac/ams/paymentrn_online.md)   or   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   API.   - `"appearance"`  :    Optional.    Used for custom appearance configuration. For more information, refer to   [Appearance customization](https://docs.antom.com/ac/cashierpay/appearance.md)  . It contains the following parameters:     - *theme*    : Theme color.   - *layout*    : Arrangement method.   - *variables*    : Override underlying CSS custom properties using CSS design tokens (e.g.,   `color-primary`  ) to implement theme customization. |

   2. Implement   `AMSPaymentProtocol`   to handle corresponding events in subsequent processes. It includes the following methods:

   | **Method** | **Required** | **Description** |
| --- | --- | --- |
| `initConfiguration:completion:` | Yes | A callback function for monitoring exceptions during payment component initialization. The callback parameters include the error     *code*    . Refer to the   [callback function event codes](https://docs.antom.com/ac/sdks/ref.md#l1qwb)   for handling. |
| `onSubmitPayCallback:` | No | A callback function for monitoring exceptions when launching the payment page. The callback parameters include the error     *code*     and     *message*    . Refer to the   [callback function event codes](https://docs.antom.com/ac/sdks/ref.md#UOmXC)   for handling. |

 The following shows a sample code for creating the Payment Element instance using   `AMSPaymentElement`  :

   ```objectivec
#import <AMSComponent/AMSComponent-Swift.h>

// Create an AMSPaymentElementConfiguration object
AMSPaymentElementConfiguration *componentConfig = [AMSPaymentElementConfiguration new];
componentConfig.locale = @"en_US";

NSString *appearance = @"{\n  \"theme\": \"night\",\n  \"layout\": {\n    \"type\": \"Tabs\"\n  },\n  \"variables\": {\n    \"content-quaternary\": \"#FFFF00\"\n  }\n}";

// Set sandbox environment. If left empty, the online production environment will be used by default
NSDictionary *options = @{@"showLoading": @"true",
                          @"sandbox": @"true",
                          @"appearance": appearance
                          };
componentConfig.options = options;

// initConfiguration usage
[[AMSPaymentElement shared] initConfiguration:componentConfig completion:^(AMSStatusResult * _Nonnull result) {
    // Handle error events during the initConfiguration phase
    if (result.error) {
        // Handle failure
        if ([result.error.code isEqualToString:@"UI_STATE_ERROR"]) {
            NSLog(@"integration code error, please check the integration code");
        } else {
            NSLog(@"unknown error, please contact support");
        }
    } else {
        // Handle success
    }
}];

// Set callback to listen for payment events on the checkout page
[AMSPaymentElement shared].paymentDelegate = self;

// Server calls the Create Payment Session API to obtain paymentSessionData

#pragma AMSPaymentProtocol
// Handle submitPay phase event codes via callback
- (void)onSubmitPayCallback:(AMSStatusResult *)eventResult {
    AMSStatusResultType statusType = eventResult.status;
    AMSResultError *error = eventResult.error;

    switch (statusType) {
        case AMSStatusResultTypePROCESSING:
            if (error && error.code) {
                if ([@"PAYMENT_IN_PROCESS" isEqualToString:error.code]) {
                    NSLog(@"payment is in processing, please try polling the payment result from the server");
                } else if ([@"USER_CANCELED" isEqualToString:error.code]) {
                    NSLog(@"user cancelled the payment process, please try invoke createComponent again");
                } else if ([@"UNKNOWN_EXCEPTION" isEqualToString:error.code]) {
                    NSLog(@"unknown exception, please contact support");
                } else if ([@"PAYMENT_RESULT_TIMEOUT" isEqualToString:error.code]) {
                    NSLog(@"get payment result timeout, please try polling the payment result from the server");
                }
            }
            break;
        case AMSStatusResultTypeCANCELLED:
            // fall through
        case AMSStatusResultTypeSUCCESS:
            NSLog(@"payment cancelled or success, do nothing");
            break;
        case AMSStatusResultTypeFAIL:
            if (error && error.code) {
                if ([@"ORDER_IS_CANCELLED" isEqualToString:error.code]) {
                    NSLog(@"the merchant has proactively canceled the order, please check on your own.");
                } else if ([@"ORDER_IS_CLOSED" isEqualToString:error.code]) {
                    NSLog(@"the order has timed out and is closed, please re-initiate payment using a new paymentRequestId.");
                } else {
                    NSLog(@"unknown error, please contact support");
                }
            }
            break;
        default:
            break;
    }
}
```

   2. Use the   `createComponent`   function from the instance object to invoke Payment Element:

   | **Method** | **Required** | **Description** |
| --- | --- | --- |
| `createComponent:completion:` | No | A callback function for monitoring payment events on the checkout page. The callback parameters include the error     *code*    . Refer to the   [callback function event codes](https://docs.antom.com/ac/sdks/ref.md#efco9k)   for handling. |

   ```objectivec
// Callback event code method - createComponent usage
[[AMSPaymentElement shared] createComponent:paymentSessionData completion:^(AMSStatusResult * _Nonnull result) {
    if (result.error) {
        // Handle failure
        if ([result.error.code isEqualToString:@"UI_STATE_ERROR"]) {
            NSLog(@"integration code error, please check the integration code");
        } else if ([result.error.code isEqualToString:@"PARAM_INVALID"]) {
            NSLog(@"session data invalid, please check the session data");
        } else if ([result.error.code isEqualToString:@"INITIALIZE_WEB_TIMEOUT"]) {
            NSLog(@"web app timeout, please invoke component again");
        } else {
            NSLog(@"unknown error, please contact support");
        }
    } else {
        // Handle success
    }
}];

```

### Unmount Payment Element {#f31st}

 Call the   `onDestroy`   method to release SDK component resources in the following scenarios:

 - When the buyer navigates away from the checkout page, release the component resources created by the    ​  [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)   API   .
- When the buyer initiates multiple payments and the parameters in `initConfiguration` had changed, release the component resources previously created by the   [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)   API.

   ```objectivec
// Release SDK component resources
[[AMSPaymentElement shared] onDestroy];
```

   You do not need to call   `onDestroy`   in the following scenarios, the SDK automatically releases resources:

 - When the buyer initiates multiple payments and the parameters in   `AMSPaymentElementConfiguration`   remain unchanged. The SDK will automatically reclaim some resources after payment concludes to reset to the state before   `createComponent`  .

### Redirect to the merchant page {#zyDEQ}

 The following scenarios describe how redirecting to the merchant page and returning payment results are handled. Please follow the guidelines below:

 | **"notRedirectAfterComplete"** | **Payment result** | **Recommended action** |
| --- | --- | --- |
| `true` | Success/Failure | If you set     *notRedirectAfterComplete*     to   `true`   when creating the Payment Element instance and the payment method supports completing payments within the SDK, the payment result will be returned via the   `onSubmitPayCallback:`   method. You need to handle the redirect logic yourself based on the   [event code](https://docs.antom.com/ac/sdks/ref.md#UOmXC)   returned by   `onSubmitPayCallback:`  . |
| `false` | Success | After payment is completed, Payment Element will automatically redirect to the     *paymentRedirectUrl*     result page you provided in the      [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)   API. |
| `false` | Failure | The payment result will be returned via the   `onSubmitPayCallback:`   method. You need to handle the redirect logic yourself based on the   [event code](https://docs.antom.com/ac/sdks/ref.md#UOmXC)   returned by   `onSubmitPayCallback:`  . |

 > **[INFO]** **Note**    :
>
>  - If the payment requires redirecting to an external page (the payment method does not support payment within the SDK), the payment result will not be returned via   `onSubmitPayCallback:`  . After completing the payment on the external payment page, the payment method will determine whether to automatically redirect back to the     *paymentRedirectUrl*     you provided.
> - The payment results returned by the   `onSubmitPayCallback:`   method are only for client-side page navigation and status display. For the final order status, please obtain it through   [Step 4: Obtain the payment result](#2MxqX3)  .

## Step 4: Obtain the payment result   **[Server-side]** {#2MxqX3}

 After the buyer completes the payment or the payment times out, Antom will send the corresponding payment results to you through server interaction. You can obtain the payment results using one of the following methods:

 - Receive asynchronous notifications from Antom
- Inquire about the payment result

<!-- TabGroup -->

**Tab: Receive asynchronous notifications**

**1\. Configure the webhook URL to receive asynchronous notifications**

 When a payment succeeds or fails, Antom will send an asynchronous notification to the webhook URL you set. You can choose one of the following two methods to configure the webhook URL for receiving notifications (if both are set, the URL specified in the request takes precedence):

 - If each of your orders has a unique notification URL, it is recommended to set the webhook URL in each request. You can pass the asynchronous notification receiving URL for the specific order through     *paymentNotifyUrl*     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 URL**    . For detailed steps, refer to   [Notification URL](https://docs.antom.com/ac/merchant_service/notification.md)  .

 The following code shows a sample of the asynchronous notification request:

<!-- TabGroup -->

**Tab: Card payments, Apple Pay, Google Pay**

```json
{
  "actualPaymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "cardInfo": {
    "avsResultRaw": "A",
    "cardBrand": "MASTERCARD",
    "cardNo": "****************",
    "cardToken":"exxxxe",
    "cvvResultRaw": "Y",
    "funding": "DEBIT",
    "issuingCountry": "US",
    "networkTransactionId": "XXXXX",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "paymentMethodType": "CARD",
  "paymentCreateTime": "2024-01-01T00:00:00+08:00",
  "paymentId": "20240101123456789XXXX",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultInfo": {
    "avsResultRaw": "A",
    "cardBrand": "MASTERCARD",
    "cardNo": "****************",
    "cardToken":"exxxxe", // store cardToken for future card payments
    "cvvResultRaw": "Y",
    "funding": "DEBIT",
    "issuingCountry": "US",
    "networkTransactionId": "XXXXX",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "paymentTime": "2024-01-01T00:01:00+08:00",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
```

   The following table shows the possible values of     *result.resultStatus*     in the notification request of payment result. Please handle the result according to the guidance provided:

   | ***result.resultStatus*** | **Message** | **Further action** |
| --- | --- | --- |
| `S` | Authorization    was successful. | You may proceed to initiate a capture. |
| `F` | Authorization    failed. | Please use a new     *paymentRequestId*        and initiate the payment again. |

**Tab: APM payments**

```json
{
    "actualPaymentAmount": {
        "currency": "HKD",
        "value": "100"
    },
    "notifyType": "PAYMENT_RESULT",
    "paymentAmount": {
        "currency": "HKD",
        "value": "100"
    },
    "paymentCreateTime": "2025-02-04T22:11:19-08:00",
    "paymentId": "20240101123456789XXXX",
    "paymentMethodType": "ALIPAY_HK",
    "paymentRequestId": "paymentRequestId01",
    "paymentResultInfo": {

    },
    "paymentTime": "2025-02-04T22:14:25-08:00",
    "pspCustomerInfo": {
        "pspCustomerId": "216022003753XXXX",
        "pspName": "ALIPAY_HK"
    },
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}
```

   The following table shows the possible values of     *result.resultStatus*     in the notification request of payment result. Please handle the result according to the guidance provided:

 | ***result.resultStatus*** | **Message** | **Further action** |
| --- | --- | --- |
| `S` | Payment was successful. | **​**    You may proceed to ship the goods. |
| `F` | Payment failed. | Please use a new     *paymentRequestId*        and initiate the payment again. |

<!-- /TabGroup -->
 **2\. Verify the asynchronous notification**

 When 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
import javax.servlet.http.HttpServletRequest;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.alipay.global.api.model.Result;
import com.alipay.global.api.model.ResultStatusType;
import com.alipay.global.api.response.AlipayResponse;
import com.alipay.global.api.tools.WebhookTool;

@RestController
public class PaymentNotifyHandleBySDK {

    /**
     * alipay public key, used to verify signature
     */
    private static final String SERVER_PUBLIC_KEY = "";
  
    /**
     * payment result notify processor
     * using <a href="https://spring.io">Spring Framework</a>
     *
     * @param request    HttpServletRequest
     * @param notifyBody notify body
     * @return
     */
    @PostMapping("/payNotify")
    public Object payNotifyHandler(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");

        Result result;
        AlipayResponse response = new AlipayResponse();

        try {
            // verify the signature of notification
            boolean verifyResult = WebhookTool.checkSignature(requestUri, requestMethod, clientId, requestTime, signature, notifyBody, SERVER_PUBLIC_KEY);
            if (!verifyResult) {
                throw new RuntimeException("Invalid notify signature");
            }

            // deserialize the notification body
  
            // update the order status with notify result

            // respond the server that the notification is received
            result = new Result("SUCCESS", "success", ResultStatusType.S);

        } catch (Exception e) {
            String errorMsg = e.getMessage();
            // handle error condition
            result = new Result("ERROR", errorMsg, ResultStatusType.F);
        }
        response.setResult(result);
        return ResponseEntity.ok().body(response);
    }

}
```

   Whether the payment is successful or not, each notification request must be responded to in the format specified below. Otherwise, Antom will resend the asynchronous notification.

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

   > **[INFO]** **Common questions**
>
>  **Q: When will the notification be sent?**
>
>  A: It depends on whether the payment is completed:
>
>  - If the payment is successfully completed, Antom will 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 payment is not completed, Antom needs to close the order first before sending an asynchronous notification. The time it takes for different payment methods to close the order varies, usually defaulting to 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 did not respond 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: When responding to an asynchronous notification, do I need to add a digital signature?**
>
>  A: 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.
>
>  ​
>
>  **Q: What key parameters do I need to use in the notification?**  
>    A: Please note the following key parameters:
>
>  - *result*    : For APM payments, it represents the final payment result. For  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)  ,   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md) , and card payments, it only represents the authorization result, and further capture is required.
> - *paymentRequestId*    : The payment request ID used for inquiries, cancellations, and reconciliation.
> - *paymentId*    : The payment order ID generated by Antom, used for refunds and reconciliation.
> - *paymentAmount*    : The payment amount.

**Tab: Inquire about the result**

You can also inquire about the payment result by calling the   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   API using     *paymentRequestId*     from the payment request,    regardless of whether it is an APM payment, card payment,  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)  , or   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md) .

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

 ```java
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 sample code shows a request message:

   ```json
{
  "paymentRequestId": "paymentRequestId01"
}
```

   The following sample code shows a response message:

<!-- TabGroup -->

**Tab: APM payments**

```json
{
  "actualPaymentAmount": {
    "currency": "THB",
    "value": "299"
  },
  "paymentAmount": {
    "currency": "THB",
    "value": "299"
  },
  "paymentId": "20240101123456789XXXX",
  "paymentMethodType": "TRUEMONEY",
  "paymentRedirectUrl": "https://kademo.intlalipay.cn/melitigo/Test_114.html",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultCode": "SUCCESS",
  "paymentResultMessage": "success.",
  "paymentStatus": "SUCCESS",
  "paymentMethodType": "TRUEMONEY",
  "paymentTime": "2025-02-17T08:06:43-08:00",
  "pspCustomerInfo": {
    "pspName": "TRUEMONEY"
  },
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
```

**Tab: Card payments, Apple Pay, Google Pay**

```json
{
    "actualPaymentAmount": {
        "currency": "USD",
        "value": "5000"
    },
    "authExpiryTime": "2024-12-17T21:56:56-08:00",
    "cardInfo": {
        "cardBrand": "VISA",
        "funding": "CREDIT",
        "issuingCountry": "US"
    },
    "paymentAmount": {
        "currency": "USD",
        "value": "5000"
    },
    "paymentId": "20240101123456789XXXX",
    "paymentMethodType": "CARD",
    "paymentRedirectUrl": "http://gol.alipay.net:8080/amsdemo/result?paymentRequestId=amsdmpay_yanfei_wzh_20240111_191505_666",
    "paymentRequestId": "paymentRequestId01",
    "paymentResultCode": "SUCCESS",
    "paymentResultInfo": {
        "avsResultRaw": "M",
        "cardBrand": "VISA",
        "cardNo": "************9954",
        "cvvResultRaw": "U",
        "funding": "CREDIT",
        "issuingCountry": "US",
        "networkTransactionId": "123qwe456rew",
        "paymentMethodRegion": "GLOBAL",
        "threeDSResult": {
            "cavv": "",
            "eci": ""
        }
    },
    "paymentResultMessage": "success.",
    "paymentStatus": "SUCCESS",
    "paymentTime": "2024-12-10T21:56:57-08:00",
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}
```

<!-- /TabGroup -->
   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)  .

 > **[INFO]** **Common questions**
>
>  **Q: What key parameters should I pay attention to when using the**       [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)       **API to check the payment or authorization status?**
>
>  A: Please note the following key parameters:
>
>  - *result*    :    Only indicates the result of the API call. For APM payments, the final payment result should be determined based on     *paymentStatus*     (  `SUCCESS`  /  `FAIL`  /  `PROCESSING`  ). For card payments,  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)  , and   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md) ,     *paymentStatus*     only represents the authorization result, and the decision to ship goods should rely on the capture result.
> - *paymentAmount*    : Used to verify the payment amount.
> - *paymentId*    : The payment order ID generated by Antom, used for refunds and reconciliation.
>
>  ​
>
>  **Q: How often should I call the inquiryPayment API?**
>
>  A: Call the   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   API constantly with an interval of 2 seconds until the final payment result is obtained or an asynchronous payment result notification is received.

<!-- /TabGroup -->

## Step 5: Capture   **[Server-side]** **[For card payments or Apple Pay only]** {#2qu0V5}

 Antom provides both automatic and manual capture methods. You can choose based on your business needs. After initiating capture, you can obtain the result via asynchronous notification or active inquiry. For specific operations, refer to   [Capture](https://docs.antom.com/ac/cashierpay/capture.md)  .

**Tab: Android**

# User experience {#3BEWwv}

 The following figures demonstrate the user experience of using Payment Element in different scenarios:

<!-- TabGroup -->

**Tab: Payment Element-rendered payment method list**

The following figure shows templates for invoking the Payment Element-rendered payment method list in a pop-up:

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/83d1a1b7-e30b-40cc-8b72-bb350ba3c395.png) If you use the Payment Element-rendered payment method list, all supported payment methods will be displayed on the checkout page by default. The following figures illustrate the user experience for different payment methods:

<!-- TabGroup -->

**Tab: Scan to pay**

Payment Element displays a QR code for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/4e0fd2d7-196e-4f0c-a424-35fd36883389.png)

**Tab: Redirect to payment page**

Payment Element redirects to the payment method page for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/fa7d21a7-3bc9-4bb1-a334-5910f5c4cfad.png)

**Tab: New card payment**

Payment Element displays the card detail collection page for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/054517ec-1b96-4e8b-a43d-0f8ebec53401.png)

**Tab: Stored card payments**

Payment Element handles the stored card payment scenario.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/48da6b02-d667-43af-9f45-ba17a6141a42.png)

<!-- /TabGroup -->

**Tab: Merchant-rendered payment method list**

The following figure shows templates of merchant-rendered payment method list:

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/fe5b70f9-c2c0-41b6-8b76-c22ea5f5efbf.png) If you render the payment methods by specifying them yourself, the following figures demonstrate the user experience for different payment methods:

<!-- TabGroup -->

**Tab: Scan to pay**

Payment Element displays a QR code for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/5c280a88-d3fb-48d2-8fb7-0e9833d7d99d.png)

**Tab: Redirect to payment page**

Payment Element redirects to the payment method page for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/34b1d2d5-2952-4c18-8941-67167652babf.png)

**Tab: New card payment**

Payment Element displays the card detail collection page for buyers to complete the payment.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/7846ecfc-3a15-4175-a3d6-a4ccb31dfbf8.png)

<!-- /TabGroup -->

<!-- /TabGroup -->

# Order lifecycle {#3iYCQo}

 Learn about the lifecycle of different payment methods:

<!-- TabGroup -->

**Tab: APM Payments**

For APM payments, such as  [Alipay](https://docs.antom.com/ac/antomop/alipay_cn.md)  and  [Touch'n Go eWallet](https://docs.antom.com/ac/antomop/touchngo.md) , funds are transferred directly to your account once the payment is initiated and completed by the buyer. You can  [cancel](#Otb6j)  or  [refund](#kg4oU)  the order within the allowable period.

   ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/6da32eae-f8c2-495f-a6ce-c8a4f7b27c2e.png)

**Tab: Card payments, Apple Pay, Google Pay**

For card payments,  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)  , and   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md) , the order lifecycle includes the following stages:

 1. Authorization: After the buyer completes the payment using a card, the funds are temporarily frozen. You can   [cancel](#Otb6j)   the order during the allowable period from when the order is placed until authorization is completed.
2. Capture   : You can manually capture the frozen funds to transfer them to your account, or let Antom automatically handle capture for you. For details, refer to   [Capture](https://docs.antom.com/ac/cashierpay/capture.md)  . After capture, you can initiate a   [refund](#kg4oU)   within the allowable period if needed.
3. Chargeback: You may submit a chargeback defense based on the specific situation. For more information, refer to   [Dispute](#AoEw6)  .

   ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/abc1f3bf-4223-4ed2-adc3-35862da1bfeb.png)

<!-- /TabGroup -->

# Payment flow {#3nigJF}

 The following flow illustrates how to integrate One-time Payments using Payment Element:

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/47f3836c-03c0-452f-b3e2-c4217016ba8d.png) 1. **The buyer lands on the checkout page and submits payment.**
2. **Create a payment session request.**  
   You can obtain the payment session by calling the   [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)        API.
3. **Invoke Payment Element.**  
   On the client side, invoke Payment Element using the payment session. You can choose to use the Payment Element-rendered payment method list, or render the payment methods by specifying them yourself. Payment Element will handle information processing, collect payment details, perform redirects, manage app invocations, display QR codes, and conduct validations based on the features of the selected payment method. After the payment is completed, depending on your configuration and the payment method features, you need to handle redirections based on the result returned by the   `onSubmitPayCallback`   method, or the system will automatically return to your result page.
4. **Confirm the payment result.**  
   Obtain the payment result by using one of the following two 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. When the payment is successful or expires, Antom will use   [**notifyPayment**](https://docs.antom.com/ac/ams/paymentrn_online.md)   to send asynchronous notifications to you.
  - Synchronous inquiry: Call the   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   API to check the payment status.

 > **[INFO]** **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 mode 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. **Initiate capture and obtain the 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 capture status.

# Integration preparations {#h33KAW}

 Before you start integrating, read   [Integration guide](https://docs.antom.com/integration_guide_en.md)   and   [API overview](https://docs.antom.com/ac/ams/api_fund.md)   to understand the integration steps of the server-side API and the precautions for calling the API. Furthermore, ensure the following prerequisites are met:

 - Obtained your 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)  .
- Integrate the client-side SDK package by following the steps detailed in   [Integrate the SDK package for Android](https://docs.antom.com/ac/sdks/android.md)  , and ensure to use the latest SDK version or no lower than 1.46.0.

# Integration steps {#33t0Y}

 Start your integration by taking the following steps:

 1. (Optional) Preload the SDK
2. Create a payment session
3. Invoke Payment Element
4. Obtain    the payment result
5. Capture

## (Optional) Step 1: Preload the SDK   **[Client-side]** {#chKYz}

 Before creating a payment session, it is highly recommended that you preload the SDK to improve the rendering speed of the checkout page, reducing the waiting time for buyers during the payment. Follow the code example below to perform the preloading:

 ```java
 AMSPaymentElement.preload(getApplicationContext());
```

## Step 2: Create a payment session   **[Server-side]** {#K3Wal}

 Call the      [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)      API with order information to create a payment session and obtain the     *paymentSessionData*     required to invoke Payment Element. You can choose to either render the payment methods by specifying them yourself or use the Payment Element-rendered payment method list. It is recommended that you create a payment session after the buyer clicks the payment button. Depending on the method you selected for rendering the payment method list at the checkout page, pass the corresponding parameters when calling the   [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)      API.

 - Render the payment methods by yourself:    When rendering the payment method list yourself, you must pass the parameters for specifying payment methods listed in the table below. If Payment Element needs to collect payment details, pass the card payment parameters listed in the table below.

 - When using the Payment    Element-rendered    payment method list, you only need to pass the basic parameters listed in the table below. Payment Element renders all supported payment methods on the checkout page by default, but you can [specify payment methods](#L9xOX) to display only the options you need.

   | **Type** | **Parameter name** | **Required** | **Description** |
| --- | --- | --- | --- |
| Basic parameters | *productCode* | Yes | For Payment Element, the value is fixed as      `CASHIER_PAYMENT`  . |
| *productScene* | Yes | For Payment Element, the value is fixed as      `ELEMENT_PAYMENT`  . |  |
| *paymentRequestId* | Yes | The unique ID assigned by the merchant to identify a payment request. |  |
| *paymentAmount* | Yes | The payment amount that the merchant requests to receive in the order currency. |  |
| *paymentRedirectUrl* | Yes | The merchant page URL that the buyer is redirected to after the payment is completed. |  |
| *paymentNotifyUrl* | No | The payment result notification URL, which can be passed in through the API or set as a fixed value through Antom Dashboard. If both are set, the value in the API takes precedence. |  |
| *settlementStrategy* | Yes | The settlement strategy for the payment request. |  |
| *order.referenceOrderId* | Yes | The unique ID to identify the order on the merchant side. |  |
| *order.orderDescription* | Yes | Summary description of the order. |  |
| *env.terminalType* | No | Terminal type of which the merchant service applies to. Valid values are: - `WEB`  : The client-side terminal type is a website, which is opened via a PC browser. - `WAP`  : The client-side terminal type is an H5 page, which is opened via a mobile browser. - `APP`  : The client-side terminal type is a mobile application.   > **[INFO]** **Note**    : This parameter is required for  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)   and   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md) . |  |
| *env.osType* | No | The operating system type from which the buyer initiated the transaction. Valid values: - `IOS`  : Apple's iOS. - `ANDROID`  : Google's Android.   > **[INFO]** **Note**    : Specify this parameter when     *env.terminalType*     is   `WAP`   or   `APP`  . |  |
| *env.clientIp* | No | The IP address of the client device. > **[INFO]** **Note**    : This parameter is required for card payments,  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)   and   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md)  scenarios. |  |
| Card payment parameters (Refer to   [Card payment features](#abqU1)  ) | *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.buyer* | Yes | Buyer information. At least one of the following must be provided: - *order.buyer.referenceBuyerId* - *order.buyer.buyerPhoneNo* - *order.buyer.buyerEmail* |  |
| *availablePaymentMethod.paymentMethodMetaData.is3DSAuthentication* | No | Determine whether to set the transaction authentication type to 3DS based on risk and dispute history. Valid values are: - `true`  : indicates that the transaction authentication type is 3DS authentication. - `false`  : indicates that the transaction authentication type is Non-3DS authentication. Default if empty or not provided. |  |
| *availablePaymentMethod.paymentMethodMetaData.tokenizeMode* | No | The tokenize mode. Indicates whether card information needs to be stored. When you opt to   [store card details](https://docs.antom.com/ac/cashierpay/tokenization.md)  , the actual information is replaced with a unique and secure token that can be used for future payments. Valid values are: - `ENABLED`  : indicates that you obtain card binding authorization and want to store card information for future payments. - `DISABLED`  : indicates that you don’t need to store card information. The same applies when the value is empty or you do not specify this parameter. - `ASKFORCONSENT`  : indicates that you present a button on the page, allowing the buyer to choose whether or not they want to store the card information. |  |
| *availablePaymentMethod.paymentMethodMetaData.isCardOnFile* | No | Indicates whether the card used in this transaction has been   [previously processed and stored](https://docs.antom.com/ac/cashierpay/cof.md)   by the merchant. Valid values are: - `true`  : The card used in the transaction has been previously processed and stored by the merchant. Set to   `true`   for stored card payments. - `false`  : Default. The card is new and has not been used previously on the merchant side. |  |
| *savedPaymentMethods.paymentMethodId* | No | Used for stored card payments.    The value of this parameter is that of     *cardToken*     obtained from the new card payment. |  |
| Parameters for specifying payment methods (Refer to   [Specify payment methods](#L9xOX)  ) | *availablePaymentMethod.paymentMethodTypeList.paymentMethodType* | No | Used to specify payment methods. You can specify one or multiple payment methods. Refer to   [Enumeration values of payment methods](https://docs.antom.com/ac/pm/enumeration_values.md)   for valid values. |
| *availablePaymentMethod.paymentMethodTypeList.paymentMethodOrder* | No | Set the priority order of payment methods. |  |
| *availablePaymentMethod.paymentMethodTypeList.expressCheckout* | No | Specifies whether to enable the express checkout option for a payment method. Currently, only   `ALIPAY_CN`  ,   `APPLEPAY`   and   `GOOGLEPAY`  can be set as express checkout methods. Valid values are: - `true`  : Enables express checkout for this payment method. - `false`  : Disables express checkout for this payment method.   > **[INFO]** **Note**    : This parameter is currently supported only on Android and iOS. |  |

 The above parameters are the basic parameters for creating a payment session, for full parameters and additional requirements for certain payment methods 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
  @PostMapping("/payment/createSession")
    public ResponseEntity<ApiResponse> createPaymentSession(@RequestBody PaymentVO payment) {
        AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
        alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
        alipayPaymentSessionRequest.setProductScene(ProductSceneConstants.ELEMENT_PAYMENT);

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

        // 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>
        long amountMinorLong = Money.of(CurrencyUnit.of(payment.currency), new BigDecimal(payment.amountValue)).getAmountMinorLong();

        // set amount
        Amount amount = Amount.builder().currency(payment.currency).value(String.valueOf(amountMinorLong)).build();
        alipayPaymentSessionRequest.setPaymentAmount(amount);

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

        // set buyer info
        Buyer buyer = Buyer.builder().referenceBuyerId("yourBuyerId").build();

        // replace with your orderId
        String orderId = UUID.randomUUID().toString();
        // set order Info
        Order order = Order.builder().referenceOrderId(orderId).
                orderDescription("antom sdk testing order").orderAmount(amount).buyer(buyer).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/receivePaymentNotify");

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

        AlipayPaymentSessionResponse alipayPaymentSessionResponse;
        try {
            long startTime = System.currentTimeMillis();
            System.out.println("payment request: " + JSON.toJSONString(alipayPaymentSessionRequest));
            alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
            System.out.println("payment response: " + JSON.toJSONString(alipayPaymentSessionResponse));
            System.out.println("payment request cost time: " + (System.currentTimeMillis() - startTime) + "ms\n");
        } catch (AlipayApiException e) {
            return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), e));
        }
        return ResponseEntity.ok().body(new ApiResponse(paymentRequestId, payment.getUserId(), alipayPaymentSessionResponse));
    }
```

<!-- TabGroup -->

**Tab: Merchant-rendered payment method list**

If you render the payment method list yourself, you must integrate by specifying individual payment methods. The following code shows a sample of the request message:

   ```json
{
   "env": {
        "terminalType": "APP",
        "clientIp": "***.***.***.***", // The buyer's IP adress
        "osType": "ANDROID"
 },
  "order": {
    "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
    "orderAmount": {
      "currency": "HKD",
      "value": "300"
    },
    "orderDescription": "AMSDM_GIFT",
    "referenceOrderId": "PAYMENT_2025*********138_AUTO"
  },
  "paymentAmount": {
    "currency": "HKD",
    "value": "300"
  },
  "settlementStrategy": {
    "settlementCurrency": "USD"
  },
  "availablePaymentMethod": {
    "paymentMethodTypeList": [
      {
        "paymentMethodType": "ALIPAY_CN" // Specify payment method
      }
    ]
  },
  "paymentNotifyUrl": "https://www.*********.com",
  "paymentRedirectUrl": "https://www.*********u.com",
  "paymentRequestId": "PAYMENT_2025*********201_AUTO",
  "productCode": "CASHIER_PAYMENT",
  "productScene": "ELEMENT_PAYMENT"
}
```

**Tab: Payment Element-rendered payment method list**

If you use Payment Element-rendered payment method list, Payment Element will display all supported payment methods by default. The following code shows a sample of the request message:

   ```json
{
   "env": {
        "terminalType": "APP",
        "clientIp": "***.***.***.***", // The buyer's IP adress
        "osType": "ANDROID"
 },
    "order": {
      "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
        "orderAmount": {
            "currency": "HKD",
            "value": "300"
        },
        "orderDescription": "AMSDM_GIFT",
        "referenceOrderId": "PAYMENT_2025*********138_AUTO"
    },
    "paymentAmount": {
        "currency": "HKD",
        "value": "300"
    },
    "settlementStrategy": {
        "settlementCurrency": "USD"
    },
    "paymentNotifyUrl": "https://www.*********.com",
    "paymentRedirectUrl": "https://www.*********.com",
    "paymentRequestId": "PAYMENT_2025*********201_AUTO",
    "productCode": "CASHIER_PAYMENT",
    "productScene": "ELEMENT_PAYMENT"
}
```

<!-- /TabGroup -->
   The following code shows a sample of the response, which contains the following parameters:

 - *result.resultStatus*    :    The result of the   [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)   API call.
- *paymentSessionData*    : The payment session data to be returned to the client.
- *paymentSessionExpiryTime*    : The expiration time of the payment session.

   ```json
 {
  "paymentSessionData": "gpZy************fQ==",
  "paymentSessionExpiryTime": "2023-04-06T03:28:49+08:00",
  "paymentSessionId": "paymentSessionId****",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
```

 The table below shows the possible values of     *result.resultStatus*     in the response. Please handle the result according to the guidance provided:

   | ***result.resultStatus*** | **Message** | **Further action** |
| --- | --- | --- |
| `S` | The payment session was successfully created, and     *paymentSessionData*     is returned. | Proceed to the next steps. |
| `U` | Unknown error. | Please use a new          *paymentRequestId*     and call the API again. If the issue persists, contact Antom Technical Support. |
| `F` | Failed to create the payment session. | Please check and verify whether the current API required request fields (including header fields and body fields) are correctly passed and valid. |

 > **[INFO]** **Note**    : If no response is received, it may indicate a network timeout. Please use a new     *paymentRequestId*     and call the API again. If the issue persists, contact Antom Technical Support.

 > **[INFO]** **Common questions**
>
>  **Q: Can I use Chinese characters in the value of the request parameters?**
>
>  A: To avoid incompatibility of certain payment methods, do not use Chinese characters for fields in the request.
>
>  ​
>
>  **Q: How to set the address to receive payment notification?**
>
>  A: Specify     *paymentNotifyUrl*     in the      [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)      API to receive the asynchronous notification about the payment result (  [**notifyPayment**](https://docs.antom.com/docs/ac/ams/paymentrn_online.md)  ), or configure the receiving URL in Antom Dashboard. If the URL is specified in both the request and Antom Dashboard, the value specified in the request takes precedence.
>
>  ​
>
>  **Q: Does the returned**       ***paymentSessionData***       **require processing before passing it to the client?**
>
>  A: Do not process or modify     *paymentSessionData*     in any way, as this may cause the Payment Element invocation to fail.

## Step 3: Invoke Payment Element   **[Client-side]** {#FW22fpW}

 Use     *paymentSessionData*     to invoke Payment Element on your client. After the buyer clicks to submit payment, Payment Element will handle the entire flow based on the selected payment method, including displaying QR codes, redirecting to payment pages, performing 3DS authentication, and returning to the merchant’s result page.

 1. After obtaining     *paymentSessionData*     from the server, use the   `AMSPaymentElement`   class to create SDK instance.

   1. Creating the   `AMSPaymentElementConfiguration`  object includes the following parameters:

 | **Parameter name** | **Required** | **Type** | **Description** |
| --- | --- | --- | --- |
| *locale* | No | String | Used to pass in language information. Pass the corresponding value based on the region of the payment method. Valid values are listed as follows. If other values are passed, English is used by default: - `en_US`  : Default value. English - `pt_BR`  : Portuguese (Brazil) - `pt_PT`  : Portuguese - `es_ES`  : Spanish - `ko_KR`  : Korean - `zh_CN`  : Simplified Chinese - `zh_HK`  : Traditional Chinese - `ms_MY`  : Malay - `in_ID`  : Indonesian - `th_TH`  : Thai - `vi_VN`  : Vietnamese - `tl_PH`  : Filipino - `it_IT`  : Italian - `de_DE`  : German - `fr_FR`  : French - `nl_NL`  : Dutch - `ja_JP`  : Japanese - `ro`  : Romanian - `pl_PL`  : Polish - `ar_SA`  : Arabic - `tr_TR`  : Turkish - `hi_IN`  : Hindi |
| *options* | No | Key-value | Used to specify whether to use the default loading mode and sandbox environment. Valid values are: - `"sandbox", "true"`  ：Sandbox environment. - `"sandbox", "false"`  ：Default value. Production environment. - `"showLoading", "true"`  ：Default value. The default loading mode is used. - `"showLoading", "false"`  ：The default loading mode is not used.. - `"notRedirectAfterComplete"`  ：Optional. Boolean type. Used to set whether to redirect back to your page after payment completion. Valid values are:     - `false`  ：Default value. Redirects to your page after successful payment completion. The same applies if the value is empty.   - `true`  ：No redirection after payment completion. You need to manually control the subsequent payment flow based on client-side event codes.   > **[INFO]** **Note**    : The payment result event codes returned on the client-side are for reference only in page navigation. Transaction status updates must be based on the results returned by the server-side        [**notifyPayment**](https://docs.antom.com/ac/ams/paymentrn_online.md)        or   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)        API.   - `"appearance"`  : Optional. Used for custom appearance configuration. For more information, refer to  [Appearance customization](https://docs.antom.com/ac/cashierpay/appearance.md)  . It contains the following parameters:     - *theme*    : Theme color.   - *layout*    : Arrangement method.   - *variables*    : Override underlying CSS custom properties using CSS design tokens (e.g.,   `color-primary`  ) to implement theme customization. |

   2. Implement   `OnCreateComponentListener`  to handle events in the process of invoking the payment component and launching the payment page. It includes the following methods:

 | **Method** | **Required** | **Description** |
| --- | --- | --- |
| `onCreateComponentCallback` | No | A callback function for monitoring exceptions during payment component initialization. The callback parameters include the error     *code*     and     *message*    . Refer to the   [callback function event codes](https://docs.antom.com/ac/sdks/ref.md#efco9k)   for handling. |

   3. Implement   `OnSubmitPayListener`  to handle events related to the payment initiation process. It includes the following methods:

 | **Method** | **Required** | **Description** |
| --- | --- | --- |
| `onSubmitPayCallback` | No | A callback function for monitoring events during the payment process. The callback parameters include the error     *code*     and     *status*    . Refer to the   [callback function event codes](https://docs.antom.com/ac/sdks/ref.md#UOmXC)   for handling. |

 The following shows a sample code for creating the SDK instance using   `AMSPaymentElement`   :

   ```java
AMSPaymentElementConfiguration configuration = new AMSPaymentElementConfiguration();
configuration.setLocale(new Locale("en", "US"));
configuration.setOption("showLoading", "true");
configuration.setOption("sandbox", "true");
configuration.setOption("notRedirectAfterComplete", "false");
String appearance = "{\"theme\":\"night\",\"layout\":{\"type\":\"accordion\"},\"variables\":{\"content-primary\":\"#ff5b4d\"}}";
configuration.setOption("appearance", appearance);

configuration.setOnCreateComponentListener(new OnCreateComponentListener() {
    @Override
    public void onCreateComponentCallback(AMSStatusResult statusResult) {
        if (statusResult.getError() != null) {
            switch (statusResult.getError().getCode()) {
                case "UI_STATE_ERROR":
                    System.out.println("integration code error, please check the integration code");
                    break;
                case "PARAM_INVALID":
                    System.out.println("session data invalid, please check the session data");
                    break;
                case "INITIALIZE_WEB_TIMEOUT":
                    System.out.println("web app timeout, please invoke component again");
                    break;
                default:
                    System.out.println("unknown error, please contact support");
                break;
            }
        }
    }
});

configuration.setOnSubmitPayListener(new OnSubmitPayListener() {
    @Override
    public void onSubmitPayCallback(AMSStatusResult statusResult) {
        AMSStatus status = statusResult.getStatus();
        AMSResultError error = statusResult.getError();
        if (status ==  AMSStatus.PROCESSING) {
           if (error != null && error.getCode() != null) {
               if ("PAYMENT_IN_PROCESS".equals(error.getCode())) {
                   System.out.println("payment is in processing, please try polling the payment result from the server");
               } else if ("USER_CANCELED".equals(error.getCode())){
                   System.out.println("user cancelled the payment process, please try invoke createComponent again");
               } else if ("UNKNOWN_EXCEPTION".equals(error.getCode())) {
                   System.out.println("unknown exception, please contact support");
               } else if ("PAYMENT_RESULT_TIMEOUT".equals(error.getCode())){
                   System.out.println("get payment result timeout, please try polling the payment result from the server");
               }
           }
        } else if (status == AMSStatus.CANCELLED || status == AMSStatus.SUCCESS) {
            System.out.println("payment cancelled or success, do nothing");
        } else if (status == AMSStatus.FAIL) {
            if (error != null && error.getCode() != null) {
                if ("ORDER_IS_CANCELLED".equals(error.getCode())) {
                    System.out.println("the merchant has proactively canceled the order, please check on your own.");
                } else if ("ORDER_IS_CLOSED".equals(error.getCode()) || "INQUIRY_PAYMENT_SESSION_FAILED".equals(error.getCode())){
                    System.out.println("the order has timed out and is closed, please re-initiate payment using a new paymentRequestId.");
                } else {
                    System.out.println("unknown error, please contact support");
                }
            }
        }
    }
});

AMSPaymentElement amsPaymentElement = new AMSPaymentElement.Builder(this, (AMSPaymentElementConfiguration) configuration).build();

```

   2. Use the   `createComponent`      function from the instance object to invoke Payment Element:

   ```java
// paymentSessionData obtained when creating a payment session
String paymentSessionData = "exxxxe";

amsPaymentElement.createComponent(this, paymentSessionData);
```

### Unmount Payment Element {#1xGNou}

 Call the   `onDestory`   method to release SDK component resources in the following scenarios:

 - When the buyer navigates away from the checkout page, release the component resources created by the   [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)   API.
- When the buyer initiates multiple payments and the parameters in   `AMSPaymentElementConfiguration`      had changed, release the component resources previously created by the   [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)   API.

   ```java
// release SDK component resources
amsPaymentElement.onDestroy();
```

   You do not need to call   `onDestroy`  in the following scenarios, the SDK automatically releases resources (requires Android SDK version 1.33.0 or higher):

 - When the buyer initiates multiple payments and the parameters in   `AMSPaymentElementConfiguration`   remain unchanged, the SDK will automatically reclaim some resources after payment concludes to reset to the state before   `createComponent`  .

### Redirect to the merchant page {#rfgDEQ}

 The following scenarios describe how redirecting to the merchant page and returning payment results are handled. Please follow the guidelines below:

 | **"notRedirectAfterComplete"** | **Payment result** | **Recommended action** |
| --- | --- | --- |
| `true` | Success/Failure | If you set     *notRedirectAfterComplete*     to   `true`      when creating the Payment Element instance and the payment method supports completing payments within the SDK, the payment result will be returned via the   `onSubmitPayCallback`  method. You need to handle the redirect logic yourself based on the   [event code](https://docs.antom.com/ac/sdks/ref.md#UOmXC)   returned by   `onSubmitPayCallback`  . |
| `false` | Success | After payment is completed, Payment Element will automatically redirect to the paymentRedirectUrl result page you provided in the        [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md)   API     *paymentRedirectUrl*     . |
| `false` | Failure | The payment result will be returned via the   `onSubmitPayCallback`  method. You need to handle the redirect logic yourself based on the   [event code](https://docs.antom.com/ac/sdks/ref.md#UOmXC)   returned by   `onSubmitPayCallback`  . |

 > **[INFO]** **Note**    :
>
>  - If the payment requires redirecting to an external page (the payment method does not support payment within the SDK), the payment result will not be returned via   `onSubmitPayCallback`  . After completing the payment on the external payment page, the payment method will determine whether to automatically redirect back to the     *paymentRedirectUrl*    you provided.
> - The payment results returned by the   `onSubmitPayCallback`      method are only for client-side page navigation and status display. For the final order status, please obtain it through   [Step 4: Obtain the payment result](#3xqX3)  .

## Step 4: Obtain the payment result   **[Server-side]** {#3xqX3}

 After the buyer completes the payment or the payment times out, Antom will send the corresponding payment results to you through server interaction. You can obtain the payment results using one of the following methods:

 - Receive asynchronous notifications from Antom
- Inquire about the payment result

<!-- TabGroup -->

**Tab: Receive asynchronous notifications**

**1\. Configure the webhook URL to receive asynchronous notifications**

 When a payment succeeds or fails, Antom will send an asynchronous notification to the webhook URL you set. You can choose one of the following two methods to configure the webhook URL for receiving notifications (if both are set, the URL specified in the request takes precedence):

 - If each of your orders has a unique notification URL, it is recommended to set the webhook URL in each request. You can pass the asynchronous notification receiving URL for the specific order through     *paymentNotifyUrl*     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 URL**    . For detailed steps, refer to   [Notification URL](https://docs.antom.com/ac/merchant_service/notification.md)  .

 The following code shows a sample of the asynchronous notification request:

<!-- TabGroup -->

**Tab: Card payments, Apple Pay, Google Pay**

```json
{
  "actualPaymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "cardInfo": {
    "avsResultRaw": "A",
    "cardBrand": "MASTERCARD",
    "cardNo": "****************",
    "cardToken":"exxxxe",
    "cvvResultRaw": "Y",
    "funding": "DEBIT",
    "issuingCountry": "US",
    "networkTransactionId": "XXXXX",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "paymentMethodType": "CARD",
  "paymentCreateTime": "2024-01-01T00:00:00+08:00",
  "paymentId": "20240101123456789XXXX",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultInfo": {
    "avsResultRaw": "A",
    "cardBrand": "MASTERCARD",
    "cardNo": "****************",
    "cardToken":"exxxxe", // store cardToken for future card payments
    "cvvResultRaw": "Y",
    "funding": "DEBIT",
    "issuingCountry": "US",
    "networkTransactionId": "XXXXX",
    "paymentMethodRegion": "GLOBAL",
    "threeDSResult": {
      "cavv": "",
      "eci": ""
    }
  },
  "paymentTime": "2024-01-01T00:01:00+08:00",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
```

   The following table shows the possible values of     *result.resultStatus*     in the notification request of payment result. Please handle the result according to the guidance provided:

   | ***result.resultStatus*** | **Message** | **Further action** |
| --- | --- | --- |
| `S` | Authorization    was successful. | You may proceed to initiate a capture. |
| `F` | Authorization    failed. | Please use a new     *paymentRequestId*        and initiate the payment again. |

**Tab: APM payments**

```json
{
    "actualPaymentAmount": {
        "currency": "HKD",
        "value": "100"
    },
    "notifyType": "PAYMENT_RESULT",
    "paymentAmount": {
        "currency": "HKD",
        "value": "100"
    },
    "paymentCreateTime": "2025-02-04T22:11:19-08:00",
    "paymentId": "20240101123456789XXXX",
    "paymentMethodType": "ALIPAY_HK",
    "paymentRequestId": "paymentRequestId01",
    "paymentResultInfo": {

    },
    "paymentTime": "2025-02-04T22:14:25-08:00",
    "pspCustomerInfo": {
        "pspCustomerId": "216022003753XXXX",
        "pspName": "ALIPAY_HK"
    },
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}
```

   The following table shows the possible values of     *result.resultStatus*     in the notification request of payment result. Please handle the result according to the guidance provided:

 | ***result.resultStatus*** | **Message** | **Further action** |
| --- | --- | --- |
| `S` | Payment was successful. | **​**    You may proceed to ship the goods. |
| `F` | Payment failed. | Please use a new     *paymentRequestId*        and initiate the payment again. |

<!-- /TabGroup -->
 **2\. Verify the asynchronous notification**

 When 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
import javax.servlet.http.HttpServletRequest;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.alipay.global.api.model.Result;
import com.alipay.global.api.model.ResultStatusType;
import com.alipay.global.api.response.AlipayResponse;
import com.alipay.global.api.tools.WebhookTool;

@RestController
public class PaymentNotifyHandleBySDK {

    /**
     * alipay public key, used to verify signature
     */
    private static final String SERVER_PUBLIC_KEY = "";
  
    /**
     * payment result notify processor
     * using <a href="https://spring.io">Spring Framework</a>
     *
     * @param request    HttpServletRequest
     * @param notifyBody notify body
     * @return
     */
    @PostMapping("/payNotify")
    public Object payNotifyHandler(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");

        Result result;
        AlipayResponse response = new AlipayResponse();

        try {
            // verify the signature of notification
            boolean verifyResult = WebhookTool.checkSignature(requestUri, requestMethod, clientId, requestTime, signature, notifyBody, SERVER_PUBLIC_KEY);
            if (!verifyResult) {
                throw new RuntimeException("Invalid notify signature");
            }

            // deserialize the notification body
  
            // update the order status with notify result

            // respond the server that the notification is received
            result = new Result("SUCCESS", "success", ResultStatusType.S);

        } catch (Exception e) {
            String errorMsg = e.getMessage();
            // handle error condition
            result = new Result("ERROR", errorMsg, ResultStatusType.F);
        }
        response.setResult(result);
        return ResponseEntity.ok().body(response);
    }

}
```

   Whether the payment is successful or not, each notification request must be responded to in the format specified below. Otherwise, Antom will resend the asynchronous notification.

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

   > **[INFO]** **Common questions**
>
>  **Q: When will the notification be sent?**
>
>  A: It depends on whether the payment is completed:
>
>  - If the payment is successfully completed, Antom will 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 payment is not completed, Antom needs to close the order first before sending an asynchronous notification. The time it takes for different payment methods to close the order varies, usually defaulting to 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 did not respond 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: When responding to an asynchronous notification, do I need to add a digital signature?**
>
>  A: 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.
>
>  ​
>
>  **Q: What key parameters do I need to use in the notification?**  
>    A: Please note the following key parameters:
>
>  - *result*    : For APM payments, it represents the final payment result. For  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)  ,   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md) , and card payments, it only represents the authorization result, and further capture is required.
> - *paymentRequestId*    : The payment request ID used for inquiries, cancellations, and reconciliation.
> - *paymentId*    : The payment order ID generated by Antom, used for refunds and reconciliation.
> - *paymentAmount*    : The payment amount.

**Tab: Inquire about the result**

You can also inquire about the payment result by calling the   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   API using     *paymentRequestId*     from the payment request,    regardless of whether it is an APM payment, card payment,  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)  , or   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md) .

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

 ```java
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 sample code shows a request message:

   ```json
{
  "paymentRequestId": "paymentRequestId01"
}
```

   The following sample code shows a response message:

<!-- TabGroup -->

**Tab: APM payments**

```json
{
  "actualPaymentAmount": {
    "currency": "THB",
    "value": "299"
  },
  "paymentAmount": {
    "currency": "THB",
    "value": "299"
  },
  "paymentId": "20240101123456789XXXX",
  "paymentMethodType": "TRUEMONEY",
  "paymentRedirectUrl": "https://kademo.intlalipay.cn/melitigo/Test_114.html",
  "paymentRequestId": "paymentRequestId01",
  "paymentResultCode": "SUCCESS",
  "paymentResultMessage": "success.",
  "paymentStatus": "SUCCESS",
  "paymentMethodType": "TRUEMONEY",
  "paymentTime": "2025-02-17T08:06:43-08:00",
  "pspCustomerInfo": {
    "pspName": "TRUEMONEY"
  },
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
```

**Tab: Card payments, Apple Pay, Google Pay**

```json
{
    "actualPaymentAmount": {
        "currency": "USD",
        "value": "5000"
    },
    "authExpiryTime": "2024-12-17T21:56:56-08:00",
    "cardInfo": {
        "cardBrand": "VISA",
        "funding": "CREDIT",
        "issuingCountry": "US"
    },
    "paymentAmount": {
        "currency": "USD",
        "value": "5000"
    },
    "paymentId": "20240101123456789XXXX",
    "paymentMethodType": "CARD",
    "paymentRedirectUrl": "http://gol.alipay.net:8080/amsdemo/result?paymentRequestId=amsdmpay_yanfei_wzh_20240111_191505_666",
    "paymentRequestId": "paymentRequestId01",
    "paymentResultCode": "SUCCESS",
    "paymentResultInfo": {
        "avsResultRaw": "M",
        "cardBrand": "VISA",
        "cardNo": "************9954",
        "cvvResultRaw": "U",
        "funding": "CREDIT",
        "issuingCountry": "US",
        "networkTransactionId": "123qwe456rew",
        "paymentMethodRegion": "GLOBAL",
        "threeDSResult": {
            "cavv": "",
            "eci": ""
        }
    },
    "paymentResultMessage": "success.",
    "paymentStatus": "SUCCESS",
    "paymentTime": "2024-12-10T21:56:57-08:00",
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}
```

<!-- /TabGroup -->
   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)  .

 > **[INFO]** **Common questions**
>
>  **Q: What key parameters should I pay attention to when using the**       [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)       **API to check the payment or authorization status?**
>
>  A: Please note the following key parameters:
>
>  - *result*    :    Only indicates the result of the API call. For APM payments, the final payment result should be determined based on     *paymentStatus*     (  `SUCCESS`  /  `FAIL`  /  `PROCESSING`  ). For card payments,  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)  , and   [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md) ,     *paymentStatus*     only represents the authorization result, and the decision to ship goods should rely on the capture result.
> - *paymentAmount*    : Used to verify the payment amount.
> - *paymentId*    : The payment order ID generated by Antom, used for refunds and reconciliation.
>
>  ​
>
>  **Q: How often should I call the inquiryPayment API?**
>
>  A: Call the   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   API constantly with an interval of 2 seconds until the final payment result is obtained or an asynchronous payment result notification is received.

<!-- /TabGroup -->

## Step 5: Capture   **[Server-side]** **[For card payments or Google Pay only]** {#3u0V5}

 Antom provides both automatic and manual capture methods. You can choose based on your business needs. After initiating capture, you can obtain the result via asynchronous notification or active inquiry. For specific operations, refer to   [Capture](https://docs.antom.com/ac/cashierpay/capture.md)  .

<!-- /ToggleTab -->

# After payments {#BJbEu}

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

## Cancellation   **[Server-side]** {#Otb6j}

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

## Refund   **[Server-side]** {#kg4oU}

 Different payment methods have varying refund capabilities. To learn about Antom refund rules and how to initiate a refund for a successful transaction, refer to   [Refund](https://docs.antom.com/ac/cashierpay/refund.md)  .

## Dispute   **[Server-side]** {#AoEw6}

 Antom provides dispute resolution services for contested transactions. For more information, refer to [Dispute Guidance](https://docs.antom.com/ac/dispute/overview.md) and [Dispute resolution](https://docs.antom.com/ac/dispute/dispute_resolution.md).

# Payment method features {#RvQap}

 This section explains differences in supported features across payment methods.

## Default timeout {#v6YBS}

 Default order timeout varies by payment method. For specifics, refer to   [Default timeout](https://docs.antom.com/ac/pm/supported_pm.md#ju3pe)  .

 > **[INFO]** **Note**    : Since Payment Element orders have a default validity period of 1 hour, the actual timeout period is extended by 1 hour beyond the payment method’s default timeout. For example, if a payment method’s default timeout is 14 minutes, the actual timeout period for a Payment Element order will be 1 hour and 14 minutes.

## Integration key points {#l5xra}

 Below are key integration points and recommended approaches for different payment methods.

 | **Payment method** | **Key points** | **Recommended solution** |
| --- | --- | --- |
| [PayPay](https://docs.antom.com/ac/antomop/paypay_mdx.md) | - *paymentRedirectUrl*     should be no longer than 255 characters. - Refunds for an order cannot exceed 20 times. | *paymentRedirectUrl*     should be no longer than 255 characters. |
| [QRIS](https://docs.antom.com/ac/antomop/qris.md) | Payment discrepancy may occur. | When such payment discrepancies occur (the user makes a payment but you receive a notification of payment failure), once Antom receives a payment success message from the downstream payment method, Antom will settle the funds to you. After you receive the funds, you can independently handle any subsequent refunds. And the corresponding settlement details report will include this transaction. |
| [PromptPay](https://docs.antom.com/ac/antomop/promptpay.md) | Payment discrepancy may occur. |  |
| [Konbini](https://docs.antom.com/ac/antomop/konbini_mdx.md) ,  [Konbini (7-Eleven)](https://docs.antom.com/ac/antomop/Konbini_711_mdx.md) ,  [Pay-easy](https://docs.antom.com/ac/antomop/payeasy.md) | - Cannot redirect back to the merchant page. - Payment discrepancy may occur. |  |
| Maybank | Once the payment is completed, there may be a 5-minute delay in sending the asynchronous notification. | Display a prompt of "order is being confirmed" to buyers. |
| [OVO](https://docs.antom.com/ac/antomop/ovo.md) ,  [Pix](https://docs.antom.com/ac/antomop/pix.md) ,  [BANCOMAT Pay](https://docs.antom.com/ac/antomop/bancomatpay.md) | The payment method app cannot be launched automatically. | The buyer must manually launch the payment method app to complete the payment. |
| [Siam Commercial Bank](https://docs.antom.com/ac/antomop/scb.md) | - A processing fee may be applied to payments. - Not supported on PC. | Prompt the buyer that a processing fee may be applied to payments made using the payment method. The fee amount is determined by the buyer's bank level. |
| [Bank of Ayudhya](https://docs.antom.com/ac/antomop/bay.md) | - A processing fee may be applied to payments. - Not supported on PC. | Prompt the buyer that a processing fee may be applied to payments made using the payment method. The fee amount is determined by the buyer's bank level. |
| [GoPay](https://docs.antom.com/ac/antomop/gopay.md) ,  [Bangkok Bank](https://docs.antom.com/ac/antomop/bangkok_bank.md) ,  [Siam Commercial Bank](https://docs.antom.com/ac/antomop/scb.md) ,  [Bank of Ayudhya](https://docs.antom.com/ac/antomop/bay.md) ,  [KrungThai Bank](https://docs.antom.com/ac/antomop/kyb.md) | Not supported on PC. | None |
| [NAVER Pay](https://docs.antom.com/ac/antomop/naverpay.md) | - Requires additional integration for PC clients. - After login, the buyer completes the payment in a new tab instead of the original page. | Enable browser pop-up permissions and use a new     *browser*     object or window to handle the payment. |
| [Express Bank Transfer](https://docs.antom.com/ac/antomop/express_bank_transfer.md) | *paymentRedirectUrl*     has restrictions on special characters. | Avoid using the "&" symbol in     *paymentRedirectUrl*    . |

## Card payment features {#abqU1}

 Payment Element supports the following card payment features.    Click to get    detailed information and usage instructions:

 - [3D Secure 2](https://docs.antom.com/ac/pm/3ds.md)
- [Antom 3DS-Retry](https://docs.antom.com/ac/pm/3ds_retry.md)
- [MIT (Merchant-Initiated Transaction)](https://docs.antom.com/ac/pm/mit.md)
- [Antom Tokenization](https://docs.antom.com/ac/pm/tokenization.md)
- [COF (Card-on-File)](https://docs.antom.com/ac/pm/cof.md)

# Additional content {#GBkuL}

 Antom also offers the following customization options:

 - [**Appearance customization**](https://docs.antom.com/ac/cashierpay/appearance.md)  : Antom provides extensive styling options, including theme, layout, and CSS customization.
- [**Google Pay**](https://docs.antom.com/ac/cashierpay/gpay_element.md)  : Buyers can pay using credit or debit cards stored in their Google account. With Payment Element, no additional  [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md)  SDK integration is needed—it loads  [Google Pay](https://docs.antom.com/ac/antomop/googlepay.md)  automatically.
- [**Apple Pay**](https://docs.antom.com/ac/cashierpay/apay_element.md)  : Buyers can pay using credit or debit cards stored in their Apple account. With Payment Element, no additional  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)  SDK integration is needed—it loads  [Apple Pay](https://docs.antom.com/ac/antomop/applepay.md)  automatically.

## Specify a payment method {#L9xOX}

 You can 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 Payment Element, the order of the payment method list, and the display of quick payments. 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*    : Specifies whether to enable the express checkout option for a payment method. Currently, only   `ALIPAY_CN`  ,   `APPLEPAY`   and   `GOOGLEPAY`   can be set as express checkout methods. Valid values are:     - `true`  :    Enables express checkout for this payment method.   - `false`  : Disables express checkout for this payment method.   > **[INFO]** **Note**    : The     *expressCheckout*     parameter is currently supported only on Android and iOS. |

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

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

## Payment methods requiring embedding {#Ygtd4X}

 The following payment methods require you to embed the payment details collection component:

 | **Payment method category** | **Payment method** | **Enum value** |
| --- | --- | --- |
| Card | [Mastercard](https://docs.antom.com/ac/antomop/mastercard_mdx.md) | `CARD` |
| [Visa](https://docs.antom.com/ac/antomop/visa_mdx.md) | `CARD` |  |
| [American Express](https://docs.antom.com/ac/antomop/amex_mdx.md) | `CARD` |  |
| [Brazilian cards](https://docs.antom.com/ac/antomop/brazilian_mdx.md) | `CARD` |  |
| [Chilean cards](https://docs.antom.com/ac/antomop/chilean_mdx.md) | `CARD` |  |
| [Diners](https://docs.antom.com/ac/antomop/diners_mdx.md) | `CARD` |  |
| [Discover](https://docs.antom.com/ac/antomop/discover_mdx.md) | `CARD` |  |
| [South Korean Cards (Local cards)](https://docs.antom.com/ac/antomop/south_korean_mdx.md) | `CARD` |  |
| [Mexican cards](https://docs.antom.com/ac/antomop/mexican_mdx.md) | `CARD` |  |
| [Peruvian cards](https://docs.antom.com/ac/antomop/peruvian_mdx.md) | `CARD` |  |
| [UnionPay](https://docs.antom.com/ac/antomop/unionpay_mdx.md) | `CARD` |  |
| Digital wallet | [OVO](https://docs.antom.com/ac/antomop/ovo.md) | `OVO` |
| [Mercado Pago](https://docs.antom.com/ac/antomop/mp_mdx.md)   (Mexico) | `MERCADOPAGO_MX` |  |
| [Mercado Pago](https://docs.antom.com/ac/antomop/mp_mdx.md)   (Brazil) | `MERCADOPAGO_BR` |  |
| [Mercado Pago](https://docs.antom.com/ac/antomop/mp_mdx.md)   (Peru) | `MERCADOPAGO_PE` |  |
| [Mercado Pago](https://docs.antom.com/ac/antomop/mp_mdx.md)   (Chile) | `MERCADOPAGO_CL` |  |
| Cash payment | [Konbini (7-Eleven)](https://docs.antom.com/ac/antomop/Konbini_711_mdx.md) | `SEVENELEVEN` |
| [Konbini](https://docs.antom.com/ac/antomop/konbini_mdx.md) | `KONBINI` |  |
| Online banking | [BANCOMAT Pay](https://docs.antom.com/ac/antomop/bancomatpay.md) | `BANCOMATPAY` |
| [BLIK](https://docs.antom.com/ac/antomop/blik.md) | `BLIK` |  |
| [Pay-easy](https://docs.antom.com/ac/antomop/payeasy.md) | `ONLINEBANKING_PAYEASY` |  |
| [FPX](https://docs.antom.com/ac/antomop/fpx.md) | `ONLINEBANKING_FPX` |  |