@lunora/payment 1.0.0-alpha.23 → 1.0.0-alpha.25
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 +2 -0
- package/dist/index.d.mts +214 -25
- package/dist/index.d.ts +214 -25
- package/dist/packem_shared/{adapter.d-SULGy2QF.d.mts → adapter.d-BOheUepr.d.mts} +121 -15
- package/dist/packem_shared/{adapter.d-SULGy2QF.d.ts → adapter.d-BOheUepr.d.ts} +121 -15
- package/dist/providers/autumn-features.d.mts +41 -6
- package/dist/providers/autumn-features.d.ts +41 -6
- package/dist/providers/autumn.d.mts +10 -1
- package/dist/providers/autumn.d.ts +10 -1
- package/dist/providers/creem.d.mts +10 -1
- package/dist/providers/creem.d.ts +10 -1
- package/dist/providers/dodopayments.d.mts +10 -1
- package/dist/providers/dodopayments.d.ts +10 -1
- package/dist/providers/polar.d.mts +10 -1
- package/dist/providers/polar.d.ts +10 -1
- package/dist/providers/stripe.d.mts +10 -1
- package/dist/providers/stripe.d.ts +10 -1
- package/package.json +4 -4
|
@@ -4,21 +4,31 @@
|
|
|
4
4
|
* The provider is a stateless translator; the store owns all state. These types are the
|
|
5
5
|
* provider-agnostic vocabulary every adapter normalizes onto.
|
|
6
6
|
*/
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* ISO-4217 currency code (uppercase, 3 letters). Not enumerated — provider coverage varies.
|
|
9
|
+
* @experimental
|
|
10
|
+
*/
|
|
8
11
|
type CurrencyCode = string;
|
|
9
12
|
/**
|
|
10
13
|
* Money as integer minor units + currency. Always carry the two together.
|
|
11
14
|
*
|
|
12
15
|
* `minorUnits` is a `bigint`, which is **not** JSON-serializable — cross the RPC/wire boundary
|
|
13
16
|
* with the `toMoneyJSON` / `fromMoneyJSON` helpers (see `./money`).
|
|
17
|
+
* @experimental
|
|
14
18
|
*/
|
|
15
19
|
interface Money {
|
|
16
20
|
readonly currency: CurrencyCode;
|
|
17
21
|
readonly minorUnits: bigint;
|
|
18
22
|
}
|
|
19
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Stable provider identifier (Medusa-style). Ships Stripe/Polar/Autumn/Dodo plus Creem, an EU-friendly MoR.
|
|
25
|
+
* @experimental
|
|
26
|
+
*/
|
|
20
27
|
type ProviderId = "autumn" | "creem" | "dodopayments" | "polar" | "stripe";
|
|
21
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* What a provider can do — encoded in types so tax/UX assumptions aren't tribal knowledge.
|
|
30
|
+
* @experimental
|
|
31
|
+
*/
|
|
22
32
|
interface ProviderCapabilities {
|
|
23
33
|
/** True for Polar / Lemon Squeezy / Paddle; false for Stripe (PSP) and Autumn (runs on your own Stripe). Drives tax/invoice ownership. */
|
|
24
34
|
readonly merchantOfRecord: boolean;
|
|
@@ -27,10 +37,20 @@ interface ProviderCapabilities {
|
|
|
27
37
|
/** Usage-based / metered billing. */
|
|
28
38
|
readonly usageMetering: boolean;
|
|
29
39
|
}
|
|
30
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* Lifecycle state of a one-time payment session.
|
|
42
|
+
* @experimental
|
|
43
|
+
*/
|
|
31
44
|
type PaymentState = "authorized" | "canceled" | "captured" | "failed" | "initiated" | "partially_refunded" | "refunded";
|
|
32
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* Lifecycle state of a subscription.
|
|
47
|
+
* @experimental
|
|
48
|
+
*/
|
|
33
49
|
type SubscriptionState = "active" | "canceled" | "past_due" | "paused" | "trialing";
|
|
50
|
+
/**
|
|
51
|
+
* `Customer` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
52
|
+
* @experimental
|
|
53
|
+
*/
|
|
34
54
|
interface Customer {
|
|
35
55
|
readonly createdAt: number;
|
|
36
56
|
readonly email?: string;
|
|
@@ -40,6 +60,10 @@ interface Customer {
|
|
|
40
60
|
/** App-side owner the customer belongs to (user / org / workspace). Opaque to this package. */
|
|
41
61
|
readonly referenceId: string;
|
|
42
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* `PaymentSession` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
65
|
+
* @experimental
|
|
66
|
+
*/
|
|
43
67
|
interface PaymentSession {
|
|
44
68
|
readonly amount: Money;
|
|
45
69
|
readonly capturedAmount: Money;
|
|
@@ -52,6 +76,10 @@ interface PaymentSession {
|
|
|
52
76
|
readonly state: PaymentState;
|
|
53
77
|
readonly updatedAt: number;
|
|
54
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* `Subscription` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
81
|
+
* @experimental
|
|
82
|
+
*/
|
|
55
83
|
interface Subscription {
|
|
56
84
|
readonly cancelAtPeriodEnd: boolean;
|
|
57
85
|
readonly createdAt: number;
|
|
@@ -66,11 +94,19 @@ interface Subscription {
|
|
|
66
94
|
readonly state: SubscriptionState;
|
|
67
95
|
readonly updatedAt: number;
|
|
68
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* `CustomerRef` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
99
|
+
* @experimental
|
|
100
|
+
*/
|
|
69
101
|
interface CustomerRef {
|
|
70
102
|
readonly email?: string;
|
|
71
103
|
readonly metadata?: Record<string, string>;
|
|
72
104
|
readonly referenceId: string;
|
|
73
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* `CheckoutInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
108
|
+
* @experimental
|
|
109
|
+
*/
|
|
74
110
|
interface CheckoutInput {
|
|
75
111
|
readonly cancelUrl: string;
|
|
76
112
|
/**
|
|
@@ -93,6 +129,10 @@ interface CheckoutInput {
|
|
|
93
129
|
readonly referenceId: string;
|
|
94
130
|
readonly successUrl: string;
|
|
95
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* `CheckoutResult` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
134
|
+
* @experimental
|
|
135
|
+
*/
|
|
96
136
|
interface CheckoutResult {
|
|
97
137
|
readonly id: string;
|
|
98
138
|
readonly provider: ProviderId;
|
|
@@ -102,15 +142,23 @@ interface CheckoutResult {
|
|
|
102
142
|
* `attach` input — subscribe a reference to a plan. A thin, plan-oriented skin over
|
|
103
143
|
* {@link CheckoutInput}: `mode` defaults to `"subscription"` (the common case), so callers pass
|
|
104
144
|
* just `{ referenceId, priceId, successUrl, cancelUrl }`.
|
|
145
|
+
* @experimental
|
|
105
146
|
*/
|
|
106
147
|
interface AttachInput extends Omit<CheckoutInput, "mode"> {
|
|
107
148
|
readonly mode?: CheckoutInput["mode"];
|
|
108
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* `PortalInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
152
|
+
* @experimental
|
|
153
|
+
*/
|
|
109
154
|
interface PortalInput {
|
|
110
155
|
readonly customerId: string;
|
|
111
156
|
readonly returnUrl: string;
|
|
112
157
|
}
|
|
113
|
-
/**
|
|
158
|
+
/**
|
|
159
|
+
* A single durable usage record — one metered event for a `(referenceId, featureId)` pair.
|
|
160
|
+
* @experimental
|
|
161
|
+
*/
|
|
114
162
|
interface UsageEvent {
|
|
115
163
|
readonly createdAt: number;
|
|
116
164
|
readonly featureId: string;
|
|
@@ -122,7 +170,10 @@ interface UsageEvent {
|
|
|
122
170
|
/** Whether the event was successfully forwarded to the provider's metering API. */
|
|
123
171
|
readonly reportedToProvider: boolean;
|
|
124
172
|
}
|
|
125
|
-
/**
|
|
173
|
+
/**
|
|
174
|
+
* `track` input — record metered usage for a reference's feature.
|
|
175
|
+
* @experimental
|
|
176
|
+
*/
|
|
126
177
|
interface TrackInput {
|
|
127
178
|
readonly featureId: string;
|
|
128
179
|
/** Caller-supplied dedupe key; a fresh one is generated when omitted (so each call records). */
|
|
@@ -138,7 +189,10 @@ interface TrackInput {
|
|
|
138
189
|
readonly quantity?: number;
|
|
139
190
|
readonly referenceId: string;
|
|
140
191
|
}
|
|
141
|
-
/**
|
|
192
|
+
/**
|
|
193
|
+
* Result of a `track` call.
|
|
194
|
+
* @experimental
|
|
195
|
+
*/
|
|
142
196
|
interface TrackResult {
|
|
143
197
|
/** True when this call inserted a new usage event; false when deduplicated by idempotency key. */
|
|
144
198
|
readonly recorded: boolean;
|
|
@@ -148,6 +202,7 @@ interface TrackResult {
|
|
|
148
202
|
/**
|
|
149
203
|
* `check` input — is a reference allowed something right now? Pass `featureId` to check a feature
|
|
150
204
|
* grant/allowance, or `priceId` to check active access to a product (one of the two is required).
|
|
205
|
+
* @experimental
|
|
151
206
|
*/
|
|
152
207
|
interface CheckInput {
|
|
153
208
|
/** Feature to check a grant/allowance for. Provide this **or** `priceId`. */
|
|
@@ -158,7 +213,10 @@ interface CheckInput {
|
|
|
158
213
|
readonly quantity?: number;
|
|
159
214
|
readonly referenceId: string;
|
|
160
215
|
}
|
|
161
|
-
/**
|
|
216
|
+
/**
|
|
217
|
+
* Result of a `check` call.
|
|
218
|
+
* @experimental
|
|
219
|
+
*/
|
|
162
220
|
interface CheckResult {
|
|
163
221
|
/** Whether the reference may consume `quantity` units of the feature right now. */
|
|
164
222
|
readonly allowed: boolean;
|
|
@@ -171,11 +229,17 @@ interface CheckResult {
|
|
|
171
229
|
/** Usage consumed this period, for metered features only. */
|
|
172
230
|
readonly used?: number;
|
|
173
231
|
}
|
|
174
|
-
/**
|
|
232
|
+
/**
|
|
233
|
+
* One feature's resolved allowance for a reference — a {@link CheckResult} tagged with its feature.
|
|
234
|
+
* @experimental
|
|
235
|
+
*/
|
|
175
236
|
interface FeatureBalance extends CheckResult {
|
|
176
237
|
readonly featureId: string;
|
|
177
238
|
}
|
|
178
|
-
/**
|
|
239
|
+
/**
|
|
240
|
+
* Input the adapter forwards to the provider's metering API (Stripe Meter Events / Polar ingestion).
|
|
241
|
+
* @experimental
|
|
242
|
+
*/
|
|
179
243
|
interface ReportUsageInput {
|
|
180
244
|
/** Provider customer id, when known (Stripe meter events key on it). */
|
|
181
245
|
readonly customerId?: string;
|
|
@@ -186,12 +250,20 @@ interface ReportUsageInput {
|
|
|
186
250
|
/** Event time in epoch ms; defaults to now at the provider. */
|
|
187
251
|
readonly timestamp?: number;
|
|
188
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* `CaptureInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
255
|
+
* @experimental
|
|
256
|
+
*/
|
|
189
257
|
interface CaptureInput {
|
|
190
258
|
/** Partial capture amount; full capture when omitted. */
|
|
191
259
|
readonly amount?: Money;
|
|
192
260
|
readonly idempotencyKey?: string;
|
|
193
261
|
readonly sessionId: string;
|
|
194
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* `RefundInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
265
|
+
* @experimental
|
|
266
|
+
*/
|
|
195
267
|
interface RefundInput {
|
|
196
268
|
/** Partial refund amount; full refund when omitted. */
|
|
197
269
|
readonly amount?: Money;
|
|
@@ -199,16 +271,27 @@ interface RefundInput {
|
|
|
199
271
|
readonly reason?: string;
|
|
200
272
|
readonly sessionId: string;
|
|
201
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* `CancelSubscriptionOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
276
|
+
* @experimental
|
|
277
|
+
*/
|
|
202
278
|
interface CancelSubscriptionOptions {
|
|
203
279
|
/** Cancel at period end instead of immediately. */
|
|
204
280
|
readonly atPeriodEnd?: boolean;
|
|
205
281
|
readonly idempotencyKey?: string;
|
|
206
282
|
}
|
|
283
|
+
/**
|
|
284
|
+
* `SubscriptionPatch` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
285
|
+
* @experimental
|
|
286
|
+
*/
|
|
207
287
|
interface SubscriptionPatch {
|
|
208
288
|
readonly priceId?: string;
|
|
209
289
|
readonly quantity?: number;
|
|
210
290
|
}
|
|
211
|
-
/**
|
|
291
|
+
/**
|
|
292
|
+
* Normalized webhook outcome — the *core state transition* a provider event implies.
|
|
293
|
+
* @experimental
|
|
294
|
+
*/
|
|
212
295
|
type WebhookActionType = "payment.authorized" | "payment.captured" | "payment.failed" | "payment.refunded" | "subscription.active" | "subscription.canceled" | "subscription.past_due" | "subscription.paused" | "subscription.updated" | "unhandled";
|
|
213
296
|
/**
|
|
214
297
|
* How a refund action's {@link WebhookAction.amount} should be interpreted by the sync layer.
|
|
@@ -220,8 +303,13 @@ type WebhookActionType = "payment.authorized" | "payment.captured" | "payment.fa
|
|
|
220
303
|
* rather than adding, so repeated partial-refund events do not over-count.
|
|
221
304
|
*
|
|
222
305
|
* Omitted means `"delta"`, preserving the original behavior for callers that predate this field.
|
|
306
|
+
* @experimental
|
|
223
307
|
*/
|
|
224
308
|
type RefundAmountKind = "absolute" | "delta";
|
|
309
|
+
/**
|
|
310
|
+
* `WebhookAction` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
311
|
+
* @experimental
|
|
312
|
+
*/
|
|
225
313
|
interface WebhookAction {
|
|
226
314
|
readonly amount?: Money;
|
|
227
315
|
/**
|
|
@@ -245,15 +333,25 @@ interface WebhookAction {
|
|
|
245
333
|
readonly subscriptionId?: string;
|
|
246
334
|
readonly type: WebhookActionType;
|
|
247
335
|
}
|
|
248
|
-
/**
|
|
336
|
+
/**
|
|
337
|
+
* Result of applying a webhook action to the store.
|
|
338
|
+
* @experimental
|
|
339
|
+
*/
|
|
249
340
|
interface ApplyResult {
|
|
250
341
|
readonly applied: boolean;
|
|
251
342
|
readonly reason?: "duplicate" | "illegal_transition" | "invalid_refund_amount" | "ok" | "unhandled";
|
|
252
343
|
}
|
|
253
|
-
/**
|
|
344
|
+
/**
|
|
345
|
+
* A read-only header bag; the platform `Headers` object satisfies it.
|
|
346
|
+
* @experimental
|
|
347
|
+
*/
|
|
254
348
|
interface WebhookHeaders {
|
|
255
349
|
get: (name: string) => null | string;
|
|
256
350
|
}
|
|
351
|
+
/**
|
|
352
|
+
* `WebhookInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
353
|
+
* @experimental
|
|
354
|
+
*/
|
|
257
355
|
interface WebhookInput {
|
|
258
356
|
/** Request headers (signature schemes read provider-specific headers from here). */
|
|
259
357
|
readonly headers: WebhookHeaders;
|
|
@@ -265,6 +363,7 @@ interface WebhookInput {
|
|
|
265
363
|
*
|
|
266
364
|
* Adapters never own state — they make provider calls and normalize provider events into a
|
|
267
365
|
* `WebhookAction`. All durable state lives in the payment store.
|
|
366
|
+
* @experimental
|
|
268
367
|
*/
|
|
269
368
|
interface PaymentAdapter {
|
|
270
369
|
cancelPayment: (sessionId: string, options?: {
|
|
@@ -311,11 +410,18 @@ interface PaymentAdapter {
|
|
|
311
410
|
resumeSubscription: (subscriptionId: string) => Promise<Subscription>;
|
|
312
411
|
updateSubscription: (subscriptionId: string, patch: SubscriptionPatch) => Promise<Subscription>;
|
|
313
412
|
}
|
|
314
|
-
/**
|
|
413
|
+
/**
|
|
414
|
+
* Registry of adapters keyed by provider id — supports dual-register during provider migration.
|
|
415
|
+
* @experimental
|
|
416
|
+
*/
|
|
315
417
|
interface AdapterRegistry {
|
|
316
418
|
all: () => PaymentAdapter[];
|
|
317
419
|
get: (provider: ProviderId) => PaymentAdapter;
|
|
318
420
|
has: (provider: ProviderId) => boolean;
|
|
319
421
|
}
|
|
422
|
+
/**
|
|
423
|
+
* `createAdapterRegistry` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
424
|
+
* @experimental
|
|
425
|
+
*/
|
|
320
426
|
declare const createAdapterRegistry: (adapters: ReadonlyArray<PaymentAdapter>) => AdapterRegistry;
|
|
321
427
|
export { ApplyResult as A, Customer as C, FeatureBalance as F, Money as M, PaymentAdapter as P, RefundAmountKind as R, Subscription as S, TrackInput as T, UsageEvent as U, WebhookActionType as W, ProviderId as a, PaymentSession as b, AttachInput as c, CheckoutResult as d, CancelSubscriptionOptions as e, CheckInput as f, CheckResult as g, CheckoutInput as h, TrackResult as i, CurrencyCode as j, PaymentState as k, SubscriptionState as l, WebhookAction as m, AdapterRegistry as n, CaptureInput as o, CustomerRef as p, PortalInput as q, ProviderCapabilities as r, RefundInput as s, ReportUsageInput as t, SubscriptionPatch as u, WebhookHeaders as v, WebhookInput as w, createAdapterRegistry as x };
|
|
@@ -4,21 +4,31 @@
|
|
|
4
4
|
* The provider is a stateless translator; the store owns all state. These types are the
|
|
5
5
|
* provider-agnostic vocabulary every adapter normalizes onto.
|
|
6
6
|
*/
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* ISO-4217 currency code (uppercase, 3 letters). Not enumerated — provider coverage varies.
|
|
9
|
+
* @experimental
|
|
10
|
+
*/
|
|
8
11
|
type CurrencyCode = string;
|
|
9
12
|
/**
|
|
10
13
|
* Money as integer minor units + currency. Always carry the two together.
|
|
11
14
|
*
|
|
12
15
|
* `minorUnits` is a `bigint`, which is **not** JSON-serializable — cross the RPC/wire boundary
|
|
13
16
|
* with the `toMoneyJSON` / `fromMoneyJSON` helpers (see `./money`).
|
|
17
|
+
* @experimental
|
|
14
18
|
*/
|
|
15
19
|
interface Money {
|
|
16
20
|
readonly currency: CurrencyCode;
|
|
17
21
|
readonly minorUnits: bigint;
|
|
18
22
|
}
|
|
19
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Stable provider identifier (Medusa-style). Ships Stripe/Polar/Autumn/Dodo plus Creem, an EU-friendly MoR.
|
|
25
|
+
* @experimental
|
|
26
|
+
*/
|
|
20
27
|
type ProviderId = "autumn" | "creem" | "dodopayments" | "polar" | "stripe";
|
|
21
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* What a provider can do — encoded in types so tax/UX assumptions aren't tribal knowledge.
|
|
30
|
+
* @experimental
|
|
31
|
+
*/
|
|
22
32
|
interface ProviderCapabilities {
|
|
23
33
|
/** True for Polar / Lemon Squeezy / Paddle; false for Stripe (PSP) and Autumn (runs on your own Stripe). Drives tax/invoice ownership. */
|
|
24
34
|
readonly merchantOfRecord: boolean;
|
|
@@ -27,10 +37,20 @@ interface ProviderCapabilities {
|
|
|
27
37
|
/** Usage-based / metered billing. */
|
|
28
38
|
readonly usageMetering: boolean;
|
|
29
39
|
}
|
|
30
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* Lifecycle state of a one-time payment session.
|
|
42
|
+
* @experimental
|
|
43
|
+
*/
|
|
31
44
|
type PaymentState = "authorized" | "canceled" | "captured" | "failed" | "initiated" | "partially_refunded" | "refunded";
|
|
32
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* Lifecycle state of a subscription.
|
|
47
|
+
* @experimental
|
|
48
|
+
*/
|
|
33
49
|
type SubscriptionState = "active" | "canceled" | "past_due" | "paused" | "trialing";
|
|
50
|
+
/**
|
|
51
|
+
* `Customer` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
52
|
+
* @experimental
|
|
53
|
+
*/
|
|
34
54
|
interface Customer {
|
|
35
55
|
readonly createdAt: number;
|
|
36
56
|
readonly email?: string;
|
|
@@ -40,6 +60,10 @@ interface Customer {
|
|
|
40
60
|
/** App-side owner the customer belongs to (user / org / workspace). Opaque to this package. */
|
|
41
61
|
readonly referenceId: string;
|
|
42
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* `PaymentSession` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
65
|
+
* @experimental
|
|
66
|
+
*/
|
|
43
67
|
interface PaymentSession {
|
|
44
68
|
readonly amount: Money;
|
|
45
69
|
readonly capturedAmount: Money;
|
|
@@ -52,6 +76,10 @@ interface PaymentSession {
|
|
|
52
76
|
readonly state: PaymentState;
|
|
53
77
|
readonly updatedAt: number;
|
|
54
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* `Subscription` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
81
|
+
* @experimental
|
|
82
|
+
*/
|
|
55
83
|
interface Subscription {
|
|
56
84
|
readonly cancelAtPeriodEnd: boolean;
|
|
57
85
|
readonly createdAt: number;
|
|
@@ -66,11 +94,19 @@ interface Subscription {
|
|
|
66
94
|
readonly state: SubscriptionState;
|
|
67
95
|
readonly updatedAt: number;
|
|
68
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* `CustomerRef` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
99
|
+
* @experimental
|
|
100
|
+
*/
|
|
69
101
|
interface CustomerRef {
|
|
70
102
|
readonly email?: string;
|
|
71
103
|
readonly metadata?: Record<string, string>;
|
|
72
104
|
readonly referenceId: string;
|
|
73
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* `CheckoutInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
108
|
+
* @experimental
|
|
109
|
+
*/
|
|
74
110
|
interface CheckoutInput {
|
|
75
111
|
readonly cancelUrl: string;
|
|
76
112
|
/**
|
|
@@ -93,6 +129,10 @@ interface CheckoutInput {
|
|
|
93
129
|
readonly referenceId: string;
|
|
94
130
|
readonly successUrl: string;
|
|
95
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* `CheckoutResult` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
134
|
+
* @experimental
|
|
135
|
+
*/
|
|
96
136
|
interface CheckoutResult {
|
|
97
137
|
readonly id: string;
|
|
98
138
|
readonly provider: ProviderId;
|
|
@@ -102,15 +142,23 @@ interface CheckoutResult {
|
|
|
102
142
|
* `attach` input — subscribe a reference to a plan. A thin, plan-oriented skin over
|
|
103
143
|
* {@link CheckoutInput}: `mode` defaults to `"subscription"` (the common case), so callers pass
|
|
104
144
|
* just `{ referenceId, priceId, successUrl, cancelUrl }`.
|
|
145
|
+
* @experimental
|
|
105
146
|
*/
|
|
106
147
|
interface AttachInput extends Omit<CheckoutInput, "mode"> {
|
|
107
148
|
readonly mode?: CheckoutInput["mode"];
|
|
108
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* `PortalInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
152
|
+
* @experimental
|
|
153
|
+
*/
|
|
109
154
|
interface PortalInput {
|
|
110
155
|
readonly customerId: string;
|
|
111
156
|
readonly returnUrl: string;
|
|
112
157
|
}
|
|
113
|
-
/**
|
|
158
|
+
/**
|
|
159
|
+
* A single durable usage record — one metered event for a `(referenceId, featureId)` pair.
|
|
160
|
+
* @experimental
|
|
161
|
+
*/
|
|
114
162
|
interface UsageEvent {
|
|
115
163
|
readonly createdAt: number;
|
|
116
164
|
readonly featureId: string;
|
|
@@ -122,7 +170,10 @@ interface UsageEvent {
|
|
|
122
170
|
/** Whether the event was successfully forwarded to the provider's metering API. */
|
|
123
171
|
readonly reportedToProvider: boolean;
|
|
124
172
|
}
|
|
125
|
-
/**
|
|
173
|
+
/**
|
|
174
|
+
* `track` input — record metered usage for a reference's feature.
|
|
175
|
+
* @experimental
|
|
176
|
+
*/
|
|
126
177
|
interface TrackInput {
|
|
127
178
|
readonly featureId: string;
|
|
128
179
|
/** Caller-supplied dedupe key; a fresh one is generated when omitted (so each call records). */
|
|
@@ -138,7 +189,10 @@ interface TrackInput {
|
|
|
138
189
|
readonly quantity?: number;
|
|
139
190
|
readonly referenceId: string;
|
|
140
191
|
}
|
|
141
|
-
/**
|
|
192
|
+
/**
|
|
193
|
+
* Result of a `track` call.
|
|
194
|
+
* @experimental
|
|
195
|
+
*/
|
|
142
196
|
interface TrackResult {
|
|
143
197
|
/** True when this call inserted a new usage event; false when deduplicated by idempotency key. */
|
|
144
198
|
readonly recorded: boolean;
|
|
@@ -148,6 +202,7 @@ interface TrackResult {
|
|
|
148
202
|
/**
|
|
149
203
|
* `check` input — is a reference allowed something right now? Pass `featureId` to check a feature
|
|
150
204
|
* grant/allowance, or `priceId` to check active access to a product (one of the two is required).
|
|
205
|
+
* @experimental
|
|
151
206
|
*/
|
|
152
207
|
interface CheckInput {
|
|
153
208
|
/** Feature to check a grant/allowance for. Provide this **or** `priceId`. */
|
|
@@ -158,7 +213,10 @@ interface CheckInput {
|
|
|
158
213
|
readonly quantity?: number;
|
|
159
214
|
readonly referenceId: string;
|
|
160
215
|
}
|
|
161
|
-
/**
|
|
216
|
+
/**
|
|
217
|
+
* Result of a `check` call.
|
|
218
|
+
* @experimental
|
|
219
|
+
*/
|
|
162
220
|
interface CheckResult {
|
|
163
221
|
/** Whether the reference may consume `quantity` units of the feature right now. */
|
|
164
222
|
readonly allowed: boolean;
|
|
@@ -171,11 +229,17 @@ interface CheckResult {
|
|
|
171
229
|
/** Usage consumed this period, for metered features only. */
|
|
172
230
|
readonly used?: number;
|
|
173
231
|
}
|
|
174
|
-
/**
|
|
232
|
+
/**
|
|
233
|
+
* One feature's resolved allowance for a reference — a {@link CheckResult} tagged with its feature.
|
|
234
|
+
* @experimental
|
|
235
|
+
*/
|
|
175
236
|
interface FeatureBalance extends CheckResult {
|
|
176
237
|
readonly featureId: string;
|
|
177
238
|
}
|
|
178
|
-
/**
|
|
239
|
+
/**
|
|
240
|
+
* Input the adapter forwards to the provider's metering API (Stripe Meter Events / Polar ingestion).
|
|
241
|
+
* @experimental
|
|
242
|
+
*/
|
|
179
243
|
interface ReportUsageInput {
|
|
180
244
|
/** Provider customer id, when known (Stripe meter events key on it). */
|
|
181
245
|
readonly customerId?: string;
|
|
@@ -186,12 +250,20 @@ interface ReportUsageInput {
|
|
|
186
250
|
/** Event time in epoch ms; defaults to now at the provider. */
|
|
187
251
|
readonly timestamp?: number;
|
|
188
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* `CaptureInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
255
|
+
* @experimental
|
|
256
|
+
*/
|
|
189
257
|
interface CaptureInput {
|
|
190
258
|
/** Partial capture amount; full capture when omitted. */
|
|
191
259
|
readonly amount?: Money;
|
|
192
260
|
readonly idempotencyKey?: string;
|
|
193
261
|
readonly sessionId: string;
|
|
194
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* `RefundInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
265
|
+
* @experimental
|
|
266
|
+
*/
|
|
195
267
|
interface RefundInput {
|
|
196
268
|
/** Partial refund amount; full refund when omitted. */
|
|
197
269
|
readonly amount?: Money;
|
|
@@ -199,16 +271,27 @@ interface RefundInput {
|
|
|
199
271
|
readonly reason?: string;
|
|
200
272
|
readonly sessionId: string;
|
|
201
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* `CancelSubscriptionOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
276
|
+
* @experimental
|
|
277
|
+
*/
|
|
202
278
|
interface CancelSubscriptionOptions {
|
|
203
279
|
/** Cancel at period end instead of immediately. */
|
|
204
280
|
readonly atPeriodEnd?: boolean;
|
|
205
281
|
readonly idempotencyKey?: string;
|
|
206
282
|
}
|
|
283
|
+
/**
|
|
284
|
+
* `SubscriptionPatch` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
285
|
+
* @experimental
|
|
286
|
+
*/
|
|
207
287
|
interface SubscriptionPatch {
|
|
208
288
|
readonly priceId?: string;
|
|
209
289
|
readonly quantity?: number;
|
|
210
290
|
}
|
|
211
|
-
/**
|
|
291
|
+
/**
|
|
292
|
+
* Normalized webhook outcome — the *core state transition* a provider event implies.
|
|
293
|
+
* @experimental
|
|
294
|
+
*/
|
|
212
295
|
type WebhookActionType = "payment.authorized" | "payment.captured" | "payment.failed" | "payment.refunded" | "subscription.active" | "subscription.canceled" | "subscription.past_due" | "subscription.paused" | "subscription.updated" | "unhandled";
|
|
213
296
|
/**
|
|
214
297
|
* How a refund action's {@link WebhookAction.amount} should be interpreted by the sync layer.
|
|
@@ -220,8 +303,13 @@ type WebhookActionType = "payment.authorized" | "payment.captured" | "payment.fa
|
|
|
220
303
|
* rather than adding, so repeated partial-refund events do not over-count.
|
|
221
304
|
*
|
|
222
305
|
* Omitted means `"delta"`, preserving the original behavior for callers that predate this field.
|
|
306
|
+
* @experimental
|
|
223
307
|
*/
|
|
224
308
|
type RefundAmountKind = "absolute" | "delta";
|
|
309
|
+
/**
|
|
310
|
+
* `WebhookAction` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
311
|
+
* @experimental
|
|
312
|
+
*/
|
|
225
313
|
interface WebhookAction {
|
|
226
314
|
readonly amount?: Money;
|
|
227
315
|
/**
|
|
@@ -245,15 +333,25 @@ interface WebhookAction {
|
|
|
245
333
|
readonly subscriptionId?: string;
|
|
246
334
|
readonly type: WebhookActionType;
|
|
247
335
|
}
|
|
248
|
-
/**
|
|
336
|
+
/**
|
|
337
|
+
* Result of applying a webhook action to the store.
|
|
338
|
+
* @experimental
|
|
339
|
+
*/
|
|
249
340
|
interface ApplyResult {
|
|
250
341
|
readonly applied: boolean;
|
|
251
342
|
readonly reason?: "duplicate" | "illegal_transition" | "invalid_refund_amount" | "ok" | "unhandled";
|
|
252
343
|
}
|
|
253
|
-
/**
|
|
344
|
+
/**
|
|
345
|
+
* A read-only header bag; the platform `Headers` object satisfies it.
|
|
346
|
+
* @experimental
|
|
347
|
+
*/
|
|
254
348
|
interface WebhookHeaders {
|
|
255
349
|
get: (name: string) => null | string;
|
|
256
350
|
}
|
|
351
|
+
/**
|
|
352
|
+
* `WebhookInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
353
|
+
* @experimental
|
|
354
|
+
*/
|
|
257
355
|
interface WebhookInput {
|
|
258
356
|
/** Request headers (signature schemes read provider-specific headers from here). */
|
|
259
357
|
readonly headers: WebhookHeaders;
|
|
@@ -265,6 +363,7 @@ interface WebhookInput {
|
|
|
265
363
|
*
|
|
266
364
|
* Adapters never own state — they make provider calls and normalize provider events into a
|
|
267
365
|
* `WebhookAction`. All durable state lives in the payment store.
|
|
366
|
+
* @experimental
|
|
268
367
|
*/
|
|
269
368
|
interface PaymentAdapter {
|
|
270
369
|
cancelPayment: (sessionId: string, options?: {
|
|
@@ -311,11 +410,18 @@ interface PaymentAdapter {
|
|
|
311
410
|
resumeSubscription: (subscriptionId: string) => Promise<Subscription>;
|
|
312
411
|
updateSubscription: (subscriptionId: string, patch: SubscriptionPatch) => Promise<Subscription>;
|
|
313
412
|
}
|
|
314
|
-
/**
|
|
413
|
+
/**
|
|
414
|
+
* Registry of adapters keyed by provider id — supports dual-register during provider migration.
|
|
415
|
+
* @experimental
|
|
416
|
+
*/
|
|
315
417
|
interface AdapterRegistry {
|
|
316
418
|
all: () => PaymentAdapter[];
|
|
317
419
|
get: (provider: ProviderId) => PaymentAdapter;
|
|
318
420
|
has: (provider: ProviderId) => boolean;
|
|
319
421
|
}
|
|
422
|
+
/**
|
|
423
|
+
* `createAdapterRegistry` is part of the experimental `@lunora/payment` API and may change without a major version bump.
|
|
424
|
+
* @experimental
|
|
425
|
+
*/
|
|
320
426
|
declare const createAdapterRegistry: (adapters: ReadonlyArray<PaymentAdapter>) => AdapterRegistry;
|
|
321
427
|
export { ApplyResult as A, Customer as C, FeatureBalance as F, Money as M, PaymentAdapter as P, RefundAmountKind as R, Subscription as S, TrackInput as T, UsageEvent as U, WebhookActionType as W, ProviderId as a, PaymentSession as b, AttachInput as c, CheckoutResult as d, CancelSubscriptionOptions as e, CheckInput as f, CheckResult as g, CheckoutInput as h, TrackResult as i, CurrencyCode as j, PaymentState as k, SubscriptionState as l, WebhookAction as m, AdapterRegistry as n, CaptureInput as o, CustomerRef as p, PortalInput as q, ProviderCapabilities as r, RefundInput as s, ReportUsageInput as t, SubscriptionPatch as u, WebhookHeaders as v, WebhookInput as w, createAdapterRegistry as x };
|