Creating separate charges and transfers
Use separate charges and transfers for Express or Custom accounts where you collect charges that might be a different amount than what’s paid out to your connected accounts. The platform is responsible for Stripe fees, refunds, and chargebacks. For more information about the different types of Connect charges, see the documentation on choosing an approach.
Stripe supports separate charges and transfers in the following regions:
- Australia
- Brazil
- Canada
- Japan
- Malaysia
- Mexico
- New Zealand
- SEPA
- Singapore
- United States
Caution
- In most scenarios, your platform and any connected account must be in the same region. Attempting to transfer funds across a disallowed border returns an error. For information about cross-region support, see Cross-border transfers. You must only use transfers in combination with the permitted use cases for charges, tops-ups and fees.
- We don’t support all SEPA countries. You can use separate charge and transfer for only the countries listed on Global availability.
To associate a Charge with a Transfer, first create a unique string to use as a group identifier. When you create a PaymentIntent, Charge, or Transfer object, assign that string to its transfer_group
attribute. Use the transfer_group
to identify objects that are associated with each other.
When Stripe automatically creates a charge for a PaymentIntent with a transfer_group
value, it assigns the same value to the charge’s transfer_group
.
For the complete flow, see accept a payment.
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.
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. You can perform transfers and charges in any order.
By default, a transfer request fails when the amount exceeds the platform’s available account balance. You can instead validate the transfer amount against its associated charge by specifying that charge as the transfer’s source_transaction. In that case, the transfer request automatically succeeds but isn’t executed 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
.
Collecting fees
When using separate charges and transfers, the platform can collect fees on a charge by reducing the amount it transfers to the destination accounts. For example, consider a restaurant delivery service transaction that involves payments to the restaurant and to the driver:
- The customer pays a 100 USD charge.
- Stripe collects a 3.20 USD fee and adds the remaining 96.80 USD to the platform account’s pending balance.
- The platform transfers 70 USD to the restaurant’s connected account and 20 USD to the driver’s connected account.
- A platform fee of 6.80 USD remains in the platform account.
To learn about processing payments in multiple currencies with Connect, see Working with multiple currencies.
Refunding charges
You can refund charges created on your platform using its secret key. However, refunding a charge has no impact on any associated transfers. It’s up to your platform to reconcile any amount owed back to it by reducing subsequent transfer amounts or by reversing transfers (as explained next).
Reversing transfers
Connect supports the ability to reverse transfers made to connected accounts, either entirely or partially (by setting an amount
value):
Transfer reversals add the specified (or entire) amount back to the platform’s available balance, reducing the connected account’s available balance accordingly. It is only possible to reverse a transfer if the connected account’s available balance is greater than the reversal amount or has connected reserves enabled.
If the transfer reversal requires a currency conversion, and the reversal amount would result in a zero balance after the conversion, it returns an error.
Using on_behalf_of
Optionally, you can set the on_behalf_of
parameter to the ID of a connected account to make that account the business of record for the payment. When using on_behalf_of
:
- Charges are settled in the connected account’s country and settlement currency.
- The fee structure for the connected account’s country is used.
- The connected account’s statement descriptor is displayed on the customer’s credit card statement.
- If the connected account is in a different country than the platform, the connected account’s address and phone number are displayed on the customer’s credit card statement.
- The number of days that a pending balance is held before being paid out depends on the
delay_days
setting on the connected account.
If on_behalf_of
is omitted, the platform is the business of record for the payment.
Caution
The on_behalf_of
attribute is supported only for connected accounts with the card_payments capability. Accounts under the recipient service agreement can’t request card_payments
.
In the latest version of the API, specifying the automatic_payment_methods
parameter is optional because Stripe enables its functionality by default.
Transfer availability
The default behavior is to transfer funds from the platform account’s available balance. Attempting a transfer that exceeds the available balance fails with an error. To avoid this problem, when creating a transfer, tie it to an existing charge by specifying the charge ID as the source_transaction
parameter. With a source_transaction
, the transfer request returns success regardless of your available balance. However, the funds don’t become available in the destination account until the funds from the associated charge are available to transfer from the platform account.
If the source charge has a transfer_group
value, Stripe assigns the same value to the transfer’s transfer_group
. If it doesn’t, then Stripe generates a string in the format group_
plus the associated PaymentIntent ID, for example: group_pi_2NHDDD589O8KAxCG0179Du2s
. It assigns that string as the transfer_group
for both the charge and the transfer.
Note
You must specify the source_transaction
when you create a transfer. You can’t update that attribute later.
You can get the charge ID from the PaymentIntent:
- Get the PaymentIntent’s latest_charge attribute. This attribute is the ID of the most recent charge associated with the PaymentIntent.
- Request a list of charges, specifying the
payment_intent
in the request. This method returns full data for all charges associated with the PaymentIntent.
When using this parameter:
- The amount of the transfer must not exceed the amount of the source charge
- You can create multiple transfers with the same
source_transaction
, as long as the sum of the transfers doesn’t exceed the source charge - The transfer takes on the pending status of the associated charge: if the funds from the charge become available in N days, the payment that the destination Stripe account receives from the transfer also becomes available in N days
- Stripe automatically creates a
transfer_group
for you - The currency of the balance transaction associated with the charge must match the currency of the transfer
Asynchronous payment methods, like ACH, can fail after a subsequent transfer request is made. For these payments, avoid using source_transaction
. Instead, wait until a charge.succeeded event is triggered before transferring the funds. If you have to use source_transaction
with these payments, you must implement functionality to manage payment failures.
When a payment used as a source_transaction
fails, funds from your platform’s account balance are transferred to the connected account to cover the payment. To recover these funds, reverse the transfer associated with the failed source_transaction
.