# Capture

> Discover how to capture funds through automatic or manual methods.

Depending on your business needs, choose one of the following methods to capture funds:

-   Automatic capture
-   Manual capture

> **Note**: The [South Korean issuer-authenticated cards](https://docs.antom.com/ac/cashierpay/issuer_auth_pay.md) only supports automatic capture initiated by Antom for you.

## Automatic capture

The default value of _paymentFactor.captureMode_ in the [**pay (One-time Payments)**](https://docs.antom.com/ac/ams/payment_cashier.md) or the [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API is `AUTOMATIC`. This means that after the buyer authorizes the payment, Antom will automatically capture the funds for you without any additional confirmation step. The [**notifyCapture (One-time Payments)**](https://docs.antom.com/ac/ams/notify_capture.md) API sends you the capture result via an asynchronous notification. You can also inquire about the capture result through the [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md) API.

## Manual capture

If you need to decide whether to initiate capture based on risk control results, inventory status, or other business logic after the buyer's authorization, you can set the value of _paymentFactor.captureMode_ in the [**pay (One-time Payments)**](https://docs.antom.com/ac/ams/payment_cashier.md) or [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API to `MANUAL` . In this case, you must call the [**capture (One-time Payments)**](https://docs.antom.com/ac/ams/capture.md) API to initiate capture manually. The [**notifyCapture (One-time Payments)**](https://docs.antom.com/ac/ams/notify_capture.md) API sends you the capture result via an asynchronous notification. You can also inquire about the capture result through the [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md) API.

### Integration steps

Start your integration by taking the following steps:

1.  Initiate a capture request.
2.  Retrieve the capture result.

#### Step 1: Initiate a capture request Server-side

After successful authorization, intiate a capture using the [**capture (One-time Payments)**](https://docs.antom.com/ac/ams/capture.md) API, the key parameters are listed as follows:

| **Parameter name** | **Required** | **Description** |
| --- | --- | --- |
| _captureRequestId_ | Yes | A unique identifier that you assign to a capture request. Each capture request must be assigned with a new value. |
| _captureAmount.currency_ | Yes | The currency of the capture amount. The currency must be consistent with the currency of the payment amount (_paymentAmount.currency_) in the [**pay (One-time Payments)**](https://docs.antom.com/ac/ams/payment_cashier.md) or [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API. |
| _captureAmount.value_ | Yes | The capture amount, which must be consistent with the amount of the payment amount (_paymentAmount_) in the [**pay (One-time Payments)**](https://docs.antom.com/ac/ams/payment_cashier.md) or [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API. |
| _paymentId_ | Yes | A unique identifier that Antom assigns to an order. The value of this parameter must be consistent with the _paymentId_ in the request of [**notifyPayment**](https://docs.antom.com/ac/ams/paymentrn_online.md). |

The following sample code shows how to call the [**capture (One-time Payments)**](https://docs.antom.com/ac/ams/capture.md) API:

```java
public static void capture() {
    AlipayCaptureRequest alipayCaptureRequest = new AlipayCaptureRequest();

    Amount amount = Amount.builder().currency("USD").value("2000").build();
    alipayCaptureRequest.setCaptureAmount(amount);

    // replace with your captureRequestId
    String captureRequestId = UUID.randomUUID().toString();
    alipayCaptureRequest.setCaptureRequestId(captureRequestId);

    // replace with your paymentId
    alipayCaptureRequest.setPaymentId("20241212********0211082739");

    AlipayCaptureResponse alipayCaptureResponse = null;
    try {
        alipayCaptureResponse = CLIENT.execute(alipayCaptureRequest);
    } catch (AlipayApiException e) {
        String errorMsg = e.getMessage();
    }
}
```

The following shows the sample code of a capture request: 

```json
{
    "paymentId": "20241212********0211082739",
    "captureRequestId": "4c6c8ffd-*******eeb5af0e3f4",
    "captureAmount": {
        "currency": "USD",
        "value": "2000"
    }
}
```

The following shows the sample code of a capture response:

```json
{
    "captureAmount": {
        "currency": "USD",
        "value": "2000"
    },
    "captureId": "2024121219********670209694544",
    "captureRequestId": "4c6c8ffd-*******eeb5af0e3f4",
    "captureTime": "2024-12-11T23:34:03-08:00",
    "paymentId": "20241212********0211082739",
    "result": {
        "resultCode": "SUCCESS",
        "resultMessage": "success",
        "resultStatus": "S"
    }
}
```

The table shows the possible values that the _result.resultStatus_ parameter in the response message may return. Please handle the result according to the guidances:

| _**result.resultStatus**_ | **Message** | **Further action** |
| --- | --- | --- |
| `S` | Indicates that the capture is successful. | You can proceed with the order and save the Antom side _captureId_ information for future refund handling. |
| `U` | Indicates that the capture is being processed. | You can call the [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md) API to obtain the capture result or wait for the capture result notification. |
| `F` | Indicates that the capture failed. | Troubleshoot based on the returned error codes and try again. If the problem persists, contact Antom technical support. |

> **Note**: If you did not receive a response message, it might be due to a network timeout. You can call the [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md) API to obtain the capture result or wait for the capture result notification.

#### Step 2: Receive a capture response Server-side

Use one of the following methods to retrieve the capture result:

-   Receive an asynchronous notification
-   Inquire about the capture result

> **Note**: When capture succeeds or fails, Antom will send you the asynchronous notification for the corresponding capture result via the webhook URL you configured. If the [**capture (One-time Payments)**](https://docs.antom.com/ac/ams/capture.md) API contains exceptions and returns `F`, the asynchronous notification will not be triggerred.

#### Tab: Receive an asynchronous notification

After initiating the capture, Antom will send you an asynchronous notification through the [**notifyCapture (One-time Payments)**](https://docs.antom.com/ac/ams/notify_capture.md) API. Please configure it according to the following steps:

1.  **Set the webhook URL to receive notifications**

You can choose one of following two methods to set the webhook URL to receive notifications. If you set the webhook URL both in the API and Antom Dashboard, the one set in Antom Dashboard takes precedence.

-   If you have set the asynchronous notification URL for the order in the _paymentNotifyUrl_ parameter when calling the [**pay (One-time Payments)**](https://docs.antom.com/ac/ams/payment_cashier.md) or [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API, there is no need to set it again. In this case, the capture notification and authorization notification URLs remain the same. Currently, it is not supported to pass in the notification URL for receiving capture results separately via the API.
-   If all your orders share a unified notification URL, you can set the webhook URL on [Antom Dashboard](http://dashboard.alipay.com) through **Developer > Notification Address**. In this case, the notification URL for capture results and authorization results are two separate URLs. Antom Dashboard only supports fixed URL configuration and does not support URLs containing parameter information such as order numbers. For detailed steps, refer to [Notification URL](https://docs.antom.com/ac/merchant_service/notification.md).

The capture resquest contains the following key parameters:

-   _resultStatus_: Required. The capture result of the order, which is the final basis of your shipment.
-   _captureId_: The unique ID that is assigned by Antom to identify a capture.
-   _captureAmount_: The capture amount.

The following is the notification request sample code:

```json
{
  "captureAmount": {
    "currency": "USD",
    "value": "2000"
  },
  "captureId": "2024121219********670209694544",
  "captureRequestId": "4c6c8ffd-*******eeb5af0e3f4",
  "captureTime": "2024-12-11T23:34:03-08:00",
  "paymentId": "20241212********0211082739",
  "notifyType": "CAPTURE_RESULT",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
```

The table shows the possible values that the _result.resultStatus_ parameter in the request message may return. Please handle the result according to the guidances:

| _**result.resultStatus**_ | **Message** | **Further actions** |
| --- | --- | --- |
| `S` | Indicates that the capture is successful. | You can proceed with the order and save the Antom side _captureId_ information for future refund handling. |
| `F` | Indicates that the capture failed. | Use a different _captureRequestId_ and try again, or contact Antom Technical Support. |

2.  **Verify asynchronous notifications**

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

You need to verify the signature of the capture 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

            // handle your own business logic.

            // acknowledge that the notification is 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);
    }

}
```

You do not need to countersign the response of the result notification. However, you must respond to each notification request in the following fixed format, regardless of whether the capture is successful or not. 

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

#### Tab: Inquire about the capture result

If you are unable to retrieve the final result (`S` for success/ `F` for failure) from the asynchronous notification or the capture response, we recommend that you inquire about the capture status by calling the [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md) API.

The following code shows how to call the [**inquiryPayment**](https://docs.antom.com/ac/apo/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 code shows an example of a request:

```json
{
  "paymentRequestId": "Merchant_Request_ID_XXXXXX"
}
```

The following sample codes of the response:

```json
{
  "result": {
    "resultStatus": "S",
    "resultCode": "SUCCESS",
    "resultMessage": "success."
  },
  "paymentId": "2022XXXXXXXXX",
  "paymentResultCode": "SUCCESS",
  "paymentRequestId": "Merchant_Request_ID_XXXXXX",
  "paymentResultMessage": "success",
  "paymentTime": "2022-09-29T07:12:54-07:00",
  "transactions": [
    {
      "transactionType": "CAPTURE",
      "transactionStatus": "SUCCESS",
      "transactionRequestId": "test_test_test_XXXX",
      "transactionAmount": {
        "currency": "BRL",
        "value": "110"
      },
      "transactionId": "2022XXXXXXXX",
      "transactionResult": {
        "resultStatus": "S",
        "resultCode": "SUCCESS",
        "resultMessage": "success"
      }
    }
  ],
  "paymentAmount": {
    "currency": "BRL",
    "value": "110"
  },
  "paymentStatus": "SUCCESS"
}
```

When you retrieve the capture response, ensure that _transactions.transactionType_ and _transactions.transactionRequestId_ meet the following requirements, and handle the [returned value of _transactions.transactionResult.resultStatus_](https://docs.antom.com/ac/ams/paymentri_online.md#Responseparameters-transactions-transactionResult-resultStatus) accordingly:

-   When the value of _transactionType_ is `CAPTURE`.
-   In the manual capture mode, the value of _transactionRequestId_ must match the value of _captureRequestId_ in your capture request.

## Common questions

### In the automatic capture mode, if the timeout period you set through _paymentExpireTime_ is reached, the buyer has completed authorization, but Antom has not yet completed the capture, how will this be handled?

Depending on the actual processing status of the transaction, it will be handled as follows:

-   If both authorization and capture are completed before the timeout: Antom will send you asynchronous notifications of the authorization result and the capture result. In this case, the capture status in the query result will be `S`.
-   If authorization was initiated before the timeout but the final result has not been returned: After receiving the authorization result from the payment method, Antom will automatically void the transaction. In this case, the authorization status in the query result will be `F` and no capture status will be returned.
-   If authorization is completed before the timeout, but the automatic capture is initiated at or after the timeout: Antom will not initiate capture. You will receive the authorization result notification but no capture result notification. In this caset, there will be no capture status in the query result. It is recommended that you proactively [cancel the transaction](https://docs.antom.com/ac/cashierpay/cancel.md) to release the buyer’s frozen funds.
-   If authorization is completed and capture is initiated before the timeout, but the capture result has not been returned: After receiving the capture result from the payment method, Antom will automatically initiate refund for the transaction. In this case, the capture status in the query result will be `F`, and the refund status will be `S`.

If you did not set _paymentExpireTime__,_ the default timeout period of Antom is 14 minutes. Ensure the buyer completes authorization within this period; the timing of the capture initiation is not affected by this limit.

### In the automatic capture mode, how soon will I receive the capture result notification after successful authorization?

After successful authorization, Antom will automatically initiate the capture immediately and send the capture result to you via asynchronous notification within seconds.

### In the manual capture mode, how long after successful authorization do I need to initiate a capture request?

If you manually initiate capture by calling the [**capture (One-time Payments)**](https://docs.antom.com/ac/ams/capture.md) API, you must complete the operation within 7 days after successful authorization. If no capture is initiated within 7 days, Antom will automatically void the order and release the frozen funds for the buyer.

### Does the capture request support retrying the original request?

The capture API implements an idempotency mechanism based on the _captureRequestId_. The retry rules are as follows:

-   If the first response returns _resultStatus_\=`S` (Success), no retry is needed.
-   If the first response returns _resultStatus_\=`F` (Failure), retries are not supported; repeated requests will still return failure status.
-   If the first response returns _resultStatus_\=`U` (Processing), retries are supported; subsequent requests will return the final processing result (Success S/Failure F).

### Does the notification URL for capture results need to be consistent with the authorization result notification URL?

By default, the notification URLs for capture results and authorization results are consistent. If you need to send capture result notifications to an independent URL, you can configure the notification URL in [Antom Dashboard](https://docs.antom.com/ac/merchant_service/notification.md). The configuration restrictions for capture notification URLs are as follows:

-   Antom Dashboard only supports fixed URL configuration and does not support URLs containing parameter information such as order numbers.
-   Currently, passing capture result notification URLs separately through the API is not supported.

### What should I do when authorization is completed but I receive a capture failure notification?

A capture notification failure means that fund transfer has not occurred definitively. You can cancel the authorization to avoid freezing the buyer's funds and contact Antom Technical Support for troubleshooting.

### Does the capture amount need to be consistent with the authorization amount?

They need to be consistent. Currently, only full capture is supported; partial capture is not supported.

### After initiating manual capture through the [**capture (One-time Payments)**](https://docs.antom.com/ac/ams/capture.md) API, if I don't receive a capture result notification, how should I handle it?

You can actively query the capture result through the [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md) API. Avoid initiating duplicate capture requests. When an order is in `CAPTURE_IN_PROCESS` status, duplicate requests will trigger an "amount exceeded" error.

### When using the [inquiryPayment](https://docs.antom.com/ac/ams/paymentri_online.md) API to check capture status, what key parameters should I pay attention to?

Please pay attention to the following key parameters:

-   _result_: Only indicates the call result of the [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md) API. For APM payments, the payment result of the order should be determined based on _paymentStatus_ (`SUCCESS`/`FAIL`/`PROCESSING`). For card payments, Apple Pay, and Google Pay, _paymentStatus_ only represents the authorization result; shipping decisions should depend on capture results.
-   In the _transactions\[\]_ array, filter for transactions where _transactionType_ = `CAPTURE` (In the manual capture mode, you must also ensure that the value of _transactionRequestId_ match the value of _captureRequestId_ in your capture request), then the corresponding _transactionResult.resultStatus_ is the capture result.
-   _paymentAmount_: Used to verify the payment amount.
-   _paymentId_: Represents the payment order ID generated by Antom, used for refunds and reconciliation.

### How often should I call the [inquiryPayment](https://docs.antom.com/ac/ams/paymentri_online.md) API?

Call the [**inquiryPayment**](https://docs.antom.com/ac/ams/paymentri_online.md) API continuously at 2-second intervals until you obtain the final payment result or receive an asynchronous payment result notification.

### Q: Why is the _paymentId_ in the synchronous response of the [**capture (One-time Payments)**](https://docs.antom.com/ac/ams/capture.md) API and the [**notifyCapture (One-time Payments)**](https://docs.antom.com/ac/ams/notify_capture.md) request inconsistent with the _paymentId_ synchronously returned by the [**pay (One-time Payments)**](https://docs.antom.com/ac/ams/payment_cashier.md) or [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API?

A: For [API-hosted card payment integration](https://docs.antom.com/ac/cashierpay/cardcollant.md), [Checkout Page integration](https://docs.antom.com/ac/cashierpay/HOSTEDCKP.md), and [Payment Element integration](https://docs.antom.com/ac/cashierpay/element.md), Antom allows buyers to return to the card information entry page for retry in certain payment failure scenarios. Each retry submission generates a new _paymentId_. Therefore, the _paymentId_ in the synchronous response of the [**capture (One-time Payments)**](https://docs.antom.com/ac/ams/capture.md) API and the [**notifyCapture (One-time Payments)**](https://docs.antom.com/ac/ams/notify_capture.md) request may differ from the original _paymentId_ returned in the response of the [**pay (One-time Payments)**](https://docs.antom.com/ac/ams/payment_cashier.md) or [**createPaymentSession (One-time Payments)**](https://docs.antom.com/ac/ams/session_cashier.md) API.