Billing
Customer, Product, Plan, Price, Subscription, Invoice, Payment -- revenue powered by Stripe.
Seven entities form the complete billing graph -- from product catalog to recurring subscriptions to payment collection. Every entity is Stripe-backed. Creating a Subscription in headless.ly creates a Stripe subscription. Stripe webhooks flow back as immutable events.
import { Customer, Product, Plan, Price, Subscription, Invoice } from '@headlessly/billing'
const customer = await Customer.create({
name: 'Acme Dev',
email: 'billing@acme.dev',
organization: 'org_fX9bL5nRd',
})
const product = await Product.create({
name: 'Headlessly Pro',
type: 'Software',
status: 'Active',
visibility: 'Public',
})
const plan = await Plan.create({
name: 'Pro Monthly',
product: product.$id,
trialDays: 14,
status: 'Active',
})
const price = await Price.create({
amount: 4900,
currency: 'usd',
interval: 'Monthly',
plan: plan.$id,
active: true,
})
const subscription = await Subscription.create({
customer: customer.$id,
plan: plan.$id,
status: 'Trialing',
currentPeriodStart: new Date(),
currentPeriodEnd: new Date(Date.now() + 14 * 86400000),
startedAt: new Date(),
})
// After trial ends, activate
await Subscription.activate(subscription.$id)The Billing Graph
Product ──< Plan ──< Price
│
Customer ──< Subscription ──> Plan
│ │
├──< Invoice ──┘
│ │
└──< Payment ──> InvoiceProducts contain Plans, Plans contain Prices. A Customer subscribes to a Plan via a Subscription. Subscriptions generate Invoices, and Payments settle those Invoices. Every arrow is a typed relationship in the Noun schema.
Entities
| Entity | Description | Custom Verbs |
|---|---|---|
| Customer | Stripe Customer -- the billing identity | -- |
| Product | What you sell -- software, services, addons, bundles | -- |
| Plan | Pricing tiers with trial configuration and feature limits | -- |
| Price | Amount, currency, and interval -- maps to Stripe Prices | -- |
| Subscription | Active paying relationships with full lifecycle | pause, cancel, reactivate, upgrade, downgrade, activate, renew |
| Invoice | Bills generated from subscriptions | pay, void, finalize |
| Payment | Money movement -- charges and refunds | refund, capture |
Stripe as Truth Source
All billing entities sync bidirectionally with Stripe. headless.ly is not a payment processor -- it is the typed graph layer on top of Stripe.
- Writes to headless.ly create corresponding Stripe objects via the Stripe API
- Stripe webhooks flow back as events, keeping the graph in sync
- Stripe IDs are stored on every entity (
stripeCustomerId,stripeProductId,stripeSubscriptionId, etc.) as indexed unique fields - Financial metrics (MRR, churn, NRR, LTV) are derived from real Stripe data -- headless baremetrics
Cross-Domain Connections
Billing is the revenue engine that connects to every other domain:
import { Deal } from '@headlessly/crm'
Deal.won((deal, $) => {
const customer = await $.Customer.create({
name: deal.name,
email: deal.contact,
organization: deal.organization,
})
await $.Subscription.create({
customer: customer.$id,
plan: 'plan_Nw8rTxJv',
})
})- CRM: Deal close triggers Customer and Subscription creation
- Analytics: Every billing event feeds into Metric and Funnel (MRR, churn, conversion)
- Support: Customer is linked to Ticket for billing inquiries
- Marketing: Subscription status drives Segment membership for retention campaigns
Package
npm install @headlessly/billingimport { Customer, Product, Plan, Price, Subscription, Invoice, Payment } from '@headlessly/billing'Or via the unified SDK:
import { $ } from '@headlessly/sdk'
await $.Customer.create({ name: 'Acme Dev', email: 'billing@acme.dev' })
await $.Subscription.find({ status: 'Active' })