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

APM payments (Web/WAP)

The Antom SDK is a pre-built UI component that simplifies the process of integrating Antom payment services. This component offers a simple and quick way to integrate all payment methods supported by Antom, including credit cards, digital wallets, bank transfers, online banking, and more.

The SDK component can automatically adapt to the buyer's device and location, performing tasks such as information collection, redirection, switching between apps, displaying QR codes, and more based on the characteristics of the payment method. You can easily provide a comprehensive payment solution on your website or application, saving a significant amount of time and resources required to build each payment interface and process.

User experience

The following figures show the user journey of paying on a shopping website or mobile web app:

Web user experience

4个.jpg

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

For each payment method, the payment flow is composed of the following steps:

333.webp

  1. The buyer lands on the checkout page.
  2. Create the createPaymentSession request
    After the buyer selects a payment method and submits the order, you can obtain the payment session by calling the createPaymentSession interface.
  3. Invoke the client SDK
    On the client side, invoke the SDK through the payment session. The SDK will handle information collection, redirection, app invocation, QR code display, verification, and other processes based on the payment method's characteristics.
  4. Get the payment result
    Obtain the payment result by using one of the following two methods:
    • Asynchronous Notification: Specify the paymentNotifyUrl in the createPaymentSession interface to set the address for receiving asynchronous notifications. When the payment is successful or expires, Antom will use notifyPayment to send asynchronous notifications to you.
    • Synchronous Inquiry: Call the inquiryPayment interface to check the payment status.

Integration steps

Start your integration by taking the following steps:

  1. Create a payment session
  2. Create and invoke the SDK
  3. Obtain payment result

Step 1: Create a payment session Server-side

When a buyer selects a payment method provided by Antom, you need to collect key information such as the payment request ID, order amount, payment method, order description, payment redirect URL, and payment result notification URL, call the createPaymentSession API to create a payment session, and return the payment session to the client.

Antom provides server-side API libraries for multiple languages. The following codes use Java as an example. You need to install Java 6 or higher.

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

Create a singleton resource to make a request to Antom.

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 session

Creating a payment session includes the following parameters:

Parameter name

Required

Description

productCode

The value is fixed to CASHIER_PAYMENT.

paymentRequestId

The unique ID generated by the merchant, a new ID is required every time a payment is initiated.

paymentAmount

Payment amount, should be set according to the smallest unit of the order currency, e.g. CNY for cents, KRW for dollars.

paymentMethod

Payment method enumeration

paymentRedirectUrl

Merchant's payment result page, according to the server-side results, not a fixed success page.

order

Order information, including order amount, order ID, and order description on the merchant side.

paymentNotifyUrl

Payment result notification address, which can be passed in through the interface or set as a fixed value through the portal.

settlementStrategy

Settlement currency of the payment, if the business has signed more than one settlement currency, you need to specify it in the interface.

The above parameters are the basic parameters for creating a payment session, for full parameters and additional requirements for certain payment methods please refer to createPaymentSession (Checkout Payment).

Sample code of calling the createPaymentSession API

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

copy
private static void createPaymentSession() {
    AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
    alipayPaymentSessionRequest.setProductCode(ProductCodeType.CASHIER_PAYMENT);

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

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

    // set paymentMethod
    PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("SHOPEEPAY_SG").build();
    alipayPaymentSessionRequest.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();
    alipayPaymentSessionRequest.setOrder(order);

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

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

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

The following code shows a sample of the request message:

copy
{
  "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"
}

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

  • paymentSessionData: the payment session to be returned to the frontend
  • paymentSessionExpiryTime: the expiration time of the payment session.

copy
{
  "paymentSessionData": "gM5Y/Go6+IXMPSOZrYtukCdodtwxuSFsn1vRPSB8CzkDqlb1g2W7dDipOkoMRs/x2W7g7qVhjEM7RUGroIT8Cw==&&SG&&188&&eyJhY3Rpb24iOnsiYXBwIjp7fSwibmVlZFZlcmlmeUFuZFJlc3VtZSI6ZmFsc2UsInNraXBTZGtRdWVyeSI6ZmFsc2UsIndhcCI6e30sIndlYiI6e319LCJjbGllbnRJZCI6IlNBTkRCT1hfNVlCWjBMMlpIUjhSMDg5NzgiLCJleHRlbmRJbmZvIjoie1widmVyc2lvbk1hcFwiOntcIndlYlwiOntcIjEuMS4wXCI6e1widGFyZ2V0V2ViVmVyaXNvblwiOlwiMS4xLjBcIn0sXCIxLjIuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMi4wXCJ9fSxcImlPU1wiOntcIjEuMS4wXCI6e1widGFyZ2V0V2ViVmVyaXNvblwiOlwiMS4xLjBcIn0sXCIxLjIuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMi4wXCJ9fSxcIkFuZHJvaWRcIjp7XCIxLjEuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMS4wXCJ9LFwiMS4yLjBcIjp7XCJ0YXJnZXRXZWJWZXJpc29uXCI6XCIxLjIuMFwifX19fSIsInBheW1lbnRTZXNzaW9uQ29uZmlnIjp7InBheW1lbnRNZXRob2RDYXRlZ29yeVR5cGUiOiJBUE0iLCJwcm9kdWN0U2NlbmUiOiJDQVNISUVSX1BBWU1FTlQiLCJwcm9kdWN0U2NlbmVWZXJzaW9uIjoiMS4wIn19",
  "paymentSessionExpiryTime": "2024-01-01T00:00:00+08:00",
  "paymentSessionId": "gM5Y/Go6+IXMPSOZrYtukCdodtwxuSFsn1vRPSB8Czn6HfgqNzo2ogbIk1NUQS35",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}

Common questions

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.

Step 2: Create and invoke the SDK Client-side

The Antom SDK is a component used for handling payment processes. You initiate the SDK by creating a payment session to collect information, switch between apps, and display QR codes based on the payment method specified in createPaymentSession API.

After the buyer selects a payment method on the page, you need to create the SDK and initiate it with a payment session.

Install

Before beginning the integration, make sure that you have completed the following environment preparations:

  • Properly handle compatibility issues: Provide corresponding polyfills for Internet Explorer and other old browser versions. We recommend that you use babel-preset-env to address browser compatibility issues when you build a project.
  • Use the following recommended browser versions:
    • For mobile browsers:
      • iOS 11 and later.
      • Android 5.0 and later.
    • For computer browsers, use the following recommended versions:

imageEdge

Last 2 versions

imageFirefox

Last 2 versions

imageChrome

Last 2 versions

imageSafari

Last 2 versions

imageOpera

Last 2 versions

imageElectron

Last 2 versions

You can integrate the SDK resource package via CDN or npm.

copy
<script src="https://sdk.marmot-cloud.com/package/ams-checkout/1.16.0/dist/umd/ams-checkout.min.js"></script>
copy
npm install @alipay/ams-checkout

Instantiate the SDK

Create the SDK instance by using the AMSCashierPayment and specify basic configurations. Configuration objects includes the following parameters:

Parameter name

Required

Description

environment

It is used to pass in environmental information. Valid values are:

  • sandbox: Sandbox environment
  • prod: Production environment

locale

It is used to pass in language information. Valid values are listed as follows. You can choose the value to pass based on the region of the payment method. If other values are passed, the local language is used by default:

  • en_US: English
  • pt_BR: Portuguese
  • ko_KR: Korean
  • es_ES: Spanish
  • ms_MY: Malay
  • in_ID: Indonesian
  • tl_PH: Tagalog
  • th_TH: Thai
  • vi_VN: Vietnamese
  • fr_FR: French
  • nl_NL: Dutch
  • it_IT: Italian
  • de_DE: German
  • zh_CN: Simplified Chinese
  • zh_HK: Traditional Chines

analytics

It is used to configure and analyze data. It contains a value below:

  • enabled: Optional Boolean. It defaults to true, which indicates that you allow the SDK to upload and analyze operational data to deliver a better service. If you do not allow the data to be uploaded and analyzed, specify it as false.

onLog

It is a callback method that is used to generate the error information about logs and API exceptions during the execution of the SDK.

onEventCallback

A callback function returns a specific event code when a payment event happens during SDK runtime, like payment result or a form submission error. For further information, please refer to the References.

The following sample code shows how to obtain the browser language:

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

The following sample code shows how to instantiate the SDK:

copy
// import { AMSCashierPayment } from '@alipay/ams-checkout'

const checkoutApp = new window.AMSCashierPayment({
  environment: "sandbox",
  locale: "en_US",
  onLog: ({code, message}) => {},
  onEventCallback: ({code, message}) => {},
});

//Request the server to get paymentSessionData

Invoke the SDK

Use the createComponent function in the instance object to create a payment component:

Parameter name

Required

Description

sessionData

Create a configuration object by using the sessionData parameter: Pass the complete data in the paymentSessionData parameter obtained in the response through the createpaymentSession (Checkout Payment) API to the sessionData parameter.

appearance

Customized appearance theme configuration, and it contains the following child parameters:

  • showLoading: Optional. Boolean type. The default value is true, which shows the default loading animation. If you don't use the default loading animation, you need to specify this value as false. Refer to Other Advanced Features for more details.

The following sample code shows how to call createComponent:

copy
async function create(sessionData) {
  await checkoutApp.createComponent({ 
    sessionData: sessionData, 
    appearance:{
      showLoading: true, // Set as true by default to enable the default loading pattern
    }
  });
}

Call the unmount method to free SDK component resources in the following situations:

  • When the buyer switches views to exit the checkout page, free the component resources created in the createPaymentSession.
  • When the buyer initiates multiple payments, free the component resources created in the previous createPaymentSession.
  • When the buyer completes the payment and sets notRedirectAfterComplete to true, free the component resources after obtaining specific payment result codes.
copy
// Free SDK component resources
checkoutApp.unmount();

Common questions

Q: What can I do when I receive SDK_CREATEPAYMENT_PARAMETER_ERROR?

A: When you receive this event code, check if the sessionData passed in is correct and complete.

Q: What can I do when I receive SDK_PAYMENT_ERROR or a rendering view error occurred?

A: Check the network request for any exceptions during interface initialization, such as network timeouts. Ensure that the environment for creating payment session request is consistent with the environment used for SDK instantiation. Check whether the parameters in the createPaymentSession API are passed correctly. If the interface exceptions persist, feel free to contact us for further troubleshooting.

Display payment results

You can use the payment component to handle payment methods which require a redirect (asynchronous payments), and those that do not (synchronous payments).

Redirect payment

The payment process of some payment methods needs to leave the original web page and jump to the organization's page to complete the payment, such as the payment method of online banking. In this case, the buyer is redirected to the paymentRedirectUrl that you provided in createPaymentSession API after completing the payment. You can obtain the payment result by active query and and show it to the buyer in that URL.

Non-redirect payment

For payment without redirection, the payment result will be given through the onEventCallback function. The payment result here is only for front-end display, and the final order status is subject to the server side.

You need to customize the processing flow you want for each payment result through the data in the result of onEventCallback.

The following are the possible event codes of the payment result returned by onEventCallback.

Event code

Message

Solution

SDK_PAYMENT_SUCCESSFUL

Payment was successful.

Suggest redirecting buyers to the payment result page.

SDK_PAYMENT_PROCESSING

Payment was being processed.

We suggest that you check the value of paymentResultCode in the onEventCallback result data for details. Guide buyers to retry the payment based on the provided information.

SDK_PAYMENT_FAIL

Payment failed.

We suggest that you check the value of paymentResultCode in the onEventCallback result data for details. Guide buyers to retry the payment based on the provided information.

SDK_PAYMENT_CANCEL

The buyer exits the payment page without submitting the order.

The SDK can be re-invoked with a paymentSessionData within the validity period; if it has expired, the paymentSessionData needs to be re-requested.

SDK_PAYMENT_ERROR

The payment status was abnormal.

We suggest that you check the value of paymentResultCode in the onEventCallback result data for details. Guide buyers to retry the payment based on the provided information.

The following sample code shows how to process the onEventCallback:

copy
function onEventCallback({ code, result }) {
  switch (code) {
    case 'SDK_PAYMENT_SUCCESSFUL':
      // Payment was successful. Redirect buyers to the payment result page.
      break;
    case 'SDK_PAYMENT_PROCESSING':
      console.log('Check the payment result data', result);
      // Payment was being processed. Guide buyers to retry the payment based on the provided information.
      break;
    case 'SDK_PAYMENT_FAIL':
      console.log('Check the payment result data', result);
      // Payment failed. Guide buyers to retry the payment based on the provided information.
      break;
    case 'SDK_PAYMENT_CANCEL':
      // Guide buyers to retry the payment.
      break;
    case 'SDK_PAYMENT_ERROR':
      console.log('Check the payment result data', result);
      // The payment status was abnormal. Guide buyers to retry the payment based on the provided information.
      break;
    default:
      break;
  }
}

Step 3: Obtain payment result Server-side

After the buyer completes the payment or the payment times out, Antom sends the corresponding payment results to you through server interactions, you can obtain the payment result by one of the following methods:

  • Receive the asynchronous notification
  • Inquire about the result

Receive the asynchronous notification

When the payment reaches a final status of success or failure, Antom sends an asynchronous notification to the paymentNotifyUrl specified in the createPaymentSession API through the notifyPayment API. When you receive the notification from Antom, you are required to return a response as instructed in Requirements.

Antom allows you to specify the URL in the paymentNotifyUrl parameter within the createPaymentSession API. If the URL for each payment is the same, you can also configure it in the Antom Dashboard.

The following code shows a sample of the notification request:

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.

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

You can call the inquiryPayment API to initiate a query on the result of an order.

Parameter name

Required

Description

paymentRequestId

The payment request ID generated by the merchant.

The parameter is not a full set of parameters, please refer to the inquiryPayment API for full set of parameters and additional requirements for certain payment methods.

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 a sample of the request message:

copy
{
  "paymentRequestId": "paymentRequestId01"
}

The following code shows a sample of the response message:

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.

Sample codes

Full sample codes for front-end:

copy
// Step 1: Instantiate the SDK and handle the callback event.
const onEventCallback = function({ code, result }) {
  switch (code) {
    case 'SDK_PAYMENT_SUCCESSFUL':
      // Payment was successful. Redirect buyers to the payment result page.
      break;
    case 'SDK_PAYMENT_PROCESSING':
      console.log('Check the payment result data', result);
      // Payment was being processed. Guide buyers to retry the payment based on the provided information.
      break;
    case 'SDK_PAYMENT_FAIL':
      console.log('Check the payment result data', result);
      // Payment failed. Guide buyers to retry the payment based on the provided information.
      break;
    case 'SDK_PAYMENT_CANCEL':
      // Guide buyers to retry the payment.
      break;
    case 'SDK_PAYMENT_ERROR':
      console.log('Check the payment result data', result);
      // The payment status was abnormal. Guide buyers to retry the payment based on the provided information.
      break;
    default:
      break;
  }
}
const checkoutApp = new window.AMSCashierPayment({
  environment: "sandbox",
  locale: "en_US",
  onLog: ({code, message}) => {},
  onEventCallback: onEventCallback,
});
// Handle payment button events.
document
  .querySelector("#your form id")
  .addEventListener("submit", handleSubmit);

async function handleSubmit() {
  // Step 2: The server calls createPaymentSession API to obtain paymentSessionData.
  async function getPaymentSessionData() {
    const url = "Fill in the server address";
    const config = {
      // Fill in the request configuration.
    };
    const response = await fetch(url, config);
    // Obtain the value of the paymentSessionData parameter in the response.
    const { paymentSessionData } = await response.json();
    return paymentSessionData;
  }
  const paymentSessionData = await getPaymentSessionData();

  // Step 3: Create rendering components.
  await checkoutApp.createComponent({ 
    sessionData: paymentSessionData, 
    appearance:{
      showLoading: true, // Set as true by default to enable the default loading pattern.
    }, 
  });
}

Event codes

You might see two types of event codes:

  • Status codes: Returned by onEventCallback during the component's runtime lifecycle.
  • Error codes: Returned by onEventCallback or onError during the component initialization phase.

Type

Code

Description

Further action

Status codes

SDK_START_OF_LOADING

The loading animation starts to play during the payment component creation.

No further action.

SDK_END_OF_LOADING

The loading animation ends during the payment component creation.

No further action.

Error codes

SDK_INTERNAL_ERROR

The internal error of the SDK occurs.

Contact Antom Technical Support to resolve the issue.

SDK_CREATEPAYMENT_PARAMETER_ERROR

The parameters passed into the AMSCashierPayment method are incorrect.

Ensure the parameters are passed correctly and send a new request.

SDK_INIT_PARAMETER_ERROR

The parameters passed into the createComponent method are incorrect.

Ensure the parameters are passed correctly and send a new request.

SDK_CREATECOMPONENT_ERROR

An exception occurs when calling the createComponent method.

Contact Antom Technical Support to resolve the issue.

SDK_CALL_URL_ERROR

The payment method client failed to be revoked.

Contact Antom Technical Support to resolve the issue.