> This page is for version v1 (default).
> For other versions, use one of these documentation indexes:
> - v1 (default): https://developers.truemed.com/v-1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.truemed.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.truemed.com/_mcp/server.

# Manual and delayed capture

> How to authorize a payment at checkout and capture it later, when you're ready to fulfill.

[Manual capture](/guides/overview/glossary#manual-capture) is the process of placing an authorization hold on a card, and then capturing the payment later, typically at the time of fulfillment.

> **Note**
>
> The initial invocation of [`create_payment_session`](/api-reference/payment-sessions/create-payment-session) requires that the customer be present in the checkout flow. Additional calls for capture or voids don't require customer-in-flow.

Authorization holds for [manual capture](/guides/overview/glossary#manual-capture) are created and managed using the same [`create_payment_session`](/api-reference/payment-sessions/create-payment-session) endpoint outlined in [Accept Your First Payment](/guides/setup/api/payment-sessions/accept-your-first-payment).

Manual capture relies on your system storing the `id` field from the payment session response and calling [`/payments/v1/payment_session/{business_id}/capture`](/api-reference/payment-sessions/capture-payment-session) when the payment should be captured, or [`/payments/v1/payment_session/{business_id}/void`](/api-reference/payment-sessions/void-payment-session) to release the authorization hold.

## Suggested implementation

Use manual capture when your order should be authorized at checkout, but charged later after a
fulfillment decision.

#### Create the payment session as an authorization

Pass `kind: "authorization"` to
[`create_payment_session`](/api-reference/payment-sessions/create-payment-session). Store the
returned payment session `id` on your order.

#### Wait for the authorization webhook

Listen for
[`payment_session_complete`](/api-reference/payment-sessions/payment-session-completed-webhook).
For manual capture, the key post-checkout webhook status is `authorized`. This means the
authorization hold is ready to capture or void.

#### Capture when you are ready to fulfill

Call [`capture_payment_session`](/api-reference/payment-sessions/capture-payment-session) with a
unique `idempotency_key`, the `total_amount` to capture, and the `item_details` being captured.

#### Fulfill after capture succeeds

The authorization webhook tells you the funds are held, not captured. Fulfill after your capture
request succeeds for the amount you intend to charge.

#### Void if you will not fulfill

If the order should not be fulfilled, call
[`void_payment_session`](/api-reference/payment-sessions/void-payment-session) to release the
authorization hold.

> **Note**
>
> If you need to capture more than the original authorization amount, void the authorization and create
> a new payment session. Capture amounts must be less than or equal to the original authorization.

## Flow diagram

```mermaid
sequenceDiagram
    participant User
    participant Merchant
    participant Truemed

    User->>Merchant: Click "Pay with HSA/FSA"
    Merchant->>Truemed: POST /create_payment_session (kind: authorization)
    Truemed-->>Merchant: redirect_url + payment_session_id
    Merchant->>Merchant: Store payment_session_id on order
    Merchant->>User: Redirect to Truemed
    User->>Truemed: Complete health survey
    User->>Truemed: Enter HSA/FSA card details
    Truemed-->>User: Redirect to success_url
    Truemed->>Merchant: payment_session_complete (processing)
    Note over Merchant: Do not fulfill yet
    Truemed->>Merchant: payment_session_complete (authorized)
    Note over Merchant: Authorization hold is ready
    alt Ready to fulfill
        Merchant->>Truemed: POST /payment_session/{business_id}/capture
        Truemed-->>Merchant: Capture succeeds
        Note over Merchant: Fulfill order
    else Order should not be fulfilled
        Merchant->>Truemed: POST /payment_session/{business_id}/void
        Truemed-->>Merchant: Void request accepted
        Truemed->>Merchant: payment_session_complete (authorization_voided)
        Note over Merchant: Release order without fulfillment
    end
```

## Request body

The [`create_payment_session`](/api-reference/payment-sessions/create-payment-session) endpoint can be invoked with the additional fields described here.

| Field  | Type   | Description                                             |
| ------ | ------ | ------------------------------------------------------- |
| `kind` | string | One of: `one_time_payment` (default) or `authorization` |

### Kind values

* `one_time_payment` **(DEFAULT)**: The charge is [immediately captured](/guides/overview/glossary#immediate-capture). This is the default if this field is not set.
* `authorization`: A `one_time_payment` authorization hold only. Must be manually captured or voided with a follow-up API call.

## Response body

The response is the same as described in the [`create_payment_session`](/api-reference/payment-sessions/create-payment-session) API reference, with additional error states.

### Bad request

HTTP Status: `400`

If a field is missing or the request otherwise can't be processed, we'll return a `400`.

## Capture and void operations

Once an authorization hold has been created, you can either capture or void it:

* **Capture**: Call [`POST /payments/v1/payment_session/{business_id}/capture`](/api-reference/payment-sessions/capture-payment-session) to capture the authorized amount.
* **Void**: Call [`POST /payments/v1/payment_session/{business_id}/void`](/api-reference/payment-sessions/void-payment-session) to release the authorization hold without capturing.

### Capture request

Use a unique `idempotency_key` for each capture attempt. Include the total amount being captured and
the specific items included in the capture.

If you plan to capture by item, provide `item_id` on each `order_items` entry when creating the
payment session so you can reference those same items in `item_details`.

```bash
curl https://dev-api.truemed.com/payments/v1/payment_session/c51f5d44-9f8d-4e9f-bc5f-929a6f9f2f51/capture \
  -X POST \
  -H "Content-Type: application/json" \
  -H "x-truemed-api-key: $TRUEMED_API_KEY" \
  -d '{
    "total_amount": 12500,
    "idempotency_key": "capture_order_12345",
    "final": true,
    "item_details": [
      {
        "item_id": "line_item_1",
        "quantity": 1,
        "total": 12500
      }
    ]
  }'
```

Set `final` to `false` only if you plan to make additional captures against the same authorization.
This requires multi-capture, which is off by default — see
[Capturing in multiple parts](#capturing-in-multiple-parts).

### Void request

Void the authorization when the order should not be fulfilled.

```bash
curl https://dev-api.truemed.com/payments/v1/payment_session/c51f5d44-9f8d-4e9f-bc5f-929a6f9f2f51/void \
  -X POST \
  -H "Content-Type: application/json" \
  -H "x-truemed-api-key: $TRUEMED_API_KEY" \
  -d '{
    "idempotency_key": "void_order_12345"
  }'
```

## Capturing in multiple parts

Multi-capture lets you capture part of one authorization at a time, usually once per shipment. Each capture
collects what shipped; the rest stays authorized until your final capture.

Set [`request_multicapture: true`](/api-reference/payment-sessions/create-payment-session) in the
`create_payment_session` request. Truemed then requests multi-capture when it authorizes the cards. The card network
confirms availability for each transaction, and Truemed returns the result as
[`multicapture_available`](/api-reference/payment-sessions/payment-session-completed-webhook) in the authorized
`payment_session_complete` webhook and in
[`get_payment_session`](/api-reference/payment-sessions/retrieve-payment-session). Check it before you ship part of
an order.

When [`multicapture_available`](/api-reference/payment-sessions/payment-session-completed-webhook) is `true`,
capture each shipment as it goes out with `final: false`. When the networks have not made multi-capture available,
the session supports only a single capture. Attempting multi-capture with `final: false` in this case is rejected.

> **Best practices**
>
> **Check [`multicapture_available`](/api-reference/payment-sessions/payment-session-completed-webhook) before you
> split an order.** When it's `false`, capture the full order in one request.
>
> **Capture items that may qualify for HSA/FSA spending first, and shared shipping with them or at the end.** That
> keeps the most money on the customer's HSA/FSA card.
>
> **Put tax, shipping and discounts on the items at checkout if you know them.** Then each item's capture is
> simply its `total`.
>
> **Send `final: true` on the last capture.** It releases whatever you didn't collect.

### Turning it on

1. Ask Truemed to enable multi-capture for your sales channel.
2. Create the session with
   [`kind: "authorization"` and `request_multicapture: true`](/api-reference/payment-sessions/create-payment-session).
   Sessions that save or reuse a card (`tokenize` or `payment_token`) can't use it.
3. Once the session is authorized, read `multicapture_available` on the
   [`payment_session_complete`](/api-reference/payment-sessions/payment-session-completed-webhook) webhook or
   [`get_payment_session`](/api-reference/payment-sessions/retrieve-payment-session).

If [`multicapture_available`](/api-reference/payment-sessions/payment-session-completed-webhook) is `false`, the card
network allowed only one capture. A `final: false` capture will be rejected, and a final capture releases everything
it doesn't collect. Decide how to fulfill that order before you ship part of it.

### Capturing

Send one [`capture_payment_session`](/api-reference/payment-sessions/capture-payment-session) per shipment,
each with a new `idempotency_key`, the units that shipped in `item_details`, and `final: false` until the last.

```bash
curl https://dev-api.truemed.com/payments/v1/payment_session/c51f5d44-9f8d-4e9f-bc5f-929a6f9f2f51/capture \
  -X POST \
  -H "Content-Type: application/json" \
  -H "x-truemed-api-key: $TRUEMED_API_KEY" \
  -d '{
    "total_amount": 6000,
    "idempotency_key": "capture_order_12345_shipment_1",
    "final": false,
    "item_details": [
      { "item_id": "line_item_1", "quantity": 2, "total": 6000 }
    ]
  }'
```

To close without collecting more, send `total_amount: 0`, `item_details: []` and `final: true`, or
[void](/api-reference/payment-sessions/void-payment-session) the session. A capture of everything still owed
closes the session on its own.

### Partial quantities: why a rounding rule, and which one

An item's [`max_capture_amount`](/api-reference/payment-sessions/payment-session-completed-webhook) covers its full
quantity, but its units may be captured separately. Rounding each capture independently could leave cents behind or
let the captures collect more than the item's limit. Truemed therefore calculates each capture from the cumulative
quantity:

`share(k) = max_capture_amount × k ÷ quantity`, rounded half up to the nearest cent

If `b` units were captured before and the next capture contains `n`, their base share is
`share(b + n) - share(b)`. This produces the same total whether units are captured individually, in groups, or all
at once.

Your system may place a rounding cent on a different unit than Truemed does. To accommodate that, the cumulative
limit allows up to one additional cent per captured unit, without ever exceeding `max_capture_amount`. For example,
when `max_capture_amount` is `1000` and `quantity` is `3`, the item's captures may total up to `334` after one unit,
`669` after two, and `1000` after all three. Amount left uncollected on an earlier unit does not otherwise increase
what a later unit may collect.

### Shipping, tax and discounts sent for the whole order

If you send them in the session's top-level
[`amount_details`](/api-reference/payment-sessions/create-payment-session), Truemed splits them across the items when
the session is authorized. Each item publishes its
[`order_level_charges_share`](/api-reference/payment-sessions/payment-session-completed-webhook),
[`order_level_discounts_share`](/api-reference/payment-sessions/payment-session-completed-webhook), and
[`max_capture_amount`](/api-reference/payment-sessions/payment-session-completed-webhook): its total plus the charges
share less the discounts share. Captures can then carry that money in either of two ways:

* **Send item totals and let Truemed work it out.**
  [`total_amount`](/api-reference/payment-sessions/capture-payment-session) can be the items' totals plus any
  order-level money still owed, so one box can carry all the shipping. Coming in under the items' totals applies
  your order-level discounts.
* **Declare it.** Send [`amount_details`](/api-reference/payment-sessions/capture-payment-session) on the capture or
  on each item, in the same shape as at checkout, when your fulfillment system knows each box's tax, shipping and
  discounts. A discount declared on an item belongs to that item, and an item you send without `amount_details`
  keeps the charges and discounts it was created with.

If a session's first capture sends no `amount_details`, later captures can't send them either; a final capture
without `amount_details` collects what's left. A session whose first capture declares can mix declared and inferred
captures.

If a discount only applies to some items, such as a bundle deal, declare it on those items: otherwise Truemed
spreads it across the whole order. The [capture reference](/api-reference/payment-sessions/capture-payment-session)
has the exact rules.

### Good to know

* **\$0.50 minimum.** A card can't be charged less than \$0.50 in one capture. If an item worth less than that
  ships last on its own, add it to an earlier box or leave it uncollected.
* **The regular card's authorization.** When a customer splits payment between an HSA/FSA card and a regular
  card, Truemed may authorize a little more on the regular card than the customer's share, so later boxes can
  always be charged. You never collect more than the order total, and the unused part is released when the
  session closes.
* **HSA/FSA money on the regular card.** Sometimes money that may qualify for HSA/FSA spending has to go on the
  regular card, for example eligible shipping captured before the items it belongs to. The receipt still reports
  the full eligible amount, so the customer can choose to seek reimbursement from their HSA/FSA administrator for
  the portion charged to the regular card.
* **Limits.** One authorization allows at most 50 non-final captures plus the final one.

### Refunds

Each capture appears in `captures[]` on the session with its own `id`. Refund against a specific capture by
passing that `id` as `capture_id` on [`create_refund`](/api-reference/payment-sessions/create-refund), one
refund per capture. A refund doesn't free up authorization for later captures.