Create destination charges
Create charges on your platform account, collect fees, and immediately transfer the remaining funds to your connected accounts.
Create destination charges when customers transact with your platform for products or services provided by your connected accounts and you immediately transfer funds to your connected accounts. With this charge type:
- You create a charge on your platform’s account.
- You determine whether some or all of those funds are transferred to the connected account.
- Your account balance is debited for the cost of the Stripe fees, refunds, and chargebacks.
This charge type is most optimal for marketplaces such as Airbnb, a home rental marketplace or Lyft, a ridesharing app.
Destination charges are only supported if both your platform and the connected account are in the same country. For cross-border support, you must specify the settlement merchant to the connected account using the on_behalf_of parameter on the Payment Intent or other valid cross-border transfers scenarios.
Remarque
We recommend using destination charges for connected accounts that have access to the Express Dashboard or no dashboard access.
Build a custom payments integration by embedding UI components on your site, using Stripe Elements. The client-side and server-side code builds a checkout form that accepts various payment methods. See how this integration compares to Stripe’s other integration types.
Integration effort
Integration type
Combine UI components into a custom payment flow
UI customization
CSS-level customization with the Appearance API
First, register for a Stripe account.
Use our official libraries to access the Stripe API from your application:
Create a PaymentIntentServer-side
Stripe uses a PaymentIntent object to represent your intent to collect a payment from a customer, tracking charge attempts and payment state changes throughout the process.
The payment methods shown to customers during the checkout process are also included on the PaymentIntent. You can let Stripe automatically pull payment methods from your Dashboard settings or you can list them manually.
Unless your integration requires a code-based option for offering payment methods, don’t list payment methods manually. Stripe evaluates the currency, payment method restrictions, and other parameters to determine the list of supported payment methods. Stripe prioritizes payment methods that help increase conversion and are most relevant to the currency and the customer’s location. Stripe hides lower priority payment methods in an overflow menu.
Retrieve the client secret
The PaymentIntent includes a client secret that the client side uses to securely complete the payment process. You can use different approaches to pass the client secret to the client side.
Collect payment detailsClient-side
Collect payment details on the client with the Payment Element. The Payment Element is a prebuilt UI component that simplifies collecting payment details for a variety of payment methods.
The Payment Element contains an iframe that securely sends payment information to Stripe over an HTTPS connection. Avoid placing the Payment Element within another iframe because some payment methods require redirecting to another page for payment confirmation.
If you do choose to use an iframe and want to accept Apple Pay or Google Pay, the iframe must have the allow attribute set to equal "payment *"
.
The checkout page address must start with https://
rather than http://
for your integration to work. You can test your integration without using HTTPS, but remember to enable it when you’re ready to accept live payments.
The Payment Element renders a dynamic form that allows your customer to pick a payment method. For each payment method, the form automatically asks the customer to fill in all necessary payment details.
Customize appearance
Customize the Payment Element to match the design of your site by passing the appearance object into options
when creating the Elements
provider.
Collect addresses
By default, the Payment Element only collects the necessary billing address details. To collect a customer’s full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
Request Apple Pay merchant token
If you’ve configured your integration to accept Apple Pay payments, we recommend configuring the Apple Pay interface to return a merchant token to enable merchant initiated transactions (MIT). Request the relevant merchant token type in the Payment Element.
Submit the payment to StripeClient-side
Use stripe.confirmPayment to complete the payment using details from the Payment Element. Provide a return_url to this function to indicate where Stripe should redirect the user after they complete the payment. Your user may be first redirected to an intermediate site, like a bank authorization page, before being redirected to the return_
. Card payments immediately redirect to the return_
when a payment is successful.
If you don’t want to redirect for card payments after payment completion, you can set redirect to if_
. This only redirects customers that check out with redirect-based payment methods.
Make sure the return_
corresponds to a page on your website that provides the status of the payment. When Stripe redirects the customer to the return_
, we provide the following URL query parameters:
Parameter | Description |
---|---|
payment_ | The unique identifier for the PaymentIntent . |
payment_ | The client secret of the PaymentIntent object. |
Mise en garde
If you have tooling that tracks the customer’s browser session, you might need to add the stripe.
domain to the referrer exclude list. Redirects cause some tools to create new sessions, which prevents you from tracking the complete session.
Use one of the query parameters to retrieve the PaymentIntent. Inspect the status of the PaymentIntent to decide what to show your customers. You can also append your own query parameters when providing the return_
, which persist through the redirect process.
Handle post-payment eventsServer-side
Stripe sends a payment_intent.succeeded event when the payment completes. Use the Dashboard webhook tool or follow the webhook guide 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 rather than 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, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.
In addition to handling the payment_
event, we recommend handling these other events when collecting payments with the Payment Element:
Event | Description | Action |
---|---|---|
payment_intent.succeeded | Sent when a customer successfully completes a payment. | Send the customer an order confirmation and fulfill their order. |
payment_intent.processing | Sent when a customer successfully initiates a payment, but the payment has yet to complete. This event is most commonly sent when the customer initiates a bank debit. It’s followed by either a payment_ or payment_ event in the future. | Send the customer an order confirmation that indicates their payment is pending. For digital goods, you might want to fulfill the order before waiting for payment to complete. |
payment_intent.payment_failed | Sent when a customer attempts a payment, but the payment fails. | If a payment transitions from processing to payment_ , offer the customer another attempt to pay. |
Test the integration
See Testing for additional information to test your integration.
Collect fees
When a payment is processed, rather than transfer the full amount of the transaction to a connected account, your platform can decide to take a portion of the transaction amount in the form of fees. You can set fee pricing in two different ways:
Use the Platform Pricing Tool to set and test application fee pricing rules. This no-code feature in the Stripe Dashboard is currently only available for platforms responsible for paying Stripe fees.
Set your pricing rules in-house, specifying fees directly in a PaymentIntent using either the application_fee_amount or transfer_data[amount] parameter. Fees set with this method override the pricing logic specified in the Platform Pricing Tool.
Specify the settlement merchant 
The settlement merchant is dependent on the capabilities set on an account and how a charge is created. The settlement merchant determines whose information is used to make the charge. This includes the statement descriptor (either the platform’s or the connected account’s) that’s displayed on the customer’s credit card or bank statement for that charge.
Specifying the settlement merchant allows you to be more explicit about who to create charges for. For example, some platforms prefer to be the settlement merchant because the end customer interacts directly with their platform (such as on-demand platforms). However, some platforms have connected accounts that interact directly with end customers instead (such as a storefront on an e-commerce platform). In these scenarios, it might make more sense for the connected account to be the settlement merchant.
You can set the on_
parameter to the ID of a connected account to make that account the settlement merchant for the payment. When using on_
:
- Charges settle 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_
is omitted, the platform is the business of record for the payment.
Mise en garde
The on_
parameter is supported only for connected accounts with a payments capability such as card_payments. Accounts under the recipient service agreement can’t request card_
or other payments capabilities.
Issue refunds 
If you are using the Payment Intents API, refunds should be issued against the most recent charge that is created.
Charges created on the platform account can be refunded using the platform account’s secret key. When refunding a charge that has a transfer_
, by default the destination account keeps the funds that were transferred to it, leaving the platform account to cover the negative balance from the refund. To pull back the funds from the connected account to cover the refund, set the reverse_
parameter to true
when creating the refund:
By default, the entire charge is refunded, but you can create a partial refund by setting an amount
value as a positive integer.
If the refund results in the entire charge being refunded, the entire transfer is reversed. Otherwise, a proportional amount of the transfer is reversed.
Refund application fees 
When refunding a charge with an application fee, by default the platform account keeps the funds from the application fee. To push the application fee funds back to the connected account, set the refund_application_fee parameter to true
when creating the refund:
Note that if you refund the application fee for a destination charge, you must also reverse the transfer. If the refund results in the entire charge being refunded, the entire application fee is refunded as well. Otherwise, a proportional amount of the application fee is refunded.
Alternatively, you can provide a refund_
value of false and refund the application fee separately through the API.
Failed refunds
If a refund fails, or you cancel it, the amount of the failed refund returns to your platform account’s Stripe balance. Create a Transfer to move the funds to the connected account, as needed.
Handle disputes 
For destination charges, with or without on_
, Stripe debits dispute amounts and fees from your platform account.
We recommend setting up a webhook to listen to dispute created events. When that happens, you can attempt to recover funds from the connected account by reversing the transfer through the Dashboard or by creating a transfer reversal.
If the connected account has a negative balance, Stripe attempts to debit its external account if debit_
is set to true
.
If you challenge the dispute and win, you can transfer the funds that you previously reversed back to the connected account. If your platform has an insufficient balance, the transfer fails. Prevent insufficient balance errors by adding funds to your Stripe balance.
Erreur fréquente
Retransferring a previous reversal is subject to cross-border transfer restrictions, meaning you might have no means to repay your connected account. Instead, wait to recover disputed cross-border payment transfers for destination charges with on_
until after a dispute is lost.