How it fits together
The sale is yours, so the money lands in your balance first. Bachs moves the seller’s share to the seller’s balance when the charge settles, and the seller withdraws from there.What you’ll use
Before you start
- A sandbox API key (
sk_sandbox_...). See Authentication. - The
connectcapabilityactiveon your account. See Become a platform.
https://sandbox-api.bachs.io. Going live is the same calls against https://api.bachs.io with an sk_live_ key. See Take Connect live.
Steps
1
Create the seller
A marketplace seller receives money; it never takes payments of its own. So it only needs the Copy the
recipient configuration, and its onboarding stays short. Naming no payment-accepting capability is what keeps it that way.id. Every step below uses it as the seller’s account id.transfers is what lets the seller receive its share, and payouts is what lets it withdraw. In sandbox both are active immediately; in live they start pending_review until a reviewer enables them. See Capabilities and Testing Connect.2
Create something to sell
The product is yours, not the seller’s: you are the merchant of record. Price it in NGN, which settles the same day.Copy the product
id for the next step.3
Create the checkout, naming the seller
transfer_data.destination is what makes this a destination charge: the sale is yours, and the account you name is paid out of it. platform_fee is the part you keep; naming transfer_data.amount instead fixes what the seller receives, with your platform keeping the rest. See Destination charges for both.checkout_id and checkout_url.Out of the 100000.00 the customer pays, 20000.00 is yours and the rest is the seller’s.4
Send the customer to pay
In your integration you redirect the customer to
checkout_url and they pay on the page we host. To finish this guide, open the link and complete the payment there.This account is in sandbox, so the payment is simulated, no funds move. See Test payment outcomes.5
Confirm the payment landed
The simulated outcome finalizes a second or two later. Read the checkout back until In your integration you would not poll for this. Subscribe to checkout.completed instead and react when it arrives.
status is completed:6
Read the split
The seller’s share moves as a transfer when the charge settles, never sooner. Filter by the seller’s account id:
status is paid once settlement has posted the movement. source_charge_id ties the share back to the sale that produced it, which is what you show a seller asking where an amount came from.The transfer carries the full 100000.00 the customer paid, not the 80000.00 the seller ends up with: because you named your own cut with platform_fee, that cut settles separately, readable at Platform fees. Naming transfer_data.amount instead would fix the seller’s share directly, and the transfer would carry only that. See Destination charges for both forms.7
Read the seller's balance
The share is the seller’s own money now, in its own balance. Send Drop the header to read your own, which went up by
X-Account-Id to read an account’s balance instead of yours:19850.00. That is the whole sale accounted for:Your
20000.00 fee is what you keep, and our fee comes out of it because the sale is yours. See Processing fees.The seller held no NGN until this sale. An account holds a currency once money arrives in it.
What you built
A sale that belongs to your marketplace, split with the seller who fulfilled it, and a transfer you can point at to explain where the money went. The seller can withdraw its balance once it has given you a payout destination, which is one of the requirements it still owes. Read what is outstanding fromrequirements.currently_due on the account, and see Onboard through the API for collecting it, or Onboarding to hand the whole flow to us.
Because the sale is yours, a refund or a lost dispute debits you, not the seller. See Refunds and disputes before you go live.
Webhooks to handle
Create your endpoint withevent_source set to connect or all, or it receives nothing about your sellers’ accounts. On an event from a seller’s account, the top-level account field names the seller.
See Monitor onboarding for reacting to onboarding without polling.
Edge cases
The seller has not finished onboarding
The seller has not finished onboarding
A seller can withdraw only once it has given you a payout destination and its
payouts capability is active. In production, capabilities start restricted until a reviewer enables them, so wait for capability.updated rather than assuming. See Requirements.The customer asks for a refund
The customer asks for a refund
The sale is yours, so a refund debits your balance, not the seller’s. Decide how you recover the seller’s share before you go live. See Refunds and disputes.
The customer disputes the payment
The customer disputes the payment
You are liable, as the owner of the charge. The disputed amount is set aside from your available balance while the dispute is open, and the dispute fee is charged when it opens. See Disputes on Connect.
The seller asks for its money before settlement
The seller asks for its money before settlement
The seller’s share moves when the charge settles, not when the customer pays. Show the seller its earnings from
transfer.created, and don’t send a second, manual transfer for the same sale.A seller's withdrawal fails
A seller's withdrawal fails
You receive
payout.failed, and the amount returns to the seller’s balance. Ask the seller to check its destination. A destination is used only once it is usable. See Payouts on Connect.Go-live checklist
- Your platform has completed registered-business compliance and
connectisactivein production. See Take Connect live. - Your production keys have only the scopes you use, such as
connected_accounts:writeandpayouts:write. - Your production webhook endpoint has
event_sourceset toconnectorall, and its signing secret is checked against a live delivery. - Your integration waits for capabilities to become
activein production instead of assuming them. - Every transfer and withdrawal sends an
Idempotency-Key, and a5xxis checked before it is retried. - Your team knows that refunds and lost disputes debit your balance.
Build it with an AI assistant
Give this prompt to a coding assistant that can work with your app’s code. It builds the flow on this page into your own app. For prompts that need nothing from Connect, and the rules to give your assistant, see Build with AI. What you’ll build: your platform collects a payment, keeps its fee, and the seller’s share reaches the seller’s Bachs balance at settlement. The seller can then pay out to its own approved destination. Have ready: the Connect capability, seller records, your fee, and the collection currency. Start with one seller per order. If each business should own its sale, use Platform for businesses.Prompt
Check the result
- The correct seller account ID is saved against each seller.
- The payment is accounted for across the seller’s share, platform fee, and processing fee.
- Settlement creates one seller transfer; the app does not send another manually.
- Blocked capabilities or an unusable destination prevent a payout.
- The app tracks payout status through delivery or failure.
- Your team understands the platform’s responsibility for refunds and disputes.
Next steps
- Build a SaaS platform, where the account sells instead of you
- Payouts
- Destination charges
- Platform fees
- Take Connect live

