Hanzo Billing
Subscriptions, usage, invoices
Charge a fixed price, charge for what someone used, or charge for both on the same invoice. Plans, prices, meters, coupons and credits are separate objects, so a pricing change is a new price rather than a migration — and your servers never hold a card number to do any of it.
The objects you bill with
Small pieces that compose, rather than one plan type that has to cover every case.
Plans and prices
A plan says what someone gets. A price says what it costs. Keeping them apart is what lets you change a price without touching anyone already on the old one.
Meters
Post an event when something is used and the meter aggregates it. The invoice reads the meter at the end of the period, so nobody has to add up rows by hand.
Invoices
Line items assembled from the subscription and the meters, with tax calculated on the invoice itself. Preview one before it is issued, which is when a pricing mistake is still cheap.
Credits and refunds
Issue credit against a balance, or refund a payment that already settled. Both leave a record, because a customer arguing about a bill is really arguing about a history.
Coupons and discounts
Apply one to a subscription or to a single invoice. A discount is an object on the invoice rather than an adjusted number, so the reason the total changed is still legible.
Webhooks
The provider tells us a payment settled and we tell you. One endpoint per provider, so adding a second processor does not mean a second integration on your side.
Report the use, then charge for it
import { Hanzo } from '@hanzo/billing';
const billing = new Hanzo({ apiKey: process.env.HANZO_API_KEY });
// Report usage in real time
await billing.usage.record({
customer: 'cus_abc123',
meter: 'api_requests',
value: 1,
timestamp: new Date(),
});
// Subscribe with metered pricing
await billing.subscriptions.create({
customer: 'cus_abc123',
items: [{ price: 'price_api_metered' }],
payment_behavior: 'default_incomplete',
});