Stripe Billing Ops
Source: docs/runbooks/stripe-billing-ops.md
---
title: Stripe Billing Operations Runbook
description: Stripe billing operations, webhook validation, autopay behavior, dunning recovery, and rollback procedures.
owner: ops
last_reviewed: 2026-03-03
audience: internal
status: active
---
# Stripe Billing Operations Runbook
Purpose: operate Stripe execution safely while keeping RGL8R as billable-system source of truth.
## Billing model
- RGL8R determines billable eligibility and invoice data.
- Stripe executes payment collection and payment-method storage.
- Stripe state is synchronized back to local billing records.
## Required env vars
- `STRIPE_ENABLED`
- `STRIPE_SECRET_KEY`
- `STRIPE_WEBHOOK_SECRET`
- `STRIPE_AUTOPAY_ENABLED`
- `STRIPE_WEBHOOK_TOLERANCE_SECONDS`
## Webhook contract
Endpoint: `POST /api/billing/stripe/webhook`
Implementation requirements:
1. Route uses `express.raw({ type: 'application/json' })` before JSON middleware.
2. Signature verified against raw body using `stripe-signature` header.
3. Duplicate `event_id` values for already-processed or ignored events are idempotent no-ops. Failed or in-flight events are retried on the next webhook delivery.
4. Event processing result persisted in `app.stripe_webhook_events`.
## Event handling
- `invoice.paid`
- mark local invoice `paid`
- set `paidAt`
- `invoice.payment_failed`
- annotate local invoice metadata with failure context
- keep invoice in recoverable state for dunning/retry path
## Incident response
1. If webhook signature failures spike:
- verify webhook secret rotation state,
- verify raw-body middleware order,
- verify proxy does not mutate payload.
2. If payment status drift appears:
- compare Stripe event timeline with `stripe_webhook_events`,
- replay missing events if needed,
- reconcile local invoice statuses.
3. If duplicate events flood:
- confirm idempotency table uniqueness is intact,
- verify processed/ignored duplicates are skipped and failed events are retried.
## Manual recovery
1. Identify invoice IDs in failed/ignored event rows.
2. Re-fetch Stripe invoice status via dashboard/API.
3. Apply controlled local correction with audit note.
4. Re-run post-recovery contract checks.