Stripe | Financial Infrastructure to Grow Your Revenue

Stripe | Financial Infrastructure to Grow Your Revenue

4466 articles

Capture a payment multiple times


Private preview

Capture a payment multiple times Private preview

Capture a card-present payment multiple times, up to the authorized amount.

Multicapture lets you capture a card-present PaymentIntent multiple times, up to the full authorized amount. You can use this to authorize a total amount and capture funds as you fulfill part of the order.

IC+ feature

We offer multicapture to users on IC+ pricing. If you’re on standard Stripe pricing and want access to this feature, contact us using the form at Stripe support.

Interested in getting early access to multicapture on Terminal?

Enter your email to request access.

Availability

When using multicapture on Terminal, be aware of the following requirements:

  • It only applies to card _ present payments. Learn more about online card payments support .
  • Use capture_method set to manual . Multicapture requires manual capture so that you can perform multiple partial captures on the PaymentIntent.
  • It’s available on American Express, Cartes Bancaires, Diners Club, Discover, Japan Credit Bureau (JCB), Mastercard, and Visa.
  • Multicapture isn’t supported for separate charges and transfers fund flows using source_transaction .

JCB multicapture is only available in Australia, Canada, New Zealand, and the United States.

Automatic capture methods

The API currently accepts request_multicapture="if_available" when capture_method is set to automatic or automatic_async without returning an error. In this case, multicapture.status on the charge may show available, but you can’t perform multiple captures because the PaymentIntent is automatically captured in full. Always set capture_method to manual when you intend to use multicapture. A future API version may return a validation error for this combination.

Best practices

  • Multicapture on Terminal adheres to the card-present authorization validity windows. The card-present authorization validity window can be shorter than for online payments (card-not-present). Make sure to capture the payment within the authorization validity window, to prevent the funds from releasing and the payment status changing to canceled. If you use the API, the payment_method_details.card.capture_before attribute on the charge indicates when the authorization expires.
  • When using multicapture to send separate shipments for one order, proactively notify your customer with the details of each shipment. This can avoid inquiries and chargebacks from customers because of confusion with seeing multiple transactions on their bank statement. Use the following best practices when notifying customers:
  • Inform them of the estimated delivery date and transaction amount for each shipment at the time of checkout, before purchase.
  • Notify them upon each shipment, along with the transaction amount.
  • Disclose your full refund and cancellation policy.

Compliance

You’re responsible for your compliance with all applicable laws, regulations, and network rules when using multicapture. Consult the rules for the card networks that you want to use this feature with to make sure you comply with all applicable rules, which vary by network.

Request multicapture support Client-side Server-side

When creating or updating a PaymentIntent, you can request the ability to multicapture. Set the payment_method_options.card_present.request_multicapture to if_available and the capture_method to manual.

Command Line

Select a language

cURL

Stripe CLI

Ruby

Python

PHP

Java

Node.js

Go

.NET

No results

You can also provide request_multicapture when confirming the PaymentIntent.

Check eligibility after confirmation Client-side

Confirm the PaymentIntent and verify payment_method_details.card_present.multicapture.status on the latest_charge to determine if multicapture is available for that payment.

{
 "id": "pi_xxx",
 "status": "requires_capture",
 "latest_charge": {
 "id": "ch_xxx",
 "payment_method_details": {
 "type": "card_present",
 "card_present": {
 "multicapture": {
 "status": "available"
 }
 }
 }
 }
}

Not all PaymentIntents are eligible for multicapture. If the status is unavailable, use a single capture as usual.

Capture the PaymentIntent Server-side

For a PaymentIntent in the requires_capture state where multicapture.status is available, you can capture part of the authorized amount by setting the amount_to_capture to the desired amount and final_capture to false. Instruct Stripe not to release the remaining uncaptured funds by setting final_capture to false.

Note

Stripe allows up to 50 non-final captures for a single PaymentIntent. You can then perform one additional final capture to complete the payment.

Command Line

Select a language

cURL

Stripe CLI

Ruby

Python

PHP

Java

Node.js

Go

.NET

No results

Each partial capture updates the PaymentIntent fields:

  • amount _ capturable decreases
  • amount _ received increases
  • status remains requires _ capture until final capture

Final capture Server-side

To complete the payment and release any remaining uncaptured amount, set final_capture to true. You can also omit it, because true is the default.

Command Line

Select a language

cURL

Stripe CLI

Ruby

Python

PHP

Java

Node.js

Go

.NET

No results

After final capture, the PaymentIntent transitions to succeeded.

Optional Release uncaptured funds Server-side

Testing

You can test multicapture for card-present payments in a sandbox. Set the payment_method_options.card_present.request_multicapture to if_available, and verify the multicapture.status after confirmation before attempting partial captures.

Refunds

For a PaymentIntent in requires_capture state, you can refund any number of times up to the total captured amount minus the total refunded amount, which is the amount_received — amount_refunded. The charge.refunded field transitions to true only when the final capture has been performed and the entire amount_received is refunded.

Stripe doesn’t support partial refunds with refund_application_fee=true or reverse_transfer=true. Instead, you can perform partial fee refunds by manually performing partial fee refunds and transfer reversals using the application fee refund and transfer reversal endpoints. After using the application fee refund or transfer reversal endpoints, Stripe doesn’t support any further refunds with refund_application_fee=true or reverse_transfer=true respectively.

Connect

Multicapture supports all Connect use cases, with the exception of Separate Charges and Transfers with the source_transaction parameter. The application_fee_amount and transfer_data[amount] parameters have some additional validations. Consider the following validations when implementing multicapture with Connect:

  • Setting application _ fee _ amount or transfer _ data[amount] on the first capture makes it required for all subsequent captures. Each application _ fee _ amount and transfer _ data[amount] passed at capture time overrides the values passed in on PaymentIntent creation, confirmation, and update.
  • Stripe doesn’t support partial refunds on multicapture payments with refund_application_fee=true or reverse_transfer=true. You can perform partial fee refunds or transfer reversals using the application fee refund and transfer reversal endpoints.

Webhooks

Charge updated webhooks

We send a charge.updated webhook each time you capture a payment.

For example, on the first capture of a destination charge multicapture payment with an application_fee_amount, we update these fields from empty to non-empty values.

// charge.updated
{
 "data": {
 "id": "ch_xxx",
 "object": "charge",
 "amount": 1000,
 "balance_transaction": "txn_xxx", // applicable to all charges
 "transfer": "tr_xxx", // applicable to destination charges only
 "application_fee": "fee_xxx", // applicable to Connect only
 ...
 },
 "previous_attributes": {
 "balance_transaction": null, // applicable to all charges
 "transfer": null, // applicable to destination charges only
 "application_fee": null // applicable to Connect only
 }
}

payment_intent.amount_capturable_updated

We send payment_intent.amount_capturable_updated on every capture, regardless of amount_to_capture and final_capture values.

For example, if we capture 1 USD from a PaymentIntent with an amount of 10 USD, the PaymentIntent’s amount_capturable field updates to 9 USD.

// payment_intent.amount_capturable_updated
{
 "data": {
 "id": "pi_xxx",
 "object": "payment_intent",
 "amount": 1000,
 "amount_capturable": 900 // 1000 - 100 = 900
 ...
 },
 "previous_attributes": {
 "amount_capturable": 1000
 }
}

Charge captured events

We send a charge.captured event for final captures or at the end of the authorization window to reverse the authorization of the uncaptured amount. The captured field for a charge only becomes true after a final capture or authorization reversal.

For example, if we do a capture with amount=0 and final_capture=true, the captured attribute on the charge changes from false to true.

// charge.captured
{
 "data": {
 "id": "ch_xxx",
 "object": "charge",
 "captured": true
 ...
 },
 "previous_attributes": {
 "captured": false
 }
}

Refund webhooks

Multicapture refund webhooks are no different than non-multicapture refund webhooks.

During each partial refund, we send a refund.created event. For connected accounts, we also send application_fee.refunded events when we refund application fees and transfer.reversed events when we reverse transfers.

See also

Last verified 2026-09-24

Is this helpful?