A guide to delayed marketplace payments (like Upwork or Fiverr) with Bubble and Stripe Connect

If you’re building a marketplace with Bubble, you’re very likely using Stripe Connect to process payments. It’s relatively straightforward to implement a basic marketplace payment flow where:

  • The customer pays for a good/service on the marketplace via a Stripe Checkout Session/Payment link
  • The payment is split between the platform (EG Etsy) and the seller on the platform (EG the Etsy seller)
  • The good/service is delivered and everyone is happy

HOWEVER, not all marketplaces are that straightforward. In fact, most aren’t. I’ve been running the Stripe Connect - Marketplace plugin for about 2 years. It’s been installed in > 600 marketplace apps built on Bubble and I’ve interacted with a huge number of folks building different types of marketplaces in that time.

One of the most common ‘complex’ marketplace payment flows I’ve come across is the ‘delayed payment’ / ‘escrow*’ style payment flow. This is where the customer pays for the good/service being sold on the marketplace immediately, but the seller doesn’t actually fulfil the service or deliver the goods to the customer until a later date.

As a result, the marketplace owner may not wish for the funds to be released to the seller until the service has been fulfilled or the goods have been delivered.

Some examples of this:

  • A freelancer marketplace like Upwork, where the customer pays for the service upfront, but the freelancer doesn’t actually complete the job for a number of days/weeks/months
  • A rental accommodation marketplace like Airbnb, where the customer pays for the accommodation upfront, but their booking may not actually be until a few months later
  • A rideshare marketplace like Uber, where the customer provides their payment details when booking an Uber, but they don’t actually pay for the ride until after they’ve been delivered

*Please note that ‘escrow’ has a very specific legal meaning and Stripe explicitly state that they do not provide escrow services or support escrow accounts.

The rest of this post will go through 3 ways you can implement these types of marketplace payment flows:

  • Manual payouts
  • Separate charges and transfers
  • Authorize and capture

Manual payouts
Manual payouts allow you to control the timing of when funds are released from the seller’s connected Stripe account to their bank account. A typical payment flow involving manual payouts would be as follows:

  • Customer purchases a good/service from a seller (who has a Stripe Express account) on a marketplace using a destination charge
  • 80% goes to the seller’s Stripe account and the marketplace takes the remaining 20% as a fee
  • Once the good/service has been delivered, the customer marks the job as complete
  • A manual payout is made so that the funds that were in the seller’s Stripe balance are paid out to their bank account

I personally think manual payouts are the best solution for most marketplaces where there’s a delayed payment flow.

Advantages

  • Manual payouts can be used with global marketplaces, where the seller’s business may be registered in a different country to the platform itself (EG if a freelancer is registered in France and the freelance marketplace itself is registered in the US). This is a big advantage over the ‘Separate charges and transfer’ approach in particular (see disadvantage #1 of the separate charges and transfer approach below for full details)
  • While you do need to pay out the funds to the seller within a specific period of time (see disadvantage #2 below), you have a much longer window to do this in vs. the ‘authorize and capture’ approach (where you typically have to capture the funds within 7 days of the initial payment)

Disadvantages

  • You’ll need to ensure there’s sufficient available funds in the seller’s connected account to pay them out. This may seem like a strange problem. After all, if the customer pays for the good/service immediately, why would the funds not be available? There are a number of reasons, but the big one is that Stripe typically schedules a new account’s first payout for 7-14 days AFTER that account receives their first payment. This problem can also be an issue with the ‘separate charges and transfers’ and ‘authorize and capture’ approaches, but tends to be less of an issue because the seller will be on a rolling payout schedule (either daily, weekly or monthly). The best solution to this is to build in some logic that checks whether or not there are sufficient funds available to pay out (see 10:02 of this video for an example)
  • You must pay out the funds within a specific timeframe. This varies by country (you can see the Stripe docs on this here), but as of the time of writing you have to pay out funds within 2 years in the US and 90 days in most other countries.

You can learn how to implement manual payouts (using the Stripe Connect - Marketplace plugin) in the below video tutorial

Separate Charges and Transfers

With separate charges and transfers, the charge on your platform account is decoupled from the transfer of funds to the seller’s connected account.

  • The customer pays for the good/service on your marketplace and the full value of the payment immediately goes to your platform account
  • The funds stay there in their entirety until the good/service has been delivered*
  • The seller’s fee then gets transferred to their connected account via a Stripe transfer

Advantages

  • You can transfer funds to multiple parties. This can be necessary if you’re running a multi-sided marketplace. EG, if you’re running a food delivery marketplace like Doordash, you may need to split each payment between: 1) the restaurant, 2) the delivery driver and 3) your platform.

Disadvantages

  • In most cases, the platform and connected account must be in the same region. This is a big limitation for global marketplaces where the platform and the seller may be registered in different countries
  • You need to ensure you have sufficient funds in the platform account to transfer to the seller’s connected account at the appropriate time. This can be an issue if you’ve had refund requests in the period between when the initial payment was made and before the transfer is made

You can learn how to implement the separate charges and transfers approach (using the Stripe Connect - Marketplace plugin) in the below video tutorial. The relevant section is from 32:07 to 37:11.

Authorize and Capture

This method allows the customer to ‘authorize’ a payment immediately, but the payment doesn’t actually go through until it is ‘captured’ at a later point in time. It’s effectively putting a payment on hold. This approach is typically best suited to a marketplace where there’s a very small time gap between when the customer orders the good/service and when it’s delivered.

The best example is probably an Uber-style marketplace. The customer may authorise a payment for a ride when ordering via the Uber app, but the payment doesn’t actually get captured until the customer has been delivered to their destination.

  • The key here is to set the ‘capture_method’ to ‘manual’ when processing the charge. This will set the PaymentIntent Status to ‘requires_capture’ and puts the payment on hold
  • When the services has been delivered, you can then ‘capture’ the payment, at which point the payment is processed and split between the platform and the seller

Advantages

  • It’s probably the easiest of the 3 methods described in this post to implement
  • You don’t have to worry about having sufficient funds in your platform account to transfer to connected accounts (like with the separate charges and transfers approach) or having sufficient funds available to pay out (like with manual payouts)

Disadvantages

  • In most cases, the authorization for an online card payment is only valid for up to 7 days. This may make this approach unsuitable for marketplaces where there’s a longer time period between the initial authorization and when it gets captured (like with many services or freelancer marketplaces).

Note: It is possible to place an extended hold on online card payments for up to 30 days (see relevant Stripe docs here).

You can learn how to implement the authorize and capture approach (using the Stripe Connect - Marketplace plugin) in the below video tutorial. The relevant section is from 11:06 to 23:06.

Further reading/resources

Disclaimer

Absolutely none of this should be taken as the absolute source of truth when it comes to delayed marketplace payments (and is definitely not legal advice). It’s simply what I’ve observed from helping a lot of people with their marketplace payment flows over the past couple of years.

Great guide, thanks for publishing!

Bookmarking this, thanks!

No problem @jahanzeb.khn07 :slight_smile:

Hi everyone,

@alexcooney5 Thanks for this comprehensive guide on delayed marketplace payments!

However, I’m struggling to apply any of the 3 solutions you presented to our specific use case. Maybe I’m missing something?


Our constraints:

We’re building a short-term rental marketplace in France with these requirements:

  • Platform registered in France, but hosts and properties across multiple countries
  • Bookings up to 12 months in advance
    • Ideally: Charge immediately at booking (secures reservation, reduces no-show risk)
    • Reality according to our research so far: Can’t hold funds 12 months due to Stripe 90-day payout limit
  • Host can only withdraw funds 2 days after check-in (traveler protection - ensures property was delivered as promised)
  • No ACPR license required (ACPR = French financial regulator; platforms holding customer funds for extended periods need a payment institution license, which is complex and expensive to obtain)

The core problem: How to secure long-term bookings financially while respecting Stripe’s 90-day limit, supporting global hosts, and avoiding fund custody regulations?


Why the 3 solutions presented don’t seem to fit:

Solution 1: Manual payouts

This seems the closest to our needs, but:

  • Stripe 90-day payout limit: You mention funds must be paid out within 90 days (most countries). If we charge immediately at booking and payout at check-in +2 days, that’s potentially 12 months between charge and payout = exceeds 90-day limit

Question: Is there a way to use manual payouts for bookings made 12 months in advance while respecting the 90-day payout limit?

Solution 2: Separate Charges and Transfers

  • Fund holding issue: Funds sit on platform balance for up to 12 months before transfer = likely triggers ACPR licensing requirement in France (platform acts as fund custodian)
  • Same 90-day transfer limit mentioned in Stripe docs

Solution 3: Authorize and Capture

  • Authorization expiry: You mention authorization valid for 7 days (max 30 with extended auth). Our bookings can be made 12 months in advance = authorization would expire long before check-in
  • Not suitable for long-term advance bookings

Am I understanding these limitations correctly, or is there a workaround I’m missing?


Our current approach (but not ideal):

After researching extensively and discussing with Stripe support, here’s the only configuration that seems to meet our constraints:

1. At booking time (up to 12 months before check-in):

Create Checkout Session (mode: “setup”)
→ Customer enters card + 3DS authentication
→ Save payment_method_id (no charge yet)

2. At check-in -80 days:

Create Invoice with:

  • auto_advance: true (enables Smart Retries)
  • on_behalf_of: host_express_account (host = Merchant of Record)
  • transfer_data: { destination: host_express_account }
  • application_fee_amount: commission
  • default_payment_method: saved_payment_method

→ Stripe automatically charges the card
→ Funds go directly to host Express account
→ Manual payouts enabled (host can’t withdraw yet)

(80-day delay chosen to respect Stripe’s 90-day limit between charge and payout)

3. At check-in +2 days:

Create Payout (API call)
→ Funds released to host bank account

Confirmed by Stripe support:

  • Smart Retries work with Invoice auto-charged
  • on_behalf_of + transfer_data supported with Invoice API
  • No time limit between SetupIntent and charge (can be 12 months)
  • Manual payouts allow controlling when host receives funds

Limitations of this approach:

  • High risk of expired/invalid cards at D-80 (bookings made 6-12 months prior)
  • Requires complex workflows for payment failure recovery
  • Degraded UX (emails like “Your card expired, please update”)
  • Estimated 10-25% failure rate after 6-12 months

Questions for the community:

  1. Is there a better Stripe Connect configuration for long-term bookings with delayed fund release that we haven’t identified?
  2. Has anyone implemented a similar marketplace (rentals, travel, events with advance bookings) in Bubble? What approach did you use?
  3. Escrow alternatives: Should we consider a regulated escrow service like MangoPay instead of Stripe Connect for this use case? (They seem to allow unlimited fund holding duration)
  4. ACPR compliance: For EU-based Bubble developers, how do you handle the “fund holding” regulatory aspect for marketplaces?

Any advice or alternative approaches would be greatly appreciated! :folded_hands:

Thanks for your precious help!

Yup, using the separate charges and transfers. As long as the backend is well configured and Stripe Webhooks are put together, it works well (in development testing at least).

Thanks! Yes, separate charges and transfers works technically, but in my case (vacation rentals with bookings up to 12 months in advance), holding funds that long on platform balance seems to trigger ACPR payment institution licensing requirements in France.

I need a solution that avoids holding customer funds on platform balance to stay compliant without a license.