3 Stripe Connect bugs that silently hold or duplicate seller payouts
3 Stripe Connect bugs that silently hold or duplicate seller payouts If you run a marketplace on Stripe Connect, payouts to your sellers are the part that actually has to be boringly correct. Here are three bugs that s
3 Stripe Connect bugs that silently hold or duplicate seller payouts
If you run a marketplace on Stripe Connect, payouts to your sellers are the part that actually has to be boringly correct. Here are three bugs that show up again and again in real integrations β none of them throw an exception, which is exactly why they survive in production for months.
1. Instant payout race with unsettled balance
You trigger an instant payout right after a charge succeeds. The charge shows as succeeded, but the matching balance_transaction hasn't settled yet (Stripe settles asynchronously, usually seconds later but sometimes longer under load). The payout request either fails with insufficient_funds or β worse β your retry logic fires a second payout once the balance does settle, and now you've queued two payouts for one sale.
Fix: gate instant payouts on the balance_transaction.available_on timestamp or on a webhook (balance.available), not on the charge event alone. Never blind-retry a payout call without checking payouts.list first for one already in flight.
2. Multi-currency balances netting the wrong way
A Connect account that accepts more than one settlement currency has a separate balance per currency. Your internal ledger, if it assumes one balance number, will net a negative balance in currency A against a positive one in currency B and conclude the seller is owed money when Stripe's payout schedule has actually put that specific currency balance on hold. The payout API will just silently skip the held currency β no error, no webhook, it just doesn't happen.
Fix: reconcile per-currency, not per-account. Pull balance.retrieve and compare available and pending array entries by currency code before assuming a payout will go out.
3. Non-idempotent handling of payout.paid / payout.failed
Stripe retries webhooks that don't return 2xx fast enough, and under load your handler can legitimately take too long. If payout.paid isn't deduplicated by event.id or payout.id before you mark it reconciled in your ledger, a retried webhook double-reconciles the same payout β sellers' dashboards show the payout twice, support tickets follow.
Fix: store processed event IDs (or payout IDs + status) and check before writing, not just before responding 200.
All three are easy to miss because Stripe's test mode doesn't reproduce the timing and currency conditions that trigger them β you only see them once real money and real settlement delays are involved.
If you want a second pair of eyes on your Connect payout logic specifically (not a generic checklist, an actual read of your repo against these and 4 other failure modes), I run a fixed-price audit: $39, 48h turnaround, full refund if your repo isn't reviewable. https://buy.stripe.com/6oU4gy6gZ6hYfGH7tu7IY0i
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.