Joey Hershkop

← Back to all projects

Building End-to-End Stripe Billing for a B2B SaaS Platform

Production Engineering • PHP, PostgreSQL, Stripe API, HMAC Webhook Security, React, Playwright

100%
HMAC Verified Events
0
Duplicate Event Drift
Full-Stack
API, Schema & UI Ownership
Live
In Production with Real Clients

The Problem

A growing B2B SaaS platform needed a robust, fully automated billing system: self-serve customer checkout, tiered subscription plans, upgrades, downgrades, and billing portal access.

Handling financial transactions is uniquely unforgiving. Network timeouts, out-of-order webhook delivery, or duplicate retry requests can easily corrupt customer subscription states, double-charge accounts, or grant unauthorized platform access. The system required absolute integrity across every layer of the billing lifecycle.

What I Built

I took primary ownership of the billing architecture from database schema migrations to frontend client interfaces:

  • Hardened Ingestion Middleware: Engineered custom PSR-7 middleware that intercepts the raw, unparsed HTTP request body prior to body parsing, enabling strict HMAC-SHA256 signature verification against Stripe's signing secrets.
  • Idempotent Event Ingestion: Built a deduplication layer keyed on Stripe Event IDs to ensure that network retries and duplicate webhooks execute as safe no-ops without double-applying mutations.
  • PostgreSQL State Mirroring: Designed a normalized database schema (subscriptions, billing periods, customer mappings) that serves as a fast, local source of truth for permission gating without incurring blocking third-party API calls on critical user read paths.
  • Transactional Admin Console: Created internal tooling for operations teams to safely view audit trails, manage comp accounts, and resolve billing edge cases.
  • React Subscription UI: Built a responsive plan comparison interface with billing cycle toggles, Stripe Checkout flows, and Customer Portal integration.

The Interesting Engineering

1. Cryptographic Webhook Ingestion

Webhooks arrive over public HTTP endpoints. To defend against spoofing and replay attacks, Stripe signs payloads using HMAC-SHA256. However, standard PHP and framework body parsers mutate or normalize whitespace and string encoding, invalidating the hash calculation.

I implemented StripeWebhookRawBodyMiddleware to capture byte-exact payloads before framework parsing, paired with a comprehensive PHPUnit test suite validating both valid signatures and rejected tampering attempts.

2. Idempotency & State Machine Integrity

Stripe guarantees at-least-once delivery, meaning webhooks can arrive multiple times or out of order (e.g., an invoice.payment_succeeded arriving before a customer.subscription.created finishes committing).

I implemented atomic upsert operations, database transaction boundaries, and state deduplication guards. If an event has already been recorded in the event ledger, subsequent arrivals are immediately acknowledged with a 200 OK without re-executing business logic.

3. Decoupling User Reads from External APIs

Querying the Stripe API synchronously on every user page load or permission check introduces unacceptable latency and external point-of-failure risks. By modeling subscription state directly in PostgreSQL and maintaining high-fidelity event synchronization via webhooks, user queries execute against local relational indexes in sub-milliseconds.

What Was Hard & Lessons Learned

The biggest takeaway was that payment engineering is 10% happy-path checkout logic and 90% failure mode management: network dropouts, webhook replays, invoice failure cascades, and raw payload serialization quirks. Writing deterministic unit and integration tests around adversarial inputs proved essential to maintaining long-term stability.

Outcome: The billing infrastructure was shipped and is operating reliably in production with real clients, enabling self-serve subscription monetization and automated lifecycle management.