@fonderie/billing 5.3.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -0
- package/brain/outcomes.md +71 -0
- package/brain/signatures.md +230 -13
- package/dist/{index-CBhthuMn.d.ts → index-BdNYDuhk.d.ts} +108 -9
- package/dist/{index-CS1QagwE.d.cts → index-Ca4pXx07.d.cts} +108 -9
- package/dist/index.cjs +1097 -146
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +137 -15
- package/dist/index.d.ts +137 -15
- package/dist/index.js +1076 -145
- package/dist/index.js.map +1 -1
- package/dist/middlewares/index.cjs +180 -0
- package/dist/middlewares/index.cjs.map +1 -1
- package/dist/middlewares/index.d.cts +1 -1
- package/dist/middlewares/index.d.ts +1 -1
- package/dist/middlewares/index.js +180 -0
- package/dist/middlewares/index.js.map +1 -1
- package/dist/migrations/sql/006_wallet.sql +85 -0
- package/dist/types.cjs +17 -3
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +34 -7
- package/dist/types.d.ts +34 -7
- package/dist/types.js +13 -2
- package/dist/types.js.map +1 -1
- package/package.json +4 -4
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { Middleware, IFonderieContext } from '@fonderie/core';
|
|
2
2
|
import { IStoreAdapter } from '@fonderie/store';
|
|
3
|
-
import { SubscriberType, PolicyEntry } from './types.cjs';
|
|
3
|
+
import { SubscriberType, BillingInterval, PolicyEntry, IWalletRate } from './types.cjs';
|
|
4
4
|
|
|
5
5
|
interface IBillingEvent {
|
|
6
6
|
type: string;
|
|
7
7
|
subscription: INormalizedSubscription | null;
|
|
8
|
+
payment?: INormalizedPayment | null;
|
|
9
|
+
}
|
|
10
|
+
interface INormalizedPayment {
|
|
11
|
+
sessionId: string;
|
|
12
|
+
providerTxId: string | null;
|
|
13
|
+
amountTotal: bigint | null;
|
|
14
|
+
currency: string | null;
|
|
15
|
+
paymentStatus: string | null;
|
|
16
|
+
metadata: Record<string, string>;
|
|
8
17
|
}
|
|
9
18
|
interface INormalizedSubscription {
|
|
10
19
|
subscriberType: SubscriberType;
|
|
@@ -21,14 +30,14 @@ interface INormalizedSubscription {
|
|
|
21
30
|
currentPeriodEnd: Date;
|
|
22
31
|
cancelAtPeriodEnd: boolean;
|
|
23
32
|
trialEndsAt: Date | null;
|
|
24
|
-
interval:
|
|
33
|
+
interval: BillingInterval;
|
|
25
34
|
}
|
|
26
35
|
interface IResolvedPrice {
|
|
27
36
|
priceId: string;
|
|
28
37
|
lookupKey: string | null;
|
|
29
|
-
unitAmount:
|
|
38
|
+
unitAmount: bigint;
|
|
30
39
|
currency: string;
|
|
31
|
-
interval:
|
|
40
|
+
interval: BillingInterval;
|
|
32
41
|
nickname: string | null;
|
|
33
42
|
productId: string;
|
|
34
43
|
active: boolean;
|
|
@@ -54,6 +63,20 @@ interface IBillingProvider {
|
|
|
54
63
|
}): Promise<{
|
|
55
64
|
url: string;
|
|
56
65
|
}>;
|
|
66
|
+
createPaymentCheckoutSession?(opts: {
|
|
67
|
+
customerId: string;
|
|
68
|
+
amount: bigint;
|
|
69
|
+
currency: string;
|
|
70
|
+
name: string;
|
|
71
|
+
quantity?: number;
|
|
72
|
+
priceId?: string;
|
|
73
|
+
metadata: Record<string, string>;
|
|
74
|
+
successUrl: string;
|
|
75
|
+
cancelUrl: string;
|
|
76
|
+
}): Promise<{
|
|
77
|
+
url: string;
|
|
78
|
+
sessionId: string;
|
|
79
|
+
}>;
|
|
57
80
|
resolvePriceById(priceId: string): Promise<IResolvedPrice | null>;
|
|
58
81
|
resolvePricesByLookupKey(lookupKeys: string[]): Promise<Map<string, IResolvedPrice>>;
|
|
59
82
|
updateSubscription(opts: {
|
|
@@ -88,10 +111,12 @@ interface IBillingPlanPrice {
|
|
|
88
111
|
/** Stripe price id. Used for hydration and as a lookup_key fallback. */
|
|
89
112
|
priceId?: string;
|
|
90
113
|
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
114
|
+
* Display amount in the smallest currency unit (bigint, e.g. 1999n = $19.99) —
|
|
115
|
+
* the seed value written to fonderie_plans and the fallback shown (flagged
|
|
116
|
+
* pricingStale) when hydration is off or Stripe is unreachable. When
|
|
117
|
+
* hydration resolves a live price, the live amount wins.
|
|
93
118
|
*/
|
|
94
|
-
amount?:
|
|
119
|
+
amount?: bigint;
|
|
95
120
|
}
|
|
96
121
|
/**
|
|
97
122
|
* Read-through pricing: amount/currency come from Stripe (source of truth) rather
|
|
@@ -99,7 +124,7 @@ interface IBillingPlanPrice {
|
|
|
99
124
|
* See packages/billing/docs/pricing-hydration.md.
|
|
100
125
|
*/
|
|
101
126
|
interface IBillingPricingConfig {
|
|
102
|
-
/** Kill-switch. When false (default),
|
|
127
|
+
/** Kill-switch. When false (default), serve the configured amount/USD directly. */
|
|
103
128
|
hydration?: boolean;
|
|
104
129
|
/** Fresh-cache TTL. Default 300_000 (5m). */
|
|
105
130
|
cacheTtlMs?: number;
|
|
@@ -112,6 +137,28 @@ interface IBillingPlanDefaults {
|
|
|
112
137
|
warnAt?: number;
|
|
113
138
|
buffer?: number;
|
|
114
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Per-plan wallet economics. Requires config.wallet to be set — a plan-level
|
|
142
|
+
* wallet without the global opt-in is ignored (with a boot warning).
|
|
143
|
+
*/
|
|
144
|
+
interface IBillingPlanWallet {
|
|
145
|
+
/** Overrides the global wallet currency for this plan's grants and rates. */
|
|
146
|
+
currency?: string;
|
|
147
|
+
/** Display precision override. */
|
|
148
|
+
precision?: number;
|
|
149
|
+
/**
|
|
150
|
+
* Credits auto-granted once per grantPeriod, applied lazily by withBilling
|
|
151
|
+
* on the subscriber's first request of the period. Only granted while the
|
|
152
|
+
* subscription is active or trialing (no new credit while payment fails).
|
|
153
|
+
*/
|
|
154
|
+
grantAmount?: bigint;
|
|
155
|
+
/** Grant cadence for grantAmount. Default 'month'. */
|
|
156
|
+
grantPeriod?: 'month' | 'week' | 'day';
|
|
157
|
+
/** How far below zero rate debits may take the balance. Default 0n (block at zero). */
|
|
158
|
+
overdraftLimit?: bigint;
|
|
159
|
+
/** Per-metric unit costs, e.g. { 'sms:send': { cost: 75n, unit: 'msg' } }. */
|
|
160
|
+
rates?: Record<string, IWalletRate>;
|
|
161
|
+
}
|
|
115
162
|
interface IBillingPlan {
|
|
116
163
|
name: string;
|
|
117
164
|
description?: string;
|
|
@@ -121,6 +168,7 @@ interface IBillingPlan {
|
|
|
121
168
|
yearly?: IBillingPlanPrice;
|
|
122
169
|
defaults?: IBillingPlanDefaults;
|
|
123
170
|
policy?: Record<string, PolicyEntry>;
|
|
171
|
+
wallet?: IBillingPlanWallet;
|
|
124
172
|
metadata?: Record<string, unknown>;
|
|
125
173
|
}
|
|
126
174
|
type RateLimitBackendConfig = 'memory' | 'db' | ICounterBackend;
|
|
@@ -128,6 +176,56 @@ interface IBillingNotificationsConfig {
|
|
|
128
176
|
warnAt?: boolean;
|
|
129
177
|
softHit?: boolean;
|
|
130
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* A purchasable credit top-up, synced to fonderie_credit_packs at boot (same
|
|
181
|
+
* pattern as plans). Purchases go through the provider's one-time checkout;
|
|
182
|
+
* the payment webhook credits `credits` to the buyer's wallet.
|
|
183
|
+
*/
|
|
184
|
+
interface IBillingCreditPack {
|
|
185
|
+
/** Stable identifier used by POST /billing/wallet/checkout, e.g. 'small'. */
|
|
186
|
+
id: string;
|
|
187
|
+
name: string;
|
|
188
|
+
/** Wallet credits granted on purchase, in the smallest wallet unit. */
|
|
189
|
+
credits: bigint;
|
|
190
|
+
/** Purchase price in the provider's smallest currency unit. */
|
|
191
|
+
priceAmount: bigint;
|
|
192
|
+
/**
|
|
193
|
+
* ISO 4217 PAYMENT currency for the provider charge; defaults to the
|
|
194
|
+
* buyer's wallet currency. Credits always land in the buyer's wallet
|
|
195
|
+
* currency regardless of what the charge was priced in.
|
|
196
|
+
*/
|
|
197
|
+
currency?: string;
|
|
198
|
+
/** Existing provider Price id — used instead of the ad-hoc priceAmount. */
|
|
199
|
+
priceId?: string;
|
|
200
|
+
/** Inactive packs stay in the DB but can no longer be checked out. */
|
|
201
|
+
active?: boolean;
|
|
202
|
+
metadata?: Record<string, unknown>;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Opt-in stored-value wallet. Presence of this object activates the wallet
|
|
206
|
+
* subsystem (routes, credit packs, per-plan grants and rates); leaving it out
|
|
207
|
+
* changes nothing for existing subscription-only consumers.
|
|
208
|
+
*/
|
|
209
|
+
interface IBillingWalletConfig {
|
|
210
|
+
/** Default wallet currency when a plan doesn't override it. Default 'USD'. */
|
|
211
|
+
currency?: string;
|
|
212
|
+
/** Display precision — decimal places of the smallest unit. Default 2. */
|
|
213
|
+
precision?: number;
|
|
214
|
+
/**
|
|
215
|
+
* Bearer token guarding POST /billing/wallet/grant (manual support/ops
|
|
216
|
+
* grants). The route is only registered when a token is configured.
|
|
217
|
+
*/
|
|
218
|
+
adminToken?: string;
|
|
219
|
+
/**
|
|
220
|
+
* Signing secret for POST /billing/webhook/payment. REQUIRED for pack
|
|
221
|
+
* purchases: the route answers 500 until it is set, and it deliberately
|
|
222
|
+
* does NOT fall back to the subscription webhook's secret — per-endpoint
|
|
223
|
+
* secrets keep a delivery captured for one endpoint from replaying
|
|
224
|
+
* against the other.
|
|
225
|
+
*/
|
|
226
|
+
webhookSecret?: string;
|
|
227
|
+
creditPacks?: IBillingCreditPack[];
|
|
228
|
+
}
|
|
131
229
|
interface IBillingConfig {
|
|
132
230
|
provider: IBillingProvider;
|
|
133
231
|
plans: IBillingPlan[];
|
|
@@ -139,6 +237,7 @@ interface IBillingConfig {
|
|
|
139
237
|
};
|
|
140
238
|
notifications?: IBillingNotificationsConfig;
|
|
141
239
|
pricing?: IBillingPricingConfig;
|
|
240
|
+
wallet?: IBillingWalletConfig;
|
|
142
241
|
}
|
|
143
242
|
declare const MESSAGE_KEYS: {
|
|
144
243
|
readonly limitWarning: "billing.limit-warning";
|
|
@@ -152,4 +251,4 @@ declare function requirePlan(plans: string | string[], store: IStoreAdapter, ctx
|
|
|
152
251
|
|
|
153
252
|
declare function withBilling(store: IStoreAdapter, config: IBillingConfig, backend: ICounterBackend): Middleware;
|
|
154
253
|
|
|
155
|
-
export { type BillingMessageKey as B, type IBillingConfig as I, MESSAGE_KEYS as M, type RateLimitBackendConfig as R, type IBillingProvider as a, type IResolvedPrice as b, type IBillingEvent as c, type
|
|
254
|
+
export { type BillingMessageKey as B, type IBillingConfig as I, MESSAGE_KEYS as M, type RateLimitBackendConfig as R, type IBillingProvider as a, type IResolvedPrice as b, type IBillingEvent as c, type IBillingPlan as d, type ICounterBackend as e, type IBillingCreditPack as f, type IBillingNotificationsConfig as g, type IBillingPlanDefaults as h, type IBillingPlanPrice as i, type IBillingPlanWallet as j, type IBillingPricingConfig as k, type IBillingWalletConfig as l, type INormalizedPayment as m, requirePlan as r, withBilling as w };
|