Stripe Connect (Express) is the default for multi-vendor marketplaces
Context
Aspire's marketplace products (Alby Studio, Alby Place, future Aspire Marketplace projects) need to onboard merchants + accept their customers' payments + take a platform fee + payout to merchants. Without a default, each new marketplace re-debates Stripe vs Zinga Pay vs PayPal vs Square vs custom escrow.
Detail
Options considered
| Option | Pros | Cons |
|---|---|---|
| A โ Stripe Connect (Express) | Battle-tested, AU support, Express dashboard handles merchant onboarding KYC, Connect Webhooks for split payments | Per-transaction fee (~2.9% + 30ยข AUD card) + payout fees |
| B โ Custom escrow on Postgres | Full control | Compliance nightmare, AU regulatory risk, no FDIC/AFCA-equivalent protection |
| C โ Zinga Pay (Aspire's own payment rail) | Aspire-controlled, no platform fee leakage | Not yet built; defers shipping marketplaces |
| D โ PayPal Marketplaces | Familiar to consumers | Worse merchant UX than Stripe, AU support patchy |
Decision
We chose: Stripe Connect (Express) โ option A.
Rationale
- Onboarding-as-a-service โ Stripe handles KYC, bank account verification, beneficial-ownership disclosure. Saves Aspire writing all that compliance code.
- Express dashboard โ merchants see their own dashboard at Stripe's domain (no need to build a payouts UI in alby-studio).
- Webhook-driven โ
checkout.session.completedโ fan out to platform DB + send merchant payout record. Idempotent handler protects against duplicate webhooks. - AU-native โ Stripe AU handles GST collection + reporting cleanly; less custom code.
Architecture
Customer โ checkout.stripe.com (Express flow)
โ Stripe Connect splits payment:
- Vendor receives (price - platform_fee_pct)
- Platform (Aspire) receives platform_fee_pct
โ Stripe Webhook โ alby-studio /api/webhooks/stripe
โ Update Order.status = paid
โ Send merchant notification (Telegram per [[shared/decisions/telegram-bot-pattern]])
โ Send customer receipt (SendGrid)
Constraints we accepted
- Stripe takes ~2.9% + 30ยข AUD per card transaction (cost passed to vendor or platform takes thinner margin)
- Vendor must complete Stripe KYC to receive payouts โ onboarding friction
- Webhook reliability is Stripe's problem; idempotent handler is Aspire's
Per-marketplace customization
Each marketplace has its own Stripe platform account (e.g., alby-studio platform = acct_alby_studio_prod). Cross-marketplace vendor accounts are NOT shared โ a vendor selling on Alby Studio AND a future Aspire Marketplace would have 2 separate Connect accounts.
Revisit trigger
- Stripe AU pricing changes >25%
- Zinga Pay ships AND has comparable Express-equivalent UX
- A marketplace has >$5M ARR โ at scale, in-house escrow becomes cheaper than Stripe's percentage
Actions
- [x] alby-studio: Stripe Connect Express wired end-to-end (live 2026-05-04, see graphify-audit-2026-05-21)
- [ ] alby-studio: switch from Sandbox to live keys (per
_STATUS.mdNEXT items โ Kom action) - [ ] Future Aspire marketplaces inherit this pattern
Related
- aspire-llm-gateway-only-egress โ companion pattern: one egress for AI, one rail for payments
- aspire-hub โ merchant identity NOT linked to Hub (Hub = staff, Stripe Connect = vendors)
๐ Relationships
graph LR
stripe_connect_marketplace_default["stripe-connect-marketplace-default"]:::self
stripe_connect_marketplace_default --> telegram_bot_pattern["telegram-bot-pattern"]
stripe_connect_marketplace_default --> graphify_audit_2026_05_21["graphify-audit-2026-05-21"]
stripe_connect_marketplace_default --> aspire_llm_gateway_only_egress["aspire-llm-gateway-only-egress"]
stripe_connect_marketplace_default --> aspire_hub["aspire-hub"]
classDef self fill:#715EE3,color:#fff,stroke:#291F50;