# Store a card (SDK)

> This guide instructs you on how to integrate independent card binding through SDK, allowing buyers to bind their bank cards at any stage of the payment process.

 export const AlertDeprecate = () => (  <svg aria-hidden="true" focusable="false" width="32" height="32" style={{
  marginRight: 16,
  marginTop: 2,
  flexShrink: 0
}} fill="#d97706" // Darker yellow icon
viewBox="0 0 24 24">
      <circle cx="12" cy="12" r="12" fill="#ffe066" /> {/* Lighter yellow circle */}
      <path d="M12 8v4" stroke="#d97706" strokeWidth="2" strokeLinecap="round" />
      <circle cx="12" cy="16" r="1" fill="#d97706" />
    </svg>   Deprecation Notice:       ); <AlertDeprecate>
  The content of this guide has been deprecated.<br />
</AlertDeprecate> This guide instructs you on how to integrate independent card binding through SDK, allowing buyers to bind their bank cards at any stage of the payment process. In this solution, Antom is responsible for collecting and storing the buyer’s card plain information. After the card binding is successfully completed, Antom returns the corresponding card token (    *cardToken*    ). Since sensitive cardholder data does not pass through your servers, this approach helps you eliminate the compliance burden of PCI-DSS. You are not required to build a PCI-DSS compliant payment environment nor obtain PCI compliance certification. In subsequent transactions, you can directly use the     *cardToken*     parameter to initiate payments without collecting the buyer's card information again. For token (    *cardToken*    ) payments, please refer to   [Card-on-File (COF) transactions](https://docs.antom.com/ac/pm/cof.md)  .

## User experience {#mGlBw}

 The following images illustrate the user experience on the web and mobile platforms during the card binding process (including both embedded and pop-up card binding experiences) and the subsequent payment flow.

<!-- TabGroup -->

**Tab: Web**

<!-- TabGroup -->

**Tab: Embedded card-binding experience**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2026/png/15f3da45-d897-4ae4-870c-81946feb55d7.png)

**Tab: Pop‑up card‑binding experience**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2026/png/84451656-84d7-4ce3-8a0d-961c8b9effeb.png)

**Tab: Subsequent payments**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2026/png/fac03fb2-96b5-4cc5-9050-73e01f1c7669.png)

<!-- /TabGroup -->

**Tab: Mobile**

<!-- TabGroup -->

**Tab: Embedded card-binding experience**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2026/png/f0cde370-d754-4fdc-9ef5-9b9ba8a1bd39.png)

**Tab: Pop‑up card‑binding experience**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2026/png/8faebb46-634e-4181-b4ec-3599004dba23.png)

**Tab: Subsequent payments**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2026/png/0fc876a5-1827-4304-98e2-f0c365f0b125.png)

<!-- /TabGroup -->

<!-- /TabGroup -->

## Binding process {#FunOr}

 The following steps describe the card binding process:

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2026/png/75f97003-d510-4937-983a-5bceda6b63d7.png)

 1. **The buyer clicks to bind a card.**
2. **Call the createVaultingSession API and initiate a card binding request.**  
   After the buyer clicks the card binding button, your server calls the Antom server's   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)   API to initiate the card binding request.
3. **Initiate**      **the SDK component.**  
   Invoke the SDK component with the     *vaultingSessionData*     returned from the   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)   API. The SDK presents a page for collecting card details.
4. **The buyer completes the card binding process.**  
   On the card information collection page, the buyer inputs card details to complete card binding.
5. **(Optional) The buyer completes 3D authentication.**  
   If 3D authentication is specified, the buyer needs to complete 3D authentication.
6. **Obtain the card binding result.**  
 You can obtain the card binding result through either of the following two methods:

   - Asynchronous notification:   Antom will send you the card binding result notifications via the   [**notifyVaulting**](https://docs.antom.com/ac/ams/notify_vaulting.md)   API.
  - Synchronous inquiry:    Call the   [**inquireVaulting**](https://docs.antom.com/ac/ams/inquire_vaulting.md)        API to check the card binding status.

 > **[INFO]** **Note**    : On the card binding management page, you must present the masked card number of the buyer’s bound card. For subsequent payments, pass in your request the token obtained from the initial card binding through the   [**notifyVaulting**](https://docs.antom.com/ac/ams/notify_vaulting.md)   or   [**inquireVaulting**](https://docs.antom.com/ac/ams/inquire_vaulting.md)        API.

<!-- ToggleTab query="platform" -->

**Tab: Web/WAP**

## Integration preparations {#KD7YH}

 Before you start integrating, read the   [Integration guide](https://docs.antom.com/integration_guide_en.md)   and   [API overview](https://docs.antom.com/ac/ams/api_fund.md)   to understand the integration steps of the server-side API and the precautions for calling the API. Furthermore, ensure the following prerequisites are met:

 - Obtained your client ID
- Complete the key configuration
- Complete the configuration of     *vaultingNotificationUrl*      to receive the asynchronous notification
- Integrate the server-side SDK package, install the server-side library, and initialize a request instance. For more details, refer to   [Server-side SDKs](https://docs.antom.com/ac/sdks/server_sdks.md)  .
- Integrate the client-side SDK package by following the steps of   [Integrate the SDK package for Web/WAP](https://docs.antom.com/ac/sdks/web.md)  .

## Integration steps {#GbwR1}

 Follow the steps below to begin your integration:

 1. (Optional) Preload the card binding page
2. Create a vaulting sesssion
3. Invoke the SDK component
4. Obtain the card binding result

### Step 1: (Optional) Preload the card binding page  **[Client-side]** {#gzEVk}

 It is strongly recommended to perform a preloading process when loading the card‑binding page to enhance the rendering speed of the checkout page. This process does not impact your page performance. Refer to the following code example to implement preloading.

 ```java
// import { AMSVaulting } from '@alipay/ams-checkout';

AMSVaulting.preload();
```

### Step 2: Create a vaulting sesssion  **[Server-side]** {#FlMBV}

 When a buyer selects a payment method provided by Antom, you need to collect key information such as card binding request ID, card binding redirect URL, and card binding result notification URL, call the   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)        API to create a vaulting session, and return the vaulting session to the client.

 Creating a payment session includes the following parameters:

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *paymentMethodType* | Yes | The payment method to be bound. |
| *vaultingRequestId* | Yes | The unique ID generated by the merchant. Every time you initiate card binding, you must have a new ID. |
| *vaultingNotificationUrl* | Yes | The card binding result notification address. |
| *redirectUrl* | No | The URL to be redirected to after card binding. |
| *is3DSAuthentication* | No | Specify whether 3D authentication is required for this card binding request. Set the value to   `true`   if 3D authentication is required. For details, refer to   [3D Secure 2](https://docs.antom.com/ac/pm/3ds.md)  . > **[INFO]** **Notes**    : - [South Korean Cards](https://docs.antom.com/ac/antomop/south_korean_mdx.md)       do not support 3D authentication. > - If subsequent payments involve   [Merchant-Initiated Transaction (MIT)](https://docs.antom.com/ac/pm/mit.md)   scenarios, the card scheme strongly recommends specifying 3D authentication when binding the card. |

 For more information about complete parameters, refer to the   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)   API.

 The following sample code shows how to call the   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)   API:

 ```java
public static void createVaultingSession(){
    AlipayVaultingSessionRequest alipayVaultingSessionRequest = new AlipayVaultingSessionRequest();

    // Replace with your paymentRequestId
    String vaultingRequestId = UUID.randomUUID().toString();
    alipayVaultingSessionRequest.setVaultingRequestId(vaultingRequestId);

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

    // Bind the card
    AlipayVaultingSessionResponse alipayVaultingSessionResponse;
    try{
        alipayVaultingSessionResponse = CLIENT.execute(alipayVaultingSessionRequest);
    }catch (AlipayApiException e){
        String errorMsg = e.getMessage();
        // Handle error condition
    }

}
```

 The following code shows a sample of the request:

 ```json
{
  "paymentMethodType": "CARD",
  "redirectUrl": "http://www.yourRedirectUrl.com",
  "vaultingNotificationUrl": "http://www.yourNotifyUrl.com",
  "vaultingRequestId": "4a17609d-1749-4f53-a2fb-8bdba8d5aad8"
}
```

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

 - *vaultingSessionData*    : The vaulting session data to be returned to the client.
- *vaultingSessionExpiryTime*    : The expiration time of the vaulting session.

 ```json
{
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  },
  "vaultingSessionData": "qOnxVjFYB/QNieiGGnf3P7XOreGIRi7dSZDMzCzT5DzGLaI5a5paDhEAgmG8IwVuTCHscscPdJg==&&SG&&188&&eyJleHRlbmRJbmZvIjoie1widmVyc2lvbk1hcFwiOntcIndlYlwiOntcIjEuMS4wXCI6e1widGFyZ2V0V2ViVmVyaXNvblwiOlwiMS4xLjBcIn0sXCIxLjIuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMi4wXCJ9fSxcImlPU1wiOntcIjEuMS4wXCI6e1widGFyZ2V0V2ViVmVyaXNvblwiOlwiMS4xLjBcIn0sXCIxLjIuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMi4wXCJ9fSxcIkFuZHJvaWRcIjp7XCIxLjEuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMS4wXCJ9LFwiMS4yLjBcIjp7XCJ0YXJnZXRXZWJWZXJpc29uXCI6XCIxLjIuMFwifX19fSIsInBheW1lbnRTZXNzaW9uQ29uZmlnIjp7InBheW1lbnRNZXRob2RDYXRlZ29yeVR5cGUiOiJDQVJEIiwicHJvZHVjdFNjZW5lIjoiVkFVTFRJTkciLCJwcm9kdWN0U2NlbmVWZXJzaW9uIjoiMS4wIn0sInNraXBSZW5kZXJQYXltZW50TWV0aG9kIjpm******",
  "vaultingSessionExpiryTime": "2024-12-31T12:06:05+08:00",
  "vaultingSessionId": "********qOnxVjFYB/QNieiGGnf3P7XOreGIRi7fAxqpLf+1appjsXAs5Eq1H"
}
```

### Step 3: Invoke the SDK component  **[Client-side]** {#t0rGw}

 Use     *vaultingSessionData*     to invoke the SDK, and the SDK renders the required card payment element collection page and handles the 3D Secure flow, allowing the buyer to complete a server‑to‑server card binding process.

#### 1\. Instantiate the client SDK {#yXTQH}

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

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *locale* | No | 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, English is used by default: - `en_US`  : English - `es_ES`  : Spanish - `fr_FR`  : French - `nl_NL`  : Dutch - `it_IT`  : Italian - `de_DE`  : German - `zh_CN`  : Simplified Chinese - `zh_HK`  : Traditional Chinese - `pt_PT`  : Portuguese (Portugal) - `ro`  : Romanian - `pl_PL`  : Polish - `th_TH`  : Thai |
| *environment* | Yes | It is used to pass in environmental information. Valid values are: - `sandbox`  : Sandbox environment - `prod`  : Production environment |
| *onEventCallback* | No | When events occur during SDK runtime (such as card binding results or form submission errors), the callback method returns specific event codes. |

 ​   The following sample code shows how to instantiate the SDK:

<!-- TabGroup -->

**Tab: Initialize SDK via npm**

```javascript
import { AMSVaulting } from '@alipay/ams-checkout' // Package Management

const checkoutApp = new AMSVaulting({
  environment: "sandbox",
  locale: "en_US",
  onEventCallback: ({ code, result }) => {}
});
```

**Tab: Initialize SDK via CDN**

```javascript
const checkoutApp = new window.AMSVaulting({
  environment: "sandbox",
  locale: "en_US",
  onEventCallback: ({ code, result }) => {}
});
```

<!-- /TabGroup -->

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

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

#### 2\. Create a card binding component {#NvSNa}

 Use the   `createComponent`   or   `mountComponent`   function in the instance object to create a card binding component.    Configuration objects includes the following parameters:

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *sessionData* | Yes | Create a configuration object by using the _sessionData_ parameter: Pass the complete data in the _vaultingSessionData_ parameter obtained in the response through the   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)        API to the _sessionData_ parameter. |
| *appearance* | No | Customized appearance theme configuration, and it contains the following child parameters: - *showSubmitButton*    : Optional. Boolean type. The default value is      `false`  , indicates disabling the render button on the card‑binding page. |
| *notRedirectAfterComplete* | No | Boolean type. The valid values are: - `false`  : The default value,   which means it will redirect back to your page after the card binding is completed. The same applies when the value is empty. - `true`  : indicates that there is no redirection after the card binding is completed. You need to use the client event code to control the card binding to complete the subsequent process.   > **[INFO]** **Note**    : The card binding result event code returned by the client is only used as a reference for the redirect operation of the client page. For card binding status updates, refer to the results returned by the server's   [**notifyVaulting**](https://docs.antom.com/ac/ams/notify_vaulting.md)   or   [**inquireVaulting**](https://docs.antom.com/ac/ams/inquire_vaulting.md)   API. |

 There are different ways in which you can make the SDK component display on a page through a pop-up window or embedded on a page, the following are the sample codes:

<!-- TabGroup -->

**Tab: Pop-up experience**

```javascript
async function create(sessionData) {
  await checkoutApp.createComponent({
    sessionData: sessionData,
    notRedirectAfterComplete: true,
  });
}

```

**Tab: Embedded experience**

```javascript
async function create(sessionData) {
  await checkoutApp.mountComponent({
    sessionData: sessionData,
    appearance:{
      showSubmitButton: false, // Configure whether the payment button is rendered by the component.
    },
    notRedirectAfterComplete: true,
  },'#ContainerNodeId');
}

checkoutApp.submit().then(({code, message})=>{}) //When using embedded rendering and custom submit button, remember to actively call the submit method to initiate the submission process.
```

<!-- /TabGroup -->

#### 3\. Handle SDK callback event codes {#V6CZm}

 According to the configuration of the     *notRedirectAfterComplete*     parameter, handle the subsequent process accordingly:

 - If you set     *notRedirectAfterComplete*     to   `false`  , the buyer will be redirected to the _vaultingRedirectUrl_ that you provided in   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)        API after completing the card binding. You can obtain the card binding result by active query in that URL and show it to the buyer.
- If     *notRedirectAfterComplete*     is  `true`  , the card binding result will be given through the  `onEventCallback`  method. The card binding result here is only for front-end display, and the final order status is subject to the server side.

##### Event codes {#KJTM7}

 The following are the possible event codes of the card binding result returned by       `onEventCallback`  :

 | **Event code** | **Message** | **Solution** |
| --- | --- | --- |
| `SDK_ASSET_BINDING_SUCCESSFUL` | The vaulting is successful. | It is recommended to redirect the buyer to the card binding result page. |
| `SDK_ASSET_BINDING_PROCESSING` | The vaulting is being processed. | Guide the buyer to retry the card‑binding operation based on the provided information. |
| `SDK_ASSET_BINDING_FAIL` | The vaulting failed. | You can guide the buyer to complete card binding based on the   [*vaultingResultCode*](#X82wv)        . |
| `SDK_ASSET_BINDING_CANCEL` | The buyer exits the vaulting page. | You can re-invoke the SDK with the _vaultingSessionData_ that is within its validity period. If it has expired, you need to request a new _vaultingSessionData_. |
| `SDK_ASSET_BINDING_ERROR` | The vaulting status is abnormal. | You can wait for the card binding result notification, or guide the buyer to bind the card again. |

 The following sample code shows how to process the   `onEventCallback`   :

 ```javascript
function onEventCallback({ code, result }) {
  switch (code) {
    case code:
      'SDK_ASSET_BINDING_SUCCESSFUL';
      // Card binding successful, release SDK component resources and redirect to the card binding result page.
      break;
    case code:
      'SDK_ASSET_BINDING_FAIL';
      //  Card binding failed, you can guide the buyer to re-bind the card based on the vaultingResultCode error code prompt information.
      break;
    case code:
      'SDK_ASSET_BINDING_ERROR';
      // Card binding exception, you can wait for the card binding result notification or re-guide the buyer to bind the card.
      break;
    case code:
      'SDK_ASSET_BINDING_CANCEL';
      // Guide the buyer to try card binding again.
      break;
    default:
      break;
  }
}
```

 The following are sample codes for card binding results corresponding to frontend event codes:

 ```json
{
  "code": "SDK_ASSET_BINDING_SUCCESSFUL",  // Frontend event code
  "result": {
    "resultStatus": "S",
    "resultCode": "SUCCESS",
    "resultMessage": "Success"
  }
}
```

 ```json
{
  "code": "SDK_ASSET_BINDING_FAIL",  // Frontend event code  
  "result": {
    "resultStatus": "S",
    "resultCode": "SUCCESS",
    "resultMessage": "Success"
  },
  "vaultingStatus":"FAIL",
  "vaultingResultCode":"PROCESS_FAIL",
  "vaultingResultMessage":"A general business failure occurred."
}
```

#### 4\. Unmount the component {#vaf3l}

 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        [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)        API.
- When the buyer initiates multiple card binding requests, free the component resources created in the previous   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)   API.
- Free the component resources after obtaining the card binding result.

 > **[INFO]** **Note**    : Only one component can be created at a time. If you need to use different _vaultingSessionData_ or recreate the component, you must first execute the unload the method.

 ```javascript
// Free SDK component resources.
checkoutApp.unmount();
```

### Step 4: Obtain the card binding result  **[Server-side]** {#kkMwd}

 You can obtain the card binding result by one of the following methods:

 - Receive the asynchronous notification
- Inquire about the result

<!-- TabGroup -->

**Tab: Receive the asynchronous notification**

#### Receive the asynchronous notification {#TlpcY}

 Antom will send you the card binding result notifications via the   [**notifyVaulting**](https://docs.antom.com/ac/ams/notify_vaulting.md)        API.    Follow the steps below for configuration:

##### 1\. Configure the webhook URL to receive asynchronous notifications {#EDBuY}

 - If each of your card binding operations has a unique notification URL, it is recommended to set the webhook URL in each request. You can pass the asynchronous notification receiving URL for the specific order through _vaultingNotificationUrl_ in the   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)        API.

 The following code shows a sample of the asynchronous notification request:

 ```json
{
  "paymentMethodDetail": {
    "card": {
      "brand": "MASTERCARD",
      "cardToken": "ALIPAY34RlcCU3ZtZ***********************sVYl8x244tyWCloE4MwfmN48sP1+rSPQ==",
      "maskedCardNo": "************1310",
      "networkTransactionId": "112000********575887"
    },
    "paymentMethodType": "CARD"
  },
  "vaultingRequestId": "VAULT_2025*******348834_AUTO",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success",
    "resultStatus": "S"
  }
}

```

 The following table shows the possible values of _result.resultStatus_ in the notification request of authorization result. Please handle the result according to the guidance provided:

 | ***result.resultStatus*** | **Message** | **Further actions** |
| --- | --- | --- |
| `S` | Indicates that the card binding is successful. | It is recommended to store the following parameters for subsequent payments: - *cardToken*        : A token generated by Antom for subsequent payments. You can associate this information with your buyer for subsequent payments. - *brand*    : The card brand. It is recommended that you store this information to display to the buyer in subsequent payments. - *maskedCardNo*    : The masked card number. It is recommended that you store this information to display to the buyer in subsequent payments. |
| `F` | Indicates that the card binding failed. | Please check     *result.resultCode*     to identify the specific failure reason. |

##### 2\. Verify the asynchronous notification {#VaGth}

 When you receive an asynchronous notification from Antom, you are required to return the response in the  [Sample code](https://docs.antom.com/ac/auto_debit/notifications.md#OqpVS)  format, but you do not need to countersign the response.

 You need to verify the signature of the authorization payment notification sent by Antom:

 ```java
import javax.servlet.http.HttpServletRequest;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.alipay.global.api.model.Result;
import com.alipay.global.api.model.ResultStatusType;
import com.alipay.global.api.response.AlipayResponse;
import com.alipay.global.api.tools.WebhookTool;

@RestController
public class PaymentNotifyHandleBySDK {

    /**
     * alipay public key, used to verify signature
     */
    private static final String SERVER_PUBLIC_KEY = "";

    /**
     * payment result notify processor
     * using <a href="https://spring.io">Spring Framework</a>
     *
     * @param request    HttpServletRequest
     * @param notifyBody notify body
     * @return
     */
    @PostMapping("/payNotify")
    public Object payNotifyHandler(HttpServletRequest request, @RequestBody String notifyBody) {

        // retrieve the required parameters from http request
        String requestUri = request.getRequestURI();
        String requestMethod = request.getMethod();

        // retrieve the required parameters from request header
        String requestTime = request.getHeader("request-time");
        String clientId = request.getHeader("client-id");
        String signature = request.getHeader("signature");

        Result result;
        AlipayResponse response = new AlipayResponse();

        try {
            // verify the signature of notification
            boolean verifyResult = WebhookTool.checkSignature(requestUri, requestMethod, clientId, requestTime, signature, notifyBody, SERVER_PUBLIC_KEY);
            if (!verifyResult) {
                throw new RuntimeException("Invalid notify signature");
            }

            // deserialize the notification body

            // update the order status based on the notification result

            // respond to the server that the notification has been received
            result = new Result("SUCCESS", "success", ResultStatusType.S);

        } catch (Exception e) {
            String errorMsg = e.getMessage();
            // Handle error condition
            result = new Result("ERROR", errorMsg, ResultStatusType.F);
        }
        response.setResult(result);
        return ResponseEntity.ok().body(response);
    }

}
```

 Whether the card binding is successful or not, each notification request must be responded to in the format specified below. Otherwise, Antom will resend the asynchronous notification.

 ```json
{
  "result": {
    "resultCode": "SUCCESS",
    "resultStatus": "S",
    "resultMessage": "success"
  }
}
```

 > **[INFO]** **Common questions**
>
>  **Q: Will an asynchronous notification be sent immediately after a successful card binding?**
>
>  A: The asynchronous notification for the card binding result is sent within seconds, typically 3 to 5 seconds after the card binding succeeds.
>
>  ​
>
>  **Q: Will an asynchronous notification be sent if the card binding fails?**
>
>  A: Yes, it will be sent.
>
>  ​
>
>  **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 did not respond to the notification in the  [Sample code](https://docs.antom.com/ac/cashierpay/notifications.md#wkNv0)  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: Do I need to verify the signature upon receiving a card binding result notification?**
>
>  A: Yes. Signature verification is necessary to ensure that the request was sent to you by Antom. When performing verification, the assembled message must strictly adhere to the following format:   `<http-method> <http-uri> <client-id>.<request-time>.<request-body>`  . For the   `<request-body>`   part, you must use its original, unprocessed string value.
>
>  ​
>
>  **Q: How long is the validity period of the returned _cardToken_?**
>
>  A: The     *cardToken*     itself is permanently valid. If the card expires, it will become invalid at the same time. If the card expires, when you call the payment request again, Antom will return the   `INVALID_EXPIRATION_DATE`   error code. It is recommended that you guide the buyer to re-bind the updated card information.

**Tab: Inquire about the result**

#### Inquire about the result {#Pa3Wo}

 In addition to obtaining card binding results through asynchronous notifications, you can also query to get the results. You can inquire about the card binding result by calling the      [**inquireVaulting**](https://docs.antom.com/ac/ams/inquire_vaulting.md)        API using _vaultingRequestId_ from the card binding request.

 The following sample code shows how to call the   [**inquireVaulting**](https://docs.antom.com/ac/ams/inquire_vaulting.md)        API:

 ```java
public static void inquireVaulting(){
    AlipayVaultingQueryRequest alipayVaultingQueryRequest = new AlipayVaultingQueryRequest();

    //Replace with your vaultingRequestId
    alipayVaultingQueryRequest.setVaultingRequestId("c7f3ee64-c472-4d12-b8de-3157804ed55f");

    AlipayVaultingQueryResponse alipayVaultingQueryResponse;
    try{
        alipayVaultingQueryResponse = CLIENT.execute(alipayVaultingQueryRequest);
    }catch (AlipayApiException e){
        String errorMsg = e.getMessage();
        // Handle error condition
    }
}
```

 The following sample code shows a request message:

 ```json
{  
  "vaultingRequestId": "VAULT_20250508183612361_AUTO"
}
```

 ​   The following sample code shows a response message:

 ```json
{
  "paymentMethodDetail": {
    "card": {
      "brand": "MASTERCARD",
      "cardToken": "ALIPAYEfG2DFbGx2Eh****************************XA7nyWCloE4MwfmN48sP1+rSPQ==",
      "maskedCardNo": "************1310",
      "networkTransactionId": "112000********575887"
    },
    "paymentMethodType": "CARD"
  },
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  },
  "vaultingRequestId": "VAULT_2025********361_AUTO",
  "vaultingStatus": "SUCCESS"
}
```

 The table below shows the possible values of _result.resultStatus_ in the response. Please handle the result according to the guidance provided:

 | ***result.resultStatus*** | **Message** | **Further actions** |
| --- | --- | --- |
| `S` | Indicates that the API is called successfully. | You can obtain the card binding result from the _vaultingStatus_ field in the API response. - `SUCCESS`  : Indicates the card binding is successful. - `FAIL`  : Indicates the card binding failed. - `PROCESSING`  : Indicates the card binding is being processed. |
| `F` | Indicates that the API call failed. | For more information about the failure reason, refer to     *result.resultCode*    . |
| `U` | Indicates that the API call failed for unknown reasons. | Use the same _vaultingRequestId_ to try again. |

<!-- /TabGroup -->

**Tab: Android**

## Integration preparations {#vQWAU}

 Before you start integrating, read   [Integration guide](https://docs.antom.com/integration_guide_en.md)   and   [API overview](https://docs.antom.com/ac/ams/api_fund.md)   to understand the integration steps of the server-side API and the precautions for calling the API. Furthermore, ensure the following prerequisites are met:

 - Obtained your client ID
- Complete the key configuration
- Complete the configuration of     *vaultingNotificationUrl*           to receive the asynchronous notification
- Integrate the server-side SDK package, install the server-side library, and initialize a request instance. For more details, refer to   [Server-side SDKs](https://docs.antom.com/ac/sdks/server_sdks.md)  .
- Integrate the client-side SDK package by following the steps detailed in   [Integrate the SDK package for Android](https://docs.antom.com/ac/sdks/android.md)  , and ensure to use the latest SDK version.

## Integration steps {#EbtDD}

 Follow the steps below to begin your integration:

 1. (Optional) Preload the card binding page
2. Create a vaulting sesssion
3. Invoke the SDK component
4. Obtain the card binding result

### Step 1: (Optional) Preload the card binding page  **[Client-side]** {#ENJ2z}

 It is strongly recommended to perform a preloading process when loading the card‑binding page to enhance the rendering speed of the checkout page. This process does not impact your page performance. Refer to the following code example to implement preloading.

 ```java
AMSVaulting.preload(context.getApplicationContext());
//context-(required)-Android application context object.
```

### Step 2: Create a vaulting sesssion  **[Server-side]** {#wkF4x}

 When a buyer selects a payment method provided by Antom, you need to collect key information such as card binding request ID, card binding redirect URL, and card binding result notification URL, call the   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)        API to create a vaulting session, and return the vaulting session to the client.

 Creating a payment session includes the following parameters:

 Creating a payment session includes the following parameters:

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *paymentMethodType* | Yes | The payment method to be bound. |
| *vaultingRequestId* | Yes | The unique ID generated by the merchant. Every time you initiate card binding, you must have a new ID. |
| *vaultingNotificationUrl* | Yes | The card binding result notification address. |
| *redirectUrl* | No | The URL to be redirected to after card binding. |
| *is3DSAuthentication* | No | Specify whether 3D authentication is required for this card binding request. Set the value to   `true`   if 3D authentication is required. For details, refer to   [3D Secure 2](https://docs.antom.com/ac/pm/3ds.md)  . > **[INFO]** **Notes**    : - [South Korean Cards](https://docs.antom.com/ac/antomop/south_korean_mdx.md)       do not support 3D authentication. > - If subsequent payments involve   [Merchant-Initiated Transaction (MIT)](https://docs.antom.com/ac/pm/mit.md)   scenarios, the card scheme strongly recommends specifying 3D authentication when binding the card. |

 For more information about complete parameters, refer to the   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)   API.

 The following sample code shows how to call the   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)   API:

 ```java
public static void createVaultingSession(){
    AlipayVaultingSessionRequest alipayVaultingSessionRequest = new AlipayVaultingSessionRequest();

    // Replace with your paymentRequestId
    String vaultingRequestId = UUID.randomUUID().toString();
    alipayVaultingSessionRequest.setVaultingRequestId(vaultingRequestId);

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

    // Bind the card
    AlipayVaultingSessionResponse alipayVaultingSessionResponse;
    try{
        alipayVaultingSessionResponse = CLIENT.execute(alipayVaultingSessionRequest);
    }catch (AlipayApiException e){
        String errorMsg = e.getMessage();
        // Handle error condition
    }

}
```

 The following code shows a sample of the request:

 ```json
{
  "paymentMethodType": "CARD",
  "redirectUrl": "http://www.yourRedirectUrl.com",
  "vaultingNotificationUrl": "http://www.yourNotifyUrl.com",
  "vaultingRequestId": "4a17609d-1749-4f53-a2fb-8bdba8d5aad8"
}
```

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

 - *vaultingSessionData*    : The vaulting session data to be returned to the client.
- *vaultingSessionExpiryTime*    : The expiration time of the vaulting session.

 ```json
{
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  },
  "vaultingSessionData": "qOnxVjFYB/QNieiGGnf3P7XOreGIRi7dSZDMzCzT5DzGLaI5a5paDhEAgmG8IwVuTCHscscPdJg==&&SG&&188&&eyJleHRlbmRJbmZvIjoie1widmVyc2lvbk1hcFwiOntcIndlYlwiOntcIjEuMS4wXCI6e1widGFyZ2V0V2ViVmVyaXNvblwiOlwiMS4xLjBcIn0sXCIxLjIuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMi4wXCJ9fSxcImlPU1wiOntcIjEuMS4wXCI6e1widGFyZ2V0V2ViVmVyaXNvblwiOlwiMS4xLjBcIn0sXCIxLjIuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMi4wXCJ9fSxcIkFuZHJvaWRcIjp7XCIxLjEuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMS4wXCJ9LFwiMS4yLjBcIjp7XCJ0YXJnZXRXZWJWZXJpc29uXCI6XCIxLjIuMFwifX19fSIsInBheW1lbnRTZXNzaW9uQ29uZmlnIjp7InBheW1lbnRNZXRob2RDYXRlZ29yeVR5cGUiOiJDQVJEIiwicHJvZHVjdFNjZW5lIjoiVkFVTFRJTkciLCJwcm9kdWN0U2NlbmVWZXJzaW9uIjoiMS4wIn0sInNraXBSZW5kZXJQYXltZW50TWV0aG9kIjpm******",
  "vaultingSessionExpiryTime": "2024-12-31T12:06:05+08:00",
  "vaultingSessionId": "********qOnxVjFYB/QNieiGGnf3P7XOreGIRi7fAxqpLf+1appjsXAs5Eq1H"
}
```

### Step 3: Invoke the SDK component  **[Client-side]** {#m0dJz}

 Use     *vaultingSessionData*     to invoke the SDK, and the SDK renders the required card payment element collection page and handles the 3D Secure flow, allowing the buyer to complete a server‑to‑server card binding process.

#### 1\. Instantiate the client SDK {#ljtE4}

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

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *Locale* | No | 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, English is used by default: - `"en", "US"`  :English - `"es", "ES"`  :Spanish - `"fr", "FR"`  : French - `"nl", "NL"`  : Dutch - `"it", "IT"`  : Italian - `"de", "DE"`  : German - `"zh", "CN"`  : Simplified Chinese - `"zh", "HK"`  : Traditional Chinese - `"pt", "PT"`  : Portuguese (Portugal) - `"ro"`  : Romanian - `"pl", "PL"`  : Polish - `"th", "TH"`  : Thai |
| *Options* | No | Used to configure the redirection after the card binding and specify whether to use the sandbox environment. Valid values are: - `"notRedirectAfterComplete", "true"`  : Optional. Boolean type. The default value is  `false`  , indicates the buyer is redirected to your page after successful card binding. The same applies if the value is empty.  `true`      indicates there is no redirection after card binding. You need to manually control the subsequent card binding flow based on client-side event codes.   - `"sandbox", "true"`  : Sandbox environment.   - `"sandbox", "false"`  : Default value. Production environment. |
| *OnCheckoutListener* | No | Create a checkout callback listener for handling events in subsequent processes. This API includes the following methods: - `onEventCallback`  : Required. A callback function for monitoring the payment events in the checkout page. The callback function returns      *eventCode*     and     *eventResult*    .   > **[INFO]** **Note**    :    The card binding result event codes returned on the client-side are for reference only in page navigation. Vaulting status updates must be based on the results returned by the server-side   [**notifyVaulting**](https://docs.antom.com/ac/ams/notify_vaulting.md)   or   [**inquireVaulting**](https://docs.antom.com/ac/ams/inquire_vaulting.md)   API. |

 The following sample code shows how to instantiate the SDK:

 ```java
AMSVaultingConfiguration configuration = new AMSVaultingConfiguration();
configuration.setLocale(new Locale("en", "US"));
// Set sandbox environment
configuration.setOption("sandbox", "true");
// Set checkout callback listener
configuration.setOnCheckoutListener(new OnCheckoutListener() {
    @Override
    public void onEventCallback(String eventCode, AMSEventResult eventResult) {
        Log.e(TAG, "onEventCallback eventCode=" + eventCode + " eventResult=" + eventResult.toString());
    }
});
// Create AMSVaulting instance
AMSVaulting checkout = new AMSVaulting.Builder(activity, configuration).build();
```

#### 2\. Create a card binding component {#UeLtU}

 Use the   `createComponent`   or   `mountComponent`   function in the instance object to create a card binding component. Configuration objects includes the following parameters:

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *sessionData* | Yes | Create a configuration object by using the     *sessionData*     parameter: Pass the complete data in the _vaultingSessionData_ parameter obtained in the response through the   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)        API to the _sessionData_ parameter. |
| *appearance* | No | Customized appearance theme configuration, and it contains the following child parameters: - *showSubmitButton*    : Optional. Boolean type. The default value is      `false`  , indicates disabling the render button on the card‑binding page. |

 There are different ways in which you can make the SDK component display on a page through a pop-up window or embedded on a page, the following are the sample codes:

<!-- TabGroup -->

**Tab: Pop-up experience**

```java
checkout.createComponent(activity,sessionData);
//Unmount the component
checkout.onDestroy();
```

**Tab: Embedded experience**

```java
// Trigger rendering of embedded component
Map<String, Object> appearanceConfig = new HashMap<>();
appearanceConfig.put("showSubmitButton", false);
appearanceConfig.put("showSubmitLoading", true);
AMSPaymentAppearance appearance = AMSPaymentAppearance.create(appearanceConfig);
checkout.mountComponent(activity, appearance, sessionData, parentViewGroup);

String dataString = "{"billingAddress":{"zipCode":"310000","region":"CN"}}";

// The user completes input and submits binding
checkout.submit(dataString);
```

<!-- /TabGroup -->

#### 3\. Handle SDK callback event codes {#UwvsY}

 According to the configuration of the     *notRedirectAfterComplete*     parameter, handle the subsequent process accordingly:

 - If you set     *notRedirectAfterComplete*     to   `false`  , the buyer will be redirected to the _vaultingRedirectUrl_ that you provided in   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)         API after completing the card binding. You can obtain the card binding result by active query in that URL and show it to the buyer.
- If     *notRedirectAfterComplete*     is  `true`  , the card binding result will be given through the  `onEventCallback`  method. The card binding result here is only for front-end display, and the final order status is subject to the server side.

##### Event codes {#KJTM7}

 The following are the possible event codes of the card binding result returned by      `onEventCallback`      :

 | **Event code** | **Message** | **Solution** |
| --- | --- | --- |
| `SDK_ASSET_BINDING_SUCCESSFUL` | The vaulting is successful. | It is recommended to redirect the buyer to the card binding result page. |
| `SDK_ASSET_BINDING_PROCESSING` | The vaulting is being processed. | Guide the buyer to retry the card‑binding operation based on the provided information. |
| `SDK_ASSET_BINDING_FAIL` | The vaulting failed. | You can guide the buyer to complete card binding based on the   [*vaultingResultCode*](#X81wv)  . |
| `SDK_ASSET_BINDING_CANCEL` | The buyer exits the vaulting page. | You can re-invoke the SDK with the _vaultingSessionData_ that is within its validity period. If it has expired, you need to request a new _vaultingSessionData_. |
| `SDK_ASSET_BINDING_ERROR` | The vaulting status is abnormal. | You can wait for the card binding result notification, or guide the buyer to bind the card again. |

 The following sample code shows how to process the   `onEventCallback`   :

 ```java
public void onEventCallback(String eventCode, AMSEventResult eventResult) {
    Log.e(TAG, "onEventCallback eventCode=" + eventCode + " eventResult=" + eventResult.toString());

    if (!TextUtils.isEmpty(eventCode)) {
        if ("SDK_ASSET_BINDING_SUCCESSFUL".equals(eventCode)) {
            //Card binding successful, need to unmount SDK. It is recommended to redirect to the card binding result page.
        } else if ("SDK_ASSET_BINDING_FAIL".equals(eventCode)) {
            // Card binding failed. It is recommended to guide the buyer to re-bind the card based on the vaultingResultCode error code prompt information.
        } else if ("SDK_ASSET_BINDING_ERROR".equals(eventCode)) {
            // Card binding exception. It is recommended to wait for the card binding result notification or re-guide the buyer to bind the card.
        } else if ("SDK_ASSET_BINDING_CANCEL".equals(eventCode)) {
            // Guide the buyer to try card binding again.
        } else{
            // Other custom events or errors of concern
        }
    }
}
```

 The following are sample codes for card binding results corresponding to frontend event codes:

 ```json
{
  "code": "SDK_ASSET_BINDING_SUCCESSFUL",  // Front-end event code
  "result": {
    "resultStatus": "S",
    "resultCode": "SUCCESS",
    "resultMessage": "Success"
  }
}
```

 ```json
{
  "code": "SDK_ASSET_BINDING_FAIL",  // Front-end event code
  "result": {
    "resultStatus": "S",
    "resultCode": "SUCCESS",
    "resultMessage": "Success"
  },
  "vaultingStatus":"FAIL",
  "vaultingResultCode":"PROCESS_FAIL",
  "vaultingResultMessage":"A general business failure occurred."
}
```

#### 4\. Unmount the component {#oHill}

 Call the   `onDestroy()`   method to unmount the created component. You need to unmount the component in the following situations:

 - When the timeout time set by your client is reached.
- When the buyer exits the card binding page.
- When you receive the card binding result callback.

 > **[INFO]** **Note**    : Only one component can be created at a time. If you need to use different _vaultingSessionData_ or recreate the component, you must first execute the unmount method.

 ```java
checkout.onDestroy();
```

### Step 4: Obtain the card binding result  **[Server-side]** {#ujZEb}

 You can obtain the card binding result by one of the following methods:

 - Receive the asynchronous notification
- Inquire about the result

<!-- TabGroup -->

**Tab: Receive the asynchronous notification**

#### Receive the asynchronous notification {#TlpcY}

 Antom will send you the card binding result notifications via the   [**notifyVaulting**](https://docs.antom.com/ac/ams/notify_vaulting.md)        API.    Follow the steps below for configuration:

##### 1\. Configure the webhook URL to receive asynchronous notifications {#EDBuY}

 - If each of your card binding operations has a unique notification URL, it is recommended to set the webhook URL in each request. You can pass the asynchronous notification receiving URL for the specific order through _vaultingNotificationUrl_ in the   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)        API.

 The following code shows a sample of the asynchronous notification request:

 ```json
{
  "paymentMethodDetail": {
    "card": {
      "brand": "MASTERCARD",
      "cardToken": "ALIPAY34RlcCU3ZtZ***********************sVYl8x244tyWCloE4MwfmN48sP1+rSPQ==",
      "maskedCardNo": "************1310",
      "networkTransactionId": "112000********575887"
    },
    "paymentMethodType": "CARD"
  },
  "vaultingRequestId": "VAULT_2025*******348834_AUTO",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success",
    "resultStatus": "S"
  }
}

```

 The following table shows the possible values of _result.resultStatus_ in the notification request of authorization result. Please handle the result according to the guidance provided:

 | ***result.resultStatus*** | **Message** | **Further actions** |
| --- | --- | --- |
| `S` | Indicates that the card binding is successful. | It is recommended to store the following parameters for subsequent payments: - *cardToken*        : A token generated by Antom for subsequent payments. You can associate this information with your buyer for subsequent payments. - *brand*    : The card brand. It is recommended that you store this information to display to the buyer in subsequent payments. - *maskedCardNo*    : The masked card number. It is recommended that you store this information to display to the buyer in subsequent payments. |
| `F` | Indicates that the card binding failed. | Please check     *result.resultCode*     to identify the specific failure reason. |

##### 2\. Verify the asynchronous notification {#VaGth}

 When you receive an asynchronous notification from Antom, you are required to return the response in the  [Sample code](https://docs.antom.com/ac/auto_debit/notifications.md#OqpVS)  format, but you do not need to countersign the response.

 You need to verify the signature of the authorization payment notification sent by Antom:

 ```java
import javax.servlet.http.HttpServletRequest;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.alipay.global.api.model.Result;
import com.alipay.global.api.model.ResultStatusType;
import com.alipay.global.api.response.AlipayResponse;
import com.alipay.global.api.tools.WebhookTool;

@RestController
public class PaymentNotifyHandleBySDK {

    /**
     * alipay public key, used to verify signature
     */
    private static final String SERVER_PUBLIC_KEY = "";

    /**
     * payment result notify processor
     * using <a href="https://spring.io">Spring Framework</a>
     *
     * @param request    HttpServletRequest
     * @param notifyBody notify body
     * @return
     */
    @PostMapping("/payNotify")
    public Object payNotifyHandler(HttpServletRequest request, @RequestBody String notifyBody) {

        // retrieve the required parameters from http request
        String requestUri = request.getRequestURI();
        String requestMethod = request.getMethod();

        // retrieve the required parameters from request header
        String requestTime = request.getHeader("request-time");
        String clientId = request.getHeader("client-id");
        String signature = request.getHeader("signature");

        Result result;
        AlipayResponse response = new AlipayResponse();

        try {
            // verify the signature of notification
            boolean verifyResult = WebhookTool.checkSignature(requestUri, requestMethod, clientId, requestTime, signature, notifyBody, SERVER_PUBLIC_KEY);
            if (!verifyResult) {
                throw new RuntimeException("Invalid notify signature");
            }

            // deserialize the notification body

            // update the order status based on the notification result

            // respond to the server that the notification has been received
            result = new Result("SUCCESS", "success", ResultStatusType.S);

        } catch (Exception e) {
            String errorMsg = e.getMessage();
            // Handle error condition
            result = new Result("ERROR", errorMsg, ResultStatusType.F);
        }
        response.setResult(result);
        return ResponseEntity.ok().body(response);
    }

}
```

 Whether the card binding is successful or not, each notification request must be responded to in the format specified below. Otherwise, Antom will resend the asynchronous notification.

 ```json
{
  "result": {
    "resultCode": "SUCCESS",
    "resultStatus": "S",
    "resultMessage": "success"
  }
}
```

 > **[INFO]** **Common questions**
>
>  **Q: Will an asynchronous notification be sent immediately after a successful card binding?**
>
>  A: The asynchronous notification for the card binding result is sent within seconds, typically 3 to 5 seconds after the card binding succeeds.
>
>  ​
>
>  **Q: Will an asynchronous notification be sent if the card binding fails?**
>
>  A: Yes, it will be sent.
>
>  ​
>
>  **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 did not respond to the notification in the  [Sample code](https://docs.antom.com/ac/cashierpay/notifications.md#wkNv0)  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: Do I need to verify the signature upon receiving a card binding result notification?**
>
>  A: Yes. Signature verification is necessary to ensure that the request was sent to you by Antom. When performing verification, the assembled message must strictly adhere to the following format:   `<http-method> <http-uri> <client-id>.<request-time>.<request-body>`  . For the   `<request-body>`   part, you must use its original, unprocessed string value.
>
>  ​
>
>  **Q: How long is the validity period of the returned _cardToken_?**
>
>  A: The     *cardToken*     itself is permanently valid. If the card expires, it will become invalid at the same time. If the card expires, when you call the payment request again, Antom will return the   `INVALID_EXPIRATION_DATE`   error code. It is recommended that you guide the buyer to re-bind the updated card information.

**Tab: Inquire about the result**

#### Inquire about the result {#Pa3Wo}

 In addition to obtaining card binding results through asynchronous notifications, you can also query to get the results. You can inquire about the card binding result by calling the      [**inquireVaulting**](https://docs.antom.com/ac/ams/inquire_vaulting.md)        API using _vaultingRequestId_ from the card binding request.

 The following sample code shows how to call the   [**inquireVaulting**](https://docs.antom.com/ac/ams/inquire_vaulting.md)        API:

 ```java
public static void inquireVaulting(){
    AlipayVaultingQueryRequest alipayVaultingQueryRequest = new AlipayVaultingQueryRequest();

    //Replace with your vaultingRequestId
    alipayVaultingQueryRequest.setVaultingRequestId("c7f3ee64-c472-4d12-b8de-3157804ed55f");

    AlipayVaultingQueryResponse alipayVaultingQueryResponse;
    try{
        alipayVaultingQueryResponse = CLIENT.execute(alipayVaultingQueryRequest);
    }catch (AlipayApiException e){
        String errorMsg = e.getMessage();
        // Handle error condition
    }
}
```

 The following sample code shows a request message:

 ```json
{  
  "vaultingRequestId": "VAULT_20250508183612361_AUTO"
}
```

 ​   The following sample code shows a response message:

 ```json
{
  "paymentMethodDetail": {
    "card": {
      "brand": "MASTERCARD",
      "cardToken": "ALIPAYEfG2DFbGx2Eh****************************XA7nyWCloE4MwfmN48sP1+rSPQ==",
      "maskedCardNo": "************1310",
      "networkTransactionId": "112000********575887"
    },
    "paymentMethodType": "CARD"
  },
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  },
  "vaultingRequestId": "VAULT_2025********361_AUTO",
  "vaultingStatus": "SUCCESS"
}
```

 The table below shows the possible values of _result.resultStatus_ in the response. Please handle the result according to the guidance provided:

 | ***result.resultStatus*** | **Message** | **Further actions** |
| --- | --- | --- |
| `S` | Indicates that the API is called successfully. | You can obtain the card binding result from the _vaultingStatus_ field in the API response. - `SUCCESS`  : Indicates the card binding is successful. - `FAIL`  : Indicates the card binding failed. - `PROCESSING`  : Indicates the card binding is being processed. |
| `F` | Indicates that the API call failed. | For more information about the failure reason, refer to     *result.resultCode*    . |
| `U` | Indicates that the API call failed for unknown reasons. | Use the same _vaultingRequestId_ to try again. |

<!-- /TabGroup -->

**Tab: iOS**

## Integration preparations {#qd1cF}

 Before you start integrating, read   [Integration guide](https://docs.antom.com/integration_guide_en.md)   and   [API overview](https://docs.antom.com/ac/ams/api_fund.md)   to understand the integration steps of the server-side API and the precautions for calling the API. Furthermore, ensure the following prerequisites are met:

 - Obtained your client ID
- Complete the key configuration
- Complete the configuration of     *vaultingNotificationUrl*           to receive the asynchronous notification
- Integrate the server-side SDK package, install the server-side library, and initialize a request instance. For more details, refer to   [Server-side SDKs](https://docs.antom.com/ac/sdks/server_sdks.md)  .
- Integrate the client-side SDK package by following the steps detailed in   [Integrate the SDK package for iOS](https://docs.antom.com/ac/sdks/ios.md)  , and ensure to use the latest SDK version.

## Integration steps {#WeQ03}

 Follow the steps below to begin your integration:

 1. (Optional) Preload the card binding page
2. Create a vaulting sesssion
3. Invoke the SDK component
4. Obtain the card binding result

### Step 1: (Optional) Preload the card binding page  **[Client-side]** {#wfPmV}

 It is strongly recommended to perform a preloading process when loading the card‑binding page to enhance the rendering speed of the checkout page. This process does not impact your page performance. Refer to the following code example to implement preloading.

 ```objectivec
[[AMSVaulting shared] preload];
```

### Step 2: Create a vaulting sesssion   **[Server-side]** {#G1IXz}

 When a buyer selects a payment method provided by Antom, you need to collect key information such as card binding request ID, card binding redirect URL, and card binding result notification URL, call the   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)        API to create a vaulting session, and return the vaulting session to the client.

 Creating a payment session includes the following parameters:

 Creating a payment session includes the following parameters:

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *paymentMethodType* | Yes | The payment method to be bound. |
| *vaultingRequestId* | Yes | The unique ID generated by the merchant. Every time you initiate card binding, you must have a new ID. |
| *vaultingNotificationUrl* | Yes | The card binding result notification address. |
| *redirectUrl* | No | The URL to be redirected to after binding. |
| *is3DSAuthentication* | No | Specify whether 3D authentication is required for this card binding request. Set the value to   `true`   if 3D authentication is required. For details, refer to   [3D Secure 2](https://docs.antom.com/ac/pm/3ds.md)  . > **[INFO]** **Notes**    : - [South Korean Cards](https://docs.antom.com/ac/antomop/south_korean_mdx.md)       do not support 3D authentication. > - If subsequent payments involve   [Merchant-Initiated Transaction (MIT)](https://docs.antom.com/ac/pm/mit.md)   scenarios, the card scheme strongly recommends specifying 3D authentication when binding the card. |

 For more information about complete parameters, refer to the   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)   API.

 The following sample code shows how to call the   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)   API:

 ```java
public static void createVaultingSession(){
    AlipayVaultingSessionRequest alipayVaultingSessionRequest = new AlipayVaultingSessionRequest();

    // Replace with your paymentRequestId
    String vaultingRequestId = UUID.randomUUID().toString();
    alipayVaultingSessionRequest.setVaultingRequestId(vaultingRequestId);

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

    // Bind the card
    AlipayVaultingSessionResponse alipayVaultingSessionResponse;
    try{
        alipayVaultingSessionResponse = CLIENT.execute(alipayVaultingSessionRequest);
    }catch (AlipayApiException e){
        String errorMsg = e.getMessage();
        // Handle error condition
    }

}
```

 The following code shows a sample of the request:

 ```json
{
  "paymentMethodType": "CARD",
  "redirectUrl": "http://www.yourRedirectUrl.com",
  "vaultingNotificationUrl": "http://www.yourNotifyUrl.com",
  "vaultingRequestId": "4a17609d-1749-4f53-a2fb-8bdba8d5aad8"
}
```

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

 - *vaultingSessionData*    : The vaulting session data to be returned to the client.
- *vaultingSessionExpiryTime*    : The expiration time of the vaulting session.

 ```json
{
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  },
  "vaultingSessionData": "qOnxVjFYB/QNieiGGnf3P7XOreGIRi7dSZDMzCzT5DzGLaI5a5paDhEAgmG8IwVuTCHscscPdJg==&&SG&&188&&eyJleHRlbmRJbmZvIjoie1widmVyc2lvbk1hcFwiOntcIndlYlwiOntcIjEuMS4wXCI6e1widGFyZ2V0V2ViVmVyaXNvblwiOlwiMS4xLjBcIn0sXCIxLjIuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMi4wXCJ9fSxcImlPU1wiOntcIjEuMS4wXCI6e1widGFyZ2V0V2ViVmVyaXNvblwiOlwiMS4xLjBcIn0sXCIxLjIuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMi4wXCJ9fSxcIkFuZHJvaWRcIjp7XCIxLjEuMFwiOntcInRhcmdldFdlYlZlcmlzb25cIjpcIjEuMS4wXCJ9LFwiMS4yLjBcIjp7XCJ0YXJnZXRXZWJWZXJpc29uXCI6XCIxLjIuMFwifX19fSIsInBheW1lbnRTZXNzaW9uQ29uZmlnIjp7InBheW1lbnRNZXRob2RDYXRlZ29yeVR5cGUiOiJDQVJEIiwicHJvZHVjdFNjZW5lIjoiVkFVTFRJTkciLCJwcm9kdWN0U2NlbmVWZXJzaW9uIjoiMS4wIn0sInNraXBSZW5kZXJQYXltZW50TWV0aG9kIjpm******",
  "vaultingSessionExpiryTime": "2024-12-31T12:06:05+08:00",
  "vaultingSessionId": "********qOnxVjFYB/QNieiGGnf3P7XOreGIRi7fAxqpLf+1appjsXAs5Eq1H"
}
```

### Step 3: Invoke the SDK component  **[Client-side]** {#CrIYX}

 Use     *vaultingSessionData*     to invoke the SDK, and the SDK renders the required card payment element collection page and handles the 3D Secure flow, allowing the buyer to complete a server‑to‑server card binding process.

#### 1\. Instantiate the client SDK {#EgskW}

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

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *locale* | No | 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, English is used by default: - `en_US`  : English - `es_ES`  : Spanish - `fr_FR`  : French - `nl_NL`  : Dutch - `it_IT`  : Italian - `de_DE`  : German - `zh_CN`  : Simplified Chinese - `zh_HK`  : Traditional Chinese - `pt_PT`  : Portuguese (Portugal) - `ro`  : Romanian - `pl_PL`  : Polish - `th_TH`  : Thai |
| *options* | No | Used to configure the redirection after the card binding and specify whether to use the sandbox environment. Valid values are: - `"notRedirectAfterComplete", "true"`  : Optional. Boolean type. The default value is  `false`  indicates the buyer is redirected to your page after successful card binding. The same applies if the value is empty.   `true`      indicates there is no redirection after card binding. You need to manually control the subsequent card binding flow based on client-side event codes.   - `"sandbox", "true"`  : Sandbox environment.   - `"sandbox", "false"`  : Default value. Production environment. |

 The following sample code shows how to instantiate the SDK:

 ```objectivec
#import <AMSComponent/AMSComponent-Swift.h>

AMSVaultingConfiguration *componentConfig = [AMSVaultingConfiguration new];
componentConfig.locale = @"en_US";
// set sandbox environment, not production environment
NSDictionary *options = @{@"sandbox": @"true",
                          @"notRedirectAfterComplete": @"true"
                          };
componentConfig.options = options;

[[AMSVaulting shared] initConfiguration:componentConfig];
[AMSVaulting shared].paymentDelegate = self;

[[AMSVaulting shared] createComponent:vaultingSessionData];

#pragma AMSPaymentProtocol
- (void)onEventCallback:(NSString *)eventCode eventResult:(AMSEventResult *)eventResult
{
    NSLog(@"eventCode%@ eventResult%@", eventCode, eventResult);
}
```

#### 2\. Create a card binding component {#Iy1TN}

 Use the   `createComponent`   or   `mountComponent`   function in the instance object to create a card binding component. Configuration objects includes the following parameters:

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *sessionData* | Yes | Create a configuration object by using the     *sessionData*     parameter: Pass the complete data in the _vaultingSessionData_ parameter obtained in the response through the   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)        API to the _sessionData_ parameter. |
| *appearance* | No | Customized appearance theme configuration, and it contains the following child parameters: - *showSubmitButton*    : Optional. Boolean type. The default value is      `false`  , indicates disabling the render button on the card‑binding page. |

 There are different ways in which you can make the SDK component display on a page through a pop-up window or embedded on a page, the following are the sample codes:

<!-- TabGroup -->

**Tab: Pop-up experience**

```objectivec
[[AMSVaulting shared] createComponent:sessionData];
//Unmount the component
[[AMSVaulting shared] onDestroy];
```

**Tab: Embedded experience**

```objectivec
[[AMSVaulting shared] mountComponent:sessionData];

// The user completes input and submits binding
NSString *dataString = @"{"billingAddress":{"zipCode":"310000","region":"CN"}}";

[[AMSVaulting shared] submit: dataString];
//Unmount the component
[[AMSVaulting shared] onDestroy];
```

<!-- /TabGroup -->

#### 3\. Handle SDK callback event codes {#ciZkt}

 According to the configuration of the     *notRedirectAfterComplete*     parameter, handle the subsequent process accordingly:

 - If you set     *notRedirectAfterComplete*     to   `false`  , the buyer will be redirected to the _vaultingRedirectUrl_ that you provided in   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)         API after completing the card binding. You can obtain the card binding result by active query in that URL and show it to the buyer.
- If     *notRedirectAfterComplete*     is  `true`  , the card binding result will be given through the  `onEventCallback`  method. The card binding result here is only for front-end display, and the final order status is subject to the server side.

##### Event codes {#KJTM7}

 The following are the possible event codes of the card binding result returned by      `onEventCallback`      :

 | **Event code** | **Message** | **Solution** |
| --- | --- | --- |
| `SDK_ASSET_BINDING_SUCCESSFUL` | The vaulting is successful. | It is recommended to redirect the buyer to the card binding result page. |
| `SDK_ASSET_BINDING_PROCESSING` | The vaulting is being processed. | Guide the buyer to retry the card‑binding operation based on the provided information. |
| `SDK_ASSET_BINDING_FAIL` | The vaulting failed. | You can guide the buyer to complete card binding based on the   [*vaultingResultCode*](#X81wv)  . |
| `SDK_ASSET_BINDING_CANCEL` | The buyer exits the vaulting page. | You can re-invoke the SDK with the _vaultingSessionData_ that is within its validity period. If it has expired, you need to request a new _vaultingSessionData_. |
| `SDK_ASSET_BINDING_ERROR` | The vaulting status is abnormal. | You can wait for the card binding result notification, or guide the buyer to bind the card again. |

 The following sample code shows how to process the   `onEventCallback`   :

 ```objectivec
#import <AMSComponent/AMSComponent-Swift.h>

#pragma AMSPaymentProtocol
- (void)onEventCallback:(NSString *)eventCode eventResult:(AMSEventResult *)eventResult
{
    if ([eventCode isEqualToString:@"SDK_ASSET_BINDING_SUCCESSFUL"]) {
        // Card binding successful, need to unmount SDK. It is recommended to redirect to the card binding result page.
    } else if ([eventCode isEqualToString:@"SDK_ASSET_BINDING_FAIL"]) {
        // Card binding failed. It is recommended to guide the buyer to re-bind the card based on the vaultingResultCode error code prompt information.
    } else if ([eventCode isEqualToString:@"SDK_ASSET_BINDING_ERROR"]) {
        // Card binding exception. It is recommended to wait for the card binding result notification or re-guide the buyer to bind the card.
    } else if ([eventCode isEqualToString:@"SDK_ASSET_BINDING_CANCEL"]) {
        // Guide the buyer to try card binding again.
    } else {
        // Other custom events or errors of concern
    }
    NSLog(@"eventCode%@ eventResult%@", eventCode, eventResult);
}
```

 The following are sample codes for card binding results corresponding to frontend event codes:

 ```json
{
  "code": "SDK_ASSET_BINDING_SUCCESSFUL",  // Front-end event code
  "result": {
    "resultStatus": "S",
    "resultCode": "SUCCESS",
    "resultMessage": "Success"
  }
}
```

 ```json
{
  "code": "SDK_ASSET_BINDING_FAIL",  // Front-end event code
  "result": {
    "resultStatus": "S",
    "resultCode": "SUCCESS",
    "resultMessage": "Success"
  },
  "vaultingStatus":"FAIL",
  "vaultingResultCode":"PROCESS_FAIL",
  "vaultingResultMessage":"A general business failure occurred."
}
```

#### 4\. Unmount the component {#YWfsz}

 Call the   `onDestroy()`   method to unmount the created component. You need to unmount the component in the following situations:

 - When the timeout time set by your client is reached.
- When the buyer exits the card binding page.
- When you receive the card binding result callback.

 > **[INFO]** **Note**    : Only one component can be created at a time. If you need to use different _vaultingSessionData_ or recreate the component, you must first execute the unmount method.

 ```objectivec
[[AMSVaulting shared] onDestroy];
```

### Step 4: Obtain the card binding result  **[Server-side]** {#XnMZ4}

 You can obtain the card binding result by one of the following methods:

 - Receive the asynchronous notification
- Inquire about the result

<!-- TabGroup -->

**Tab: Receive the asynchronous notification**

#### Receive the asynchronous notification {#TlpcY}

 Antom will send you the card binding result notifications via the   [**notifyVaulting**](https://docs.antom.com/ac/ams/notify_vaulting.md)        API.    Follow the steps below for configuration:

##### 1\. Configure the webhook URL to receive asynchronous notifications {#EDBuY}

 - If each of your card binding operations has a unique notification URL, it is recommended to set the webhook URL in each request. You can pass the asynchronous notification receiving URL for the specific order through _vaultingNotificationUrl_ in the   [**createVaultingSession**](https://docs.antom.com/ac/ams/vaulting_session.md)        API.

 The following code shows a sample of the asynchronous notification request:

 ```json
{
  "paymentMethodDetail": {
    "card": {
      "brand": "MASTERCARD",
      "cardToken": "ALIPAY34RlcCU3ZtZ***********************sVYl8x244tyWCloE4MwfmN48sP1+rSPQ==",
      "maskedCardNo": "************1310",
      "networkTransactionId": "112000********575887"
    },
    "paymentMethodType": "CARD"
  },
  "vaultingRequestId": "VAULT_2025*******348834_AUTO",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success",
    "resultStatus": "S"
  }
}

```

 The following table shows the possible values of _result.resultStatus_ in the notification request of authorization result. Please handle the result according to the guidance provided:

 | ***result.resultStatus*** | **Message** | **Further actions** |
| --- | --- | --- |
| `S` | Indicates that the card binding is successful. | It is recommended to store the following parameters for subsequent payments: - *cardToken*        : A token generated by Antom for subsequent payments. You can associate this information with your buyer for subsequent payments. - *brand*    : The card brand. It is recommended that you store this information to display to the buyer in subsequent payments. - *maskedCardNo*    : The masked card number. It is recommended that you store this information to display to the buyer in subsequent payments. |
| `F` | Indicates that the card binding failed. | Please check     *result.resultCode*     to identify the specific failure reason. |

##### 2\. Verify the asynchronous notification {#VaGth}

 When you receive an asynchronous notification from Antom, you are required to return the response in the  [Sample code](https://docs.antom.com/ac/auto_debit/notifications.md#OqpVS)  format, but you do not need to countersign the response.

 You need to verify the signature of the authorization payment notification sent by Antom:

 ```java
import javax.servlet.http.HttpServletRequest;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.alipay.global.api.model.Result;
import com.alipay.global.api.model.ResultStatusType;
import com.alipay.global.api.response.AlipayResponse;
import com.alipay.global.api.tools.WebhookTool;

@RestController
public class PaymentNotifyHandleBySDK {

    /**
     * alipay public key, used to verify signature
     */
    private static final String SERVER_PUBLIC_KEY = "";

    /**
     * payment result notify processor
     * using <a href="https://spring.io">Spring Framework</a>
     *
     * @param request    HttpServletRequest
     * @param notifyBody notify body
     * @return
     */
    @PostMapping("/payNotify")
    public Object payNotifyHandler(HttpServletRequest request, @RequestBody String notifyBody) {

        // retrieve the required parameters from http request
        String requestUri = request.getRequestURI();
        String requestMethod = request.getMethod();

        // retrieve the required parameters from request header
        String requestTime = request.getHeader("request-time");
        String clientId = request.getHeader("client-id");
        String signature = request.getHeader("signature");

        Result result;
        AlipayResponse response = new AlipayResponse();

        try {
            // verify the signature of notification
            boolean verifyResult = WebhookTool.checkSignature(requestUri, requestMethod, clientId, requestTime, signature, notifyBody, SERVER_PUBLIC_KEY);
            if (!verifyResult) {
                throw new RuntimeException("Invalid notify signature");
            }

            // deserialize the notification body

            // update the order status based on the notification result

            // respond to the server that the notification has been received
            result = new Result("SUCCESS", "success", ResultStatusType.S);

        } catch (Exception e) {
            String errorMsg = e.getMessage();
            // Handle error condition
            result = new Result("ERROR", errorMsg, ResultStatusType.F);
        }
        response.setResult(result);
        return ResponseEntity.ok().body(response);
    }

}
```

 Whether the card binding is successful or not, each notification request must be responded to in the format specified below. Otherwise, Antom will resend the asynchronous notification.

 ```json
{
  "result": {
    "resultCode": "SUCCESS",
    "resultStatus": "S",
    "resultMessage": "success"
  }
}
```

 > **[INFO]** **Common questions**
>
>  **Q: Will an asynchronous notification be sent immediately after a successful card binding?**
>
>  A: The asynchronous notification for the card binding result is sent within seconds, typically 3 to 5 seconds after the card binding succeeds.
>
>  ​
>
>  **Q: Will an asynchronous notification be sent if the card binding fails?**
>
>  A: Yes, it will be sent.
>
>  ​
>
>  **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 did not respond to the notification in the  [Sample code](https://docs.antom.com/ac/cashierpay/notifications.md#wkNv0)  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: Do I need to verify the signature upon receiving a card binding result notification?**
>
>  A: Yes. Signature verification is necessary to ensure that the request was sent to you by Antom. When performing verification, the assembled message must strictly adhere to the following format:   `<http-method> <http-uri> <client-id>.<request-time>.<request-body>`  . For the   `<request-body>`   part, you must use its original, unprocessed string value.
>
>  ​
>
>  **Q: How long is the validity period of the returned _cardToken_?**
>
>  A: The     *cardToken*     itself is permanently valid. If the card expires, it will become invalid at the same time. If the card expires, when you call the payment request again, Antom will return the   `INVALID_EXPIRATION_DATE`   error code. It is recommended that you guide the buyer to re-bind the updated card information.

**Tab: Inquire about the result**

#### Inquire about the result {#Pa3Wo}

 In addition to obtaining card binding results through asynchronous notifications, you can also query to get the results. You can inquire about the card binding result by calling the      [**inquireVaulting**](https://docs.antom.com/ac/ams/inquire_vaulting.md)        API using _vaultingRequestId_ from the card binding request.

 The following sample code shows how to call the   [**inquireVaulting**](https://docs.antom.com/ac/ams/inquire_vaulting.md)        API:

 ```java
public static void inquireVaulting(){
    AlipayVaultingQueryRequest alipayVaultingQueryRequest = new AlipayVaultingQueryRequest();

    //Replace with your vaultingRequestId
    alipayVaultingQueryRequest.setVaultingRequestId("c7f3ee64-c472-4d12-b8de-3157804ed55f");

    AlipayVaultingQueryResponse alipayVaultingQueryResponse;
    try{
        alipayVaultingQueryResponse = CLIENT.execute(alipayVaultingQueryRequest);
    }catch (AlipayApiException e){
        String errorMsg = e.getMessage();
        // Handle error condition
    }
}
```

 The following sample code shows a request message:

 ```json
{  
  "vaultingRequestId": "VAULT_20250508183612361_AUTO"
}
```

 ​   The following sample code shows a response message:

 ```json
{
  "paymentMethodDetail": {
    "card": {
      "brand": "MASTERCARD",
      "cardToken": "ALIPAYEfG2DFbGx2Eh****************************XA7nyWCloE4MwfmN48sP1+rSPQ==",
      "maskedCardNo": "************1310",
      "networkTransactionId": "112000********575887"
    },
    "paymentMethodType": "CARD"
  },
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  },
  "vaultingRequestId": "VAULT_2025********361_AUTO",
  "vaultingStatus": "SUCCESS"
}
```

 The table below shows the possible values of _result.resultStatus_ in the response. Please handle the result according to the guidance provided:

 | ***result.resultStatus*** | **Message** | **Further actions** |
| --- | --- | --- |
| `S` | Indicates that the API is called successfully. | You can obtain the card binding result from the _vaultingStatus_ field in the API response. - `SUCCESS`  : Indicates the card binding is successful. - `FAIL`  : Indicates the card binding failed. - `PROCESSING`  : Indicates the card binding is being processed. |
| `F` | Indicates that the API call failed. | For more information about the failure reason, refer to     *result.resultCode*    . |
| `U` | Indicates that the API call failed for unknown reasons. | Use the same _vaultingRequestId_ to try again. |

<!-- /TabGroup -->

<!-- /ToggleTab -->
