@absolutejs/billing
v0.14.0
Published
Provider-neutral pricing and invoice computation used by the hosted AbsoluteJS.ai platform. Converts metered usage into exact integer-micro line items with tiers and allowances.
Maintainers
Readme
@absolutejs/billing
Provider-neutral pricing and invoice computation used by the hosted AbsoluteJS.ai platform.
@absolutejs/billing is the pure-function layer between
@absolutejs/metering (which collects usage events) and an
invoicing backend (Stripe, QuickBooks, an internal billing engine).
It does two things:
createPlan(...)— declares a priced product: optional flat base fee, per-dimension unit prices, optional graduated tiers, optional per-dimension free allowances.computeInvoice({ plan, period, tenant, usage })— pure function that turns aUsagesnapshot into anInvoicewith line items and a total.
All money math is done in integer micros (1 micro = 1/1,000,000
of a currency unit — the same denomination Stripe stores prices in
internally). Float drift is structurally impossible: a $0.0002
per-request price is 200 and rounding policy is explicit.
import { createPlan, computeInvoice, formatMicros } from "@absolutejs/billing";
const plan = createPlan({
name: "pro",
currency: "usd",
basePriceMicros: 20_000_000, // $20/mo
pricedDimensions: {
requests: { perUnitMicros: 200, freeTier: 1_000_000 },
cpuMs: { perUnitMicros: 50, unit: 1000, freeTier: 60_000 * 60 * 10 },
bytesEgress: {
perUnitMicros: 100,
unit: 1024 * 1024,
freeTier: 100 * 1024 * 1024,
},
hibernationGbSeconds: { perUnitMicros: 5 },
},
});
const invoice = computeInvoice({
plan,
tenant: "acme",
period: { start, end },
usage, // a Usage from @absolutejs/metering
});
console.log(formatMicros(invoice.totalMicros, invoice.currency));
// "27.50 USD"Pricing shapes
A PricedDimension is one of three:
- Flat per-unit —
{ perUnitMicros: 200, unit: 1 } - Tiered (graduated) —
{ tiers: [{ upTo: 1_000_000, perUnitMicros: 200 }, { upTo: Infinity, perUnitMicros: 100 }] } - Custom —
{ price: (chargedQuantity) => micros }(escape hatch for surge / caps / non-monotonic pricing)
Optional knobs:
freeTier— units subtracted before pricingunit— divisor sobytesEgresspriced as MB ↔unit: 1024*1024label— invoice line-item display name
Plan-level knobs:
basePriceMicros— flat fee per periodminimumChargeMicros— floor; an adjustment line item fills any gaprounding—'truncate'(default; sub-cent → $0.00) or'round-half-up'currency— display label; not convertedmetadata— arbitrary keys that flow through to the invoice
Why pure?
The control plane needs to:
- Preview an upcoming invoice before the period closes
- Re-price a past period under a new plan ("what would this customer have paid on the proposed enterprise tier?")
- Dry-run plan changes before publishing them
A pure cost-model function makes all three trivial — no Stripe SDK,
no side effects, no IO. The Stripe push (or QuickBooks export, or
mailed-PDF generator) lives outside this package, in
@absolutejs/billing-adapters/*.
License
BSL-1.1 with named carveout against hosted SaaS billing platforms
(Metronome, Orb, Lago, Stripe Billing, m3ter, Chargebee). See
LICENSE. Change date: 2030-05-31 → Apache 2.0.
Prepaid service credits
Durable balances, reservations, capped work, and migration rules are available through the prepaid, prepaid-postgres, and credit-work subpaths.
Secure credit checkout
Purchase-only handoffs provide expiring, single-use browser capabilities without a full login session.
@absolutejs/billing/reports provides customer-facing status, receipt pagination, and usage contracts. parseUsageRange uses a half-open UTC date interval of at most 90 days (default: the last 30 days including today). Receipt cursors are positions, never authorization: bind every query, reversal join, and cursor to the caller's account. Readers must project through the public helpers, which omit provider costs, payment tokens and vault references. Usage day and feature totals must reconcile exactly; purchased dollars and consumed service credits are different measures. Automatic refill is currently unsupported.
Deferred progress
checkpointDeferred(accountId, workId, binding, expectedRevision, value) saves
progress without settling or reserving more credits. The initial revision is 0;
success returns the incremented revision and saved string. It verifies the bound
effect and authorization, rejects stale revisions and terminal work, and limits
the value to one million characters. Existing work uses the same JSON state
column; no schema migration is required.
A checkpoint is not an execution lease. Claim execution separately, persist an in-flight marker before any provider call, drain metering before saving its result, and retain the reservation if the outcome is uncertain.
Uncapped embedding plans and application budgets
Pass monthlyTokenLimit: null in EmbeddingUsageSnapshot when the configured
provider plan has no monthly embedding-token cap. monthlyBudgetTokens can
separately describe a host-owned spending guardrail; it is never reported as
provider quota. Both values are host configuration, not a live provider balance.
exhausted: true reports currently refused embeddings without assuming a monthly
cap caused the refusal. Member allowances remain the host application's policy.
