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
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.
Payment flow
For each payment method, the payment flow composed of the following steps:
- The buyer enters the checkout page.
- The merchant server initiates a payment request through payment method, amount, currency, and other information.
- The merchant client redirects to the URL returned by the payment request.
- The merchant server receives payment result notification.
Quick start
Start your integration by taking the following steps:
Step 1: (Optional) Add a list of payment methods
Add the logo and name of the payment methods to be integrated to the payment method list on the payment page for buyers to select. You can obtain the logo and name in one of the following two ways:
- Contact Antom Technical Support to obtain. 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:
Step 2: Invoke the pay API and get the payment continuation URL
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
Antom provides server-side API libraries for multiple languages. The following code uses Java as an example. You need to install Java 6 or higher.
Install an API library
You can find the latest version on GitHub.
<dependency>
<groupId>com.alipay.global.sdk</groupId>
<artifactId>global-open-sdk-java</artifactId>
<version>2.0.21</version>
</dependency>
Initialize the request instance
String merchantPrivateKey = "YOUR PRIVATE KEY";
String alipayPublicKey = "ALIPAY PUBLIC KEY"
AlipayClient defaultAlipayClient = new DefaultAlipayClient(EndPointConstants.SG,
merchantPrivateKey, alipayPublicKey);
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 |
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 whole parameters, refer to pay API.
The following sample code is used for initiating a payment:
AlipayPayRequest alipayPayRequest = new AlipayPayRequest();
alipayPayRequest.setClientId(CLIENT_ID);
alipayPayRequest.setPath("/ams/api/v1/payments/pay");
alipayPayRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);
// replace to your paymentRequestId
alipayPayRequest.setPaymentRequestId("paymentRequestId01");
// set amount
Amount amount = new Amount();
amount.setCurrency("HKD");
amount.setValue("100");
alipayPayRequest.setPaymentAmount(amount);
// set paymentMethod
PaymentMethod paymentMethod = new PaymentMethod();
paymentMethod.setPaymentMethodType("ALIPAY_HK");
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.WAP);
env.setClientIp("114.121.121.01");
env.setOsType(OsType.ANDROID);
alipayPayRequest.setEnv(env);
// replace to your notify url
alipayPayRequest.setPaymentNotifyUrl("http://www.yourNotifyUrl.com");
// replace to your redirect url
alipayPayRequest.setPaymentRedirectUrl("http://www.yourRedirectUrl.com");
//do the Payment
AlipayPayResponse alipayPayResponse = null;
try {
alipayPayResponse = defaultAlipayClient.execute(alipayPayRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// handle error condition
}
The following code shows a sample of the request message:
{
"paymentNotifyUrl": "http://www.yourNotifyUrl.com",
"paymentRequestId": "paymentRequestId01",
"env": {
"terminalType": "WEB",
"clientIp": "114.121.121.01"
},
"paymentAmount": {
"currency": "HKD",
"value": "100"
},
"productCode": "CASHIER_PAYMENT",
"paymentRedirectUrl": "http://www.yourRedirectUrl.com",
"paymentMethod": {
"paymentMethodType": "ALIPAY_HK"
},
"order": {
"orderAmount": {
"currency": "HKD",
"value": "100"
},
"referenceOrderId": "referenceOrderId01",
"orderDescription": "antom test order"
}
}
FAQs
How to set the value of terminalType?
- 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 parametersANDROID
orIOS
according to the buyer's mobile phone. - If the buyer initiates a transaction from app, the terminalType needs to be specified as
APP
.
Can Chinese characters be used in the request?
Do not use Chinese characters in the request field to avoid incompatible payment methods, such as QRIS and Mastercard.
How to set the payment result notification address?
Antom will send the payment result through the notifyPayment, which you can specify in the pay API via the paymentNotifyUrl parameter. If the address of each payment is the same, you can also configure it in the Antom Dashboard. If you have configured the address and set the parameter in the API, Antom will use the address set in the API.
Receive a payment response
The following code is the sample response:
{
"normalUrl": "https://open-sea.alipayplus.com/api/open/v1/ac/cashier/self/codevalue/checkout.htm?codeValue=https%3A%2F%2Fglobal.alipay.com%2F281002040090bbmmzTC4BzSex92tUglv31de",
"orderCodeForm": {
"codeDetails": [
{
"codeValue": "https://global.alipay.com/281002040090bbmmzTC4BzSex92tUglv31de",
"displayType": "TEXT"
},
{
"codeValue": "https://global.alipay.com/merchant/order/showQrImage.htm?code=https%3A%2F%2Fglobal.alipay.com%2F281002040090bbmmzTC4BzSex92tUglv31de&picSize=L",
"displayType": "BIGIMAGE"
},
{
"codeValue": "https://global.alipay.com/merchant/order/showQrImage.htm?code=https%3A%2F%2Fglobal.alipay.com%2F281002040090bbmmzTC4BzSex92tUglv31de&picSize=M",
"displayType": "MIDDLEIMAGE"
},
{
"codeValue": "https://global.alipay.com/merchant/order/showQrImage.htm?code=https%3A%2F%2Fglobal.alipay.com%2F281002040090bbmmzTC4BzSex92tUglv31de&picSize=S",
"displayType": "SMALLIMAGE"
}
],
"expireTime": "2024-01-15T01:34:45-08:00"
},
"paymentActionForm": "{\"method\":\"GET\",\"paymentActionFormType\":\"RedirectActionForm\",\"redirectUrl\":\"https://open-sea.alipayplus.com/api/open/v1/ac/cashier/self/codevalue/checkout.htm?codeValue=https%3A%2F%2Fglobal.alipay.com%2F281002040090bbmmzTC4BzSex92tUglv31de\"}",
"paymentAmount": {
"currency": "HKD",
"value": "100"
},
"paymentCreateTime": "2024-01-15T01:20:46-08:00",
"paymentId": "20240115194010800100188640298283440",
"paymentRequestId": "PAY_20240115172044263",
"redirectActionForm": {
"method": "GET",
"redirectUrl": "https://open-sea.alipayplus.com/api/open/v1/ac/cashier/self/codevalue/checkout.htm?codeValue=https%3A%2F%2Fglobal.alipay.com%2F281002040090bbmmzTC4BzSex92tUglv31de"
},
"result": {
"resultCode": "PAYMENT_IN_PROCESS",
"resultMessage": "payment in process",
"resultStatus": "U"
}
}
FAQs
What is the normalUrl?
For web 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.
What is the paymentId?
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
The merchant server passes the normalUrl to the client, and the client page handles the redirection process to normalUrl.
FAQs
How to handle different payment experiences?
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
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.
FAQs
What does the payment results page show?
In the case of successful payment or failed payment, it can redirect to the result page from the payment method side.
Does redirecting to the results page mean the payment was successful?
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 results
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 the payment result actively.
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:
{
"notifyType": "PAYMENT_RESULT",
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "success"
},
"paymentRequestId": "paymentRequestId01",
"paymentId": "2020010123456789XXXX",
"paymentAmount": {
"value": "100",
"currency": "HKD"
},
"paymentCreateTime": "2020-01-01T12:01:00+08:30",
"paymentTime": "2020-01-01T12:01:01+08:30"
}
The following is the code that verifies and returns the notification:
@RequestMapping(path = "/payResult", method = RequestMethod.POST)
public ResponseEntity<AlipayResponse> paymentNotifyProcessor(HttpServletRequest request,
@RequestBody String body) {
// retrieve the required parameters from the request header.
String requestTime = request.getHeader("request-time");
String clientId = request.getHeader("client-id");
String rawSignature = request.getHeader("signature");
String signature = "";
// get valid part from raw signature
if(rawSignature==null||rawSignature.isEmpty()){
throw new RuntimeException("empty notify signature");
}else {
String[] parts = rawSignature.split("signature=");
if (parts.length > 1) {
signature = parts[1];
}
}
// verify payment result notify's signature
boolean verifyResult = SignatureTool.verify(request.getMethod(), request.getRequestURI(),
clientId, requestTime, body, signature,
ALIPAY_PUBLIC_KEY);
if (!verifyResult) {
throw new RuntimeException("Invalid notify signature");
}
// update the record status with notify result
// respond the server that we accept the notify
Result result = new Result("SUCCESS", "success", ResultStatusType.S);
AlipayResponse response = new AlipayResponse();
response.setResult(result);
return ResponseEntity.ok().body(response);
}
The following is the notification response sample code:
{
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "Success"
}
}
FAQs
When will the notification be sent?
After the payment is completed, Antom will send the asynchronous notification to you in 3~5s. If the payment is not completed, you need to wait for Antom to close the order before sending the asynchronous notification. The time to close the order is different for different payment methods, generally the default is 14 minutes.
Will the asynchronous notification be re-sent?
If you receive an asynchronous notification from Antom, you are required to return the response in the Sample code format. If you do not respond to the asynchronous notification as required, or the asynchronous notification is not delivered due to network reasons, the notification will be automatically resent within 24 hours. 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.
Do I need to countersign the response?
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.
How do I understand the meaning of the following key fields?
- 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.
- paymentAmout: Indicates the payment amount.
Inquire about the payment result
Initiating a query request will involve the following parameters.
Parameter name | is required? | Description |
paymentRequestId | No | The payment request number generated by the merchant |
The following is the sample code:
AlipayClient defaultAlipayClient = new DefaultAlipayClient(EndPointConstants.SG,
merchantPrivateKey, alipayPublicKey);
AlipayPayQueryRequest alipayPayQueryRequest = new AlipayPayQueryRequest();
alipayPayQueryRequest.setClientId(CLIENT_ID);
alipayPayQueryRequest.setPath("/ams/sandbox/api/v1/payments/inquiryPayment");
alipayPayQueryRequest.setPaymentRequestId("paymentRequestId01");
AlipayPayQueryResponse alipayPayQueryResponse;
try {
alipayPayQueryResponse = defaultAlipayClient.execute(alipayPayQueryRequest);
} catch (AlipayApiException e) {
String errorMsg = e.getMessage();
// handle error condition
}
Obtain the response code
{
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "Success"
},
"paymentStatus": "SUCCESS",
"paymentRequestId": "paymentRequestId01",
"paymentId": "2019060811401080010018882020035XXXX",
"paymentAmount": {
"value": "100",
"currency": "HKD"
},
"paymentCreateTime": "2019-06-01T12:01:01+08:30",
"paymentTime": "2019-06-01T12:01:01+08:30",
"transactions": null
}
FAQs
How do I understand the meaning of the following key fields?
- result: the result of the API call. It only indicates the result of the inquiryPayment API call. The order result should be determined based on the paymentStatus.
SUCCESS
andFAIL
indicate final results, whilePROCESSING
indicates that the transaction is still in progress. - paymentAmount: amount verification. If there is a need for amount verification, this field can be used.
How frequently should I initiate the query?
It is recommended to initiate a round-robin query at an interval of 2 seconds until either the final payment result is retrieved or an asynchronous payment notification is received.
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 mins, and after the payment timeout, the buyer can't continue to pay. To define the timeout time, you can specify through the paymentExpireTime parameter of the pay API. After exceeding the specified time, the buyer can not 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:
{
"env": {
"terminalType": "WEB"
},
"order": {
"orderAmount": {
"currency": "CNY",
"value": "1314"
},
"orderDescription": "Cappuccino #grande (Mika's coffee shop)",
"referenceOrderId": "ORDER_0517884936248XXXX"
},
"paymentAmount": {
"currency": "CNY",
"value": "1314"
},
"paymentMethod": {
"paymentMethodType": "ALIPAY_CN"
},
"paymentExpiryTime":"2024-01-20T08:51:06+08:00",
"paymentNotifyUrl": "https://www.gaga.com/notify",
"paymentRedirectUrl": "imeituan://",
"paymentRequestId": "iJ9lsVgTx8pX7qJpvW6rfqEE2Kdv9M3lgL8e1999ydfz52uMSqwvT3qXYw8IFBYt",
"productCode": "CASHIER_PAYMENT",
"settlementStrategy": {
"settlementCurrency": "USD"
}
}
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 side is directly connected to many payment methods. There is a part of the payment method order interface time-consuming situation, which may lead to your failure to get the response. The buyer can not redirect to the payment continuation URL, affecting the success rate of payment and user experience.
It is recommended to set the interface timeout to 10s to ensure the success rate of getting the response. 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
Some payment methods support buyers to pay by scanning the code or password on PC, and you can target such payment methods without redirection. When the buyer selects this payment method, the code value in the API response will be rendered directly on the merchant's page for displaying the QR code or password, which reduces the page redirect and improves the 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 realized, which makes it easy for buyers to paste the payment into the payment method app.
Redirect to the merchant result page
- Not all payment methods pull up the app can redirect to your specified address, some payment methods are not supported, such as Kakaopay (KakaoTalk).
- If the buyer has installed more than one browser. Then when redirecting to the https result page address after payment completion, it will only redirect to the default browser, but the scheme address is not affected.
Suggestions on processing logic for merchant results pages
- Client redirection abnormality
If the buyer pays successfully, the buyer may not be able to redirect to the paymentRedirectUrl that you specified due to network reasons or the limitations of the payment method itself, and the following two points should be noted in this case:
- 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. Therefore, in order to avoid the original merchant page manually cutting back to the payment page, leading the buyer to initiate payment of the order again, it is recommended to add a pop-up window for querying the transaction results after redirecting on the original merchant's order page, when the buyer clicks on the pop-up window to display the result of the order, avoiding the payment of the order again.
- 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: the page displays the payment failure, and it is recommended to guide the re-payment;
- Payment processing: the page displays the landing effect, waits for 3-5s, and at the same time, queries the server-side payment results, if it still does not return successful or failed final results, it is recommended to display the "order processing" or "order management portal to view the final results"; it is not recommended to display the "network processing". If there is still no result, we suggest displaying "order processing" or going to "order management portal for final result".
Payment failed retry
For the same order on the merchant side, if the first payment is not completed and the buyer is supported to initiate the payment again, then it is recommended that you follow the integration steps below:
- In the payment request, set the referenceOrderId to the order ID and the paymentRequestId to the payment order ID.
- When the same order initiates payment again, the order status will be prioritized, and if the payment is successful, the buyer will be shown the "completed payment", and if the payment is not successful, the pay API will be called again to get a new normalUrl to redirect. Note that since it is the same order, the referenceOrderId can be kept unchanged, while the corresponding new payment order needs to update the paymentRequestId.
- The merchant side needs to check that there is only one successful payment order for a merchant order, if there is more than one successful payment order, then it needs to call the cancel API to refund the buyer.
- For payment methods that do not support refunds, it is recommended to cancel the first payment order before initiating a new payment.
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:
- When the merchant payment result page is displayed.
- Before shipping to the buyer.
- When you receive the Antom reconciliation file.
Open payment method URL
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:
|
normalUrl | Redirect to payment method app checkout: iOS calls the openUrl method, and Android calls the startActivity method. | Advantages:
Disadvantage:
| |
schemeUrl | Redirect to payment method app checkout: iOS calls the openUrl method, and Android calls the startActivity method. | Advantage:
Disadvantage:
| |
Only the H5 checkout is supported | normalUrl | Open the checkout URL in webview. | Advantage:
|
Support both app and H5 checkout | applinkUrl | iOS calls the openUrl method, and Android calls the startActivity method. | Advantages:
Disadvantage:
|
normalUrl | Open the checkout URL in webview. | Advantage:
Disadvantage:
| |
schemeUrl | iOS calls the openUrl method, and Android calls the startActivity method. | Advantage:
Disadvantages:
|
FAQs
What to do when encountering a disambiguation box in Android?
Refer to Google documentation for more information.
How to use WebView to load the order page?
To provide an excellent user experience, you can use the 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.