How to process shopping cart payments with Stripe Connect (multiple sellers, one payment)

If you’re building a marketplace with Bubble, you’re likely using Stripe Connect to process payments. Some marketplace payment flows are pretty straightforward to implement. For example, if you’re building a accommodation rental marketplace like Airbnb, you may have a payment flow where:

  • The customer pays for the accommodation immediately
  • The payments gets split between the host and your marketplace (likely using a destination charge)

Note: you can have more complex versions of this payment flow where there is a delay between when the payment is made and when the seller receives the payment - see this post for full details.

Things get more complicated when you’re running a marketplace like Amazon, where customers can add multiple items from different sellers to their shopping cart. You’ll still want to split the payment associated with each item in the shopping cart between the seller and your platform, but also allow the customer to pay for all the items at once. I’ve been running the Stripe Connect - Marketplace plugin for the past 2 years and have received quite a few enquiries about this type of payment flow over this time.

You can implement this into your Bubble app using Stripe’s ‘Separate Charges and Transfers’ method. The rest of this post will go through the steps involved in setting up this type of payment flow.

Important note: This approach will only work if your marketplace/platform falls into one of these two categories:

  • Your platform and all the sellers on your platform are registered in the same country (different European countries in the euro area are also ok)
  • Your platform is registered in the US and the sellers on your platform are registered in a country where Stripe supports cross-border payouts

This unfortunately means that there is currently (to my knowledge) no good solution for non-US based platforms who operate a global marketplace with sellers in different countries.

Overview of steps involved

  1. Structure your database for shopping cart-style payments
  2. Allow your sellers (or merchants) to register for a Stripe Express account and add products
  3. Create a Stripe Checkout Session with multiple items to allow customers to pay for multiple items at once
  4. Save down details to your database for the transaction as a whole and ALSO for each individual item in the customer’s shopping cart
  5. Make transfers to each of the relevant sellers
  6. Link each transfer to a specific transaction

Visually, this is how the payment flow looks:

I’ve put together a demo app at the link below (editor is public), so you can check it out if you’re looking for an actual example of how to implement this payment flow:

1. Structure your database for shopping cart-style payments
There are a number of ways you can do this, but I would suggest having the following data types:

You can view the database section of the demo app if you want to see this in Bubble.

Some key things to note:

  • Each user has their own ‘Shopping Cart’, which is essentially a list of ‘Cart Items’ (which are in turn based on the products themselves). This is going to make life a lot easier in step 3 when you’re creating a Stripe Checkout Session with multiple items.
  • Each payment will have an associated ‘Transaction’ (which is the overall payment) and a list of ‘Item Purchases’. The list of item purchases is really important in allowing us to transfer the appropriate amounts to individual sellers in steps 5 and 6.

2. Allow your sellers (or ‘merchants’) to register for a Stripe Express account and add products
You’ll need to onboard your sellers so that they have their own Stripe Express account and then let them add products to your marketplace.

You can learn how to do this (with the Stripe Connect - Marketplace plugin) in the below tutorial:

3. Create a Stripe Checkout Session with multiple items to allow customers to pay for multiple items at once

This is where your database structure will either make things pretty straightforward or very difficult. I recommend following a structure similar to what is outlined in Step #1 above and creating a new cart item each time a customer clicks ‘Add to Cart’ on a particular item:

You can then add this cart item to the ‘Current User’s Shopping Cart’:

Now when you’re creating your Stripe Checkout Session, you should be able to easily access a list of cart items. In the below example, I’m using the ‘Stripe Connect - Create Checkout Session (Multiple Items)’ action that comes with the Stripe Connect - Marketplace plugin to create the Checkout Session:

2024-08-02 16.35.16

These are the fields used in the ‘Stripe Connect - Create Checkout Session (Multiple Items)’ action:

Note that there’s no reference to the seller of each of the underlying items in this action. We will need to record this information in order to determine how much to transfer to each seller - see the next step for full details.

4. Save down details to your database for the transaction as a whole and also for each individual item in the customer’s shopping cart

As highlighted in step #1, I recommend using the following two data types to record details of a payment:

  • Transaction
  • Item Purchase

‘Transaction’ is intended to record details of the transaction as a whole, while ‘Item Purchase’ is intended to be used for individual item details.

As shown in the below screenshot, I typically create a new ‘Transaction’ when the user clicks ‘Checkout’ and then save down the Checkout Session ID to this new ‘Transaction’ after the Checkout Session has been created:

It’s a bit more difficult to create records associated with each individual item as there will likely be an uncertain number of items in the customer’s shopping cart. There are a number of ways to approach this, but what I would suggest is:

  • Add a backend workflow that creates a new ‘Item Purchase’ for each ‘Cart Item’ that’s passed through to it
  • Run this workflow on the list of ‘Cart Items’ that are in the customer’s shopping cart

Note that I’m passing through the ‘Amount’ of the item purchase, the ‘Seller Account ID’ and the ‘Transaction’ to the backend workflow. This is really important for being able to transfer the correct amount to the seller’s when the Checkout Session has been completed.

Save down this data to the ‘Item Purchase’ in the backend workflow (and add each one to the appropriate transaction):

You should end up with something like this, where you have 3 different ‘Item Purchases’ associated with the same transaction, but with a different Seller Account ID:

5. Make transfers to each of the relevant sellers
At this stage, when customers make a payment, the full value of the payment should be ending up in your platform’s Stripe account. However, your marketplace is only supposed to take a % commission of each transaction. Therefore, we need to transfer the appropriate amount to each seller after the payment has been made by the customer.

For the rest of this example, I’m going to assume we’re transferring 80% of the value of each item purchase to the seller, with the marketplace retaining a 20% commission (less Stripe fees).

I recommend using a Stripe Webhook to trigger a backend workflow whenever a Stripe Checkout Session is completed (you’ll want to use the ‘checkout.session.completed’ event). You can use this backend workflow to save down the PaymentIntent associated with the transaction. This will be crucial for step 6.

We’re then going to create another backend API workflow that will actually make the transfers. In the demo app (editor link is here), I’ve called this workflow ‘make_transfers’ and passed through 3 parameters to it: 1) Seller Account ID 2) Amount and 3) Charge ID:

I’m then using the ‘Stripe Connect - Make a Transfer’ action that comes with the Stripe Connect - Marketplace plugin to make the transfer to the relevant seller:

You’ll see I’m transferring 80% of the total amount. This is because the marketplace is taking 20% as a commission.

Of course, we need to actually trigger this ‘make_transfers’ backend workflow. I suggest triggering it in the workflow that’s being triggered by the Stripe Webhook (so you’re effectively using one API workflow to trigger another API workflow).

We’re going to schedule this API workflow to run on the list of ‘Item Purchases’ associated with the transaction that has triggered the Stripe Webhook:

You can use the Checkout Session ID that is sent via the Stripe Webhook to find the relevant transaction in your database:

6. Link each transfer to a specific transaction
You should now be able to automatically make transfers to each of the sellers when a user pays for their shopping cart items via a Stripe Checkout Session. However, you may sometimes run into an issue where Stripe fails to make the transfer and returns the following error:

This seems strange. After all, your customer has literally just made a payment that should have been more than the total amount you are transferring to all of the sellers. However, Stripe doesn’t necessarily make all of these funds available to be transferred (or paid out) to your sellers. These funds are ‘pending’ rather than ‘available’.

Fortunately, there is a solution to this. As outlined in the Stripe documentation, we can tie a transfer to an existing charge by specifying the charge ID as the source_transaction parameter.

This means the transfer will always go through successfully, even though 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.

We can implement this in the backend workflows of our Bubble app by:

  • Saving down the Charge ID associated with each transaction (I’m using the ‘Get Payment Details’ call that comes with the Stripe Connect - Marketplace plugin in this example)

  • Passing this Charge ID through to our ‘make_transfers’ backend workflow

  • Using this Charge ID to specify the source transaction when making the transfers

Disclaimer
Absolutely none of this should be taken as the absolute source of truth when it comes to implementing a shopping cart-style payment flow for a marketplace with Stripe Connect. There are doubtless a number of ways to building this type of functionality. What I’ve described is simply the best solution I’ve come across after spending quite a bit of time digging into the issue :slight_smile:

5 Likes

Thank you @alexcooney5, your plugin is a huge time-saver. Everything you do to make it as easy as possible to implement shows the integrity of your work and dedication to helping others work out these kinds of needs in the app space. So grateful for your plugins!!!

2 Likes

Thanks @joannsview! A lot of work goes into making the plugin as useful as possible, so I really appreciate the kind words :slight_smile:

We recently released a video tutorial version of this guide - see below:

Any questions just let me know :slight_smile:

1 Like

Amazing stuff, thanks so much Alex!

Quick question re the ‘Separate Charge and Transfers’ - looking at the Stripe docs, does your plugin use the ‘on_behalf_of’ parameter?

For my app, I need to ensure that each individual merchant is the business of record.

Thanks again!

Hi @jonathan16, I’m afraid it’s not possible to use the ‘on_behalf_of’ parameter when taking the ‘Separate Charges & Transfers’ approach.

The point of that approach is that you’re transacting directly with the platform, before transferring the appropriate amount onto the merchant :slight_smile:

Hi @alexcooney5,

Thanks so much for your reply here, and YT!

I do understand that that’s kind of the point of ‘Separate Charges and Transfers’ :slight_smile: , but Stripe have recognised that platforms may want to show the merchant/connected account as the business of record, and the ‘on_behalf_of’ is available, as Stripe Support confirmed below.

You can see in the Stripe docs that ‘on_behalf_of’ is nested within ‘Separate Charges and Transfers’

My use case is to bundle a bunch of payments to various merchants into a single payment from a Contractor, so they do a single large payment and the platform pays each merchant out - so your ‘Shopping Cart’ looks like a perfect way to do it!

  • Currently, with your ‘Shopping Cart’ function, does it show the platform as the payer for each payment to a merchant?
  • Could you please see if ‘on_behalf_of’ can be built into your plugin?
  • Is there any other way to do this? Can I loop a bunch of single ‘Direct Charge’ payments with just a single button click, using backend workflows? Or would the payer have to approve each on the Stripe Checkout page?

And thanks for replying on YouTube as well; don’t want to have to duplicate, but it was very helpful to see other people’s comments there too!

Thanks again!!

1 Like

Hi @jonathan16, thanks for digging into this and following up with your findings.

You were absolutely correct and I was absolutely wrong!

I’ve just released a new version of the plugin. The ‘Create Checkout Session (Multiple Items)’ action now has an additional section called ‘ON BEHALF OF’. You can set the settlement merchant ID using the ‘Settlement Merchant’ field:

You should now be able to bundle all the payments from merchants so it looks like one large payment to a contractor and then transfer the appropriate amounts to merchants after.

Sorry for being such a dummy originally and let me know how you get on :slight_smile:

1 Like

Hi @alexcooney5,

You are most welcome (glad I didn’t send you down a wrong path!) and thank you for such a great plugin, which you’ve just made even better in record time! :exploding_head:

  • Am I to understand that I would enter a list of Settlement Merchants in this new field you created, similar to 13:07 in your video, where you enter a list of Prices, Quantities and Products? So it would be something like ‘Current User’s Shopping Cart: each Item’s Store’s Merchant ID’?
  • Would I need to refer to this new ‘Settlement Merchant’ later in the process at all, even in the ‘Transfers to Merchants’ workflows, or has Stripe effectively recorded who each Merchant is at the time of this payment, and that’s all that’s needed?

Thanks again, so very much!

1 Like

No problem @jonathan16!

No, not quite. You’ll only be able to add a single Settlement Merchant. After all, we’re only processing one payment here so there can only be one entity you’re actually transacting with.

Not sure if this question will still be relevant given my previous answer, but no you will not need to refer to the ‘Settlement Merchant’ later in the process. HOWEVER, you will need to specify an account ID of each of the individual merchants you’re transferring funds to. This is covered in the written guide/video tutorial.

Hope that helps and let me know if you’ve any other questions :slight_smile:

1 Like

Thanks for your reply, @alexcooney5 !

No, not quite. You’ll only be able to add a single Settlement Merchant. After all, we’re only processing one payment here so there can only be one entity you’re actually transacting with.

Hmmm, now I’m a bit confused - apologies! For a shopping cart with multiple sellers and a single buyer, and using the ‘on_behalf_of’ parameter, why and who is the single entity? There’s only a single buyer (the Contractor), but there are multiple sellers/merchants, each of whom is doing business with the Contractor?

Apologies if I’m missing something here!!

The single entity (i.e. the entity the customer is transacting with) is the merchant you specify in the ‘Settlement Merchant’ field. If you leave this field blank, the entity the customer is transacting with is your platform.

Just so I’m clear on your use case, am I right in saying you want the following?

  • Customer (contractor) purchases different goods/services from a number of different sellers in one shopping cart-style transaction
  • You want to take a % of each product/service sold in the shopping cart as a commission for your platform

And then the part I’m not clear on:

  • You also want to set the ‘on_behalf_of’ parameter to be equal to each of the underlying merchants for each of the products the customer buys?

Is this right? If so, I’m afraid you can’t do this as you’re not processing multiple payments. You’re simply processing a single payment (with multiple line items), so you can only specify one merchant for the ‘on_behalf_of’ parameter.

Apologies if I’m missing something and let me know what you think :slight_smile:

1 Like

Hi @alexcooney5,

Thanks for your message! And for your time on this, I really appreciate it and think I’m close to getting this right.

Just so I’m clear on your use case, am I right in saying you want the following?

  • Customer (contractor) purchases different goods/services from a number of different sellers in one shopping cart-style transaction
  • You want to take a % of each product/service sold in the shopping cart as a commission for your platform

And then the part I’m not clear on:

  • You also want to set the ‘on_behalf_of’ parameter to be equal to each of the underlying merchants for each of the products the customer buys?

I guess, yes, ideally I’d like to have all 3 - though I see your point of it only being 1 payment - which is why I wondered how you’d connect the transfer to the individual merchants at a later date to the original bulk payment.

Let’s take it back a bit if we can; what is the best way to achieve what I’m looking for:

  • Contractor can purchase from a number of different sellers in a single transaction (shopping cart/bundle of goods)
  • The platform takes a % of each product/service in the shopping cart
  • The business of record for the transaction is the individual merchants. Merchants’ documentation shows they did business with the Contractor. The Contractor’s documentation shows the full amount paid, ideally broken up by Merchant. The platform’s documentation shows we only received the commission amount

  • Should I be using Separate Charges & Transfers? (I think so, as you can’t ‘loop’ Direct Charges without having the Contractor making individual payments?)
  • What’s the benefit of ‘on_behalf_of’ if you have multiple merchants, but can only have one ‘on_behalf_of’?
  • Should I just forget about ‘on_behalf_of’ and show HMRC how the platform just facilitates the payment as a pass-through to the merchants?

The Stripe docs make it look like you can have the individual Connected Account/Merchant with the ‘on_behalf_of’ parameter, but how would you ‘loop’ that for each item, without the Contractor having to pay more than once? It feels like you should be able to have each line-item in a Shopping cart having its own 'on_behalf_of?

Thank you so much again!

Hi @jonathan16, yes I think we may have overcomplicated things here :sweat_smile:

You can achieve 1 and 2 by using the Separate Charges and Transfer approach outlined in our guide/video tutorial. The customer pays for all goods/services at once and the full amount flows to your platform. You can then make transfers to the merchants so that you’re left with what’s effectively a ‘platform fee’.

HOWEVER, you can not also achieve your third requirement. The business of record will be your platform. There is no way (to my knowledge) of creating a single payment where there are multiple underlying businesses of records.

To answer your other questions:

Yes, agreed.

No real benefit. I misunderstood your original request and thought you wanted one of your underlying vendors to be the business of record, which is why I added that ‘Settlement Merchant’ field to the plugin :slight_smile:

I can’t give any advice on how best report to HMRC, but I don’t think you need to use the ‘on_behalf_of’ parameter.

I’m almost certain you can only set one account to be the settlement merchant with the on_behalf_of parameter. But if you/or Stripe support can tell me otherwise, happy to reassess (after all I have been wrong before :slight_smile: )

Hi @alexcooney5,

Thanks so much for your help on this!

I received the below from Stripe; it looks like what I want to achieve can be done :slight_smile: , but I’m a little confused as to how/where it happens! Do you understand it?

Hi Jonathan,

Yes, each specific Connected Account can use the ‘on_behalf_of’ parameter to show that they were the business of record. The ‘on_behalf_of’ parameter can be set to the ID of the connected account to make that account the settlement merchant for the payment.

When the charge is created, it will show on the invoice the specified connected account’s business information. However, the ‘on_behalf_of’ parameter does not accept a list of Connected Accounts. It can only be set to a single connected account for each charge.

So in the scenario you described, where the Contractor pays once and there are multiple Operatives involved, each Operative would need to have separate charges with the ‘on_behalf_of’ parameter set to their respective connected account. This way, each Operative will receive separate documentation showing their individual business with the Contractor.

Please refer to the following documentation for more information:

My questions:

  • Where is the ‘on_behalf_of’ used?
    ** When the platform charges the Contractor for the bulk payment (we’re using Separate Charges & Transfers)?
    **Or when the platform pays out to the Connected Accounts/Operatives? If this one, why is the ‘on_behalf_of’ set to the Connected Account’s ID, and not the Contractor’s? How are the Contractor and Connected Accounts linked?

Thanks again - feels like we’re close?!

Hey @jonathan16, I’m afraid this part of Stripe’s response confirms my understanding:

You can not create a single charge with multiple ‘on_behalf_of’ destination accounts. You will have to create multiple different charges. This means that if you want to pass through a list of ‘on_behalf_of’ parameters, your end customer can not pay for everything in a single payment.

To answer your question:

The ‘on_behalf_of’ parameter is used when the Checkout Session is being created (at least when using our plugin). See the below section of the Stripe documentation:

https://docs.stripe.com/api/checkout/sessions/create#create_checkout_session-payment_intent_data-on_behalf_of

Hey @alexcooney5,

Thanks so much for your continued help with this!

Hmmm, that does sound like that’s how it is - I wonder why Stripe seems to think I could achieve what I wanted - a single charge to a Contractor, with ‘on_behalf_of’ for each Operative? Just a cross-misunderstanding?

Is there any way you can think of that I can do what I need? Your plugin, and documentation, is so great so I’d like to use it as far as I can. Or is it just keeping track of each Operative’s amounts and showing this to HMRC re a passthrough?

Hey @jonathan16, sorry for the delay in getting back to you - was on holidays for the past while.

I’m afraid you can’t achieve what you’re looking to do with our plugin at the moment. It is not, to my knowledge, possible to create a charge with multiple different ‘on_behalf_of’ accounts set with a Checkout Session (which is really the core part of our plugin).

Sorry about that! If I ever discover a solution I’ll be sure to post here and let you know.