Home / Projects / Billing API

Billing API

A single billing service backing the whole portfolio. Stripe, subscriptions, metering, refunds, dunning, lifecycle email through Brevo — every new product gets payments wired in on the first day, not the third sprint.

Category  Infrastructure · SaaS Stack  Node · Fastify · Postgres Integrations  Stripe · Brevo Status  In development

The problem

Every new product needed billing, and every new product was implementing billing from scratch. Webhook handling, trial logic, plan upgrades, proration, dunning emails — the same code, slightly different bugs, in twenty places. The cost wasn’t the first build; it was the maintenance tax across the portfolio.

What we built

Billing API is a Fastify service backed by Postgres that owns customers, plans, subscriptions, invoices, and webhook reconciliation. Every product calls a small set of endpoints — create checkout, get entitlements, cancel subscription — and never touches Stripe directly. The service handles retries, idempotency, plan changes, and downstream lifecycle email through Brevo. Jest tests cover the state machine.

The automation angle

The flagship automation is the dunning flow: failed payment triggers a sequence of escalating reminders with grace periods, and reaches a hard cancel only after the configured policy is exhausted. Win-back happens automatically when a cancelled customer renews. The sequence is product-specific without each product having to understand it — the policy lives once, in the API.

How it’s used

  • Every paid product in the Dainty Trading portfolio.
  • Internal admin tools for support, refunds, and entitlement overrides.
  • Reporting rolling up MRR, churn, LTV across the whole portfolio in one place.

What it taught us

That billing is a state machine, and pretending otherwise costs you sleep. Modeling the lifecycle explicitly — with named states, named transitions, and a strict rule that webhook events can only mutate state through known transitions — turned a class of intermittent bugs into impossibilities. We carry that pattern into every client engagement that touches money.