NextGen Global IT ParkNextGen Global IT Park
← All posts

Stripe Connect for an EU marketplace: the KYC and payout edge cases that only show up in production

Published 25 October 2026 · Stripe Connect · Marketplaces · EU KYC

Stripe Connect's quickstart gets a marketplace taking payments in an afternoon. What it does not cover is the second month: a provider in Sweden whose payouts stopped, a customer in Spain who wants to add an hour mid-job, a refund that has to claw money back from a connected account that has already been paid out. This is what we learned building and operating Door2Day, a home-services marketplace in Spain and Sweden, with customers paying by card and providers paid out in their local currency.

It is written for the engineer adding Connect to a two-sided platform, so each section ends with what we would do from the start next time.

1. Onboarding: the requirements list is a moving target

Connect accounts are not "verified" once. Stripe attaches a requirements object to every account with currently_due, eventually_due, past_due and a current_deadline. What is required depends on the country, the business type (individual vs company) and — the part that surprises people — how much the account has processed. A Swedish sole trader can onboard with a name, date of birth and address, start earning, and weeks later be asked for an identity document because a volume threshold was crossed.

If nothing in your product watches that object, the first you hear of it is a provider asking why their money stopped.

What we do now:

2. Payouts across two countries and two currencies

Spain settles in EUR, Sweden in SEK. Customers pay in the currency of the service, and the provider is paid out in their account's default currency. The two facts that drove our design:

We use destination charges with an application_fee_amount: the customer pays the platform, the provider's share is transferred automatically, the fee stays with us. One PaymentIntent per job, transfer_data[destination] set to the provider's account. The alternative — separate charges and transfers — gives more control and more bookkeeping; we would still start with destination charges for a single-provider-per-job marketplace.

Payout timing is the other thing to design for. Stripe's default schedule for a new connected account is daily with a rolling delay that depends on the country. Providers in both countries asked about this, so the provider app shows the next expected payout date from the payout objects rather than a generic "within a few days".

3. The mid-job price change

The edge case that made us rewrite the payment flow: a customer books three hours of cleaning, the job runs long, and both sides agree on a fourth hour while the cleaner is still in the flat.

Options we considered:

We ended up with the booking authorised with modest headroom, captured for the agreed amount, and any overrun above the headroom charged as a separate PaymentIntent with the saved card and the same destination account — with the customer confirming the extra in the app before the charge. The provider-side transfer for the extra arrives as its own payout line, which the provider app explains.

4. Refunds, reversals and disputes

Webhooks we treat as mandatory: account.updated, payment_intent.succeeded, payment_intent.payment_failed, charge.refunded, charge.dispute.created, payout.paid, payout.failed, transfer.reversed. Every one of them updates our own records; the Stripe dashboard is never the source of truth for what the app shows.

5. Testing what you cannot reproduce

Stripe's test mode has test identities and test cards for most of these states — accounts that fail verification, cards that trigger disputes, payouts that fail. We keep a script that creates the full set of connected-account states for both countries and runs the webhook handlers against them, and it runs in CI. The things it cannot simulate — a real identity-document review, a real chargeback timeline — go into a runbook with the exact dashboard steps for support.

What we would do from day one next time

  1. Store the requirements object and surface deadlines to providers; never let a payout stop silently.
  2. Use Stripe-hosted onboarding for KYC in every country; do not build the forms yourself.
  3. Destination charges with an application fee, one PaymentIntent per job, headroom on the authorisation.
  4. A documented path for charging more than the booking, agreed in the app before it happens.
  5. reverse_transfer on every refund, and a one-click evidence export for disputes.
  6. Every webhook above handled and tested in CI before the first real provider signs up.

Adding payments to a marketplace, or inheriting one that was built fast? A Production-Readiness Audit covers the payment flow, the webhooks and the data behind them — $2,500, fixed price, five business days.

Book a 20-minute call