Skip to content

Authorize and capture

An authorization reserves funds on a card without moving them. A capture moves them. Splitting the two is the right shape whenever you charge before you know the final amount, or before you can deliver.

The usual cases are shipping physical goods, orders that may be partly out of stock, and anything where the total can change between checkout and fulfillment.

Before you start

  • Your Api-Key and Client-Id — see Authentication
  • A processor integration configured for cards

Step 1: Authorize

POST /v1/transactions with type set to AUTH. The request is identical to a sale apart from that one field.

Keep the id from the response. Every later step quotes it in the URL.

Step 2: Capture

POST /v1/transactions/{id}/capture, where {id} is the authorization's id.

The body is small: amount is required, tip is optional. There is no type field. It was removed from this request, and sending one is a common carry-over from older integrations.

Response

The capture record. It is a new transaction whose reference_transaction_id points at the authorization it captured. expiry is null because expiry is not echoed back on capture responses. batch_id is now assigned, so the funds settle at the next batch close.

{ "id": "TRANSACTION-01KEW35B8QP4M2X9YHFT0KDN47", "reference_transaction_id": "TRANSACTION-01KEW32V6YNV11T336VEDKL123", "type": "CAPTURE", "result": "APPROVED", "client_id": "CLIENT-01KFDKXMQ637EKEAY410MSQSXB", "client_dba": "Acme Jewelry", "integrations": [ "TSYS" ], "response_code": "00", "response_description": "Approved", "batch_id": "BATCH-01KEW32V6YNV11T33XGDR7TGWC", "is_settled": false, "time_created": "2026-07-15T16:08:23Z", "amount": 10000, "tip": 0, "currency": "USD", "payment_method": { "type": "CARD", "truncated_pan": "****-****-****-5439", "payment_token": "PAYMENT_TOKEN-01KFDKXMQ637EKEAY410MSQSXB", "expiry": null, "first_name": "John", "last_name": "Doe", "entry_method": "keyed", "auth_code": "123456", "retrieval_reference_number": "000000603076", "card_type": "UNKNOWN", "card_brand": "Visa", "cvv_result_code": "M" }, "initiator": "CUSTOMER", "network_transaction_id": "MCC1234567890", "metadata": { "order_id": "ORD-10434", "sales_channel": "web", "customer_reference": "cust-8891" } }

Three things about that response surprise people.

  • The capture is its own transaction, with its own id and a type of CAPTURE. It is not the authorization updated in place.
  • reference_transaction_id points back at the authorization. That is the link between the two.
  • expiry is null. Card expiry is not echoed on a capture response.

batch_id is populated now, so the funds settle at the next batch close.

Capture less than you authorized

Send a smaller amount. This is the normal way to handle an order that ships short, or a final total below the estimate.

{
  "amount": 7500
}

You cannot capture more than you authorized. If the total has gone up, the authorization no longer covers it — release it and authorize the new amount.

Release a hold you will not use

If the order is canceled before you ship, void the authorization so the cardholder's funds are freed rather than left on hold until the issuer expires them.

A void takes only type. It always releases the full amount, so there is no amount field to send.

Cancel, void, and refund covers the difference between voiding and refunding, and which one applies when.

How long a hold lasts

An uncaptured authorization does not last forever. The issuer decides how long, and it varies by card brand and issuer — commonly a few days to about a month.

The gateway does not expire authorizations on its own, and it does not notify you when an issuer does. If you are not going to capture, void explicitly rather than letting the hold lapse.

Next steps