Alipay, China's leading third-party online payment solutionAlipay, China's leading third-party online payment solution

APM payments

Checkout Payment can help your website or application start to accept payments online. This article introduces the integration solution to support accepting payment from the desktop browser, mobile browser or app. After integration, you can access various payment methods like digital wallets, bank cards, and bank transfers.

User experience

Web user experience

For payments initiated on a desktop website, you need to redirect the buyer to the redirection URL or open the URL in a new tab.

APM payments

Note: If you want to provide buyers with an Alipay+ unified payment experience instead of the above user experience, see Alipay+ unified payment cashier and contact Antom technical support for more integration details.

Payment flow

The payment flow of each payment method is composed of the following steps:

图1.png

  1. The buyer enters the checkout page.
  2. Create the pay request
    After the buyer selects a payment method and submits the order, call the pay API to obtain the payment link to complete the payment.
  3. Handle the payment continuation URL
    The payment continuation URL is to be returned to the client. You need to redirect the buyer to the payment continuation URL. The payment continuation URL proceeds the payment process with different operations based on the characteristics of payment methods, such as collecting information, redirecting users, invoking the app, displaying QR codes, and performing verifications.
  4. Get the payment result
    Obtain the payment result using one of the following two methods:
    • Asynchronous notification: Specify the paymentNotifyUrl in the pay 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.
    • Synchronous inquiry: Call the inquiryPayment API to check the payment status.

Integration steps

Start your integration by taking the following steps:

  1. (Optional) Add a list of payment methods
  2. Invoke the pay API and get the payment continuation URL
  3. Obtain the payment results

Step 1: (Optional) Add a list of payment methods Client-side

Add the logos and names of the payment methods you plan to integrate. This allows buyers to easily choose their preferred method of payment. You can source the logos and names in two ways:

  • Contact Antom Technical Support. The logo for Alipay+ payment methods needs to comply with the Alipay+ brand specifications, and can be self-generated according to the size and style you need. Refer to Brand asset for more information.
  • Call the consult API to obtain the payment methods and logo URL supported by the current transactions based on the currency, transaction initiation terminal type, buyer region, and contracted payment methods.

The following figures show the page effect after adding a payment method:

Web page effect

image.png

Step 2: Invoke the pay API and get the payment continuation URL Server-sideClient-side

When the buyer selects a payment method provided by Antom to make a payment, you need to collect key information such as the payment request ID, order amount, payment method, transaction environment information, order description, URL of the payment redirection page, and URL for receiving the payment result notification. Then, call the pay API to obtain the payment continuation URL, and redirect the buyer to the checkout page specified by the payment continuation URL for payment.

Initiate a payment request Server-side

Antom provides server-side API libraries for multiple languages. The following code uses Java as an example. You need to install Java 6 or later.

Install an API library

You can find the latest version on GitHub.

copy
<dependency>
    <groupId>com.alipay.global.sdk</groupId>
    <artifactId>global-open-sdk-java</artifactId>
    <version>2.0.29</version>
</dependency>

Initialize the request instance

copy
import com.alipay.global.api.AlipayClient;
import com.alipay.global.api.DefaultAlipayClient;

import com.alipay.global.api.AlipayClient;
import com.alipay.global.api.DefaultAlipayClient;
import com.alipay.global.api.model.constants.EndPointConstants;

public class Sample {
    public static final String        CLIENT_ID            = "";
    public static final String        ANTOM_PUBLIC_KEY     = "";
    public static final String        MERCHANT_PRIVATE_KEY = "";

    private final static AlipayClient CLIENT               = new DefaultAlipayClient(
            EndPointConstants.SG, MERCHANT_PRIVATE_KEY, ANTOM_PUBLIC_KEY, CLIENT_ID);

}

Create a payment request

The following parameters are included in the payment request.

Parameter name

Is required

Description

productCode

Yes

In this scenario, the field is fixed to CASHIER_PAYMENT.

paymentRequestId

Yes

A unique ID generated by the merchant.

paymentAmount

Yes

Payment amount, which is set to the smallest unit of the payment currency.

paymentMethod

Yes

Payment method enumeration value.

paymentRedirectUrl

Yes

The payment result page of the merchant side, which needs to be displayed according to the results of the server.

paymentNotifyUrl

No

The payment result notification address, which can be specified via the API or set a fixed value in the portal.

settlementStrategy

No

The settlement currency of the payment. If you have signed multiple settlement currencies, you need to specify it in the API.

order

Yes

Order information, including order amount, order ID, and order description.

env

Yes

The environment in which the buyer initiates a transaction.

For more information about the complete parameters, refer to the pay API.

The following sample code is used for initiating a payment:

copy
public static void pay() {
    AlipayPayRequest alipayPayRequest = new AlipayPayRequest();
    alipayPayRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);

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

    // set amount
    Amount amount = Amount.builder().currency("SGD").value("4200").build();
    alipayPayRequest.setPaymentAmount(amount);

    // set paymentMethod
    PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("SHOPEEPAY_SG").build();
    alipayPayRequest.setPaymentMethod(paymentMethod);

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

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

    // set order info
    Order order = Order.builder().referenceOrderId(orderId)
        .orderDescription("antom testing order").orderAmount(amount).buyer(buyer).build();
    alipayPayRequest.setOrder(order);

    // set env info
    Env env = Env.builder().terminalType(TerminalType.WEB).build();
    alipayPayRequest.setEnv(env);

    // replace with your notify url
    alipayPayRequest.setPaymentNotifyUrl("https://www.yourNotifyUrl.com");

    // replace with your redirect url
    alipayPayRequest.setPaymentRedirectUrl("https://www.yourMerchantWeb.com");

    // do Payment
    AlipayPayResponse alipayPayResponse = null;
    try {
        alipayPayResponse = CLIENT.execute(alipayPayRequest);
    } catch (AlipayApiException e) {
        String errorMsg = e.getMessage();
        // handle error condition
    }
}

The following code shows a sample of the request message:

Web sample code
copy
{
  "env": {
    "terminalType": "WEB"
  },
  "order": {
    "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
    "orderAmount": {
      "currency": "SGD",
      "value": "4200"
    },
    "orderDescription": "antom testing order",
    "referenceOrderId": "referenceOrderId01"
  },
  "paymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "paymentMethod": {
    "paymentMethodType": "SHOPEEPAY_SG"
  },
  "paymentNotifyUrl": "https://www.yourNotifyUrl.com",
  "paymentRedirectUrl": "https://www.yourMerchantWeb.com",
  "paymentRequestId": "paymentRequestId01",
  "productCode": "CASHIER_PAYMENT"
}

Common questions

Q: How to set terminalType?

A: The valid values of terminalType are:

  • If the buyer initiates a transaction from PC, the terminalType needs to be specified as WEB.
  • If the buyer initiates a transaction from the mobile browser, the terminalType needs to be specified as WAP. Add the osType parameter and fill in the corresponding system parameters ANDROID or IOS according to the buyer's mobile phone.
  • If the buyer initiates a transaction from app, the terminalType needs to be specified as APP.

Q: Can I use Chinese characters in the value of the request parameters?

A: To avoid incompatibility of a certain payment method, do not use Chinese characters for fields in the request.

Q: How to set the URL to receive the payment notification?

A: Specify paymentNotifyUrl in the createPaymentSession API to receive the asynchronous notification about the payment result (notifyPayment), 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.

Receive a payment response Server-side

The following code is the sample response:

Web sample code
copy
{
  "normalUrl": "https://iexpfront-sea-global.alipay.com/payments/method/checkout/code.html?merchantId=1881CCJjl2BBCG6rka49PGy%2FoXzNOkE7yrezQj7guluiD8%3D&paymentRequestId=%2FoPiByS7aojWVwCaUlOAAlm4WlvaPbMSy%2FrDQP1AlMDEhodChPq8Oderh2GKY%2F9p&pass=lt%5E1&clientId=SANDBOX_XXXXXXXXXX",
  "orderCodeForm": {
    "codeDetails": [
      {
        "codeValue": "https://iexpfront-sea.alipay.com/showQrImage.htm?code=mmOd8ZsZBdQWrtZgFnUVXO2o5DwcbXxhYFq5Ydp1yv0%253D&size=M&pass=lt%5E1&sid=188",
        "displayType": "MIDDLEIMAGE"
      }
    ],
    "expireTime": "2024-01-01T00:14:00+08:00"
  },
  "paymentActionForm": "{\"paymentActionFormType\":\"PaymentCodeForm\",\"paymentCodeExpireTime\":1720508173000,\"paymentCodeInfos\":[{\"paymentCodeDetails\":[{\"codeValue\":\"20240101123456789\",\"codeValueType\":\"QRCODE\",\"displayType\":\"IMAGE\"}],\"paymentCodeInfoType\":\"PAYMENT_CODE\"}]}",
  "paymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "paymentCreateTime": "2024-01-01T00:00:00+08:00",
  "paymentId": "20240101123456789XXXX",
  "paymentRequestId": "paymentRequestId01",
  "redirectActionForm": {
    "method": "GET",
    "redirectUrl": "https://iexpfront-sea-global.alipay.com/payments/method/checkout/code.html?merchantId=1881CCJjl2BBCG6rka49PGy%2FoXzNOkE7yrezQj7guluiD8%3D&paymentRequestId=%2FoPiByS7aojWVwCaUlOAAlm4WlvaPbMSy%2FrDQP1AlMDEhodChPq8Oderh2GKY%2F9p&pass=lt%5E1&clientId=SANDBOX_XXXXXXXXXX"
  },
  "result": {
    "resultCode": "PAYMENT_IN_PROCESS",
    "resultMessage": "payment in process",
    "resultStatus": "U"
  }
}

Common questions

Q: What is the normalUrl?

A: For web or WAP transactions, Antom returns normalUrl, which the server-side needs to pass to the client-side for redirection. When you initiate payment for the same order again, you need to obtain a new normalUrl for redirection.

Q: What is the paymentId?

A: If you store the corresponding order number for subsequent refunds and reconciliations, you can specify the paymentId.

Redirect to the Checkout page of the payment method Client-side

Link type of web

The merchant server passes the normalUrl to the client, and the client page handles the redirection process to normalUrl.

Common questions

Q: How to handle different payment experiences?

A: You do not need to deal with the different experiences corresponding to different payment methods. It only needs to redirect to the normalUrl through the front-end page. Different payment experiences are promoted by normalUrl to complete the rendering and payment process.

Display the payment results page Client-side

You need to provide an HTTPS address and specify it through the paymentRedirectUrl field of the pay API, which is used to display the payment results on the merchant side.

image.png

Common questions

Q: What does the payment results page show?

A: In the case of successful payment or failed payment, it can redirect to the result page from the payment method side.

Q: Does redirecting to the results page mean the payment was successful?

A: The result page cannot be used as the basis for judging whether the payment is successful:

  • After the buyer makes a successful payment, the buyer may not be redirected to the result page due to network or other reasons.
  • If the buyer has not completed the payment, it still has an entrance that can be redirected to the result page.
  • Antom does not support specifying information that represents the payment result in the paymentRedirectUrl field.

Step 3: Obtain the payment resultsClient-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 the payment result.

Receive the asynchronous notification

When a payment is completed or fails, Antom sends an asynchronous notification (notifyPayment) to the address that you specified in the pay API via the paymentNotifyUrl parameter. If the address of each payment is the same, you can also configure the address in Antom Dashboard.

The following is the notification request sample code:

copy
{
  "notifyType": "PAYMENT_RESULT",
  "result": {
    "resultCode": "SUCCESS",
    "resultStatus": "S",
    "resultMessage": "success"
  },
  "paymentRequestId": "paymentRequestId01",
  "paymentId": "20240101123456789XXXX",
  "paymentAmount": {
    "value": "4200",
    "currency": "SGD"
  },
  "paymentCreateTime": "2024-01-01T00:00:00+08:00",
  "paymentTime": "2024-01-01T00:01:00+08:00"
}

How to verify the signature of the notification and make a response to the notification, see Sign a request and verify the signature.

The following is the notification response sample code:

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

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 usually send you an asynchronous notification within 3 to 5 seconds. For some payment methods like OTC, the notification might take a bit longer.
  • If the 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 didn't make a response to the notification in the Sample code format.

The notification can be resent up to 8 times or until a correct response is received to terminate delivery. The sending intervals are as follows: 0 minutes, 2 minutes, 10 minutes, 10 minutes, 1 hour, 2 hours, 6 hours, and 15 hours.

Q: When responding to 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 format, but you do not need to countersign the response.

Q: What are the key parameters in the notification that I need to use?

A: Pay attention to the following key parameters:

  • result: indicates the payment result of the order.
  • paymentRequestId: indicates the payment request number you generated for consult, cancel, and reconciliation.
  • paymentId: indicates the payment order number generated by Antom, used for refund and reconciliation.
  • paymentAmount: indicates the payment amount.

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

No

The payment request number generated by the merchant

The following is the sample code:

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
    }
}

Obtain the response code

copy
{
  "result": {
    "resultCode": "SUCCESS",
    "resultStatus": "S",
    "resultMessage": "Success"
  },
  "paymentStatus": "SUCCESS",
  "paymentRequestId": "paymentRequestId01",
  "paymentId": "20240101123456789XXXX",
  "paymentAmount": {
    "value": "4200",
    "currency": "SGD"
  },
  "paymentCreateTime": "2024-01-01T00:00:00+08:00",
  "paymentTime": "2024-01-01T00:01:00+08:00",
  "paymentMethodType": "SHOPEEPAY_SG"
}

Common questions

Q: How often should I call the inquiryPayment API?

A: Call the inquiryPayment API constantly with an interval of 2 seconds until the final payment result is obtained or an asynchronous payment result notification is received.

Q: What are the key parameters in the notification that I need to use?

A: Pay attention to these key parameters:

  • result: represents the result of this inquiryPayment API call, the result of the order needs to be judged according to paymentStatus:
    • SUCCESS and FAIL represent the final result;
    • PROCESSING represents the processing.
  • paymentAmount: indicates the payment amount.

Best practice

Follow these best practices to improve integration efficiency.

Customize the payment timeout

In the Checkout Payment scenario, the default timeout on the Antom side is 14 minutes. After the payment timeout, the buyer can't continue to pay. You can specify the timeout time through the paymentExpireTime parameter of the pay API. After exceeding the specified time, the buyer cannot scan the code or log in to the checkout page.

The following sample code shows how to specify the paymentExpireTime parameter in the pay API:

Web sample code

copy
{
  "env": {
    "terminalType": "WEB"
  },
  "order": {
    "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
    "orderAmount": {
      "currency": "SGD",
      "value": "4200"
    },
    "orderDescription": "antom testing order",
    "referenceOrderId": "referenceOrderId01"
  },
  "paymentAmount": {
    "currency": "SGD",
    "value": "4200"
  },
  "paymentExpiryTime": "2024-01-01T00:30:00+08:00",
  "paymentMethod": {
    "paymentMethodType": "SHOPEEPAY_SG"
  },
  "paymentNotifyUrl": "https://www.yourNotifyUrl.com",
  "paymentRedirectUrl": "https://www.yourMerchantWeb.com",
  "paymentRequestId": "paymentRequestId01",
  "productCode": "CASHIER_PAYMENT"
}

If you specify paymentExpireTime, the valid time that the buyer can pay becomes the time in paymentExpireTime.

If the buyer pays after this time, there are two types of experience:

  • The buyer is unable to complete the payment.
  • The buyer receives a refund immediately after making the payment.

Obtain the payment continuation URL

Antom provides direct connections to a variety of payment methods. In some situations, processing delays in the payment method's order interface may prevent the response from being received in a timely manner. As a result, the buyer might not be redirected to the payment continuation URL, potentially reducing the payment success rate and degrading the user experience.

It is recommended to set the interface timeout to 10s to increase the response success rate. For the case of calling pay timeout, it is recommended to launch the original request to retry and get the payment continuation URL again.

Optimize the payment experience Only for Web

For transactions initiated via PC, certain payment methods allow buyers to complete their purchase using a scanned QR code or a password, eliminating the need for redirection. When the buyer selects this payment method, the corresponding code from the API response is rendered directly on your page. This allows for QR codes or passwords to be presented to the buyer promptly, streamlining the payment process and enhancing user experience.

The QR code returned by Antom will not be refreshed automatically. When displaying the QR code, add expireTime in the API response to display the timeout time. When displaying the passphrase, the copy function of the passphrase is enabled, allowing the buyer to conveniently paste the passphrase into the payment method app.

Redirect to the merchant result page

  1. Not every payment method that launches an app will redirect to the merchant-specified result page upon completion. Some payment methods are not supported, such as Kakaopay (KakaoTalk).
  2. If the buyer has multiple browsers installed, the post-payment redirect to the HTTPS result page will occur in their default browser. However, this limitation does not apply to scheme-specific URLs, which are unaffected by the buyer's choice of browser.

Suggestions on processing logic for merchant results pages

  1. Handling redirection issues

When the buyer has successfully completed a payment but encounters issues redirecting to the paymentRedirectUrl that you specified, whether due to network issues or payment method limitations, take note of the following two points:

    • You cannot use the client redirection as the basis for determining the success of the payment.
    • If the paymentRedirectUrl of the payment method page fails to redirect to the merchant page, the buyer may manually click the original merchant page. To prevent buyers from mistakenly attempting to pay for the order again, it is recommended to implement a pop-up window on the original merchant page. This pop-up should allow for transaction result inquiries. When buyers click on this pop-up, it should display the transaction outcome, thereby preventing any duplicate payment attempts.
  1. Trigger order result query after redirection

If the merchant side is pulled up after triggering a call to the inquiryPayment API, then the following different results are suggested:

    • Successful payment: The page will display the content related to the shipment after successful payment.
    • Payment Failure: Indicate that the payment failed and offer guidance for retrying the payment to encourage order completion.
    • Payment processing: Display the landing effect and implement a brief pause of 3-5 seconds before querying the server again for the payment outcome. If the result remains inconclusive (neither success nor failure), it is recommended to display "order processing" or "order management portal to view the final result.". Refrain from attributing the delay to “network processing”.

Payment failed retry

When a payment attempt for an order fails, and the buyer can retry payment for the same order, we recommend adhering to the following integration process for a seamless experience:

  1. In the payment request, set the referenceOrderId to the order ID and the paymentRequestId to the payment order ID.
  2. If payment needs to be retried for the same order, check the order status first. If payment has already succeeded, display "Completed Payment" to the buyer. If not, call the pay API again to obtain a new normalUrl for redirection. Though referenceOrderId remains the same since it's the same order, you must update the paymentRequestId for the subsequent payment attempt.
  3. Verify that each merchant order only has one successful payment associated with it. If multiple successful payments are detected for a single order, call the cancel API to initiate a refund for the buyer.
  4. For payment methods that do not offer refunds, it is recommended to cancel the initial payment before initiating a new one.

Obtain payment results

In order to guarantee the stable acquisition of payment results and avoid the situation where the buyer's payment is completed but you do not get the payment result. It is recommended that you check the payment results at the following stages:

  1. When the merchant payment result page is displayed.
  2. Before shipping to the buyer.
  3. When you receive the Antom reconciliation file.

Open payment method URL Only for App

Payment method features

Link type

Solution

Advantages and disadvantages

Only the app checkout is supported

applinkUrl

Redirect to payment method app checkout:

iOS calls the openUrl method, and Android calls the startActivity method.

Advantages:

  1. Complete the payment in the payment methods app.
  2. No need to deal with the exception that the buyer does not have the payment method app installed.

normalUrl

Redirect to payment method app checkout:

iOS calls the openUrl method, and Android calls the startActivity method.

Advantages:

  1. Complete the payment in the payment methods app.
  2. No need to deal with the exception that the buyer does not have the payment method app installed.

Disadvantage:

  1. During the payment process, the browser will be pulled up and then redirected to the payment method app.

schemeUrl

Redirect to payment method app checkout:

iOS calls the openUrl method, and Android calls the startActivity method.

Advantage:

  1. Complete the payment in the payment methods app.

Disadvantage:

  1. Handle the exception that the buyer does not install the payment method app.

Only the mobile website checkout is supported

normalUrl

Open the checkout URL in WebView.

Advantage:

  1. The ordering, payment, and delivery processes are all completed within the merchant's app.

Support both app and mobile website checkout

applinkUrl

iOS calls the openUrl method, and Android calls the startActivity method.

Advantages:

  1. Complete the payment in the payment methods app.
  2. No need to deal with the exception that the buyer does not have the payment method app installed.

Disadvantage:

  1. If the buyer does not install the payment method app, it will be downgraded to the mobile website checkout, and the payment process will be completed in the system browser.

normalUrl

Open the checkout URL in WebView.

Advantage:

  1. The ordering, payment, and delivery processes are all completed within the merchant's app.

Disadvantage:

  1. Unable to use app checkout, poor payment experience.

schemeUrl

iOS calls the openUrl method, and Android calls the startActivity method.

Advantage:

  1. Complete the payment in the payment methods app.

Disadvantages:

  1. Handle the exception that the buyer does not install the payment method app.
  2. The mobile website checkout cannot be used, and the transaction cannot be restored if the app is not installed.

Handle a disambiguation box in Android

Refer to Google documentation for more information.

Use WebView to load the order page

To provide an excellent user experience, you can use WebView to load the order page in the client. After clicking the order, you can directly redirect to the mobile application that supports the payment method to complete the payment, you can refer to the JavaScript code binding to the mobile client code to realize this interactive experience.