RyzeDeskRyzeDesk

Stripe

4105 articles

Accept a payment using separate charges and transfers


Accept a payment using separate charges and transfers

Use separate charges and transfers to accept payments.

Create separate charges and transfers to transfer funds from one payment to multiple connected accounts or when a specific user isn’t known at the time of the payment. The charge on your platform account is decoupled from the transfers to your connected accounts. With this charge type:

  • You create a charge on your platform’s account and also transfer funds to your connected accounts. The payment appears as a charge on your account and there are also transfers to connected accounts (amount determined by you), which are withdrawn from your account balance.
  • You can transfer funds to multiple connected accounts.
  • You’re the merchant of record and your account balance gets debited for the cost of the Stripe fees, refunds and chargebacks.

This charge type helps marketplaces split payments between multiple parties. For example, a restaurant delivery platform that splits payments between the restaurant and the deliverer.

Note

Funds segregation is a private preview feature that keeps payment funds in a protected holding state before you transfer them to connected accounts. This prevents allocated funds from being used for unrelated platform operations. Contact your Stripe account manager to request access.

Create a Checkout Session Server-side

A Checkout Session controls what your customer sees in the payment form such as line items, the order amount and currency and acceptable payment methods. Add a checkout button to your website that calls a server-side endpoint to create a Checkout Session.

On your server, create a Checkout Session and redirect your customer to the URL returned in the response.

Command Line

Select a language

cURL

Stripe CLI

Ruby

Python

PHP

Java

Node.js

Go

.NET

No results

ParameterValueRequired?Description
line_itemsA list of items the customer is purchasing.Required conditionallyThis attribute represents the items the customer is purchasing. The items are displayed in the Stripe-hosted checkout page.
payment_intent_data[transfer_group]A unique string that identifies a payment as being part of a group.YesWhen Stripe automatically creates a charge for a PaymentIntent with a transfer_group value, it assigns the same value to the charge’s transfer_group.
success_urlA valid URLYesStripe redirects the customer to the success URL after they complete a payment and replaces the {the related setting} string with the Checkout Session ID. Use this to retrieve the Checkout Session and inspect the status to decide what to show your customer. You can also append your own query parameters, which persist through the redirect process. See customise redirect behaviour with a Stripe-hosted page for more information.

Handle post-payment events for separate charges and transfers Server-side

Stripe sends a checkout.session.completed event when the payment completes. Use a webhook to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow.

Listen for these events instead of waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes. Some payment methods also take 2-14 days for payment confirmation. Setting up your integration to listen for asynchronous events enables you to accept multiple payment methods with a single integration.

Handle the following events when collecting payments with Checkout:

EventDescriptionNext steps
checkout.session.completedThe customer has successfully authorised the payment by submitting the Checkout form.Wait for the payment to succeed or fail.
checkout.session.async_payment_succeededThe customer’s payment succeeded.Fulfil the purchased goods or services.
checkout.session.async_payment_failedThe payment was declined, or failed for some other reason.Contact the customer via email and request that they place a new order.

These events all include the Checkout Session object. After the payment succeeds, the underlying PaymentIntent status changes from processing to succeeded or a failure status.

Create a transfer Server-side

On your server, send funds from your account to a connected account by creating a Transfer and specifying the transfer_group used.

Command Line

Select a language

cURL

Stripe CLI

Ruby

Python

PHP

Java

Node.js

Go

.NET

No results

Transfer and charge amounts don’t have to match. You can split a single charge between multiple transfers or include multiple charges in a single transfer. The following example creates an additional transfer associated with the same transfer_group.

Command Line

Select a language

cURL

Stripe CLI

Ruby

Python

PHP

Java

Node.js

Go

.NET

No results

Transfer options

You can assign any value to the transfer_group string, but it must represent a single business action. You can also make a transfer with neither an associated charge nor a transfer_group – for example, when you must pay a provider but there’s no associated customer payment.

Note

The transfer_group only identifies associated objects. It doesn’t affect any standard functionality. To prevent a transfer from executing before the funds from the associated charge are available, use the transfer’s source_transaction attribute.

By default, a transfer request fails when the amount exceeds the platform’s available account balance. Stripe doesn’t automatically retry failed transfer requests.

You can avoid failed transfer requests for transfers that are associated with charges. When you specify the associated charge as the transfer’s source_transaction, the transfer request automatically succeeds. However, we don’t execute the transfer until the funds from that charge are available in the platform account.

Note

If you use separate charges and transfers, take that into account when planning your payout schedule. Automatic payouts can interfere with transfers that don’t have a defined source_transaction.

Geographic availability

Stripe supports separate charges and transfers in the following regions:

Australia

Austria

Belgium

Brazil

Bulgaria

Canada

Croatia

Cyprus

Czech Republic

Denmark

Estonia

Finland

France

Germany

Greece

Hungary

Ireland

Italy

Japan

Latvia

Liechtenstein

Lithuania

Luxembourg

Malaysia

Malta

Mexico

Netherlands

New Zealand

Norway

Poland

Portugal

Romania

Singapore

Slovakia

Slovenia

Spain

Sweden

Switzerland

United Kingdom

United States

Stripe supports cross-border transfers on the payments balance between the United States, Canada, United Kingdom, the EEA and Switzerland. In other scenarios, your platform and any connected account must be in the same region. Attempting to transfer funds across unsupported borders or balances returns an error. See Cross-border payouts for supported funds flows between other regions.

You must only use transfers in combination with the permitted use cases for charges, tops-ups and fees. We recommend using separate charges and transfers only when you’re responsible for negative balances of your connected accounts.

Next steps

After you can process payments, monetise your marketplace by collecting application fees from your connected accounts.

Last verified 2026-09-27

Is this helpful?