Skip to content

05 — Appendix

References

Stripe documentation

Resource URL Relevance
Stripe Billing overview https://stripe.com/docs/billing Primary reference for subscriptions, prices, invoices
Stripe Invoicing API https://stripe.com/docs/api/invoices Invoice object, line items, finalization, status
Stripe Subscriptions API https://stripe.com/docs/api/subscriptions Subscription creation, metered billing, billing cycle
Stripe Prices API https://stripe.com/docs/api/prices Price types: licensed, metered, tiered, graduated
Stripe Meters API https://stripe.com/docs/billing/subscriptions/usage-based Usage-based billing via Meters (new) vs. legacy usage records
Stripe Usage Records API https://stripe.com/docs/api/usage_records Legacy metered billing path (deprecated but functional)
Stripe InvoiceItem API https://stripe.com/docs/api/invoiceitems Adding line items to upcoming invoices
Stripe Smart Retries https://stripe.com/docs/billing/revenue-recovery/smart-retries Automated failed payment retry
Stripe Dunning configuration https://stripe.com/docs/billing/revenue-recovery/dunning Dunning email schedules, Stripe-managed comms
Stripe Customer Portal https://stripe.com/docs/billing/subscriptions/customer-portal Self-service card update, invoice history
Stripe Webhooks https://stripe.com/docs/webhooks Event delivery, signature verification, retries
Stripe Webhook best practices https://stripe.com/docs/webhooks/best-practices Idempotency, ordering, failure handling
Stripe Credit Notes https://stripe.com/docs/billing/invoices/credit-notes Issuing refunds/adjustments on finalized invoices
Stripe Tax https://stripe.com/docs/tax Future enablement path (not in scope at cutover)
Stripe event types https://stripe.com/docs/api/events/types Full list of webhook event types

Cloudflare documentation

Resource URL Relevance
Cloudflare Workers https://developers.cloudflare.com/workers/ Runtime for billing Worker
Cloudflare Browser Rendering https://developers.cloudflare.com/browser-rendering/ PDF rendering from HTML (leading candidate)
Cloudflare R2 https://developers.cloudflare.com/r2/ Invoice PDF storage (replaces S3 CDN)
Workers Cron Triggers https://developers.cloudflare.com/workers/configuration/cron-triggers/ Daily reconciliation job
Workers Analytics Engine https://developers.cloudflare.com/analytics/analytics-engine/ Structured observability from billing Worker
Wrangler CLI https://developers.cloudflare.com/workers/wrangler/ Deploy, dev, secret management

Framework and library documentation

Package URL Purpose
Hono https://hono.dev TypeScript HTTP framework for billing Worker
Stripe Node SDK https://github.com/stripe/stripe-node Stripe API client (Workers-compatible)
Handlebars https://handlebarsjs.com Invoice PDF template engine
Mailgun.js https://github.com/mailgun/mailgun.js Mailgun API client (Workers-compatible)
Vitest https://vitest.dev Unit + integration testing
Project Path Relationship
Admin Dashboard Cloudflare Migration ../Admin Dashboard Cloudflare Migration/ Sibling — billing ops surface in new admin-api; this project defines what billing endpoints admin-api needs
Public API Cloudflare Migration ../Public API Cloudflare Migration/ Predecessor — auth model, deployment pipeline, observability approach to mirror
Adventive Brand Guide https://brandguide.adventive.com/dashboard Invoice PDF design reference

External services

Service Reference Purpose
Mailgun https://app.mailgun.com Invoice email delivery (stays)
Acodei https://acodei.com QuickBooks sync from Stripe events (unchanged)

Inputs

Files analyzed during this planning engagement:

File Description Source Date
application/controllers/Billing.php Invoice trigger, payment trigger, 6-step dunning, Mailgun send, month-end Excel export (960 lines) adventive-admin repo 2026-04-23
application/models/Billing_model.php All billing proxy methods, pricing tier queries, billing history (933 lines) adventive-admin repo 2026-04-23
application/libraries/Mailgun.php Custom curl-based Mailgun client, sendTemplatedEmail, invoice send paths adventive-admin repo 2026-04-23
application/config/adventive.php billing_service URL, billing email sender, HubSpot BCC, invoice CDN URL adventive-admin repo 2026-04-23
application/controllers/ManagedServiceJob.php Managed service job CRUD adventive-admin repo 2026-04-23
application/models/ManagedService_model.php Managed service job queries (505 lines) adventive-admin repo 2026-04-23
Stripe account state Products (5), Prices (5), Subscriptions (0), Invoices (10 sampled) Stripe MCP connector 2026-04-23

Open questions

The following items require a human decision before or during implementation. Items marked BLOCKING must be resolved before the indicated phase begins.

# Question Blocking phase Owner Notes
OQ-1 Stripe Smart Retries configuration: how many retries, at what intervals? B.3 (BLOCKING — must configure before first live cohort) Jeffrey Stripe default is 4 attempts over ~4 weeks. Adventive's current manual dunning runs 6 steps over 30 days. Align Smart Retries schedule with current customer expectations before retiring Adventive dunning.
OQ-2 Browser Rendering API access: has the Cloudflare account been enabled for Browser Rendering? B.2 (BLOCKING — must confirm before PDF rendering build) Patrick Browser Rendering is available on Workers Paid but must be explicitly enabled in the Cloudflare Dashboard under Workers & Pages → Browser Rendering.
OQ-3 Historical invoice export: which format and storage location? B.4 Jeffrey 14 years of billing_invoice history. Options: (a) export to R2 as JSON + original PDFs, (b) retain read-only access to legacy DB after billing_service retirement, (c) export to BigQuery. Must decide before B.8 decommissions billing_service.
OQ-4 Cohort 1 customer list: which accounts are flat-subscription-only (no metered impressions)? B.6 (BLOCKING) Jeffrey + Patrick Cohort 1 gate is pricing-model simplicity. Need a query against account_plan_usage to identify accounts with zero impression tiers (sub-only).
OQ-5 billing_service tech stack: what PDF renderer does billing_service use, and is the Handlebars template accessible? B.2 Patrick The PDF renderer in billing_service is unanalyzable from the admin repo. The template must be extracted to seed the billing Worker's src/render/templates/invoice.hbs.
OQ-6 Acodei field mapping compatibility: does Acodei handle Stripe Subscription invoices the same as manual invoices? B.3 Jeffrey Acodei captures Stripe events. Subscription-generated invoices (billing_reason=subscription) have a different event shape than manual invoices (billing_reason=manual). Confirm Acodei's field mappings cover both before first live cohort.
OQ-7 Customer Portal (B.9): opt-in or deferred? B.9 Jeffrey Customer Portal enables self-service card update and invoice history. Low implementation cost (Stripe configuration only). Decision needed: enable immediately at B.9 with customer comms, or defer until there's a specific support-cost trigger.
OQ-8 Metering signal frequency: daily push or end-of-period summary? B.4 Jeffrey + Patrick Daily impression counts from Redshift are more accurate and reduce cutover risk, but require a pipeline change. End-of-period summary matches the current billing_service behavior and is lower implementation cost. Both are compatible with Stripe metered Prices.
OQ-9 Custom arrangement inventory: how many accounts have non-standard pricing not captured in account_plan_usage? B.6 (BLOCKING for Cohort 3) Jeffrey + Patrick Cohort 3 includes custom-arrangement customers. Need a per-account audit of billing_service invoice history vs. account_plan_usage + account_plan_sub to identify discrepancies.
OQ-10 New GitHub repository: where does billing-worker live? B.1 Jeffrey Assumed adventive/adventive-billing-worker on GitHub (private). Confirm organization name, visibility, and branch protection rules.
OQ-11 Stripe webhook signing secret: staging vs. production endpoints registered separately? B.1 (staging), B.3 (production) Patrick Staging should point to Stripe test-mode endpoint; production to live-mode endpoint. Two separate signing secrets. Confirm who registers them and who has access to Stripe Dashboard Developers tab.
OQ-12 Cloudflare account ID and API token provisioning for billing Worker CI/CD B.1 Patrick GitHub Actions needs CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID as repository secrets. Same token used by admin-api CI if on same Cloudflare account.

Glossary

Term Definition
billing_service A separate internal Adventive API at billing.{domain}/api/billing/ that owns all Stripe API calls, rollup logic, and invoice PDF generation. The admin repo is a thin proxy to this service. Not to be confused with the billing Worker (the new replacement).
billing Worker The new Cloudflare Worker that replaces billing_service's Adventive-side responsibilities: webhook ingestion, PDF rendering, Mailgun delivery, and reconciliation. The billing Worker does NOT replace Stripe — it complements Stripe.
Browser Rendering Cloudflare's headless-browser API that renders HTML to PDF. The leading candidate for replacing billing_service's PDF renderer. Limit: 2 simultaneous renders per account at a time.
Credit Note A Stripe object that reduces the amount owed on a finalized invoice. Used for refunds, corrections, or goodwill adjustments. Does not create a new invoice — adjusts the existing one.
Dual-run period The phase during a cohort migration when both billing_service (legacy) and the billing Worker (new) are live simultaneously for the same customer. The billing Worker is authoritative; billing_service is a shadow check. One billing cycle minimum.
Dunning The process of communicating with customers after payment failure to recover the revenue. Currently owned by Adventive (6-step manual sequence in Billing.php). Post-migration: fully owned by Stripe (Smart Retries + Stripe dunning email schedules).
Graduated pricing A Stripe tiered price model where each tier's rate applies only to the quantity within that tier (not to the full quantity). Adventive's current impression pricing is graduated.
Hyperdrive Cloudflare's MySQL connection pooling layer. Used by the billing Worker for reconciliation reads of the legacy billing_invoice table during the dual-run period.
idempotency key A unique key that prevents duplicate operations when a request is retried. For usage events: {account_id}:{period}:{usage_type}. For Stripe API calls: passed as Idempotency-Key header.
InvoiceItem A Stripe object that adds a line item to a customer's next invoice. Used for managed service fees and custom line items. InvoiceItems are created as-accrued and automatically included when the subscription invoice finalizes.
licensed (usage_type) A Stripe Price billing model where the subscription charges a flat amount per billing cycle, regardless of usage. Used for flat monthly subscription fees.
metered (usage_type) A Stripe Price billing model where usage is reported via Usage Records (or Meters), and the subscription charges based on actual usage at period end. Used for ST/RM/CV impression pricing.
Meter The new Stripe API for usage-based billing (replaces legacy Usage Records API). Adventive should evaluate Meters vs. legacy Usage Records at B.4 — Meters offer idempotency guarantees natively.
Point of no return (B.8) The phase at which legacy billing_service is retired and the billing Worker is the sole billing runtime. After B.8, rollback requires restoring from DB backup and restarting billing_service — not a quick revert. Extra scrutiny required before B.8.
R2 Cloudflare's S3-compatible object storage. Stores invoice PDFs generated by the billing Worker (replaces billing.adventivecdn.com S3/CloudFront CDN).
reconciliation Comparing Stripe invoice totals against the legacy billing_invoice DB (during dual-run) or against Acodei/QuickBooks (post-migration) to detect discrepancies. Zero tolerance: no drift is acceptable before a cohort is marked migrated.
Smart Retries Stripe's machine-learning-based payment retry system. Automatically retries failed payments at times statistically more likely to succeed. Must be explicitly configured on the Stripe account.
Stripe-Signature HTTP header set by Stripe on every webhook delivery. Contains an HMAC-SHA256 signature over the raw request body. Billing Worker must verify this header before processing any event.
subscription A Stripe object that manages recurring billing for a customer. The billing Worker creates one Subscription per Adventive customer with the appropriate flat + metered Prices attached.
Usage Record A data point submitted to Stripe for a metered Price, reporting the quantity of usage for a subscription item in a period. Used to calculate the metered portion of a subscription invoice.

Decisions log (cross-reference)

All formal decisions are in decisions/. Summary of locked-in decisions referenced throughout this document:

Decision Summary File
Stripe Billing scope Stripe owns billing engine; Adventive owns PDF + email + metering signal decisions/2026-04-23-stripe-billing-scope.md
Custom invoice PDF retained Custom PDF non-negotiable; Cloudflare Browser Rendering leading candidate decisions/2026-04-23-custom-invoice-pdf-retained.md

Change log

Version Date Author Change
1.0 2026-04-23 Jeffrey Lambert Initial planning deliverable — repo analysis complete; Stripe inventory complete; all chapters populated; PDF generated