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

Card vaulting

Antom SDK is a pre-built UI component designed to collect card information and manage 3D authentication processes for merchants. Integration of the component does not require merchants to be PCI-eligible, making it ideal for those who prefer to entrust Antom to collect card information.

Workflow

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

下载.svg

  • The buyer lands on the checkout page.
  • Your server creates a vaulting session.
  • Your client creates and invokes the Component with the vaulting session.
  • The component collects payment elements from the buyer.
  • Your server receives vaulting result notifications.

Step 1: Create a vaulting session Server-side

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

Antom provides a multi-language server-side API librariy and follow the steps below with Java (Java 6 or higher) as an example.

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.21</version>
</dependency>

Initialize 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;

String merchantPrivateKey = "YOUR PRIVATE KEY";
String alipayPublicKey = "ALIPAY PUBLIC KEY"
AlipayClient defaultAlipayClient = new DefaultAlipayClient(EndPointConstants.SG,
                merchantPrivateKey, alipayPublicKey);

Create a vaulting session

Creating a vaulting session involves the following parameters:

Parameter name

Required

Description

paymentMethodType

The payment method that you needs to bind.

vaultingRequestId

Unique ID generated by the merchant, a new ID is required each time a vaulting session is initiated.

vaultingNotificationUrl

The notification address of the vaulting result.

redirectUrl

The URL to jump to after the vaulting is completed.

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 createVaultingSession.

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

copy
AlipayVaultingSessionRequest alipayVaultingSessionRequest = new AlipayVaultingSessionRequest();
alipayVaultingSessionRequest.setPath("/ams/api/v1/vaults/createVaultingSession");

// replace to your paymentRequestId
alipayVaultingSessionRequest.setVaultingRequestId("vaultingRequestId_001");

alipayVaultingSessionRequest.setPaymentMethodType("CARD");
alipayVaultingSessionRequest.setVaultingNotificationUrl("http://www.yourNotifyUrl.com");
alipayVaultingSessionRequest.setRedirectUrl("http://www.yourRedirectUrl.com");

AlipayVaultingSessionResponse alipayVaultingSessionResponse;

try{
    alipayVaultingSessionResponse = defaultAlipayClient.execute(alipayVaultingSessionRequest);
}catch (AlipayApiException e){
    String errorMsg = e.getMessage();
}

The following code shows a sample of the request message:

copy
{
  "paymentMethodType": "CARD",
  "vaultingRequestId": "vaultingRequestId_001",
  "vaultingNotificationUrl": "http://www.yourNotifyUrl.com",
  "redirectUrl": "http://www.yourRedirectUrl.com"
}

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

  • vaultingSessionData: the vaulting session to be returned to the frontend
  • vaultingSessionExpiryTime: the expiration time of the vaulting session.
copy
{
  "vaultingSessionData": "WxJmmCKNyIh2UOSxcMM52ljZKHpQdVVeZf7AqTB4ZywITFwBt6BfAvkCoac/OlrJdX+o7kZZ25q1iZ5t7555Xw==&&SG&&188&&eyJleHRlbmRJbmZvIjoie1widmVyc2lvbk1hcFwiOntcIndlYlwiOntcIjEuMS4wXCI6e1widGFyZ2V0V2ViVmVyaXNvblwiOlwiMS4xLjBcIn0sXCIxLjIuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMi4wXCJ9fSxcImlPU1wiOntcIjEuMS4wXCI6e1widGFyZ2V0V2ViVmVyaXNvblwiOlwiMS4xLjBcIn0sXCIxLjIuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMi4wXCJ9fSxcIkFuZHJvaWRcIjp7XCIxLjEuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMS4wXCJ9LFwiMS4yLjBcIjp7XCJ0YXJnZXRXZWJWZXJpc29uXCI6XCIxLjIuMFwifX19fSIsInBheW1lbnRTZXNzaW9uQ29uZmlnIjp7InBheW1lbnRNZXRob2RDYXRlZ29yeVR5cGUiOiJDQVJEIiwicHJvZHVjdFNjZW5lIjoiVkFVTFRJTkciLCJwcm9kdWN0U2NlbmVWZXJzaW9uIjoiMS4wIn19",
  "vaultingSessionExpiryTime": "2023-11-22T17:47:08+08:00",
  "vaultingSessionId": "WxJmmCKNyIh2UOSxcMM52ljZKHpQdVVeZf7AqTB4ZyyidRSREbL0YHpqq/hjPUaE",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}

FAQs

How to set the vaulting result notification address?

The vaulting result will be notified to you via notifyVaulting API. The URL can be passed in through the vaultingNotifyUrl parameter in the createVaultingSession API.

Step 2: Create and invoke the SDK Client-side

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

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.10.1/dist/umd/ams-checkout.min.js"></script>
copy
npm install @alipay/ams-checkout

Instantiate the SDK

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

Parameter name

Required

Description

locale

Optional. String type. 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 Chinese

enviroment

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

  • sandbox: Sandbox environment
  • prod: Production environment

analytics

Optional object. 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

Optional. 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

Optional. 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
const checkoutApp = new window.AMSCashierPayment({
  environment: "sandbox",
  locale: "en_US",
  onLog: ({code, message}) => {},
  onEventCallback: ({code, message}) => {},
});

Invoke the SDK

After buyers select a payment method on the page, you need to create the vaulting session to invoke the SDK.

Use the createComponent or mountComponent 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 createVaultingSession API to the sessionData parameter.

appearance

Optional object for 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.
  • showSubmitButton: Optional. Boolean type. The default value is false, which disables the button to render payment page.

Embedded experience vs. Popup experience

There are different ways in which you can make the Component display on a page through a pop-up window or embedded on a page.

Embedded experience

Popup experience

image.png

image.png

Popup experience

Popup experience offers the advantage of low impact on page style and relatively independent flow.

After the buyer selects a payment method on the page and clicks submit, the Component needs to be evoked, and the interaction popup will be rendered after loading.

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

Embedded experience

The embedded experience involves rendering embedded element content within the designated view, so it's essential to focus on styling adjustments for the payment list. Our embedded content's width adjusts automatically to fit the parent container, while the height dynamically updates with view changes.

copy
async function create(sessionData) {
  await checkoutApp.mountComponent({ 
    sessionData: sessionData, 
    appearance:{
      showLoading: true, // Default is true, allowing configuration of whether to display a loading animation.
      showSubmitButton: false, // Configure whether the payment button is rendered by the component.
    }, 
    notRedirectAfterComplete: true,
  },'#ContainerNodeId');
}

Embedded Submit

When using embedded rendering and a custom submit button, remember to actively call the submit function to initiate the submission process.

copy
// Execute when the buyer completes the form and clicks the submit button.
checkoutApp.submit().then(({code, message})=>{})

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();

FAQs

What can I do when I receive the SDK_CREATEPAYMENT_PARAMETER_ERROR?

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

What can I do when I receive the SDK_PAYMENT_ERROR or Rendering View Error?

When you receive this event code, please check the network request. There may be an exception in the initialization interface, and you need to make sure that the environment of the payment session creation request is consistent with the environment parameters of the instantiated SDK. Check whether the payment session creation parameters are passed correctly. If the interface exception still exists, you can contact us for troubleshooting.

What can I do when I receive the SDK_FORM_VERIFICATION_FAILED?

The reason could be that the buyer did not fill in all the required elements. Upon submission, an error code indicating form verification failure may be returned. It is recommended to guide the buyer on enhancing the form content.

Display vaulting results

If you set notRedirectAfterComplete to false, the buyer will be redirected to the vaultingRedirectUrl that you provided in createVaultingSession API after completing the vaulting. You can obtain the vaulting result by active query in that URL and show it to the buyer.

If notRedirectAfterComplete is true, the vaulting result will be given through the onEventCallback function. The vaulting 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 vaulting result through the data in the result of onEventCallback.

The following are the possible event codes of the vaulting result returned by onEventCallback:

Event code

Message

Solution

SDK_ASSET_BINDING_SUCCESSFUL

Vaulting was successful.

Suggest redirecting buyers to the vaulting result page.

SDK_ASSET_BINDING_PROCESSING

Vaulting was being processed.

Guide buyers to retry the vaulting based on the provided information.

SDK_ASSET_BINDING_FAIL

Vaulting failed.

You can follow the vaultingResultCode error code prompt message and redirect the buyer to bind the card.

SDK_ASSET_BINDING_CANCEL

The buyer exits the vaulting page without submitting the order.

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

SDK_ASSET_BINDING_ERROR

The vaulting status was abnormal.

You can wait for the notification of the card binding result or re-direct the buyer to bind the card.

The following sample code shows how to process the onEventCallback:

copy
function onEventCallback({ code, result }) {
  switch (code) {
    case code:
      'SDK_ASSET_BINDING_SUCCESSFUL';
      // Vaulting successful, free the SDK component and redirect to the vaulting result page.
      break;
    case code:
      'SDK_ASSET_BINDING_FAIL';
      // Vaulting failed. You can follow the vaultingResultCode error code prompt message and redirect the buyer to bind the card.
      break;
    case code:
      'SDK_ASSET_BINDING_ERROR';
      // Card binding is abnormal. You can wait for the notification of the card binding result or re-direct the buyer to bind the card.
      break;
    case code:
      'SDK_ASSET_BINDING_CANCEL';
      // Guide buyers to retry vaulting.
      break;
    default:
      break;
  }
}

Step 3: Obtain vaulting result Server-side

When the buyer completes the vaulting or the vaulting timeout, Antom will send the corresponding vaulting result to the merchant through the server-side interaction, you can obtain the payment result by one of the following methods:

  • Receive the asynchronous notification
  • Inquire about the result

Receive the asynchronous notification

Merchants need to implement a server-side notifyVaulting API; when the vaulting is completed, or vaulting failure, Antom will send asynchronous notification through this URL.

The following code shows a sample of the notification request:

copy
{
  "result": {
    "resultStatus": "S",
    "resultCode": "SUCCESS",
    "resultMsg": "success"
  },
  "acquirerInfo": {
    "acquirerName": "ADYEN",
    "acquirerTransactionId": "******",
    "referenceRequestId": "********"
  },
  "paymentMethodDetail": {
    "card": {
      "avsResultRaw": "4",
      "billingAddress": {
        "address1": "address1",
        "address2": "address2",
        "city": "Madrid",
        "region": "ES",
        "state": "Madrid",
        "zipCode": "280**"
      },
      "brand": "VISA",
      "cardToken": "******",
      "cvvResultRaw": "1",
      "expiredMonth": "02",
      "expiredYear": "27",
      "funding": "DEBIT",
      "issuingCountry": "BR",
      "lastFour": "0000",
      "bin": "409280",
      "issuerName": "BANCO ITAUCARD, S.A."
    },
    "paymentMethodType": "CARD"
  },
  "vaultingCreateTime": "2023-10-16T01:07:22-07:00",
  "vaultingRequestId": "requestId1697443641665"
}

The following sample code shows how to verify the signature of the notification and make a response to the notification:

copy
@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);
}

FAQs

When will the notification be sent?

After the payment is completed, Antom will send asynchronous notification to you within 3~5s, some payment methods such as offline stores take a little longer;

If the payment is not completed, Antom will send asynchronous notification only after the order is closed, the time to close the order is different for different payment methods, generally the default is 14min, you can refer to the list of payment methods for special payment methods.

If the buyer does not submit the payment, in the scenario that the Component needs to collect the payment information (such as card information), if you do not enter any information and directly turn off the Component, the notification will not be sent.

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 add a digital signature to 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 add a digital signature to your response.

How do I understand the meaning of the following key fields?
  • result: the vaulting result of the order.
  • paymentMethodDetail: the vaulting key information such as cardToken.

Inquire about the result

The merchant can call the inquireVaulting API to initiate a query on the result of an order.

Parameter name

Required

Description

vaultingRequestId

The vaulting request ID generated by the merchant.

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

copy
AlipayClient defaultAlipayClient = new DefaultAlipayClient(EndPointConstants.SG,
        merchantPrivateKey, alipayPublicKey);

AlipayPayQueryRequest alipayPayQueryRequest = new AlipayPayQueryRequest();
alipayPayQueryRequest.setClientId(CLIENT_ID);
alipayPayQueryRequest.setPath("/ams/api/v1/payments/inquiryPayment");

AlipayPayQueryResponse alipayPayQueryResponse;
try {
    alipayPayQueryResponse = defaultAlipayClient.execute(alipayPayQueryRequest);
} catch (AlipayApiException e) {
    String errorMsg = e.getMessage();
    // handle error condition
}

The following code shows a sample of the request message:

copy
{
  "vaultingRequestId": "123456789206"
}

The following code shows a sample of the response message:

copy
{
  "paymentMethodDetail": {
    "card": {
      "brand": "VISA",
      "cardToken": "ALIPAY9CGwsAeMBug+G2dSKDV6AIsNKTxAFNkOMoj8Gxvt8h0eDUbd6nO5CwMFIjEFERWxCAo/b1OjVTvtl1zspyMGcg==",
      "maskedCardNo": "************8764"
    },
    "paymentMethodType": "CARD"
  },
  "vaultingRequestId": "123487889889",
  "vaultingStatus": "SUCCESS",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}

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 and FAIL indicate final results, while PROCESSING 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.