UNPKG

business-as-code

Version:

Primitives for expressing business logic and processes as code

79 lines 2.67 kB
/** * Pricing — discriminated union with five factory variants. * * outcome — pay on delivery; tiers by complexity (S/M/L) * subscription — recurring plan + optional metered overage * perInvocation — flat per-call with included-tier ladder * composite — one-time base + metered events * percent-of — proportional charge against a realised basis * (invoice amount, collected amount, transaction volume) * with optional cap / floor * * Each factory returns a typed Pricing value with discriminator on .kind. */ export const Pricing = { outcome(opts) { if (opts.sla !== undefined) { return { kind: 'outcome', tiers: opts.tiers, sla: opts.sla }; } return { kind: 'outcome', tiers: opts.tiers }; }, subscription(opts) { const result = { kind: 'subscription', plan: opts.plan, }; if (opts.metered !== undefined) result.metered = opts.metered; if (opts.sla !== undefined) result.sla = opts.sla; return result; }, perInvocation(opts) { return { kind: 'per-invocation', tiers: opts.tiers }; }, composite(opts) { return { kind: 'composite', base: opts.base, metered: opts.metered }; }, /** * Percent-of-basis pricing — proportional charge against a realised * basis (e.g. invoice amount, collected amount, transaction volume). * * The metering runtime resolves `basis` to a concrete bigint at * settlement time, then computes the charge as * `(realised_basis * rateBasisPoints) / 10000`, optionally clamped by * `cap` / `floor`. * * @example AR Service: 2% of collected funds * ```ts * Pricing.percentOf({ basis: 'collected-amount', rateBasisPoints: 200 }) * ``` * * @example Capped: 0.75% of transaction volume, max $50/event * ```ts * Pricing.percentOf({ * basis: 'transaction-volume', * rateBasisPoints: 75, * cap: { amount: 5000n, currency: 'USD' }, * }) * ``` */ percentOf(opts) { const result = { kind: 'percent-of', basis: opts.basis, rateBasisPoints: opts.rateBasisPoints, }; if (opts.cap !== undefined) result.cap = opts.cap; if (opts.floor !== undefined) result.floor = opts.floor; return result; }, }; /** Convenience: build a Money value from a bigint + currency. */ export const money = (amount, currency = 'USD') => ({ amount, currency, }); //# sourceMappingURL=pricing.js.map