Hosted checkout page

Hosted checkout page is a standardized payment solution offered by Antom, suitable for merchants who do not maintain a checkout list and want to have their checkout page hosted by Antom. You can display product information on your own page. When the buyer pays, the hosted checkout page will display the payment method and price for the buyer to choose and complete the payment. The system supports customization of merchant brand names and logos, enabling quick deployment without requiring any technical development or ongoing maintenance.

User experience

The image shows the general user experience on the merchant's page:

image.png

Payment flow

The following process shows how to integrate the hosted mode:

yuque_diagram (8).png

  1. The buyer enters the checkout page.
  2. Create a payment session request.
    • After the buyer submits the order, the merchant server calls the createPaymentSession (One-time Payments) API to obtain normalUrl to complete the payment based on the payment method, amount, and currency.
  1. Handle Antom payment page URL.
    • After the merchant server obtains normalUrl and passes it to front end, it will redirect from the merchant front end to the payment page.
  1. Obtain the payment result.
    • When the buyer completes the payment, you can get the corresponding payment result from the Antom asynchronous notification or through the inquiryPayment API. Specify the paymentNotifyUrl in the createPaymentSession (One-time Payments) API to set the address for receiving asynchronous notifications. When the payment is successful or expires, Antom uses notifyPayment to send asynchronous notifications to you.

Integration preparations

Before you start integrating, read the Integration Guide and API Overview documents to understand the integration steps of the server-side API and the precautions for calling the API. Furthermore, ensure that the following prerequisites are met:

  • Obtain a client ID
  • Complete the key configuration
  • Complete the configuration of paymentNotifyUrl to receive the asynchronous notification
  • Integrate the server-side SDK package, install the server-side library, and initialize a request instance. For more details, refer to Server-side SDKs.

Integration steps

Follow these steps to start the integration:

  1. Create a payment session
  2. Redirect to the Antom payment page
  3. Obtain the payment results

Step 1: Create a payment session Sever-side

Creating a payment session includes the following parameters:

Parameter Type

Parameter Name

Required?

Description

Base parameters

paymentRequestId

Yes

The unique ID assigned by a merchant to identify a payment request.
paymentAmount

Yes

The payment amount that you 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 URL that is used to receive the payment result notification. You can also set the URL to receive the result notification on Antom Dashboard.

paymentMethod.paymentMethodType

Yes

The payment method type that is included in payment method options. 

Order parameters

order.orderAmount

Yes

The order amount of the merchant that directly provides services or goods to the customer. 

order.referenceOrderId

Yes

The unique ID to identify the order on the merchant side.

order.goods

Yes

Goods information, including the ID, name, price, and quantity of the goods in the order. Please note:

  • In transactions related to flight tickets, the value of goodsName must be formatted as "ticket-date-flight number-departure-arrival". For orders with multiple products, each product's information must be in this format and separated by commas, and all product information must be recorded at the same time.
  • In a hotel scenario, the value of goodsName must be formatted as "Accommodation Period (20250101-20250102), Hotel Name". For orders with multiple products, each product's information must be in this format and separated by commas, and all product information must be recorded at the same time.
  • The referenceGoodsId, goodsName, goodsUnitAmount and goodsQuantity fields are mandatory.
  • The values of orderAmount and paymentAmount are equal to the sum of the amount of all the goods. When there are multiple items involved in one order, please refer to the formula: goodsUnitAmount No.1 * goodsQuantity No.1 + goodsUnitAmount No.2 * goodsQuantity No.2 = orderAmount / paymentAmount.
order.buyer

Yes

Buyer information, including the ID, name, phone number, and email of the buyer. This parameter must be associated with two other mandatory parameters, referenceBuyerId and buyerName.fullName.

order.transit

No

Trip information, including trip modes, legs of trips and passenger information.  This field is required if it is a transaction related to flight tickets.

If the transit is a required field, then the following five fields must be provided: transitType, legs.departureTime, legs.departureAddress.city, legs.arrivalAddress.city, and legs.carrierNo.

The above parameters are the basic parameters for creating a payment session. For complete and additional requirements for specific payment methods, please refer to createPaymentSession (One-time Payments).

The following shows a sample of how to call the createPaymentSession (One-time Payments) API to initiate a payment:

copy
public static void createPaymentSession() {
    AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
    alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
    // set amount
    Amount amount = Amount.builder().currency("SGD").value("6000").build();
    alipayPaymentSessionRequest.setPaymentAmount(amount);

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

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

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

    // set goods info
    Goods goods = Goods.builder().goodsBrand("Antom Brand").goodsCategory("outdoor goods/bag").goodsName("Classic Woman Bag").goodsQuantity("1")
    .goodsSkuName("Black").goodsImageUrl("https://mdn.alipayobjects.com/portal_pdqp4x/afts/file/A*H8M9RrxlArAAAAAAAAAAAAAAAQAAAQ")
    .goodsUnitAmount(amount).goodsUrl("https://yourGoodsUrl").referenceGoodsId("yourGoodsId").build();

    // set order info
    Order order = Order.builder().referenceOrderId(orderId)
    .orderDescription("antom ckp testing order").orderAmount(amount).buyer(buyer).goods(Stream.of(goods).collect(Collectors.toList())).build();
    alipayPaymentSessionRequest.setOrder(order);

    // replace with your notifyUrl
    // or configure your notify url here: <a href="https://dashboard.antom.com/global-payments/developers/iNotify">Notification URL</a>
    alipayPaymentSessionRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com/payment/receiveNotify");
    // replace with your redirectUrl
    alipayPaymentSessionRequest.setPaymentRedirectUrl(
        "http://localhost:8080/index.html?paymentRequestId=" + paymentRequestId);

    AlipayPaymentSessionResponse alipayPaymentSessionResponse;
    try {
        alipayPaymentSessionResponse = CLIENT.execute(alipayPaymentSessionRequest);
    } catch (AlipayApiException e) {
        String errorMsg = e.getMessage();
        // handle error condition
    }
}

The following code shows samples of the request messages in different payment scenarios:

copy
{
    "order": {
        "transit": {
            "transitType": "FLIGHT",
            "legs": [
                {
                    "departureTime": "2024-11-27T12:01:01+08:00",
                   "departureAddress": {
                        "city": "SZX" //IATA three-digit code is required
                    },
                    "arrivalAddress": {
                        "city": "HKG" //IATA three-digit code is required
                    },
                    "carrierNo": "111"
                }
            ]
        },
        "orderAmount": {
            "currency": "CNY",
            "value": "1000"
        },
        "orderDescription": "Cappuccino #grande (Mika's coffee shop)",
        "referenceOrderId": "ORDER_2022111414171****",
        "buyer": {
            "referenceBuyerId": "test1234****",
            "buyerEmail": "alipay@alipay.com",
            "buyerName": {
                "fullName": "Dehua Skr Liu"
            }
        },
      "goods": [
        {
            "referenceGoodsId": "GoodsId-32078",
            "goodsUnitAmount": {
                "currency": "CNY",
                "value": "1000"
            },
            "goodsQuantity": "1",
            "goodsName": "ticket-date-flight number-departure-arrival"
        }
    ],
    },
    "env": {
        "terminalType": "WEB"  
    },
    "paymentAmount": {
        "currency": "CNY",
        "value": "1000"
    },
    "paymentMethod": {
        "paymentMethodType": "ANTOM_BIZ_ACCOUNT"
        },
      "settlementStrategy": {
            "settlementCurrency": "CNY"
        },
        "paymentNotifyUrl": "https://www.alipay.com/notify",
        "paymentRedirectUrl": "https://www.alipay.com",
        "paymentRequestId": "PAY_2022111414171****",
        "productCode": "CASHIER_PAYMENT",
        "productScene": "CHECKOUT_PAYMENT"
    }

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

  • paymentSessionExpiryTime: The specific date and time after which the payment session will expire.
  • normalUrl: The URL used to redirect to the Payment Page.
copy
{
    "normalUrl": "https://ac.alipay.com/page/antom-web-checkout/src/checkout/paymentPage/index.html?sessionData=6WaYoQqC8UG+OrtKL20nf1apMnYKw4+zAbyy2Kv0AEIx0PyZhBU5y0Y/PmBfg/zK4Bu8/XdfWTgWXowmSd+M1A==&&SG&&188&&eyJwYXltZW50U2Vzc2lvbkNvbmZpZyI6eyJwYXltZW50TWV0aG9kQ2F0ZWdvcnlUeXBlIjoiQUxMIiwicHJvZHVjdFNjZW5lIjoiQ0hFQ0tPVVRfUEFZTUVOVCIsInByb2R1Y3RTY2VuZVZlcnNpb24iOiIxLjAifX0=",
    "paymentSessionData": "6WaYoQqC8UG+OrtKL20nf1apMnYKw4+zAbyy2Kv0AEIx0PyZhBU5y0Y/PmBfg/zK4Bu8/XdfWTgWXowmSd+M1A==&&SG&&188&&eyJwYXltZW50U2Vzc2lvbkNvbmZpZyI6eyJwYXltZW50TWV0aG9kQ2F0ZWdvcnlUeXBlIjoiQUxMIiwicHJvZHVjdFNjZW5lIjoiQ0hFQ0tPVVRfUEFZTUVOVCIsInByb2R1Y3RTY2VuZVZlcnNpb24iOiIxLjAifX0=",
    "paymentSessionExpiryTime": "2024-04-19T17:10:09+08:00",
    "paymentSessionId": "6WaYoQqC8UG+OrtKL20nf1apMnYKw4+zAbyy2Kv0AEKxd/W4uVKjKYL6QfTqUS8s",
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}

The following table shows the possible values of result.resultStatus in the response message. Handle the result according to the guidance provided:

result.resultStatus

Message

Further action

S

Indicates that payment session creation succeeded.

Obtain normalUrl and return to the merchant's front end.

U

Unknown reasons.

Change the paymentRequestId and call the API again to resolve the issue. Contact Antom Technical Support if the problem persists. 

F

Indicates that the payment session creation failed.

Check and verify whether the current API required request fields (including header fields and body fields) are correctly passed and valid.

Note: If you did not receive a response message, it might be due to a network timeout. Close the current transaction order, or replace the paymentRequestId and initiate a payment request again.

Step 2: Handle Antom payment page URL Client-side

After the merchant server obtains normalUrl and passes it to front end, it will redirect from the merchant front end to the payment page. 

After obtaining the normalUrl, you need to redirect the page to the Antom payment page in the browser, or open it in a new tab.

copy
if (serverResponse.normalUrl != null) {
    window.open(serverResponse.normalUrl, '_blank');
}

The image below shows the rendering result of the redirected Antom payment page:  

image.png

Step 3: Obtain the payment results Sever-side

When the buyer completes the payment or the payment times out, you can get the corresponding payment result from the Antom asynchronous notification or by inquiring about the payment result.

Receive the asynchronous notification

You can choose one of two ways to set a webhook URL to receive notifications:

  • If each of your orders has a unique notification URL, it is recommended to set the notification URL in each request. You can specify the asynchronous notification address through the paymentNotifyUrl field of the createPaymentSession (One-time Payments) API.
  • If all your orders share a unified notification URL, you can set the notification URL in Antom Dashboard > Developer > Notification URL. Refer to Notification URL for more details.

The following is the notification request sample code:

copy
{
  "actualPaymentAmount": {
    "currency": "HKD",
    "value": "1000"
  },
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
    "currency": "HKD",
    "value": "1000"
  },
  "paymentCreateTime": "2024-05-27T02:27:13-07:00",
  "paymentId": "20240527194010800100188420225534863",
  "paymentRequestId": "101520240527410134510924020002",
  "paymentResultInfo": {},
  "paymentTime": "2024-05-27T02:27:27-07:00",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}

The table shows the possible values that the result.resultStatus field in the asynchronous notification of payment results may return. Handle the result according to the guidance:

result.resultStatus

Message

Further action

S

The payment is successful.

Store paymentId for subsequent cancellation transactions and refunds.

F

The payment is failed.

Close the current transaction order, or replace the paymentRequestId and initiate a payment request again.

You need to verify the signature of the payment notification sent by Antom. To verify the signature of the notification and make a response to the notification, see Process the notification.

You must respond to each notification request in the following fixed format, regardless of whether the payment is successful or not. 

copy
{
  "result": {
    "resultCode": "SUCCESS",
    "resultStatus": "S",
    "resultMessage": "Success"
  }
}

Inquire about the result

Call the inquiryPayment API to inquire about the payment result by specifying the following parameters:

Parameter name

Is required?

Description

paymentRequestId

Yes

The payment request number generated by the merchant.

The following sample code shows how to call the inquiryPayment API:

copy
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 is the sample code of the request message:

copy
{
  "paymentRequestId": "101520240527410134510924020002"
}

The following is the sample code of the response message:

copy
{
  "actualPaymentAmount": {
    "currency": "HKD",
    "value": "1000"
  },
  "paymentAmount": {
    "currency": "HKD",
    "value": "1000"
  },
  "paymentId": "20240527194010800100188420225534863",
  "paymentMethodType": "ANTOM_BIZ_ACCOUNT",
  "paymentRedirectUrl": "https://xxx.com/bgt_launch_app_callback.html?browser_callback_new=1&chTransId=SO000124052709420662253642020002",
  "paymentRequestId": "101520240527410134510924020002",
  "paymentResultCode": "SUCCESS",
  "paymentResultMessage": "success",
  "paymentStatus": "SUCCESS",
  "paymentTime": "2024-05-27T02:27:27-07:00",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}

The result of the order should be based on the value of paymentStatus:

paymentStatus

Message

Further action

SUCCESS

The payment is successful.

No further action is needed.

FAIL

The payment is failed.

Close the current transaction order, or replace the paymentRequestId and initiate a payment request again.

PROCESSING

The payment is in progress.

Continue to query or check again after closing the order.

After payments

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

Cancel

After the buyer places an order, you can close that order using the cancel API within a limited period. Transactions can be canceled at any time from the order placement until 00:15 (GMT+8) on T+1 day. Refer to Cancel for detailed steps.

Refund

After the transaction is paid successfully, You can initiate a refund for a successfully paid transaction by calling the refund API. Refer to Refund for detailed steps.

Reconciliation

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

Best practices

Antom provides you with best practice solutions such as the display of payment results, payment-retry solution, and API timeout settings. For more details, refer to Best practices.