Our role
We took Zuporta from a flow that charged optimistically and hoped a coach was free, to an event-driven marketplace where money only moves once both parties are provably present. Three client surfaces, one API, and a payment model that eliminated an entire class of disputes.
The commercial core of Zuporta is a distributed consensus problem wearing a wellness app. Two people in different timezones must both commit to a live session within seconds, and the payment must reflect what actually happened. We modelled the session request as a first-class entity with its own finite state machine: pending, accepted, declined, expired, each transition carrying a hard expiry and a deterministic outcome. Payment authorisation is bound to the acceptance transition, so a charge cannot exist without a corresponding session. Around that sit realtime sockets for in-app presence and push notifications for everything else, so a coach is reachable whether they are on the dashboard, on their phone, or away from both. Two-sided money movement was built in from the start: card capture, a coupon engine applied at authorisation, per-session billing and coach payouts. The same product ships as a responsive web application and a native mobile app against a shared API contract, with an administrative console behind it.
Booking That Respects Both Sides
A Charge Without a Session Is a Refund Waiting to Happen
The original flow dropped members into a paid conversation and hoped a coach was available. Every mismatch became a support ticket and a reversal. We inverted the model so the commercial event is downstream of mutual commitment, not upstream of it.
A Three-Minute Window Demands Sub-Second Delivery
A short acceptance deadline is only fair if both parties learn about it immediately. Requests, acceptances, declines, expiries and messages all had to propagate across web and mobile in seconds, including to a device with the app closed.
One Product, Two Opposing Mental Models
Members optimise for discovery and reassurance; coaches optimise for availability and earnings. Both had to feel purpose-built without forking into two codebases.
How We Built It
A Session Request State Machine
We modelled the request as its own entity with explicit pending, accepted, declined and expired states, each with a hard TTL. Payment authorisation hangs off the acceptance transition, which structurally removed a whole category of refund and dispute work from the support queue.
Dual-Channel Realtime Delivery
Websocket events drive the in-app experience while push notifications cover everything else, so reachability does not depend on the app being open. The two channels converge on the same event payload rather than drifting apart.
Two-Sided Money Movement
Card capture, a coupon engine evaluated at authorisation time, per-session billing and coach payouts were built as first-class platform concerns, because a marketplace has to move money in both directions from day one.
One Contract, Three Surfaces
Responsive web, native mobile and an administrative console consume a single shared API, so a behavioural change ships everywhere at once instead of three times.
What We Delivered
A Complete Product Suite
Responsive web platform, native mobile application and operations console, served by one API.
A Trust-Preserving Booking Model
Timed session requests with automatic expiry, charge-on-acceptance, and post-session reviews closing the feedback loop.
Discovery and Retention
Coach directory and profiles, speciality-based browsing, and a resource library that gives members a reason to return between sessions.
Commercial Operations
Billing, payouts, promotional codes, notification preferences and session history, so growth is a commercial question rather than an engineering one.



