Direct answer
A UK marketplace should choose its Stripe Connect charge route from the commercial relationship, not from the shortest code sample. Use a direct charge when the seller is visibly transacting with the buyer; a destination charge when the platform owns the checkout and one seller fulfils the order; and separate charges and transfers when one payment has several recipients, the recipient is selected later, or transfer timing must be independent. Whichever route you choose, keep an internal money ledger, process webhooks idempotently, test refunds and negative balances, and obtain UK legal, tax and payments-regulatory advice on the model.
Executive summary
- A connected account is not a complete marketplace architecture; the charge route sets the money and liability path.
- Direct, destination and separate-charge routes solve different commercial shapes and should not be swapped casually.
- Stripe events are inputs to your ledger, not your order state; duplicate, late and failed deliveries must be recoverable.
- UK seller reporting and payment-services analysis require data and decisions beyond Stripe onboarding.
The payout feature that could not be tested where it mattered
On an Appycodes engagement for a UK wholesale marketplace, the delivery record shows a vendor bulk-payout update blocked because the relevant feature was not available in staging. The next work separated write-offs from the vendor payout source, and a later record marked that payout work complete. Months afterwards, a multi-country Stripe-account change and a new PaymentIntent checkout reached implementation while full integration testing was temporarily blocked by other backend testing; the team then moved into webhook and order-level data testing.
The hard lesson was not “Stripe is difficult”. It was that money-moving behaviour cannot be accepted from a local happy path. A payout source, a write-off, the buyer charge and the seller statement are different accounting facts. If staging cannot exercise the same route, account ownership and webhook scope as production, “payment succeeded” proves too little.
Our public UK wholesale marketplace case study explains the wider, long-running ecommerce and reconciliation context. The practical conclusion for a new UK marketplace is simple: make the production money topology reproducible in test before the first seller is owed funds.
Choose the charge type from the transaction shape
Stripe documents three Connect charge types. The choice determines where the charge appears, how funds move, which statement details are used and which Stripe balance is debited for refunds and chargebacks. Stripe: how Connect charges work
| Route | Use when | Money and liability consequence | Do not choose it merely because |
|---|---|---|---|
| Direct charge | One seller transacts directly with one buyer; the marketplace mainly supplies software or discovery. | The charge is created on the connected account. Its balance receives the payment and is normally debited for refunds and chargebacks; the platform can collect an application fee. | Each seller already has a Stripe account. |
| Destination charge | The buyer experiences one platform checkout and one connected account fulfils the order or service. | The platform creates the charge and immediately routes an amount to one connected account. The platform balance bears Stripe fees, refunds and chargebacks. | It is the most familiar marketplace tutorial. |
| Separate charges and transfers | A basket has multiple sellers, the recipient is not known at charge time, or transfer timing must be decoupled. | The platform charge and one or more transfers are separate objects. The platform balance bears fees, refunds and chargebacks and needs enough available funds. | You want to “hold money” without defining the contractual and operational reason. |
Stripe says separate charges and transfers add complexity and are intended for cases such as multiple recipients, a recipient chosen after payment or transfer timing independent of the charge. It also warns that refunding the platform charge does not automatically reverse associated transfers; the platform must reconcile or reverse them. Stripe: separate charges and transfers
The on_behalf_of parameter is a settlement decision, not decorative metadata. Stripe says it changes the business-of-record treatment within Stripe, the connected account country and fee structure, statement descriptor and payout timing. That setting must agree with the seller contract, checkout copy, invoice, support process and tax position. It does not replace a qualified legal conclusion about who is merchant of record. Stripe: indirect charges and on_behalf_of
The Appycodes Marketplace Charge Route Gate
Before implementation, score five gates from 0 to 3: 0 undecided, 1 assumed, 2 documented but untested, 3 documented and tested with retained evidence. The maximum is 15. Contract and Liability are hard gates: either at zero means the team should not ship a live money route, whatever the total.
Who sells, invoices, appears on statements and owes the refund?
One seller, several sellers, or a recipient assigned after payment?
Whose balance absorbs fees, refunds, disputes and negative amounts?
When is fulfilment accepted, funds transferable and payout releasable?
Can every provider object be traced to an order and seller allocation?
This is an architecture-readiness model, not legal or financial advice and not a statistical risk score. Its value is forcing five decisions that a checkout mock-up hides. Apply it per transaction family: a marketplace can legitimately use direct charges for seller-owned stores and separate charges for a platform-curated multi-seller basket, provided each route remains explicit and reconcilable.
Your order database needs a money ledger
Do not make the order row carry every financial state. An order describes the commercial purchase; the money ledger describes movements and obligations. Keep amounts as integers in the currency's minor unit and retain the route version used when the buyer paid.
| Record | Minimum identity | Why it stays separate |
|---|---|---|
| Payment attempt | Order, attempt, PaymentIntent, charge route, gross, currency | A buyer can retry; only one attempt should become the accepted charge. |
| Seller allocation | Order line, seller, gross share, fee, tax, net, rules version | The commercial split must survive catalogue and commission-rule changes. |
| Transfer | Allocation, Stripe transfer, connected account, amount, status | One charge can create several transfers or a later transfer. |
| Refund/reversal | Original movement, reason, requested and recovered amount | Refunding the buyer and recovering seller funds are not always the same event. |
| Dispute | Charge, amount, deadline, evidence owner, liability account | A dispute is an asynchronous case, not an order-status toggle. |
| Payout observation | Connected account, payout, amount, arrival state | Transfer to a connected balance is not proof that the seller's bank received funds. |
| Provider event | Event ID, account context, type, object ID, received and processed times | Deduplicates webhooks and preserves the audit trail for replay. |
This ledger also supports a UK requirement that payment code often discovers too late. HMRC's current platform-operator guidance requires reportable seller data that can include quarterly amounts paid after deductions, fees or commissions withheld, transaction counts and available payout-account details. Stripe reports can help, but the marketplace must preserve the seller-level meaning of each deduction. HMRC: collect and verify digital-platform seller information
A destination-charge implementation with explicit boundaries
The example below is appropriate only for a one-seller, platform-led order whose Charge Route Gate has passed. It creates the provider object and immediately persists the internal attempt. It intentionally omits on_behalf_of; adding that field would change settlement semantics and should be a reviewed route version, not an incidental refactor.
// A platform-led, one-seller order. Use only after the commercial
// model confirms that the platform owns the customer-facing charge.
const intent = await stripe.paymentIntents.create(
{
amount: order.totalMinor,
currency: "gbp",
automatic_payment_methods: { enabled: true },
application_fee_amount: order.platformFeeMinor,
transfer_data: { destination: seller.stripeAccountId },
metadata: {
order_id: order.id,
seller_id: seller.id,
charge_route: "destination_v1",
allocation_version: order.allocationVersion,
},
},
{ idempotencyKey: `checkout:${order.id}:${order.paymentAttempt}` },
);
await db.paymentAttempt.upsert({
where: { providerIntentId: intent.id },
create: {
orderId: order.id,
providerIntentId: intent.id,
route: "destination",
grossMinor: order.totalMinor,
feeMinor: order.platformFeeMinor,
sellerMinor: order.totalMinor - order.platformFeeMinor,
currency: "GBP",
status: intent.status,
},
update: { status: intent.status },
});The idempotency key prevents a network retry from creating a second PaymentIntent for the same attempt. Metadata is useful for support, but it is not the ledger: it has limits, can be edited and does not model later allocations or reversals. Persist the provider ID before returning the client secret, and require the authenticated order owner to retrieve it.
Do not mark the order fulfilled from the browser success page. Stripe recommends verifying webhook signatures from the raw request body, returning a successful response quickly and processing asynchronous work separately. Connect integrations may need both platform-scope events for destination or separate charges and connected-account events for direct charges, onboarding and payout failures. Stripe: webhook endpoint guidance · Stripe: Connect webhooks
- Verify and record. Store the event ID and account context under a unique constraint before queueing work.
- Fetch and reduce. Retrieve the current provider object when needed, then apply an allowed state transition to the payment attempt.
- Post ledger movements. Create immutable allocation, transfer, fee, refund or dispute entries; do not rewrite history.
- Reconcile. A scheduled job compares internal open items with Stripe balance transactions and raises owned exceptions.
For a destination-charge refund, decide whether seller funds and the platform fee should also be reversed. Make those two decisions explicit in the case record:
await stripe.refunds.create(
{
payment_intent: payment.providerIntentId,
amount: refund.amountMinor,
reverse_transfer: true,
refund_application_fee: refund.refundPlatformFee,
metadata: { refund_id: refund.id, order_id: payment.orderId },
},
{ idempotencyKey: `refund:${refund.id}:${refund.attempt}` },
);A partial refund needs a deterministic allocation rule—per line, pro rata or operator-selected—and should never reverse more seller funds than the refunded lines justify. If a connected balance cannot cover a reversal, keep the buyer refund and seller recovery as separate statuses so customer service can see what happened.
UK checks that sit outside the PaymentIntent
Payments regulation
The FCA says that providing payment services as a regular business activity generally requires authorisation or registration unless an exclusion or exemption applies. Its commercial-agent guidance warns that acting for both payer and payee is likely to require authorisation, and that control of funds before the payee receives them is a relevant indicator. Use a regulated provider such as Stripe Connect as designed, but have a UK payments specialist review the contractual and operational flow—especially if the platform delays, pools, redirects or manually releases money. FCA: commercial agent exclusion and payment-services perimeter
Seller onboarding and reporting
Stripe-hosted or embedded onboarding is preferable to collecting sensitive verification material yourself because Stripe can collect connected-account requirements and update the flow as requirements change. Stripe: embedded onboarding But UK platform reporting is a separate data product. HMRC requires reporting platform operators in scope to collect and verify specified seller details, retain reportable transaction information and submit seller reports. Build an explicit seller-reporting profile with provenance and refresh rules rather than copying whatever fields happen to be visible from Connect.
Tax, invoices and customer promises
Decide who supplies the goods or service, who issues the VAT invoice, who sets refund terms and who handles chargebacks before release. Stripe's route can support that model; it cannot invent it. Keep tax calculations, invoice records and Connect transfers joined by your order and allocation IDs, not by customer email or statement text. This guide is technical and operational guidance, not legal, tax, financial or regulatory advice.
Six failure modes to test before live payouts
1. Seller onboarding is “complete” but a capability is inactive
Persist capability and requirement states separately from your own seller status. Block the specific action that needs the capability, explain the next step and refresh from account events. Do not reduce onboarding to one boolean.
2. Staging uses a different money topology
A test platform with no representative connected accounts, webhook scopes or payout path cannot prove the production design. Maintain test sellers for every account configuration, seed the same fee rules, and rehearse onboarding expiry, disabled payouts, refunds and disputes. This is the exact class of gap exposed in the Appycodes marketplace record.
3. The checkout succeeds but the webhook is delayed
The browser should show a processing state and poll your order endpoint. A reconciliation worker can retrieve the PaymentIntent and safely close a missing event path. Never fulfil because a query string says success=true.
4. A refund leaves the seller transfer untouched
Destination and separate-charge routes debit the platform for refunds. Decide whether to reverse seller funds, absorb the cost or recover it from future earnings. Record the buyer refund and seller recovery independently.
5. A multi-seller basket is forced through one destination
One destination charge has one connected-account destination. If the basket has several sellers, split the commercial orders before payment or use separate charges and transfers with explicit allocations. Do not hide a second seller's entitlement in an offline spreadsheet.
6. The team reconciles orders, not balances
An order total can be correct while fees, disputes, reversals or payouts are wrong. Reconcile from balance transactions to ledger movements and from ledger movements to orders. Alert on orphan provider objects, duplicate allocations, negative seller balances and transfers with no accepted fulfilment state.
Recommendations by UK marketplace type
When the platform owns booking and support and one professional fulfils each job, destination charges often match the product. Define cancellation windows, dispute evidence and seller recovery before payout.
Multi-seller baskets, order amendments, net terms and partial fulfilment make the ledger more important than the checkout. Separate card collection from seller entitlement and write-offs.
Decide whether the organiser or platform sells the ticket, when funds become releasable, and how cancellations, postponements and chargebacks affect reserves.
A charity-register match does not prove the connected account belongs to the charity or that the user may act for it. Retain a manual exception route.
After real marketplace work, Appycodes recommends one executable money-flow specification before payment UI begins: named contracting parties, charge route, fee formula, settlement setting, transfer timing, refund allocation, dispute owner, payout controls and ledger postings. Then test that specification with representative connected accounts and failure fixtures. Our B2B marketplace development service covers the product, payment, seller-operations and reconciliation layers together.
Frequently asked questions
- Which Stripe Connect charge type should a UK marketplace use?
- Use direct charges when each seller transacts directly with its own customer; destination charges when the customer buys through the platform and one connected account fulfils the order; and separate charges and transfers when one payment must be split across sellers, the seller is chosen later, or transfer timing must be decoupled from the charge. Confirm the contractual, tax and regulatory model before implementing the API route.
- Does Stripe Connect make the platform the merchant of record?
- Not by itself. Stripe's charge route and on_behalf_of setting affect the settlement merchant or business-of-record treatment inside Stripe, statement details, fees and balance liability. Your contracts, invoices, customer promises, tax position and regulated-payment analysis still need to agree with that implementation. Obtain qualified advice for the legal conclusion.
- Can a marketplace delay seller payouts with Stripe Connect?
- A marketplace can control transfer or payout timing in supported Connect configurations, but it should not describe that as escrow without specific legal advice. Delayed fulfilment, refunds, reserves, negative balances and the platform's own available balance must all be modelled and tested.
- What records should a UK marketplace keep outside Stripe?
- Keep an immutable internal record of the order, buyer charge, seller allocation, platform fee, transfers, reversals, refunds, disputes and payouts, with provider identifiers and currency in minor units. Stripe is the payment processor's record; your ledger explains the marketplace's business decision and supports customer service, accounting and HMRC seller reporting.
- Does Stripe onboarding satisfy every UK seller-verification duty?
- No. Stripe onboarding collects information needed for its services and connected-account requirements. A UK platform may separately need contractual authority, product eligibility, sanctions or sector checks and HMRC digital-platform seller information. Reuse verified data only where permitted, but do not collapse separate obligations into one 'KYC complete' flag.
Primary sources
- Stripe: Connect charge types, balance liability and chargebacks
- Stripe: separate charges, transfers, refunds and reversals
- Stripe: webhook signatures, asynchronous handling and testing
- Stripe: embedded connected-account onboarding
- FCA: payment services and the commercial agent exclusion
- HMRC: collect, verify and report digital-platform seller information
Technical and operational guidance, not legal, regulatory, tax, accounting or financial advice. Have qualified UK advisers confirm your contracts, payment-services perimeter, VAT treatment and seller-reporting obligations.
UK topic cluster
Payments & ecommerce
UK payment, marketplace, tax, shipping and reconciliation implementation guidance.
Related guide
Which Stripe payment methods should a UK business enable?
Choose customer payment methods only after billing ownership and fulfilment timing are clear.
Related guide
Anatomy of a B2B marketplace MVP
See why trust, seller operations and payments dominate marketplace delivery.
Case study
A long-running UK wholesale marketplace
Storefront, catalogue, payments and reconciliation across a multi-market B2B platform.










































