Nothing pays out until the seller’s account is
ACTIVE. Every stage of the pipeline checks the payout account status. A seller who skips onboarding can sell, but their orders sit uncaptured until the authorization window forces the issue — which is exactly why surfacing onboarding status in the vendor portal matters.What you’ll build
A working payout loop: a seller with an active Stripe Connect account, one fulfilled order, a captured payment, and a payout record that settles via webhook.Prerequisites
Stripe Connect must be configured first — provider registration, API keys, and both webhooks (payment and payout). Follow the Stripe Connect integration guide up to and including “Set up webhooks”, then come back here. For local development, keepstripe listen forwarding running.
Run the pipeline
Onboard the seller
In the Vendor Portal, the seller opens Settings → Payouts and starts onboarding. Under the hood this creates a The seller completes Stripe’s hosted flow (identity, bank account) — in test mode, Stripe’s test data completes it in a minute. When Stripe activates the account, the payout webhook delivers an
PayoutAccount (status PENDING) and an Onboarding record holding the Stripe onboarding link:account.activated event and Mercur flips the account to ACTIVE. No polling — the webhook is the source of truth.Place and fulfill an order
Place an order for one of the seller’s listings, then in the Vendor Portal fulfill it. Fulfillment matters: by default, capture requires the order to reach
fulfilled status (configurable via the payout module’s requiredFulfillmentStatus option).Watch the capture
A scheduled job runs every 15 minutes looking for orders that are ready: payment
authorized, seller ACTIVE, fulfillment status met, no payout yet. When the capture deadline approaches it emits order.capture_requested, and a subscriber captures the payment.To move faster while testing, wait for the next 15-minute tick after fulfillment.The payout lands
Once per day (1 AM UTC) a job scans captured orders without payouts and emits
payout.requested per order. The createPayoutWorkflow then:- Loads the order with its commission lines.
- Calculates
payout_amount = order.total − total_commission. - Calls Stripe to create the transfer and records a
Payout(statusPENDING).
PROCESSING → PAID (or FAILED).Verify
- Account:
GET /vendor/payout-accounts/<id>returnsstatus: "ACTIVE"after onboarding. - Capture: after fulfillment plus one job tick, the order’s payment shows as captured.
- Payout:
GET /admin/payoutslists a payout for the order, withamountequal to the order total minus the commission lines from your commission configuration. - Vendor view: the seller sees the payout and its status in the Vendor Portal’s payout history.
- Stripe: the transfer appears on the connected account in the Stripe test dashboard.
FAQ
What if the seller never completes onboarding?
What if the seller never completes onboarding?
Their orders stay uncaptured. The capture job skips orders whose seller isn’t
ACTIVE, and once the authorization window lapses the payment expires (an order.authorization_expired event fires). Surface the onboarding status prominently and chase incomplete sellers early.Why hasn't a payout appeared even though the order is captured?
Why hasn't a payout appeared even though the order is captured?
The payout job runs once per day at 1 AM UTC — a captured order waits for the next daily tick. Also check that no payout already exists for the order and that the seller’s account is still
ACTIVE (a RESTRICTED account pauses payouts until the provider clears it).What do the payout statuses mean?
What do the payout statuses mean?
PENDING — transfer initiated; PROCESSING — the provider is moving funds; PAID — settled; FAILED / CANCELED — the transfer didn’t complete. All transitions after PENDING come from provider webhook events, so a stuck status usually means the payout webhook isn’t reaching your API.Next steps
Payout
The full pipeline reference — statuses, jobs, webhook events, module options.
Stripe Connect
Provider configuration, transfers vs payouts, refunds, and EU considerations.