How to add credit-based costing and Stripe payments to a Node.js microservices backend (Express + PostgreSQL/Sequelize) that meters LLM token usage per chat message and needs real-time balance enforcement

stripe-node · verified Jul 19, 2026

Fix: Keep the credit ledger internal and use Stripe only as the payment rail. Stripe's native billing credits burn down at invoice finalization and require metered subscription prices, so they don't fit per-message pre-flight balance checks. Instead: (1) an append-only credit_transactions ledger with a unique (type, reference) constraint keyed on Stripe payment_intent/charge ids makes at-least-once webhook delivery and client retries idempotent; (2) a cached balance column updated atomically in the same DB transaction as the ledger insert serves low-latency pre-flight checks; (3) usage debits allow the balance to dip below zero (work already happened), while pre-flight checks gate new work; (4) Checkout Sessions in mode:payment with setup_future_usage:off_session save the card, enabling threshold-based auto top-up via off-session PaymentIntents, with the trigger claimed atomically (single UPDATE with cooldown window) to avoid duplicate charges; (5) verify webhook signatures against the raw body (mount express.raw before express.json for the webhook path only — body-parser skips already-parsed bodies).

stripebillingcreditswebhooksidempotencymicroservices

References