Before you start
- ✓A Stripe platform account with Connect switched on, in test mode
- ✓Your fee model written down: what you charge on each payment channel
- ✓A decision on how payments are structured (who the payment is created on) before any build starts
- ✓A way to receive Stripe's event notifications while testing
Choosing the account type and payment model
On Paypolli we run Stripe's Express accounts with destination charges: Stripe hosts merchant sign-up and the merchant dashboard, your platform creates every payment, and your fee is taken as the money moves. We've also built a product where payments are created on the merchant's own account (direct charges). It works, but every later step must then name the merchant's account, and missing one fails in ways testing rarely catches. Our ticketing marketplace guide covers when that model fits.
Signing merchants up
Each merchant gets a Stripe account able to take card payments and receive transfers, and Stripe's hosted sign-up collects their details. Sign-up links expire, so an expired link should quietly produce a fresh one, not an error.
Deciding when a merchant is ready
Finishing sign-up doesn't mean a merchant can trade. We read their status from Stripe's account notifications, with three states rather than two:
- Complete: payments and payouts on, details submitted, nothing due now or later.
- Needs attention: working, but Stripe wants something. Tell the merchant before it becomes a block.
- Has issues: anything else. Don't take payments for them.
Taking payments and setting fees
Every payment names the merchant as the business being paid and the recipient of the money, and carries your fee. On Paypolli that holds on all four channels: card readers and Tap to Pay, card-not-present, hosted checkout and payment links.
Fees are worked out in whole pence with every part rounded up: your processing cost, your margin, and a surcharge for the channel. Automated tests pin this down at the edges, where a penny either side of a rounding boundary should change the fee exactly as intended.
Refunds
A refund pulls the merchant's share back from them while your fee stays with you. Each refund carries a unique reference so a retry can't refund twice, and a refund that's later cancelled or fails puts the amount back.
Notifications you can trust
- Separate endpoints for merchant, platform and reporting events, in live and test: six on Paypolli.
- Check every notification genuinely came from Stripe, and make sure a Stripe library upgrade can't break how they're read.
- Assume every event arrives twice, and make the second copy harmless.
What usually goes wrong
From our own projects, not the manual.
Payments went out in the wrong currency
The code used the platform's own currency instead of the merchant's. Always charge in the currency of the merchant's Stripe account.
Merchants' net totals came out too low
Card reader charges were subtracted twice when working out what the merchant received. Test the net figure end to end, not just the fee.
Fees stack up on in-person payments
Tap to Pay adds Stripe's own per-transaction cost on top of the card fees, so the Tap to Pay surcharge had to rise to recover it. Work out each channel's real cost before setting its fee.
Failed card checks created phantom transactions
Each failed 3D Secure attempt on the same payment produced its own charge record. We de-duplicate on the latest charge, not the payment.
A double-click took two payments
A card-not-present form submitted twice and created two charges. Give each form a unique reference so a repeat is ignored, and disable the button once it's pressed.
Stripe notifications failed on refunds without a note
The handler expected a refund note that isn't always there, and returned an error. Never assume optional details are present.
Do it yourself, or get help?
If you're building a straightforward marketplace and your developers are comfortable with Stripe's event notifications and safe retries, Stripe's Connect documentation will get you a long way. If money moves between several parties, your fees need to recover real processing costs, or you're taking in-person payments too, get help early: payment-model and fee decisions are expensive to change once merchants are live.
Get a developer on it