# Accept payments with ACH Direct Debit

 The Automated Clearing House (ACH) Direct Debit offers a secure, reliable, and cost-effective way to facilitate electronic fund transfers between financial institutions within the United States.

 ​

 ACH Direct Debit enables businesses to seamlessly execute payments for recurring billing and account funding, significantly reducing processing fees compared to card networks or wire transfers. ACH Direct Debit enables you to build an online automatic deduction feature for your website or application. After the buyer links bank account and completes authentication and authorization during the first payment, subsequent payments can be made with just one click.

 ​

 ACH Direct Debit product supports integration on various terminal types (Web/WAP/App) for merchants in various industries.

  

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

**Tab: Web/WAP**

## User experience {#cEsdG}

 The following screenshots show the journey of paying with Trustly Direct Debit:

<!-- TabGroup -->

**Tab: First-time authorization**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/f9ff6237-9ff2-4ec9-a0a3-63b0b3deb057.png)

**Tab: Reauthentication required**

A recertification is required one year after the authorization is granted, or the payment cannot be processed.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/54a3eaad-9325-4d83-8f01-ee452736eb25.png)

**Tab: Make a payment**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/83df7e71-3af7-4dc5-9982-b4b55968baa7.png)

<!-- /TabGroup -->

## Payment flow {#bIEaV}

 The following flow diagrams illustrate the authorization and payment processes:

<!-- TabGroup -->

**Tab: Authorization**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/594f63fd-e912-4779-8850-3495e134c579.png)

**Tab: Payment**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/1384f6b5-6e3f-4d5d-9893-fb4d91bc39ff.png)

<!-- /TabGroup -->

## Integration preparations {#a99xm}

 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)   documents to understand the integration steps of the server-side API and the precautions for calling the API. Furthermore, ensure that the following prerequisites are met:

 - Obtain a client ID
- Complete the key configuration
- Complete the configuration of     *paymentNotifyUrl*     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)  .

 - Use the following recommended browser versions:

   - For mobile browsers:

     - Safari 16.6 and above (require iOS 16 and later).
    - Google Chrome 130 and above (require Android 5.0 and later).

   - For computer browsers, use the following recommended versions:

     - Safari 16.6 and above (require macOS 11 Big Sur and later).
    - Google Chrome 130 and above (require Windows 10 / macOS 11 and later).
    - Microsoft Edge 132 and above (require Windows 10 / macOS 11 and later).
    - Mozilla Firefox 128 and above (require Windows 10 / macOS 11 and later).

 Refer to   [Integrate the SDK package for Web/WAP](https://docs.antom.com/ac/sdks/web.md)   to complete integration preparations, and ensure to use SDK 1.41.0 or above.

## Integration steps {#n69JH}

 Start your integration by taking the following steps:

 1. Create a payment session (for authorization process)
2. Invoke the SDK
3. Obtain the authorization result
4. Initiate a payment
5. Obtain payment result

### Step 1: Create a payment session   **[Server-side]** {#t5pkQ}

 Call the   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)      API to create a payment session and initialize the Antom SDK using the     *paymentSessionData*     returned in the response.

 The table below lists the parameter specifications for calling the   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API during the first-time authorization and reauthorization:

 | **Parameter name** | **Child parameter name** | **Type** | **Required (First-time authorization)** | **Required (Reauthorization)** | **Description** |
| --- | --- | --- | --- | --- | --- |
| *productCode* | N/A | String | Yes | Yes | Product code. The value is fixed as  `AGREEMENT_PAYMENT`  . |
| *agreementInfo.authState* | N/A | String | Yes | Yes | The unique ID generated by the merchant to represent the authorization request. |
| *paymentRedirectUrl* | N/A | String | Yes | Yes | The merchant page URL that the buyer is redirected after successfully binding their account. |
| *paymentMethod.paymentMethodType* | N/A | String | Yes | Yes | Payment method type. The value is fixed as   `ACH_DIRECT_DEBIT`  in this case. |
| *paymentMethod.paymentMethodMetaData* > **[INFO]** **Note**    : It is recommended to pass this information during the first-time authorization for a higher success rate. | *firstName* | String | No | No | Buyer's first name. |
| *lastName* | String | No | No | Buyer's last name. |  |
| *countryCode* | String | No | No | Buyer's phone country code. |  |
| *billingAddress* | String | No | No | Buyer's billing address. |  |
| *billingPhoneNumber* | String | No | No | Buyer's phone number (excluding country code). |  |
| *billingEmail* | String | No | No | Buyer's email for receiving bills. |  |
| *merchantExternalUserEnrollDate* | String | No | No | Buyer's onboarding timestamp (in Unix format) on the merchant side. |  |
| *merchantExternalUserId* | String | No | No | Buyer's user ID on the merchant side. |  |
| *isUpdateAsset* | String | N/A | Yes | Indicates whether to update the authorization. Defaults to   `false`  . Set this parameter to   `true`   when you update the authorization. |  |
| *accessToken* | String | N/A | Yes | The access token that is used to access the corresponding scope of the buyer resource. |  |
| *scopes* | N/A | List<String> | Yes | Yes | Product Scope, The value is fixed as   `AGREEMENT_PAYMENT`  . |

 Below are code examples for first-time authorization and reauthorization.

<!-- TabGroup -->

**Tab: First-time authorization**

#### First-time authorization {#Lge1q}

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

 ```java
public static void createPaymentSession() {
    AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
    alipayPaymentSessionRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);

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

    // set paymentMethod
    PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("ACH_DIRECT_DEBIT").build();
    alipayPaymentSessionRequest.setPaymentMethod(paymentMethod);

    // set paymentMethodMetaData
    String paymentMethodMetaData = "{\"firstName\":\"Joe",\"lastName\":\"Bob\",\"billingAddress\":\"{\\\"address1\\\":\\\"37 Long Ave\\\",\\\"address2\\\":\\\"Apt 1\\\",\\\"city\\\":\\\"Boston\\\",\\\"state\\\":\\\"Massachusetts\\\",\\\"region\\\":\\\"US\\\",\\\"zipCode\\\":\\\"02134\\\"}\",\"countryCode\":\"+1\",\"billingPhoneNumber\":\"123456\",\"billingEmail\":\"billingEmail@gmail.com\",\"merchantExternalUserEnrollDate\":\"1742406307\",\"merchantExternalUserId\":\"userId-01234\"}";
    alipayPaymentSessionRequest.setPaymentMethodMetaData(paymentMethodMetaData);

    // set agreementInfo
    // replace with your authState
    String authState = UUID.randomUUID().toString();
    AgreementInfo agreementInfo = AgreementInfo.builder().authState(authState).build();
    alipayPaymentSessionRequest.setAgreementInfo(agreementInfo);

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

    // set the authorization scope
    alipayAuthConsultRequest.setScopes(new ScopeType[]{ScopeType.AGREEMENT_PAY});

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

 The following code shows a sample of the request message:

 ```json
{
  "productCode": "AGREEMENT_PAYMENT",
  "agreementInfo": {
    "authState": "paymentRequestId-123"
  },
  "paymentRedirectUrl": "https://www.yourRedirect.com",
  "paymentMethod": {
    "paymentMethodType": "ACH_DIRECT_DEBIT",
    "paymentMethodMetaData": {
        "firstName":"Joe",
        "lastName":"Bob",
        "billingAddress": {
            "address1":"37 Long Ave",
            "address2":"Apt 1",
            "city":"Boston",
            "state":"Massachusetts",
            "region":"US",
            "zipCode":"00131"
        },
        "countryCode":"+1",
        "billingPhoneNumber":"123456",
        "billingEmail":"billingEmail@gmail.com",
        "merchantExternalUserEnrollDate":"1742406307",
        "merchantExternalUserId":"userId-01234"
    }
  },
  "scopes": [
    "AGREEMENT_PAYMENT"
  ]
}
```

**Tab: Reauthorization**

#### Reauthorization {#fuzZG}

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

 ```java
public static void createPaymentSession() {
    AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
    alipayPaymentSessionRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);

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

    // set paymentMethod
    PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("ACH_DIRECT_DEBIT").build();
    alipayPaymentSessionRequest.setPaymentMethod(paymentMethod);

    // set paymentMethodMetaData
    String paymentMethodMetaData = "{\"isUpdateAsset\":\"true\", \"accessToken\":\"yourAccessToken\"}";
    alipayPaymentSessionRequest.setPaymentMethodMetaData(paymentMethodMetaData);

    // set agreementInfo
    // replace with your authState
    String authState = UUID.randomUUID().toString();
    AgreementInfo agreementInfo = AgreementInfo.builder().authState(authState).build();
    alipayPaymentSessionRequest.setAgreementInfo(agreementInfo);

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

    // set the authorization scope
    alipayAuthConsultRequest.setScopes(new ScopeType[]{ScopeType.AGREEMENT_PAY});

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

 The following code shows a sample of the request message:

 ```json
{
  "productCode": "AGREEMENT_PAYMENT",
  "agreementInfo": {
    "authState": "paymentRequestId-123"
  },
  "paymentRedirectUrl": "https://www.yourRedirect.com",
  "paymentMethod": {
    "paymentMethodType": "ACH_DIRECT_DEBIT",
    "paymentMethodMetadata": {
        "isUpdateAsset": "true",
        "accessToken": "28288803000092221760043344249yAlGLLvHy9171000061"
    }
  },
  "scopes": [
    "AGREEMENT_PAYMENT"
  ]
}
```

<!-- /TabGroup -->
 The following code shows a sample of the response, which contains the following parameters:

 - *paymentSessionData*    : the payment session data, which needs to be forwarded to your client.
- *paymentSessionExpiryTime*    : the expiration time of the payment session.

 ```json
{
  "result": {
    "resultStatus": "S",
    "resultCode": "SUCCESS",
    "resultMessage": "success."
  },
  "paymentSessionId": "UNvjVWnWPXJA4BgW+vfjsQj7PbOraafHY19X+6EqMz6Ikyj9FPVUOpv+DjiIZqMe",
  "paymentSessionData": "UNvjVWnWPXJA4BgW+vfjsQj7PbOraafHY19X+6EqMz6Kvvmsdk+akdLvoShW5avHX8e8J15P8uNVEf/PcCMyXg==&&SG&&111",
  "paymentSessionExpiryTime": "2025-07-01T09:24:47+08:00"
}
```

 Please take the next step according to the value of the     *result.resultStatus*    .

 | ***resultStatus*** | **Message** | **Further actions** |
| --- | --- | --- |
| `S` | The payment session is successfully created. | Return the obtained     *paymentSessionData*     to the merchant's frontend. |
| `F` | The payment session creation failed. | Check and verify whether the required request parameters (including the header parameters and body parameters) of the current API are correctly passed and valid. |
| `U` | The payment session creation failed due to unknown reasons. | Replace the     *paymentRequestId*     and     *authstate*     value, then retry the API call to resolve the issue. If the problem persists, contact Antom Technical Support. |

 > **[INFO]** **Note**    : If you do not receive a response, it may be due to a network timeout. Please retry the API call with a new     *paymentRequestId*     and     *authstate*     value.

 > **[INFO]** **Common questions**
>
>  **Q: When should I prompt the buyer to reattempt authorization?**  
>     **A:**     Guide the buyer to reattempt authorization when a payment fails and the   `INVALID_ACCESS_TOKEN`   error code is received.
>
>  **Q: What is the difference between providing buyer information under**       ***paymentMethodMetaData***       **and not providing it?**
>     A: There is no difference in the user interaction flow. However, it is strongly recommended to provide buyer information, as it helps improve the corresponding success rate.
>
>  **Q: How long does the buyer have to complete the authorization?**
>     A: within two hours.

### Step 2: Invoke the SDK   **[Client-side]** {#qrC7K}

#### 1\. Instantiate the SDK {#GIc21}

 Create an SDK instance and specify basic configurations. Configuration object includes the following parameters:

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *environment* | Yes | Used to specify the environment information. Valid values are: - `sandbox`  : Sandbox environment - `prod`  : Production environment |
| *locale* | No | Used to specify the language information. Currently, only English is supported. - `en_US`  : English |
| *onEventCallback* | No | A callback function that returns a specific event code when a payment event occurs during SDK runtime. > **[INFO]** **Note**    : The authorization result will not be returned via this callback function. |

 The following sample code shows how to instantiate the SDK using npm or CDN:

<!-- TabGroup -->

**Tab: npm**

```javascript
import { AMSAutoDebit } from '@alipay/ams-checkout'

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

**Tab: CDN**

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

<!-- /TabGroup -->

#### 2\. Invoke the SDK {#D6Fai}

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

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *sessionData* | Yes | Create a configuration object by using the     *sessionData*     parameter: Use the complete data of the value of     *paymentSessionData*     obtained in the response of the   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API as the value of this parameter. |

 The following sample code shows how to render the component:

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

#### 3\. Free SDK component resources {#VafEE}

 Call   `unmount`   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 (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API.
- When the buyer initiates multiple authorizations, free the component resources created in the previous   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API.

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

 > **[INFO]** **Common questions**
>
>  **Q: What can I do when I receive the `SDK_CREATEPAYMENT_PARAMETER_ERROR`?**
>
>  A: When you receive this event code, check if the     *sessionData*     passed in is correct and complete.

**Tab: iOS**

## User experience {#fc9sz}

 The following screenshots show the journey of paying with ACH Direct Debit:

<!-- TabGroup -->

**Tab: First-time authorization**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/3214c449-e1b3-4559-9cc6-c7fb23983fd8.png)

**Tab: Reauthenication required**

A recertification is required one year after the authorization is granted, or the payment cannot be processed.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/b4642818-ab6f-41f8-adcf-ad90ecb0b1e1.png)

**Tab: Make a payment**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/2b0cfa67-3769-4789-b0d5-2a99d96c530d.png)

<!-- /TabGroup -->

## Payment flow {#PcAq9}

 The following flow diagrams illustrate the authorization and payment processes:

<!-- TabGroup -->

**Tab: Authorization**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/594f63fd-e912-4779-8850-3495e134c579.png)

**Tab: Payment**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/1384f6b5-6e3f-4d5d-9893-fb4d91bc39ff.png)

<!-- /TabGroup -->

## Integration preparations {#H6wYY}

 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)   documents to understand the integration steps of the server-side API and the precautions for calling the API. Furthermore, ensure that the following prerequisites are met:

 - Obtain a client ID
- Complete the key configuration
- Complete the configuration of     *paymentNotifyUrl*     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)  .

 Version requirements:

 - Install Xcode 14 or a later version.
- Use iOS 16 or a later version.

 > **[INFO]** **Note:**     Currently, Flutter and React Native (RN) development frameworks are not supported.

 To integrate the SDK package, refer to   [Integrate the SDK Package for iOS](https://docs.antom.com/ac/sdks/ios_en.md)  .

## Integration steps {#K4w6l}

 Start your integration by taking the following steps:

 1. Create a payment session (for authorization process)
2. Invoke the SDK
3. Obtain the authorization result
4. Initiate a payment
5. Obtain payment result

### Step 1: Create a payment session   **[Server-side]** {#cclK7}

 Call the   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)      API to create a payment session and initialize the Antom SDK using the     *paymentSessionData*     returned in the response.

 The table below lists the parameter specifications for calling the   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API during the first-time authorization and reauthorization:

 | **Parameter name** | **Child parameter name** | **Type** | **Required (First-time authorization)** | **Required (Reauthorization)** | **Description** |
| --- | --- | --- | --- | --- | --- |
| *productCode* | N/A | String | Yes | Yes | Product code. The value is fixed as  `AGREEMENT_PAYMENT`  . |
| *agreementInfo.authState* | N/A | String | Yes | Yes | The unique ID generated by the merchant to represent the authorization request. |
| *paymentRedirectUrl* | N/A | String | Yes | Yes | The merchant page URL that the buyer is redirected after successfully binding their account. |
| *paymentMethod.paymentMethodType* | N/A | String | Yes | Yes | Payment method type. The value is fixed as   `ACH_DIRECT_DEBIT`  in this case. |
| *paymentMethod.paymentMethodMetaData* > **[INFO]** **Note**    : It is recommended to pass this information during the first-time authorization for a higher success rate. | *firstName* | String | No | No | Buyer's first name. |
| *lastName* | String | No | No | Buyer's last name. |  |
| *countryCode* | String | No | No | Buyer's phone country code. |  |
| *billingAddress* | String | No | No | Buyer's billing address. |  |
| *billingPhoneNumber* | String | No | No | Buyer's phone number (excluding country code). |  |
| *billingEmail* | String | No | No | Buyer's email for receiving bills. |  |
| *merchantExternalUserEnrollDate* | String | No | No | Buyer's onboarding timestamp (in Unix format) on the merchant side. |  |
| *merchantExternalUserId* | String | No | No | Buyer's user ID on the merchant side. |  |
| *isUpdateAsset* | String | N/A | Yes | Indicates whether to update the authorization. Defaults to   `false`  . Set this parameter to   `true`   when you update the authorization. |  |
| *accessToken* | String | N/A | Yes | The access token that is used to access the corresponding scope of the buyer resource. |  |
| *scopes* | N/A | List<String> | Yes | Yes | Product Scope, The value is fixed as   `AGREEMENT_PAYMENT`  . |

 Below are code examples for first-time authorization and reauthorization.

<!-- TabGroup -->

**Tab: First-time authorization**

#### First-time authorization {#iqRaA}

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

 ```java
public static void createPaymentSession() {
    AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
    alipayPaymentSessionRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);

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

    // set paymentMethod
    PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("ACH_DIRECT_DEBIT").build();
    alipayPaymentSessionRequest.setPaymentMethod(paymentMethod);

    // set paymentMethodMetaData
    String paymentMethodMetaData = "{\"firstName\":\"Joe",\"lastName\":\"Bob\",\"billingAddress\":\"{\\\"address1\\\":\\\"37 Long Ave\\\",\\\"address2\\\":\\\"Apt 1\\\",\\\"city\\\":\\\"Boston\\\",\\\"state\\\":\\\"Massachusetts\\\",\\\"region\\\":\\\"US\\\",\\\"zipCode\\\":\\\"02134\\\"}\",\"countryCode\":\"+1\",\"billingPhoneNumber\":\"123456\",\"billingEmail\":\"billingEmail@gmail.com\",\"merchantExternalUserEnrollDate\":\"1742406307\",\"merchantExternalUserId\":\"userId-01234\"}";
    alipayPaymentSessionRequest.setPaymentMethodMetaData(paymentMethodMetaData);

    // set agreementInfo
    // replace with your authState
    String authState = UUID.randomUUID().toString();
    AgreementInfo agreementInfo = AgreementInfo.builder().authState(authState).build();
    alipayPaymentSessionRequest.setAgreementInfo(agreementInfo);

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

    // set the authorization scope
    alipayAuthConsultRequest.setScopes(new ScopeType[]{ScopeType.AGREEMENT_PAY});

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

 The following code shows a sample of the request message:

 ```json
{
  "productCode": "AGREEMENT_PAYMENT",
  "agreementInfo": {
    "authState": "paymentRequestId-123"
  },
  "paymentRedirectUrl": "https://www.yourRedirect.com",
  "paymentMethod": {
    "paymentMethodType": "ACH_DIRECT_DEBIT",
    "paymentMethodMetaData": {
        "firstName":"Joe",
        "lastName":"Bob",
        "billingAddress": {
            "address1":"37 Long Ave",
            "address2":"Apt 1",
            "city":"Boston",
            "state":"Massachusetts",
            "region":"US",
            "zipCode":"00131"
        },
        "countryCode":"+1",
        "billingPhoneNumber":"123456",
        "billingEmail":"billingEmail@gmail.com",
        "merchantExternalUserEnrollDate":"1742406307",
        "merchantExternalUserId":"userId-01234"
    }
  },
  "scopes": [
    "AGREEMENT_PAYMENT"
  ]
}
```

**Tab: Reauthorization**

#### Reauthorization {#UH5TO}

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

 ```java
public static void createPaymentSession() {
    AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
    alipayPaymentSessionRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);

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

    // set paymentMethod
    PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("ACH_DIRECT_DEBIT").build();
    alipayPaymentSessionRequest.setPaymentMethod(paymentMethod);

    // set paymentMethodMetaData
    String paymentMethodMetaData = "{\"isUpdateAsset\":\"true\", \"accessToken\":\"yourAccessToken\"}";
    alipayPaymentSessionRequest.setPaymentMethodMetaData(paymentMethodMetaData);

    // set agreementInfo
    // replace with your authState
    String authState = UUID.randomUUID().toString();
    AgreementInfo agreementInfo = AgreementInfo.builder().authState(authState).build();
    alipayPaymentSessionRequest.setAgreementInfo(agreementInfo);

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

    // set the authorization scope
    alipayAuthConsultRequest.setScopes(new ScopeType[]{ScopeType.AGREEMENT_PAY});

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

 The following code shows a sample of the request message:

 ```json
{
  "productCode": "AGREEMENT_PAYMENT",
  "agreementInfo": {
    "authState": "paymentRequestId-123"
  },
  "paymentRedirectUrl": "https://www.yourRedirect.com",
  "paymentMethod": {
    "paymentMethodType": "ACH_DIRECT_DEBIT",
    "paymentMethodMetadata": {
        "isUpdateAsset": "true",
        "accessToken": "28288803000092221760043344249yAlGLLvHy9171000061"
    }
  },
  "scopes": [
    "AGREEMENT_PAYMENT"
  ]
}
```

<!-- /TabGroup -->
 The following code shows a sample of the response, which contains the following parameters:

 - *paymentSessionData*    : the payment session data, which needs to be forwarded to your client.
- *paymentSessionExpiryTime*    : the expiration time of the payment session.

 ```json
{
  "result": {
    "resultStatus": "S",
    "resultCode": "SUCCESS",
    "resultMessage": "success."
  },
  "paymentSessionId": "UNvjVWnWPXJA4BgW+vfjsQj7PbOraafHY19X+6EqMz6Ikyj9FPVUOpv+DjiIZqMe",
  "paymentSessionData": "UNvjVWnWPXJA4BgW+vfjsQj7PbOraafHY19X+6EqMz6Kvvmsdk+akdLvoShW5avHX8e8J15P8uNVEf/PcCMyXg==&&SG&&111",
  "paymentSessionExpiryTime": "2025-07-01T09:24:47+08:00"
}
```

### Step 2: Invoke the SDK   **[Client-side]** {#T20oY}

#### 1\. Instantiate the SDK {#QjrZ8}

 Create an SDK instance and specify basic configurations. Configuration object includes the following parameters:

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *locale* | No | Used to specify the language information. Currently, only English is supported. - `en_US`  : English |
| *options* | No | Used to specify whether to use the sandbox environment. Valid values are: - `"sandbox", "true"`  : Sandbox environment - `"sandbox", "false"`  : Production environment |
| *fromScheme* | No | When the buyer completes verification on the bank page, the system will redirect back to your merchant app according to the   `exampleForScheme`   configuration. |

 Implementing   `AMSPaymentProtocol`   used for handling corresponding events in subsequent processes. It contains the following method:

 | **Method** | **Required** | **Description** |
| --- | --- | --- |
| `onEventCallback` | No | A callback function that monitors payment events on the checkout page, returning     *eventCode*     and     *eventResult*    . The payment success result will not be returned by this callback function by default. A redirection to the payment success result page that you specified will take place instead. |

 The following sample code shows how to instantiate the SDK:

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

AMSAutoDebitConfiguration *componentConfig = [AMSAutoDebitConfiguration new];
componentConfig.locale = @"en_US";

componentConfig.fromScheme = @"exampleForScheme";

// Set the sandbox environment. If you leave it empty, the production environment is used by default.
NSDictionary *options = @{@"sandbox": @"true"};
componentConfig.options = options;

[[AMSAutoDebit shared] initConfiguration:componentConfig];

// Set the callback to monitor payment events on the checkout page.
[AMSAutoDebit shared].paymentDelegate = self;

-(void)onEventCallback:(NSString *)eventCode eventResult:(AMSEventResult *)eventResult {
    // For eventCode, please refer to Event codes at the end of this document.
    NSLog(@"eventCode%@ eventResult%@", eventCode, eventResult);
}

// The server calls the createPaymentSession API to obtain paymentSessionData.
```

#### 2\. Invoke the SDK {#y8XBQ}

 Call the   `createComponent`   method:

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *sessionData* | Yes | Create a configuration object by using the     *sessionData*     parameter: Use the complete data of the value of     *paymentSessionData*     obtained in the response of the   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API as the value of this parameter. |

 The merchant-client can receive notifications using the callback function. After receiving the callback notification, use the   `openURL`      method in the     *AppDelegate*     file to handle the redirection from the bank to the merchant's side:

 - Use   `canProcessOrderWithPaymentResult()`   to check whether the redirect URL, to redirect from the bank to the merchant side, is valid.
- Use   `processOrderWithPaymentResult()`   to handle the redirection from the bank to the merchant's side.

 ```typescript
[[AMSAutoDebit shared] createComponent:sessionData];

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
     if ([url.scheme isEqualToString:@"exampleForScheme"]) {
        if ([[AMSAutoDebit shared] canProcessOrderWithPaymentResult:url]) {
            [[AMSAutoDebit shared] processOrderWithPaymentResult:url];
        }
    }
    return YES;
}
```

#### 3\. Free SDK component resources {#sgQJc}

 Call   `onDestroy`      to free SDK component resources in the following situations:

 - When the buyer exits the checkout page, completely free the component resources created in the   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API.
- When the buyer initiates multiple authorizations, and the parameters in   `initConfiguration`   are changed, free the component resources created in the previous   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API.

 In the following cases, you do not need to call onDestroy, and the SDK will automatically free partial resources (when iOS SDK AMSComponents is 1.33.0 version or above).

 - When the buyer initiates multiple authorizations, and the parameters in   `initConfiguration`   have not changed. The SDK will automatically free partial resources after the payment is completed to reset to the state before   `createComponent`      was called   .

 The following sample code shows how to invoke the SDK:

 ```objectivec
[[AMSAutoDebit shared] createComponent:sessionData];

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
     if ([url.scheme isEqualToString:@"exampleForScheme"]) {
        if ([[AMSAutoDebit shared] canProcessOrderWithPaymentResult:url]) {
            [[AMSAutoDebit shared] processOrderWithPaymentResult:url];
        }
    }
    return YES;
}

//Completely free SDK component resources
[[AMSAutoDebit shared] onDestroy];
```

**Tab: Android**

## User experience {#qPNBd}

 The following screenshots show the journey of paying with ACH Direct Debit:

<!-- TabGroup -->

**Tab: First-time authorization**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/fb78bfcf-09f2-4af1-85af-dbf1e29662bb.png)

**Tab: Reauthenication required**

A recertification is required one year after the authorization is granted, or the payment cannot be processed.

 ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/1cbd3fe6-4345-45ed-a38f-a8927c773fa4.png)

**Tab: Make a payment**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/2b0cfa67-3769-4789-b0d5-2a99d96c530d.png)

<!-- /TabGroup -->

## Payment flow {#O9xav}

 The following flow diagrams illustrate the authorization and payment processes:

<!-- TabGroup -->

**Tab: Authorization**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/594f63fd-e912-4779-8850-3495e134c579.png)

**Tab: Payment**

![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/1384f6b5-6e3f-4d5d-9893-fb4d91bc39ff.png)

<!-- /TabGroup -->

## Integration preparations {#EyQrE}

 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)   documents to understand the integration steps of the server-side API and the precautions for calling the API. Furthermore, ensure that the following prerequisites are met:

 - Obtain a client ID
- Complete the key configuration
- Complete the configuration of     *paymentNotifyUrl*     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)  .

 Version requirements:

 > **[INFO]** **Important Note on Version Requirements:**
>
>  The minimum version requirements listed below are defined by our banking and are subject to change. We strongly recommend checking this documentation periodically for the most current information before beginning your integration.

 - Browser-based OAuth Flow: For buyers who do not have the app installed, this flow targets at least Android 5 (API level 21) or higher.
- App-to-App OAuth Flow: Target at least Android 11 (API level 30) or higher.

 > **[INFO]** **Note:**     Currently, Flutter and React Native (RN) development frameworks are not supported.

 To integrate the SDK package, refer to   [Integrate the SDK Package for Android](https://docs.antom.com/ac/sdks/android.md)  .

## Integration steps {#n69JH}

 Start your integration by taking the following steps:

 1. Create a payment session (for authorization process)
2. Invoke the SDK
3. Obtain the authorization result
4. Initiate a payment
5. Obtain payment result

### Step 1: Create a payment session   **[Server-side]** {#XUbco}

 Call the   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)      API to create a payment session and initialize the Antom SDK using the     *paymentSessionData*     returned in the response.

 The table below lists the parameter specifications for calling the   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API during the first-time authorization and reauthorization:

 | **Parameter name** | **Child parameter name** | **Type** | **Required (First-time authorization)** | **Required (Reauthorization)** | **Description** |
| --- | --- | --- | --- | --- | --- |
| *productCode* | N/A | String | Yes | Yes | Product code. The value is fixed as  `AGREEMENT_PAYMENT`  . |
| *agreementInfo.authState* | N/A | String | Yes | Yes | The unique ID generated by the merchant to represent the authorization request. |
| *paymentRedirectUrl* | N/A | String | Yes | Yes | The merchant page URL that the buyer is redirected after successfully binding their account. |
| *paymentMethod.paymentMethodType* | N/A | String | Yes | Yes | Payment method type. The value is fixed as   `ACH_DIRECT_DEBIT`  in this case. |
| *paymentMethod.paymentMethodMetaData* > **[INFO]** **Note**    : It is recommended to pass this information during the first-time authorization for a higher success rate. | *firstName* | String | No | No | Buyer's first name. |
| *lastName* | String | No | No | Buyer's last name. |  |
| *countryCode* | String | No | No | Buyer's phone country code. |  |
| *billingAddress* | String | No | No | Buyer's billing address. |  |
| *billingPhoneNumber* | String | No | No | Buyer's phone number (excluding country code). |  |
| *billingEmail* | String | No | No | Buyer's email for receiving bills. |  |
| *merchantExternalUserEnrollDate* | String | No | No | Buyer's onboarding timestamp (in Unix format) on the merchant side. |  |
| *merchantExternalUserId* | String | No | No | Buyer's user ID on the merchant side. |  |
| *isUpdateAsset* | String | N/A | Yes | Indicates whether to update the authorization. Defaults to   `false`  . Set this parameter to   `true`   when you update the authorization. |  |
| *accessToken* | String | N/A | Yes | The access token that is used to access the corresponding scope of the buyer resource. |  |
| *scopes* | N/A | List<String> | Yes | Yes | Product Scope, The value is fixed as   `AGREEMENT_PAYMENT`  . |

 Below are code examples for first-time authorization and reauthorization.

<!-- TabGroup -->

**Tab: First-time authorization**

#### First-time authorization {#Lge1q}

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

 ```java
public static void createPaymentSession() {
    AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
    alipayPaymentSessionRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);

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

    // set paymentMethod
    PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("ACH_DIRECT_DEBIT").build();
    alipayPaymentSessionRequest.setPaymentMethod(paymentMethod);

    // set paymentMethodMetaData
    String paymentMethodMetaData = "{\"firstName\":\"Joe",\"lastName\":\"Bob\",\"billingAddress\":\"{\\\"address1\\\":\\\"37 Long Ave\\\",\\\"address2\\\":\\\"Apt 1\\\",\\\"city\\\":\\\"Boston\\\",\\\"state\\\":\\\"Massachusetts\\\",\\\"region\\\":\\\"US\\\",\\\"zipCode\\\":\\\"02134\\\"}\",\"countryCode\":\"+1\",\"billingPhoneNumber\":\"123456\",\"billingEmail\":\"billingEmail@gmail.com\",\"merchantExternalUserEnrollDate\":\"1742406307\",\"merchantExternalUserId\":\"userId-01234\"}";
    alipayPaymentSessionRequest.setPaymentMethodMetaData(paymentMethodMetaData);

    // set agreementInfo
    // replace with your authState
    String authState = UUID.randomUUID().toString();
    AgreementInfo agreementInfo = AgreementInfo.builder().authState(authState).build();
    alipayPaymentSessionRequest.setAgreementInfo(agreementInfo);

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

    // set the authorization scope
    alipayAuthConsultRequest.setScopes(new ScopeType[]{ScopeType.AGREEMENT_PAY});

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

 The following code shows a sample of the request message:

 ```json
{
  "productCode": "AGREEMENT_PAYMENT",
  "agreementInfo": {
    "authState": "paymentRequestId-123"
  },
  "paymentRedirectUrl": "https://www.yourRedirect.com",
  "paymentMethod": {
    "paymentMethodType": "ACH_DIRECT_DEBIT",
    "paymentMethodMetaData": {
        "firstName":"Joe",
        "lastName":"Bob",
        "billingAddress": {
            "address1":"37 Long Ave",
            "address2":"Apt 1",
            "city":"Boston",
            "state":"Massachusetts",
            "region":"US",
            "zipCode":"00131"
        },
        "countryCode":"+1",
        "billingPhoneNumber":"123456",
        "billingEmail":"billingEmail@gmail.com",
        "merchantExternalUserEnrollDate":"1742406307",
        "merchantExternalUserId":"userId-01234"
    }
  },
  "scopes": [
    "AGREEMENT_PAYMENT"
  ]
}
```

**Tab: Reauthorization**

#### Reauthorization {#fuzZG}

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

 ```java
public static void createPaymentSession() {
    AlipayPaymentSessionRequest alipayPaymentSessionRequest = new AlipayPaymentSessionRequest();
    alipayPaymentSessionRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);

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

    // set paymentMethod
    PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("ACH_DIRECT_DEBIT").build();
    alipayPaymentSessionRequest.setPaymentMethod(paymentMethod);

    // set paymentMethodMetaData
    String paymentMethodMetaData = "{\"isUpdateAsset\":\"true\", \"accessToken\":\"yourAccessToken\"}";
    alipayPaymentSessionRequest.setPaymentMethodMetaData(paymentMethodMetaData);

    // set agreementInfo
    // replace with your authState
    String authState = UUID.randomUUID().toString();
    AgreementInfo agreementInfo = AgreementInfo.builder().authState(authState).build();
    alipayPaymentSessionRequest.setAgreementInfo(agreementInfo);

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

    // set the authorization scope
    alipayAuthConsultRequest.setScopes(new ScopeType[]{ScopeType.AGREEMENT_PAY});

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

 The following code shows a sample of the request message:

 ```json
{
  "productCode": "AGREEMENT_PAYMENT",
  "agreementInfo": {
    "authState": "paymentRequestId-123"
  },
  "paymentRedirectUrl": "https://www.yourRedirect.com",
  "paymentMethod": {
    "paymentMethodType": "ACH_DIRECT_DEBIT",
    "paymentMethodMetadata": {
        "isUpdateAsset": "true",
        "accessToken": "28288803000092221760043344249yAlGLLvHy9171000061"
    }
  },
  "scopes": [
    "AGREEMENT_PAYMENT"
  ]
}
```

<!-- /TabGroup -->
 The following code shows a sample of the response, which contains the following parameters:

 - *paymentSessionData*    : the payment session data, which needs to be forwarded to your client.
- *paymentSessionExpiryTime*    : the expiration time of the payment session.

 ```json
{
  "result": {
    "resultStatus": "S",
    "resultCode": "SUCCESS",
    "resultMessage": "success."
  },
  "paymentSessionId": "UNvjVWnWPXJA4BgW+vfjsQj7PbOraafHY19X+6EqMz6Ikyj9FPVUOpv+DjiIZqMe",
  "paymentSessionData": "UNvjVWnWPXJA4BgW+vfjsQj7PbOraafHY19X+6EqMz6Kvvmsdk+akdLvoShW5avHX8e8J15P8uNVEf/PcCMyXg==&&SG&&111",
  "paymentSessionExpiryTime": "2025-07-01T09:24:47+08:00"
}
```

 Please take the next step according to the value of the     *result.resultStatus*    .

 | ***resultStatus*** | **Message** | **Further actions** |
| --- | --- | --- |
| `S` | The payment session is successfully created. | Return the obtained     *paymentSessionData*     to the merchant's frontend. |
| `F` | The payment session creation failed. | Check and verify whether the required request parameters (including the header parameters and body parameters) of the current API are correctly passed and valid. |
| `U` | The payment session creation failed due to unknown reasons. | Replace the     *paymentRequestId*     and     *authstate*     value, then retry the API call to resolve the issue. If the problem persists, contact Antom Technical Support. |

 > **[INFO]** **Note**    : If you do not receive a response, it may be due to a network timeout. Please retry the API call with a new     *paymentRequestId*     and     *authstate*     value.

 > **[INFO]** **Common questions**
>
>  **Q: When should I prompt the buyer to reattempt authorization?**  
>     **A:**     Guide the buyer to reattempt authorization when a payment fails and the   `INVALID_ACCESS_TOKEN`   error code is received.
>
>  **Q: What is the difference between providing buyer information under**       ***paymentMethodMetaData***       **and not providing it?**
>     A: There is no difference in the user interaction flow. However, it is strongly recommended to provide buyer information, as it helps improve the corresponding success rate.
>
>  **Q: How long does the buyer have to complete the authorization?**
>     A: The buyer needs to complete the authorization within 1 hour.

### Step 2: Invoke the SDK   **[Client-side]** {#jFMcl}

#### 1\. Instantiate the SDK {#zNy2q}

 Create an SDK instance and specify basic configurations. Configuration object includes the following parameters:

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *setLocale* | No | Used to specify the language information. Currently, only English is supported. - `"en", "US"`  : English |
| *setOption* | No | Used to specify the window alignment mode and whether to use the sandbox environment. Valid values are: - `"sandbox", "true"`  : Sandbox environment. - `"sandbox", "false"`  : Production environment. |
| *setFromScheme* *​* | No | When a buyer completes verification in bank page, the system will redirect back to your merchant app according to the   `exampleForScheme`   configuration. |

 Implementing   `setOnCheckoutListener`   used for handling corresponding events in subsequent processes. It contains the following method:

 | **Method** | **Required** | **Description** |
| --- | --- | --- |
| `onEventCallback` | No | A callback function that monitors payment events on the checkout page, returning     *eventCode*     and     *eventResult*    . The payment success result will not be returned by this callback function by default. A redirection to the payment success result page that you specified will take place instead. |

 The following sample code shows how to instantiate the SDK:

 ```java
// Step 1: Create the AMSAutoDebitConfiguration type.
AMSAutoDebitConfiguration configuration = new AMSAutoDebitConfiguration();
configuration.setLocale(new Locale("en", "US"));
configuration.setFromScheme("exampleForScheme");
// Set the sandbox environment. If you leave it empty, the production environment is used by default.
configuration.setOption("sandbox", "true");
// Set the callback to monitor payment events on the checkout page.
configuration.setOnCheckoutListener(new OnCheckoutListener() {
    @Override
    public void onEventCallback(String eventCode, AMSEventResult eventResult) {
        // For eventCode, please refer to Event codes at the end of this document.
        Toast.makeText(activity, "eventCode=" + eventCode + " message=" + message, Toast.LENGTH_SHORT).show();
    }
});

// Instantiate AMSAutoDebit.
AMSAutoDebit checkout = new AMSAutoDebit.Builder(activity, configuration).build();
```

#### 2\. Invoke the SDK {#xqrl5}

 Call the   `createComponent`   method:

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *sessionData* | Yes | Create a configuration object by using the     *sessionData*     parameter: Use the complete data of the value of     *paymentSessionData*     obtained in the response of the   [**createPaymentSession (EasySafePay)**](https://docs.antom.com/ac/ams/createpaymentsession_easypay.md)   API as the value of this parameter. |

#### 3\. Free SDK component resources {#e0mHx}

 Call   `onDestroy`   to free SDK component resources in the following situations:

 - When the buyer exits the checkout page, free the component resources created in the   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API.
- When the buyer initiates multiple authorizations, and the parameters in  `AMSAutoDebitConfiguration`   are changed, free the component resources created in the previous   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API.

 In the following cases, you do not need to call onDestroy, and the SDK will automatically release resources (when SDK version is 1.33.0 and above).

 - When the buyer initiates multiple authorizations, and the parameters in   `AMSAutoDebitConfiguration`   have not changed. The SDK will automatically recycle some resources after the payment is completed to reset to the state before   `createComponent`  .

 The following sample code shows how to invoke the SDK:

 ```java
checkout.createComponent(activity, sessionData);

//Completely free SDK component resources
checkout.onDestroy();
```

<!-- /ToggleTab -->

#### Event codes {#RZKPY}

 The following event codes will be returned by   `onEventCallback`   during the component's runtime lifecycle.

<!-- TabGroup -->

**Tab: Web**

| **Type** | **Code** | **Description** | **Further action** |
| --- | --- | --- | --- |
| Status code | SDK_CALL_URL_SUCCESS | Successfully redirected to the merchant page. | No further action is needed. |
| SDK_PAYMENT_CANCEL | The buyer canceled the authorization (the buyer exited the authorization page without submitting the order). | You can re-invoke the SDK using     *paymentSessionData*     within its validity period; If it has expired, you need to initiate a new   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API. |  |
| Error code | SDK_LAUNCH_PAYMENT_APP_ERROR | This event code indicates one of the following situations: - Failed to redirect to the merchant page. - The     *paymentRedirectUrl*     parameter is not correctly passed when calling the   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)        API. | Check whether the     *paymentRedirectUrl*     parameter is correctly passed when calling the   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API. Web/WAP scenarios rarely experience redirection exceptions. However, in the event of any exceptions, it is recommended to verify the redirection link. For mobile app scenarios, if frequent redirection exceptions occur, contact Antom Technical Support to troubleshoot redirection or cross-application calling issues. |
| SDK_INTERNAL_ERROR | SDK internal error. | Contact Antom Technical Support. |  |

**Tab: iOS**

| **Type** | **Code** | **Description** | **Further action** |
| --- | --- | --- | --- |
| Status code | SDK_CALL_URL_SUCCESS | This event code indicates that redirect successfully for the     *paymentRedirectUrl.* | Please obtain the final payment result from Antom server. You can use the   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   API or the   [**notifyPayment**](https://docs.antom.com/ac/ams/paymentrn_online.md)   API to confirm the result. |
| SDK_PAYMENT_CANCEL | The buyer canceled the authorization (the buyer exited the authorization page without submitting the order). | You can re-invoke the SDK using     *paymentSessionData*     within its validity period; If it has expired, you need to initiate a new   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API. |  |
| Error code | SDK_LAUNCH_PAYMENT_APP_ERROR | This event code indicates one of the following situations: - Failed to redirect to the merchant page. - The     *paymentRedirectUrl*     parameter is not correctly passed when calling the   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)      API. | Check whether the     *paymentRedirectUrl*     parameter is correctly passed when calling the   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API. If frequent redirection exceptions occur, contact Antom Technical Support to troubleshoot redirection or cross-application calling issues. |
| SDK_INTERNAL_ERROR | SDK internal error. | Contact Antom Technical Support. |  |

**Tab: Android**

| **Type** | **Code** | **Description** | **Further action** |
| --- | --- | --- | --- |
| Status code | SDK_CALL_URL_SUCCESS | This event code indicates that redirect successfully for the     *paymentRedirectUrl.* *​* | Please obtain the final payment result from Antom server. You can use the   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   API or the   [**notifyPayment**](https://docs.antom.com/ac/ams/paymentrn_online.md)   API to confirm the result. |
| SDK_PAYMENT_CANCEL | The buyer canceled the authorization (the buyer exited the authorization page without submitting the order). | You can re-invoke the SDK using     *paymentSessionData*     within its validity period; If it has expired, you need to initiate a new   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API. |  |
| Error code | SDK_LAUNCH_PAYMENT_APP_ERROR | This event code indicates one of the following situations: - Failed to redirect to the merchant page. - The     *paymentRedirectUrl*     parameter is not correctly passed when calling the   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)   API. | Check whether the     *paymentRedirectUrl*     parameter is correctly passed when calling the   [**createPaymentSession (Auto Debit)**](https://docs.antom.com/ac/ams/session_autodebit.md)      API. If frequent redirection exceptions occur, contact Antom Technical Support to troubleshoot redirection or cross-application calling issues. |
| SDK_INTERNAL_ERROR | SDK internal error. | Contact Antom Technical Support. |  |

<!-- /TabGroup -->

### Step 3: Obtain authorization result   **[Server-side]** {#rI97H}

 When the authorization is successful, Antom sends you the asynchronous notification through the   [**notifyAuthorization**](https://docs.antom.com/ac/ams/notifyauth.md)   API.

 When you receive the notification, you must return a response as instructed in   [Return a receipt acknowledgment message](https://docs.antom.com/ac/cashierpay/notifications.md#vQK5A)  . Meanwhile, you must update the authorization status of the buyer in your system and display the buyer's desensitized account obtained from the notification on your authorization management page.

 The specific request parameters are as follows:

 | **Parameter name** | **Child parameter name** | **Type** | **Required** | **Description** |
| --- | --- | --- | --- | --- |
| *authorizationNotifyType* | *​* | String | Yes | This scenario uses the fixed value   `TOKEN_CREATED`  . |
| *authState* | *​* | String | Yes | Request number passed by the merchant when calling the   `createPaymentSession`   API. |
| *accessToken* | *​* | String | Yes | Authorization token from Antom. |
| *resultInfo* | *resultStatus* | String | Yes | Result status,  `S`  indicates that the authorization succeeds. |
| *resultCode* | String | Yes | Result code,  `SUCCESS`  indicates that the authorization succeeds. |  |
| *resultMessage* | String | Yes | Result message. |  |
| *passThroughInfo* *​* *​* *​* *​* | *​* | ​ | Yes | A JSON String. This parameter is used to pass additional information to the merchant. |
| *accountDisplayName* | String | Yes | Last four digits of the bank account. |  |
| *bankName* | String | Yes | Bank name. |  |
| *paymentProviderIconUrl* | String | Yes | Payment method provider's icon URL, i.e., bank logo. |  |
| *accountToken* | String | Yes | ACH Direct Debit's identifier for the buyer account. |  |

 The following code shows a sample of the notification request:

 ```json
{
    "authorizationNotifyType": "TOKEN_CREATED",
    "authState": "2025070155138201876296",
    "accessToken": "28288803000084331751341576557aUL428uGgG171000571",

    "passThroughInfo": "{\"accountDisplayName\":\"6576\",\"bankName\":\"Demo Bank\",\"paymentProviderIconUrl\":\"https://paywithmybank.com/start/assets/institutions/icons/200005501.png\",\"accountToken\":\"K0B116DW06576\"}",
  
    "resultInfo": {
        "resultStatus": "S",
        "resultCode": "SUCCESS",
        "resultMessage": "success"
    }
},

```

 > **[INFO]** **Note**    : The accessToken returned for the first-time authorization and the reauthorization are distinct, but the bank information remains unchanged.

### Step 4: Initiate a payment  **[Server-side]** {#LWrYw}

 With a successful authorization, you can provide the buyer with auto debit services. Funds will be automatically deducted for subsequent purchases without requiring the buyer to re-enter payment information.

 Specify the following parameters when initiating a payment:

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *productCode* | Yes | The payment product that is being used. For Auto Debit, the value is fixed as   `AGREEMENT_PAYMENT`  . |
| *paymentRequestId* | Yes | The unique ID generated by the merchant for each payment request. |
| *paymentAmount* | Yes | The payment amount in the smallest currency unit. For example,   `CNY`       in cents,   `KRW`       in won. |
| *paymentMethod* | Yes | The payment method that is used. |
| *paymentMethod.paymentMethodId* | Yes | The payment token (    *accessToken*    ) obtained from the   [**notifyAuthorization**](https://docs.antom.com/ac/ams/notifyauth.md)   API. |
| *paymentNotifyUrl* | No | The address for receiving payment result notifications. It can be set through the API or or set as a fixed value through   [Antom Dashboard](https://docs.antom.com/ac/merchant_service/notification.md)  . |
| *settlementStrategy* | No | The settlement strategy for the payment request. |
| *order* | Yes | Order information, including order amount, order ID, and order description. |

 The above parameters are the basic parameters for initiating a payment, refer to   [**pay (Auto Debit)**](https://docs.antom.com/ac/ams/payment_agreement.md)   for full parameters and additional requirements for certain payment methods.

 The following code is a sample of calling the   [**pay (Auto Debit)**](https://docs.antom.com/ac/ams/payment_agreement.md)   API:

 ```java
public static void pay() {
    AlipayPayRequest alipayPayRequest = new AlipayPayRequest();
    alipayPayRequest.setProductCode(ProductCodeType.AGREEMENT_PAYMENT);

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

    // set amount
    // you should convert amount unit(in practice, amount should be calculated on your serverside)
    Amount amount = Amount.builder().currency("SGD").value("550000").build();
    alipayPayRequest.setPaymentAmount(amount);

    // set paymentMethod
    PaymentMethod paymentMethod = PaymentMethod.builder().paymentMethodType("GCASH").
    paymentMethodId("2828XXX77801726307481000Iba1Pm20IU171000179").build();
    alipayPayRequest.setPaymentMethod(paymentMethod);

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

    // replace with your orderId
    String orderId = UUID.randomUUID().toString();
    // set order Info
    Order order = Order.builder().referenceOrderId(orderId).
    orderDescription("antom api testing order").orderAmount(amount).buyer(buyer).build();
    alipayPayRequest.setOrder(order);

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

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

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

 The following code shows a sample of the request message:

 ```json
{
  "env": {
    "clientIp": "114.121.121.01",
    "terminalType": "WEB"
  },
  "order": {
    "buyer": {
      "referenceBuyerId": "yourBuyerId"
    },
    "orderAmount": {
      "currency": "USD",
      "value": "550000"
    },
    "orderDescription": "antom api testing order",
    "referenceOrderId": "f69cb774-8d47-4da9-bf91-08c656581cdf"
  },
  "paymentAmount": {
    "currency": "USD",
    "value": "550000"
  },
  "paymentMethod": {
    "paymentMethodId": "2828XXX77801726307481000Iba1Pm20IU171000179",
    "paymentMethodType": "ACH_DIRECT_DEBIT"
  },
  "paymentNotifyUrl": " http://www.yourNotifyUrl.com ",
  "paymentRequestId": "AGREEMENT_PAYMENT_REQUEST_20260204_180226",
  "productCode": "AGREEMENT_PAYMENT"
}
```

 The following code shows a sample of the response message:

 ```json
{
  "paymentAmount": {
    "currency": "USD",
    "value": "550000"
  },
  "paymentCreateTime": "2020-07-03T01:17:50-07:00",
  "paymentId": "2020070311401080010018840027964XXXX",
  "paymentRequestId": "AGREEMENT_PAYMENT_REQUEST_2020070316170XXXX",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "Success",
    "resultStatus": "S"
  }
}
```

 The following table shows the possible values of     *result.resultStatus*     in the response message. Please handle the result according to the guidance provided:

 | ***result.resultStatus*** | **Message** | **Further action** |
| --- | --- | --- |
| `S` | Payment was successful. | No further action is needed. |
| `U`  ​ | Payment is being processed. | Please poll the   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   API or wait for the asynchronous notification from   [**notifyPayment**](https://docs.antom.com/ac/ams/paymentrn_online.md)        for the payment result. |
| `F` | Payment failed. | - In the scenario where the buyer clicks to pay, handle the relevant issues based on the message from     *result.resultCode*    . - In the scenario of recurring payments, if the deduction initiated from the merchant side fails, handle it based on the return value of     *result.resultCode*    :     - `USER_BALANCE_NOT_ENOUGH`  : If you need to call the API again, please note that you can retry up to 2 times within 24 hours. Frequent retries may result in rate limiting on the Antom side.   - `INVALID_ACCESS_TOKEN`  : Please guide the buyer to re-authorize.   - Other error codes: Please handle or retry after confirming the specific reason. |

 > **[INFO]** **Note**    : If no response is received, it may indicate a network timeout. Please use the same     *paymentRequestId*     and call the API again. If the issue persists, contact Antom Technical Support.

 > **[INFO]** **Common questions**
>
>  **Q: How to set**       ***terminalType***      **?**
>
>  A: The valid values of     *terminalType*     are:
>
>  - If the buyer initiates a transaction from a PC browser, the     *terminalType*     needs to be specified as   `WEB`  .
> - If the buyer initiates a transaction from the mobile browser, the     *terminalType*     needs to be specified as   `WAP`  . Add the     *osType*     parameter and fill in the corresponding system parameters   `ANDROID`   or   `IOS`   according to the buyer's mobile device.
>
>   **Q: Can I use Chinese characters in the value of the request parameters?**
>
>  A: To avoid incompatibility of certain payment methods, do not use Chinese characters for fields in the request.
>
>   **Q: How to set the address to receive payment notification?**
>
>  A: Specify     *paymentNotifyUrl*     in the   [**pay (Auto Debit)**](https://docs.antom.com/ac/ams/payment_agreement.md)   API to receive the asynchronous notification about the payment result (  [**notifyPayment**](https://docs.antom.com/docs/ac/ams/paymentrn_online.md)  ), or configure the receiving URL in Antom Dashboard. If the URL is specified in both the request and Antom Dashboard, the value specified in the request takes precedence.

### Step 5: Obtain payment result {#cKvHY}

 You can obtain the payment result using one of the following methods:

 - Receive asynchronous notifications from Antom
- Inquire about the payment result

<!-- TabGroup -->

**Tab: Receive asynchronous notifications**

**1\. Configure the webhook URL to receive asynchronous notifications**

 When the payment reaches a final status of success or failure, Antom will send an asynchronous notification to the webhook URL you set. You can choose one of the following two methods to configure the webhook URL for receiving notifications:

 - If each of your orders 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     *paymentNotifyUrl*     in the   [**pay (Auto Debit)**](https://docs.antom.com/ac/ams/payment_agreement.md)   API.
- If all your orders share a unified notification URL, you can set the webhook URL on   [Antom Dashboard](https://dashboard.alipay.com/global-payments/developers/iNotify)   through     **Developer > Notification URL**    . For detailed steps, refer to   [Notification URL](https://docs.antom.com/ac/merchant_service/notification.md)  .  ![](https://idocs-assets.marmot-cloud.com/storage/idocs87c36dc8dac653c1/yuque/idocs/2025/png/bdc97350-e940-4b6b-b40e-2c3b526759d8.png)

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

   ```json
{
  "actualPaymentAmount": {
    "currency": "USD",
    "value": "56000"
  },
  "customsDeclarationAmount": {},
  "notifyType": "PAYMENT_RESULT",
  "paymentAmount": {
    "currency": "USD",
    "value": "56000"
  },
  "paymentCreateTime": "2024-09-27T00:23:36-07:00",
  "paymentId": "202409271940108001001881E0211235544",
  "paymentRequestId": "bc93d19e-e1f6-4b68-b6b1-3d6ddc2a792a",
  "paymentTime": "2024-09-27T00:23:46-07:00",
  "pspCustomerInfo": {
    "pspCustomerId": "20881221121****",
    "pspName": "ALIPAY_HK"
  },
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
```

   The following table shows the possible values of     *result.resultStatus*     in the notification request of payment result. Please handle the result according to the guidance provided:

   | ***result.resultStatus*** | **Message** | **Further action** |
| --- | --- | --- |
| `S` | Payment was successful. | No further action is needed. |
| `U` | Payment is being processed. | Please poll the   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   API or wait for the asynchronous notification from   [**notifyPayment**](https://docs.antom.com/ac/ams/paymentrn_online.md)   for the payment result. |
| `F` | Payment failed. | - In the scenario where the buyer clicks to pay, handle the relevant issues based on the message from    *result.resultCode*    . - In the scenario of recurring payments, if the deduction initiated from the merchant side fails, handle it based on the return value of    *result.resultCode*    :     - `USER_BALANCE_NOT_ENOUGH`  : If you need to call the API again, please note that you can retry up to 2 times within 24 hours. Frequent retries may result in rate limiting on the Antom side.   - `INVALID_ACCESS_TOKEN`  : Please guide the buyer to re-authorize.   - Other error codes: Please handle or retry after confirming the specific reason. |

 **2\. Verify the asynchronous notification**

 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#vQK5A)   format, but you do not need to countersign the response.

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

   ```java
/**
 * receive notify
 *
 * @param request    request
 * @param notifyBody notify body
 * @return Result
 */
@PostMapping("/receiveNotify")
@ResponseBody
public Result receiveNotify(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");

    try {
        // verify the signature of notification
        boolean verifyResult = WebhookTool.checkSignature(requestUri, requestMethod, clientId,
                                                          requestTime, signature, notifyBody, ANTOM_PUBLIC_KEY);
        if (!verifyResult) {
            throw new RuntimeException("Invalid notify signature");
        }
        // deserialize the notification body
        JSONObject jsonObject = JSON.parseObject(notifyBody);
        String notifyType = (String)jsonObject.get("notifyType");
        if("PAYMENT_RESULT".equals(notifyType)){
            AlipayPayResultNotify paymentNotify = jsonObject.toJavaObject(AlipayPayResultNotify.class);
            if (paymentNotify != null && "SUCCESS".equals(paymentNotify.getResult().getResultCode())) {
                // handle your own business logic
                // e.g. The relationship between payment information and buyers is kept in the database
                System.out.println("receive payment notify: " + JSON.toJSONString(paymentNotify));
                return Result.builder().resultCode("SUCCESS").resultMessage("success.").resultStatus(ResultStatusType.S).build();
            }
        }

    } catch (Exception e) {
        return Result.builder().resultCode("FAIL").resultMessage("fail.").resultStatus(ResultStatusType.F).build();
    }

    return Result.builder().resultCode("SYSTEM_ERROR").resultMessage("system error.").resultStatus(ResultStatusType.F).build();
}
```

   Whether the payment 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: When will the notification be sent?**
>
>  A: It depends on whether the payment is completed:
>
>  - If the payment is successfully completed, Antom will send you an asynchronous notification within 3 to 5 seconds. For some payment methods like OTC, the notification might take a bit longer.
> - If the payment is not completed, Antom needs to close the order first before sending an asynchronous notification. The time it takes for different payment methods to close the order varies, usually defaulting to 14 minutes.
>
>   **Q: Will the asynchronous notification be re-sent?**
>
>  A: Yes, the asynchronous notification will be re-sent    automatically within 24 hours for the following cases:
>
>  - If you didn't receive the asynchronous notification due to network reasons.
> - If you receive an asynchronous notification from Antom, but you did not respond to the notification in the   [Sample code](https://docs.antom.com/ac/auto_debit/notifications.md#vQK5A)   format.
>
>  The notification can be resent up to 8 times or until a correct response is received to terminate delivery. The sending intervals are as follows: 0 minutes, 2 minutes, 10 minutes, 10 minutes, 1 hour, 2 hours, 6 hours, and 15 hours.
>
>   **Q: When responding to an asynchronous notification, do I need to add a digital signature?**
>
>  A: If you receive an asynchronous notification from Antom, you are required to return the response in the   [Sample code](https://docs.antom.com/ac/auto_debit/notifications.md#vQK5A)   format, but you do not need to countersign the response.

**Tab: Inquire about the result**

You can also inquire about the payment result by calling the   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   API using     *paymentRequestId*     from the payment request.

 | **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| *paymentRequestId* | No | The payment request ID generated by the merchant. |

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

   ```java
public static void inquiryPayment() {
    AlipayPayQueryRequest alipayPayQueryRequest = new AlipayPayQueryRequest();

    // replace with your paymentRequestId
    alipayPayQueryRequest.setPaymentRequestId("yourPaymentRequestId");

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

   The following sample code shows a response message of   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)  :

   ```json
{
    "actualPaymentAmount": {
        "currency": "USD",
        "value": "550000"
    },
    "paymentAmount": {
        "currency": "USD",
        "value": "550000"
    },
    "paymentId": "202602041140108001001819B0292782346",
    "paymentMethodType": "ACH_DIRECT_DEBIT",
    "paymentRequestId": "AGREEMENT_PAYMENT_REQUEST_20260204_180226",
    "paymentResultCode": "SUCCESS",
    "paymentResultMessage": "success.",
    "paymentStatus": "SUCCESS",
    "paymentTime": "2026-02-04T02:02:31-08:00",
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success.",
        "resultStatus": "S"
    }
}
```

   Obtain the payment status based on the value of     *paymentStatus*     in the   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   response:

 - `SUCCESS`  : Payment was successful.
- `FAIL`  : Payment failed.
- `PROCESSING`  : Payment is being processed.
- `CANCELLED`  : Payment was canceled.

 > **[INFO]** **Common questions**
>
>  **Q: How often should I call the inquiryPayment API?**
>
>  A: Call the      [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)      API constantly with an interval of 2 seconds until the final payment result is obtained or an asynchronous payment result notification is received.
>
>  **Q: What are the key parameters in the notification that I need to use?**
>
>  A: Pay attention to these key parameters:
>
>  - *result*    : Indicates the result of the   [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md)   API call, the payment result needs to be confirmed through the value of     *paymentStatus*    :
>
>    - `SUCCESS`  : Payment was successful.
>   - `FAIL`  : Payment failed.
>   - `PROCESSING`  : Payment is being processed.
>   - `CANCELLED`  : Payment was canceled.
>
>  - *paymentAmount*    : The payment amount.

<!-- /TabGroup -->

## After payments {#AOXGu}

 After completing the payment, you can perform the following actions:

### Revoke authorization {#hdayk}

 Unbinding cannot be initiated from the merchant side. While buyers are allowed to unbind on the bank's side, no notification will be sent to the merchant upon unbinding. The merchant will receive the payment error code   `INVALID_ACCESS_TOKEN`   upon the next payment attempt, at which point you can guide the buyer to re-authenticate.

### Cancel {#Wn6Ll}

 Cancellation is not supported before a successful payment.    You can cancel orders through the   [**cancel**](https://docs.antom.com/ac/ams/paymentc_online.md)   API after successful payment within the time window (by T+1 day 00:15 GMT+8). For details, refer to   [Cancel](https://docs.antom.com/ac/easypay/cancel.md)  .

### Refund {#ImKmI}

 Different payment methods have varying refund capabilities. To learn about Antom refund rules and how to initiate a refund for a successful transaction, refer to   [Refund](https://docs.antom.com/ac/auto_debit/refund.md)  .

### Reconciliation {#FQ8Y3}

 After the transaction is completed, use the financial reports provided by Antom for reconciliation. For more information on how to reconcile and the settlement rules of Antom, refer to   [Reconciliation](https://docs.antom.com/ac/auto_debit/settle_reconcile.md)  .
