Overview
The platform originally processed reservations and event payments by creating a Stripe PaymentIntent for every transaction.
That approach satisfied the initial business requirements, but as the platform evolved, new financial workflows began to emerge.
Users needed wallet top-ups.
Reservations required delayed settlement.
Managers needed withdrawals.
Payments could enter disputes before funds were released.
Campaigns introduced additional financial workflows.
Manager earnings required delayed settlement before becoming available for withdrawal.
Disputes introduced new transaction lifecycles that extended beyond a simple payment.
Each new requirement increased the amount of business logic coupled directly to Stripe.
Rather than continuing to expand the payment flow, the platform introduced an internal financial layer responsible for modeling balances, settlements, and transaction history, while Stripe became responsible only for moving money into and out of the platform.
The Problem
Direct payment processing works well when every payment immediately reaches its final destination.
Marketplace platforms rarely behave that way.
Funds may need to be:
- held before settlement
- released after a dispute window
- refunded
- forfeited
- transferred to connected accounts
- withdrawn to external bank accounts
Attempting to model those workflows directly around PaymentIntents quickly scattered financial logic throughout the application.
The system needed a single source of truth for every monetary event.
Architecture
Every marketplace financial operation now passes through the same internal platform regardless of its origin.
Bookings, events, campaigns, subscriptions, refunds, and withdrawals all share the same financial primitives.
Engineering Decisions
Stripe became responsible for moving money, while the platform became responsible for modeling ownership, balances, settlements, and financial history.
This reduced coupling between business logic and the payment provider while creating a consistent financial model across every feature.
Wallets, escrow, withdrawals, disputes, and settlements were modeled as first-class domain concepts rather than side effects of payment processing.
This allowed complex financial workflows to evolve independently from Stripe's APIs.
Challenges
Designing an internal financial platform introduced several engineering challenges.
Balance mutations had to remain atomic under concurrent requests.
Every monetary event needed to be fully auditable.
Escrow required delayed settlement without blocking API requests.
Withdrawals needed approval workflows, Stripe Connect integration, and protection against duplicate payouts.
Each of these concerns was solved independently while sharing the same underlying financial primitives.
Outcome
The resulting architecture provides a single financial platform used across the entire application.
Wallets act as the source of truth for balances.
Escrow manages delayed settlement.
Stripe Connect handles external payouts.
Background workers process long-running financial operations.
Rather than extending direct payment flows whenever a new marketplace requirement appeared, the platform now evolves by composing well-defined financial building blocks that remain reusable across reservations, events, campaigns, disputes, and withdrawals.
Related Engineering Notes
Building Reliable Withdrawals with Stripe Connect
Withdrawing money is significantly more complex than receiving it. This article explores how the platform designed a reliable withdrawal pipeline using Stripe Connect while preventing duplicate payouts, race conditions, and inconsistent balances.
Designing Escrow and Delayed Settlement
Capturing a payment does not always mean it should be immediately settled. This article explores how escrow became the foundation for handling reservations, disputes, delayed settlement, and manager payouts.
From Direct Stripe Payments to Internal Wallets
Direct payment processing worked well for the platform's initial requirements, but growing financial workflows eventually required a dedicated financial layer. This article explores why an internal wallet became the foundation for every monetary operation.