@frank/billing (0.2.1)

Published 2026-10-08 13:36:05 +11:00 by steve

Installation

@frank:registry=
npm install @frank/billing@0.2.1
"@frank/billing": "0.2.1"

About this package

@frank/billing

Stripe billing over plain REST for Frank products, money and credits in integer cents: subscription and one-off Checkout, HMAC webhook -> workspace billing state, publish billing gate, trial cohorts and reminders, and the workspace credit ledger. Ported from Blockwise src/lib/billing, src/lib/credits and src/lib/trial with no behaviour change. No Stripe SDK, no Supabase dependency: the product passes its own service client.

Public API

Everything comes from @frank/billing: configFromEnv; offers (getBillingOffer, offerRunsCheckoutTrial); Checkout (startWorkspaceCheckout, buildCheckoutSessionRequest, createOneOffCheckoutSession, validateStripePriceForOffer); webhooks (constructStripeWebhookEvent, applyStripeBillingEvent, reconciliationEventForSubscription); the gate (decidePublishBillingGate, resolvePublishBillingGate, publishBillingGateMessage); trials (loadTrialStatus, findTrialConsumedAt, recoverMissingTrialReminders); credits (grantWorkspaceCredits, reserveAdPackCredits, settleAdPackCredits, refundAdPackReservation).

Browser entry

Client components (the Blockwise publish wizard) import @frank/billing/browser instead of the root. The root entry pulls in the Stripe scaffold and the webhook/credit/reconciliation services, which import node:crypto, so a browser bundle that imports the root fails to build. The browser entry re-exports only the pure offer lookup and the catalog types it needs - getBillingOffer, findOfferByVersion, currencyForMarket, isBillingMarket/isBillingCurrency/isBillingProduct, offerRunsCheckoutTrial, offerVersionRunsCheckoutTrial and the BillingOffer / BillingCatalog / BillingOfferKey / BillingTrialStart types. Every symbol is the same implementation the root exports; nothing is copied. Server calls keep importing @frank/billing.

Config

The caller builds one BillingConfig: env (from configFromEnv(), the only process.env reader: STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, STRIPE_PRICE_ID, STRIPE_PRICE_IDS_JSON, BLOCKWISE_SELF_SERVE_TRIAL_ENABLED, BLOCKWISE_STRIPE_TOS_CONSENT), catalog (offers, markets, checkout-trial versions, roles), tables, messages, rules (cents, trial days, pack credits) and jobs.lapsePauseKind; stages and job enqueues are injected.

Example

import { configFromEnv, startWorkspaceCheckout } from "@frank/billing";
const config = { env: configFromEnv(), catalog, tables, messages, rules, jobs };
const result = await startWorkspaceCheckout(config, {
  service, workspaceId, role: "owner", userId: null, customerEmail,
  product: "ad_studio", market: "AU", successUrl, cancelUrl, idempotencyKey,
});

Dependencies

Development dependencies

ID Version
@types/node ^22.15.30
esbuild ^0.28.2
Details
npm
2026-10-08 13:36:05 +11:00
4
latest
56 KiB
Assets (1)
Versions (3) View all
0.2.1 2026-10-08
0.2.0 2026-10-04
0.1.0 2026-09-26