Gift Card Platform
Issuance and redemption for commerce clients — where a double-spent card is real money lost.
TL;DR
- Role
- Senior Software Engineer — backend lead
- Where
- Pine Labs
- Stack
- Node.jsExpressMongoDBREST APIs
- Outcomes
- 10K+ txns/dayidempotent redemptionin production
The problem
Commerce clients needed a reliable way to issue and redeem gift cards at scale. Unlike most features, every bug here has a direct monetary cost: a redemption processed twice is money created out of thin air, and a lost card is a customer support fire.
Constraints
- Payment integrity — every card operation must be exactly-once from the client's perspective
- Idempotent redemption under retries and flaky partner networks
- Reconciliation — the ledger must always be provably consistent
- Partner-facing APIs that external teams integrate against
Architecture
Requests enter through a gateway that authenticates partners and rate-limits per client. Redemption and issuance are separate services — they change for different reasons and fail differently. Every money movement lands in a ledger, and ledger events feed a queue that a reconciliation worker consumes, continuously proving the books balance. Watch the diagram: the second redemption attempt with the same idempotency key never reaches the ledger — it gets the cached response.
- redemption — reaches the ledger once
- same key retried — stopped, cached response✕
- ledger event — reconciled asynchronously
Hover or tap a component to see its responsibility.
Decisions & trade-offs
Idempotency keys with cached responses on redemption — over best-effort deduplication
Partner networks retry on timeouts. For money operations, a retry must be indistinguishable from a single call — the key makes the retry safe and the cached response makes it fast.
Append-style ledger writes — over mutating balances in place
Reconciliation and audits need history, not just current state. You can rebuild a balance from a ledger; you cannot rebuild a ledger from a balance.
Asynchronous reconciliation via a queue — over synchronous cross-checks on every transaction
Keeps the redemption hot path fast while consistency is verified continuously out of band — mismatches surface in minutes, not at month-end.
Results
- 10K+ transactions processed daily in production
- Serving commerce clients across multiple business domains
What I'd do differently
I'd build the reconciliation worker on day one instead of after the first mismatch investigation — the confidence it buys pays for itself within weeks.
Shared at pattern level — production metrics are real, implementation details are illustrative.