@venturekit-pro/billing
v0.0.42
Published
Invoicing, plans, usage tracking, and feature gating for VentureKit
Readme
@venturekit-pro/billing
Warning: This package is in active development and not production-ready. APIs may change without notice.
Billing and invoicing for VentureKit — plan definitions, feature limits, usage-to-invoice mapping, and auto-migration support.
Installation
npm install @venturekit-pro/billing@devOverview
@venturekit-pro/billing provides:
- Plan definitions —
definePlans()with feature limits and pricing tiers - Subscription management — create, upgrade, downgrade, cancel, pause, resume
- Invoice generation — from plan + usage, with tax calculation
- Usage tracking — record and meter feature usage
- Feature gating — plan-based and usage-based access control
- Auto-migrations — billing tables created automatically via
vk migrate
Note: This package handles invoicing and plan management. Payment processing is NOT included — integrate any payment provider separately.
Defining Plans
import { definePlans } from '@venturekit-pro/billing';
const plans = definePlans([
{
id: 'free',
name: 'Free',
features: {
projects: { limit: 3 },
storage: { limit: 1_000_000_000 }, // 1 GB
apiRequests: { limit: 10_000, period: 'month' },
support: false,
},
},
{
id: 'pro',
name: 'Pro',
features: {
projects: { limit: 50 },
storage: { limit: 100_000_000_000 }, // 100 GB
apiRequests: { limit: 1_000_000, period: 'month' },
support: true,
},
},
]);Feature Checking
import { getFeatureLimit, hasFeature } from '@venturekit-pro/billing';
const maxProjects = getFeatureLimit(plans, 'free', 'projects');
// → 3
const hasSupport = hasFeature(plans, 'free', 'support');
// → falseEntitlements
Plan + per-tenant overrides → what a tenant may do, with HTTP-mapped refusals you can throw straight from a route:
import { createEntitlementsResolver } from '@venturekit-pro/billing';
const entitlements = createEntitlementsResolver({
plans,
getPlanId: (tenantId) => subscriptions.currentPlanId(tenantId),
getOverrides: (tenantId) => deals.overridesFor(tenantId), // { seats: { limit: 500 } }
});
const ent = await entitlements.forSubject(ctx.tenant.id);
ent.require('api_access'); // 402 PLAN_UPGRADE_REQUIRED
await ent.requireWithinLimit('seats', () => members.count(tenantId)); // 403 PLAN_LIMIT_REACHED at the cap
ctx.tenant.quotas = ent.toQuotas({ seats: 'maxUsers' }); // feeds tenancy's quota middlewareEntitlementError carries details.featureKey / planId / limit / usage for
the upgrade prompt and renders through @venturekit/runtime's error boundary
without a runtime dependency. Call entitlements.invalidate(tenantId) after a
plan change.
Dunning
Which payment reminder an unpaid invoice is due, for a cron to ask about every open invoice. Pure and clock-free; the mail and the invoice model are yours.
import { nextDunningStep, dunningScheduleRefusal } from '@venturekit-pro/billing';
const schedule = { enabled: true, offsetsDays: [-3, 7, 14, 30] }; // days from the due date
dunningScheduleRefusal(schedule.offsetsDays); // null, or why the setting is refused
const step = nextDunningStep({
dueDate: invoice.dueDate, // 'YYYY-MM-DD'
schedule,
sent: reminders.map((r) => ({ sentAtISO: r.sentAt, offsetDays: r.step })), // step null = sent by a person
today: todayIn(customer.timezone),
});
if (step !== null) await sendReminder(invoice, step); // and record { step } for next timeThe latest step whose day has come is due; each step goes once; steps skipped over are gone (the schedule says when to nudge, not how many messages to catch up on); and a reminder a person sent since the previous step covers the current one.
Usage-to-Invoice Mapping
import { mapUsageToLineItems } from '@venturekit-pro/billing';
const lineItems = mapUsageToLineItems(currentUsage, planFeatures);
// Returns structured line items for invoice generationAuto-Migrations
When @venturekit-pro/billing is added to a project, vk migrate automatically discovers and applies billing-related database tables:
import { getBillingMigrationsDir } from '@venturekit-pro/billing';
const migrationsDir = getBillingMigrationsDir();
// Returns path to SQL migration filesAPI Reference
See the API reference for full documentation.
License
Apache-2.0 — see LICENSE for details.
