Self-built checkout page

The self-built checkout can help your website start accepting payments online, suitable for merchants who maintain their own cashier list. You can display product information and corresponding payment methods on your own page. When the buyer pays, it will be redirected to the payment page of Antom business account. This article introduces the integration solutions to accepting payment acceptance from desktop browsers.

User experience

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

image.png

Payment flow

The payment flow is composed of the following steps:

yuque_diagram (15).png

  1. The buyer enters the checkout page.
  2. Call the pay API.
    • After the buyer selects a payment method and submits the order, the merchant server calls the pay (One-time Payments) API to obtain normalUrl to complete the payment based on the payment method, amount, and currency.
  1. Handle the 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 pay (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

Start your integration by taking the following steps:

  1. Invoke the pay (One-time Payments) API and get the redirection URL
  2. Handle the Antom payment page URL
  3. Obtain the payment results

Step 1: Create a payment request Sever-side

Call the pay (One-time Payments) API to initiate a payment request and obtain the redirection URL through the normalUrl parameter returned in the response.

The following parameters are included in the payment request:

Parameter Type

Parameter Name

Required?

Description

Base parameters

paymentRequestId

Yes

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

Yes

The payment amount that you request 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. For this integration, the value is fixed as ANTOM_BIZ_ACCOUNT.

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 request. For complete and additional requirements for specific payment methods, please refer to the pay (One-time Payments) API.

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

copy
AlipayPayRequest alipayPayRequest = new AlipayPayRequest();
alipayPayRequest.setClientId(CLIENT_ID);
alipayPayRequest.setPath("/ams/api/v1/payments/pay");
alipayPayRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);

// replace with your paymentRequestId
alipayPayRequest.setPaymentRequestId("paymentRequestId01");

// set amount
Amount amount = new Amount();
amount.setCurrency("USD");
amount.setValue("100");
alipayPayRequest.setPaymentAmount(amount);

// set paymentMethod
PaymentMethod paymentMethod = new PaymentMethod();
paymentMethod.setPaymentMethodType("ANTOM_BIZ_ACCOUNT");
alipayPayRequest.setPaymentMethod(paymentMethod);

// set order Info
Order order = new Order();
order.setReferenceOrderId("referenceOrderId01");
order.setOrderDescription("antom test order");
order.setOrderAmount(amount);
alipayPayRequest.setOrder(order);

//set env Info
Env env = new Env();
env.setTerminalType(TerminalType.WEB);
alipayPayRequest.setEnv(env);

// replace with your notifyUrl
alipayPayRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com");

// replace with your redirectUrl
alipayPayRequest.setPaymentRedirectUrl("http://www.yourRedirectUrl.com");

// make the payment
AlipayPayResponse alipayPayResponse = null;
try {
  alipayPayResponse = defaultAlipayClient.execute(alipayPayRequest);
} catch (AlipayApiException e) {
  String errorMsg = e.getMessage();
  // handle the 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****",
            "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"
}

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

  • result.resultCode: Result code. The returned value is PAYMENT_IN_PROCESS indicates that the payment has been processed.
  • paymentId: The unique ID that is assigned by Antom to identify a payment.
  • normalUrl: The URL that redirects users to a WAP (only PC is supported) or web page in the default browser or the embedded WebView. When the value of result.resultCode is PAYMENT_IN_PROCESS, normalUrl is to be returned.
copy
{
    "normalUrl": "https://iexpfront-sea-global.alipay.com/payments/method/checkout/?requestId=9UKjko5EB7eoj6mq8DFLqhh%2BZ5MeSCNC%2BzOFP0%2FeNuU%3D&merchantId=1885rqVlcNMm2A5j%2F7KP%2F6pYOnqCDwjJbaGFvFMKHvVNng%3D",
    "paymentActionForm": "{\"method\":\"GET\",\"paymentActionFormType\":\"RedirectActionForm\",\"redirectUrl\":\"https://iexpfront-sea-global.alipay.com/payments/method/checkout/?requestId=9UKjko5EB7eoj6mq8DFLqhh%2BZ5MeSCNC%2BzOFP0%2FeNuU%3D&merchantId=1885rqVlcNMm2A5j%2F7KP%2F6pYOnqCDwjJbaGFvFMKHvVNng%3D\"}",
    "paymentAmount": {
        "currency": "HKD",
        "value": "1000"
    },
    "paymentCreateTime": "2024-05-27T02:27:13-07:00",
    "paymentId": "20240527194010800100188420225534863",
    "paymentRequestId": "101520240527410134510924020002",
    "redirectActionForm": {
        "method": "GET",
        "redirectUrl": "https://iexpfront-sea-global.alipay.com/payments/method/checkout/?requestId=9UKjko5EB7eoj6mq8DFLqhh%2BZ5MeSCNC%2BzOFP0%2FeNuU%3D&merchantId=1885rqVlcNMm2A5j%2F7KP%2F6pYOnqCDwjJbaGFvFMKHvVNng%3D"
    },
    "result": {
        "resultCode": "PAYMENT_IN_PROCESS",
        "resultMessage": "payment in process",
        "resultStatus": "U"
    }
}

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

F

The payment is failed.

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

U

Unknown reasons.

Handle it according to the following situations:

  • If PAYMENT_IN_PROCESS is returned, redirect the page to the payment link (normalUrl).
  • If other result codes are returned, close the current transaction order, or replace the paymentRequestId and initiate a payment request again.

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 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 actively 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 pay (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 and its key parameters:

Field Name

Is required?

Description

paymentRequestId

Yes

The unique ID that is assigned by a merchant to identify a payment request, which is consistent with the value used in

the pay (One-time Payments) request.

paymentId

Yes

The unique ID that is assigned by Antom to identify a payment.
paymentAmount

Yes

Indicates the payment amount, which is consistent with the value used in the pay (One-time Payments) request.

actualPaymentAmount

Yes

Indicates the amount paid by the buyer, which is consistent with the value of paymentAmount.

paymentMethodType

No

Indicates the payment method used by the buyer.

result.resultCode

Yes

Result code. The returned value SUCCESS indicates a successful payment.

For the full API parameters, see notifyPayment.

The sample code below shows the request message:

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

In addition to obtaining the buyer's payment result through the asynchronous notification, you can retrieve the corresponding payment result through the inquiry payments service. You can call the inquiryPayment API to inquire about the payment result by specifying the following parameter:

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 code shows an example of a request:

copy
{
  "paymentRequestId": "101520240527410134510924020002"
}

The following code shows an example of a response:

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.