GlobalKeyMarket
A multi-vendor SaaS marketplace for digital assets. Order, payment, reconciliation and automatic post-payment delivery in a single flow, with a unified operations panel for support and vendors.
Before / After
What changed in real operations once the system went into production.
Before
- Orders confirmed manually after reviewing payments in the Stripe dashboard.
- Credentials delivered by manual email, with a risk of human error.
- Per-vendor stock in uncoordinated spreadsheets.
- No real audit trail: if a customer complained, you had to hunt for evidence across emails.
- Support overwhelmed at peak moments (launches, promotions).
After
- Delivery after payment in under 30 seconds, without touching the dashboard.
- Per-vendor stock in the database, with optimistic locking on assignment.
- Every critical operation generates a persisted, auditable event (not just a log).
- Refunds and disputes with full traceability back to the original event.
- Support centralised in one console: order, payments, delivery, vendor.
Architecture
A logical view of the system. Three clear layers: frontend, domain and data. Stripe is the source of truth for payment status; the workers absorb the side effects.
Solid line: synchronous call. Dashed line: asynchronous effect or client redirect.
Technical decisions (and why)
The details that separate a quick MVP from a system that holds up in production.
Stripe is the source of truth; our endpoint is idempotent
Stripe retries webhooks on failure. If you don't handle that, it means duplicate orders, double deliveries and overwhelmed support. Each event comes in with its event-id, stored in Redis with a sensible TTL; if it has already been processed, we return 200 OK without re-running it. The result: zero duplicates even with momentary receiver outages.
Optimistic locking when assigning stock
In launches with limited stock, several customers compete for the same slot. We use optimistic locking in the transaction: if the counter changed since the read, the transaction rolls back and the customer gets a clear message at checkout. Fairer than locking the whole table and faster than serialising.
Auditable events, not just logs
Every critical operation (order, payment attempt, delivery, refund) generates a persisted event with its signed payload. Logs are for debugging; events are for answering a customer or a vendor with evidence three months later. That difference is what stops support from being reactive.
Workers separated from the webhook receiver
The receiver only validates, persists and responds fast to Stripe (under the timeout). The long side effects —delivering the product, sending email, notifying the vendor— live in async workers with retries. If a notification fails, the order stays delivered: third-party availability isn't coupled to checkout.
Role-based permissions (customer, vendor, ops, admin)
RBAC with declarative policies at the API level: each endpoint declares which role can consume it and over which resources. A vendor only sees their catalogue and orders; ops sees everything but can't touch financial configuration; admin touches it but leaves an auditable trail. Without this, multi-vendor is a bomb.
Full stack
The real detail, not "JavaScript and databases".
Frontend
- Next.js (SSR + ISR for the catalogue)
- React 18 · TypeScript
- Tailwind for design tokens
- Accessible components (basic a11y)
Backend
- Node.js API (TypeScript)
- Input validation with schemas
- Declarative RBAC per endpoint
- Idempotent endpoints for webhooks
Data
- PostgreSQL with versioned migrations
- Redis: dedupe, queues and short-lived cache
- Automatic daily backups
- Tested restores (not just backups)
Payments
- Stripe Checkout + Customer Portal
- Webhooks with verified signature
- Reconciliation by
event-id - Auditable refunds
Operations
- Nginx reverse proxy + TLS + CSP
- Reproducible deployment per environment
- Centralised structured logs
- Alerts on the team channel
Notifications
- Transactional email (verification, delivery)
- Vendor notification (new order)
- Optional Telegram/Discord for ops
- Auditable, versioned templates
Business outcome
For operations
- Support centralised in a single console.
- Traceability of every order in seconds, not hours.
- Traffic peaks absorbed without a rewrite.
- Onboarding a new vendor in hours, not days.
For the business
- Automated post-payment delivery as a real competitive advantage.
- Refunds and disputes resolved with evidence, not intuition.
- A base ready to add new vendors, categories or payment methods.
- Low operating cost relative to the volume processed.
Need something like this?
If your operations lose time on manual steps that a well-built system could absorb —post-payment delivery, reconciliation, multi-vendor reporting, internal panels— tell us the context by email. We usually reply in under 30 minutes with feasibility and the next step.
Other related services
Web development with React and Next.js · Node.js backend & APIs · Dashboards & internal panels · Payment integration (Stripe, Redsys, Bizum)