# Capture a payment multiple times Capture a card-present payment multiple times, up to the authorized amount. Multicapture lets you capture a card-present [PaymentIntent](https://docs.stripe.com/api/payment_intents/object.md) 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* (A pricing plan where businesses pay the variable network cost for each transaction plus the Stripe fee rather than a flat rate for all transactions. This pricing model provides more visibility into payments costs). If you’re on standard Stripe pricing and want access to this feature, contact us using the form at Stripe [support](https://support.stripe.com/). ### Interested in getting early access to multicapture on Terminal? Enter your email to request access. ```bash curl https://docs.stripe.com/preview/register \ -X POST \ -H "Content-Type: application/json" \ -H "Referer: https://docs.stripe.com/terminal/features/multicapture" \ -d '{"email": "EMAIL", "preview": "terminal_multicapture_preview"}' ``` ## 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](https://docs.stripe.com/payments/multicapture.md). - Use [capture_method](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-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](https://docs.stripe.com/connect/separate-charges-and-transfers.md) fund flows using [source_transaction](https://docs.stripe.com/api/transfers/create.md#create_transfer-source_transaction). > #### JCB support > > 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](https://docs.stripe.com/payments/place-a-hold-on-a-payment-method.md#card-present-transactions-inperson-payments). 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](https://docs.stripe.com/api/charges/object.md#charge_object-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](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-card_present-request_multicapture) to `if_available` and the [capture_method](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-capture_method) to `manual`. ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=5000 \ -d currency=usd \ -d "payment_method_types[]=card_present" \ -d capture_method=manual \ -d "payment_method_options[card][request_multicapture]=if_available" ``` 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. ```json { "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. ```curl curl https://api.stripe.com/v1/payment_intents/{{PAYMENT_INTENT_ID}}/capture \ -u "<>:" \ -d amount_to_capture=100 \ -d final_capture=false ``` 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. ```curl curl https://api.stripe.com/v1/payment_intents/{{PAYMENT_INTENT_ID}}/capture \ -u "<>:" \ -d amount_to_capture=200 \ -d final_capture=true ``` After final capture, the `PaymentIntent` transitions to `succeeded`. ## Optional: Release uncaptured funds [Server-side] If you performed at least one capture, you can release all remaining uncaptured funds by setting `amount_to_capture` to `0` and `final_capture` to `true`. ```curl curl https://api.stripe.com/v1/payment_intents/{{PAYMENT_INTENT_ID}}/capture \ -u "<>:" \ -d amount_to_capture=0 \ -d final_capture=true ``` ## Testing You can test multicapture for card-present payments in a [sandbox](https://docs.stripe.com/sandboxes.md). 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](https://docs.stripe.com/api/refunds.md) any number of times up to the total captured amount minus the total refunded amount, which is the [amount_received](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-amount_received)—[amount_refunded](https://docs.stripe.com/api/charges/object.md#charge_object-amount_refunded). The [charge.refunded](https://docs.stripe.com/api/charges/object.md#charge_object-refunded) field transitions to `true` only when the final capture has been performed and the entire [amount_received](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-amount_received) is refunded. Stripe doesn’t support *partial refunds* (A partial refund is any refund in which less than the remaining refundable amount is refunded in a single request. The remaining refundable amount is the payment_intent.amount_received - charge.amount_refunded) with [refund_application_fee=true](https://docs.stripe.com/api/refunds/create.md#create_refund-refund_application_fee) or [reverse_transfer=true](https://docs.stripe.com/api/refunds/create.md#create_refund-reverse_transfer). Instead, you can perform partial fee refunds by manually performing partial fee refunds and transfer reversals using the [application fee refund](https://docs.stripe.com/api/fee_refunds.md) and [transfer reversal](https://docs.stripe.com/api/transfer_reversals.md) 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](https://docs.stripe.com/connect/separate-charges-and-transfers.md) with the [source_transaction](https://docs.stripe.com/api/transfers/create.md#create_transfer-source_transaction) parameter. The [application_fee_amount](https://docs.stripe.com/api/payment_intents/capture.md#capture_payment_intent-application_fee_amount) and [transfer_data[amount]](https://docs.stripe.com/api/payment_intents/capture.md#capture_payment_intent-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* (A partial refund is any refund in which less than the remaining refundable amount is refunded in a single request. The remaining refundable amount is the payment_intent.amount_received - charge.amount_refunded) 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](https://docs.stripe.com/api/fee_refunds.md) and [transfer reversal](https://docs.stripe.com/api/transfer_reversals.md) endpoints. ## Webhooks ### Charge updated webhooks We send a [charge.updated](https://docs.stripe.com/api/events/types.md#event_types-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. ```json // 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](https://docs.stripe.com/api/events/types.md#event_types-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. ```json // 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](https://docs.stripe.com/api/events/types.md#event_types-charge.captured) event for final captures or at the end of the authorization window to reverse the authorization of the uncaptured amount. The [captured](https://docs.stripe.com/api/charges/object.md#charge_object-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](https://docs.stripe.com/api/charges/object.md#charge_object-captured) attribute on the charge changes from false to true. ```json // 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](https://docs.stripe.com/api/events/types.md#event_types-refund.created) event. For connected accounts, we also send [application_fee.refunded](https://docs.stripe.com/api/events/types.md#event_types-application_fee.refunded) events when we refund application fees and [transfer.reversed](https://docs.stripe.com/api/events/types.md#event_types-transfer.reversed) events when we reverse transfers. ## See also - [Online card payment multicapture](https://docs.stripe.com/payments/multicapture.md)