@lunora/payment 1.0.0-alpha.16 → 1.0.0-alpha.18
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/LICENSE.md +6 -0
- package/README.md +3 -2
- package/dist/index.d.mts +17 -456
- package/dist/index.d.ts +17 -456
- package/dist/index.mjs +3 -5
- package/dist/packem_shared/adapter.d-iFA55DzU.d.mts +312 -0
- package/dist/packem_shared/adapter.d-iFA55DzU.d.ts +312 -0
- package/dist/packem_shared/{constantTimeEqual-BN5Hm31G.mjs → constantTimeEqual-BQjoW85H.mjs} +13 -37
- package/dist/packem_shared/{createPayment-DP_LO7jc.mjs → createPayment-DzX-ji34.mjs} +15 -3
- package/dist/packem_shared/json-DhcPm8EO.mjs +11 -0
- package/dist/packem_shared/{lunoraDatabaseToPaymentDatabase-CQQlnRCJ.mjs → lunoraDatabaseToPaymentDatabase-CL2vdAXq.mjs} +1 -1
- package/dist/packem_shared/not-supported-C0onRyia.mjs +7 -0
- package/dist/packem_shared/subscription-event-CwEsWRCK.mjs +17 -0
- package/dist/providers/autumn-features.d.mts +94 -0
- package/dist/providers/autumn-features.d.ts +94 -0
- package/dist/providers/autumn-features.mjs +95 -0
- package/dist/providers/autumn.d.mts +19 -0
- package/dist/providers/autumn.d.ts +19 -0
- package/dist/providers/autumn.mjs +294 -0
- package/dist/providers/creem.d.mts +17 -0
- package/dist/providers/creem.d.ts +17 -0
- package/dist/providers/creem.mjs +205 -0
- package/dist/providers/dodopayments.d.mts +21 -0
- package/dist/providers/dodopayments.d.ts +21 -0
- package/dist/providers/dodopayments.mjs +259 -0
- package/dist/providers/polar.d.mts +22 -0
- package/dist/providers/polar.d.ts +22 -0
- package/dist/{packem_shared/createPolarAdapter-BovYiWCX.mjs → providers/polar.mjs} +47 -46
- package/dist/providers/stripe.d.mts +23 -0
- package/dist/providers/stripe.d.ts +23 -0
- package/dist/{packem_shared/createStripeAdapter-4a7fej3t.mjs → providers/stripe.mjs} +45 -53
- package/package.json +45 -5
- package/dist/packem_shared/json-Db337f36.mjs +0 -6
package/LICENSE.md
CHANGED
|
@@ -103,3 +103,9 @@ Unless required by applicable law or agreed to in writing, software distributed
|
|
|
103
103
|
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
104
104
|
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
105
105
|
specific language governing permissions and limitations under the License.
|
|
106
|
+
|
|
107
|
+
<!-- DEPENDENCIES -->
|
|
108
|
+
<!-- /DEPENDENCIES -->
|
|
109
|
+
|
|
110
|
+
<!-- TYPE_DEPENDENCIES -->
|
|
111
|
+
<!-- /TYPE_DEPENDENCIES -->
|
package/README.md
CHANGED
|
@@ -46,14 +46,15 @@ Part of the [Lunora](https://github.com/anolilab/lunora) framework — a type-sa
|
|
|
46
46
|
pnpm add @lunora/payment stripe
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
`stripe` is an optional peer dependency — install only the provider SDK you use; the adapter takes the client by injection.
|
|
49
|
+
`stripe` is an optional peer dependency — install only the provider SDK you use; the adapter takes the client by injection. The same holds for the other providers: `createPolarAdapter` (Polar), `createAutumnAdapter` ([Autumn](https://useautumn.com)), `createDodoPaymentsAdapter` ([Dodo Payments](https://dodopayments.com)), and `createCreemAdapter` ([Creem](https://creem.io)) take a structural client too, so no provider SDK is a hard dependency of this package. Additional providers plug in via `PaymentAdapter`.
|
|
50
50
|
|
|
51
51
|
## Usage
|
|
52
52
|
|
|
53
53
|
Build a facade from an adapter and a store, then start a hosted checkout:
|
|
54
54
|
|
|
55
55
|
```ts
|
|
56
|
-
import { createPayment,
|
|
56
|
+
import { createPayment, MemoryPaymentStore } from "@lunora/payment";
|
|
57
|
+
import { createStripeAdapter } from "@lunora/payment/stripe";
|
|
57
58
|
import Stripe from "stripe";
|
|
58
59
|
|
|
59
60
|
const payment = createPayment({
|
package/dist/index.d.mts
CHANGED
|
@@ -1,296 +1,7 @@
|
|
|
1
|
+
import { a as ProviderId, C as Customer, b as PaymentSession, S as Subscription, U as UsageEvent, W as WebhookActionType, A as ApplyResult, P as PaymentAdapter, c as AttachInput, d as CheckoutResult, e as CancelSubscriptionOptions, f as CheckInput, g as CheckResult, h as CheckoutInput, F as FeatureBalance, T as TrackInput, i as TrackResult, j as CurrencyCode, M as Money, k as PaymentState, l as SubscriptionState, m as WebhookAction } from "./packem_shared/adapter.d-iFA55DzU.mjs";
|
|
2
|
+
export { type n as AdapterRegistry, type o as CaptureInput, type p as CustomerRef, type q as PortalInput, type r as ProviderCapabilities, type R as RefundAmountKind, type s as RefundInput, type t as ReportUsageInput, type u as SubscriptionPatch, type v as WebhookHeaders, type w as WebhookInput, x as createAdapterRegistry } from "./packem_shared/adapter.d-iFA55DzU.mjs";
|
|
1
3
|
import { LunoraError } from '@lunora/errors';
|
|
2
4
|
import { TableDefinition } from '@lunora/server';
|
|
3
|
-
/**
|
|
4
|
-
* Core domain types for `@lunora/payment`.
|
|
5
|
-
*
|
|
6
|
-
* The provider is a stateless translator; the store owns all state. These types are the
|
|
7
|
-
* provider-agnostic vocabulary every adapter normalizes onto.
|
|
8
|
-
*/
|
|
9
|
-
/** ISO-4217 currency code (uppercase, 3 letters). Not enumerated — provider coverage varies. */
|
|
10
|
-
type CurrencyCode = string;
|
|
11
|
-
/**
|
|
12
|
-
* Money as integer minor units + currency. Always carry the two together.
|
|
13
|
-
*
|
|
14
|
-
* `minorUnits` is a `bigint`, which is **not** JSON-serializable — cross the RPC/wire boundary
|
|
15
|
-
* with the `toMoneyJSON` / `fromMoneyJSON` helpers (see `./money`).
|
|
16
|
-
*/
|
|
17
|
-
interface Money {
|
|
18
|
-
readonly currency: CurrencyCode;
|
|
19
|
-
readonly minorUnits: bigint;
|
|
20
|
-
}
|
|
21
|
-
/** Stable provider identifier (Medusa-style). Scoped to what Convex ships: Stripe + Polar. */
|
|
22
|
-
type ProviderId = "polar" | "stripe";
|
|
23
|
-
/** What a provider can do — encoded in types so tax/UX assumptions aren't tribal knowledge. */
|
|
24
|
-
interface ProviderCapabilities {
|
|
25
|
-
/** True for Polar / Lemon Squeezy / Paddle; false for Stripe (PSP). Drives tax/invoice ownership. */
|
|
26
|
-
readonly merchantOfRecord: boolean;
|
|
27
|
-
/** Native hosted customer/billing portal. */
|
|
28
|
-
readonly portal: boolean;
|
|
29
|
-
/** Usage-based / metered billing. */
|
|
30
|
-
readonly usageMetering: boolean;
|
|
31
|
-
}
|
|
32
|
-
/** Lifecycle state of a one-time payment session. */
|
|
33
|
-
type PaymentState = "authorized" | "canceled" | "captured" | "failed" | "initiated" | "partially_refunded" | "refunded";
|
|
34
|
-
/** Lifecycle state of a subscription. */
|
|
35
|
-
type SubscriptionState = "active" | "canceled" | "past_due" | "paused" | "trialing";
|
|
36
|
-
interface Customer {
|
|
37
|
-
readonly createdAt: number;
|
|
38
|
-
readonly email?: string;
|
|
39
|
-
/** Provider-side customer id. */
|
|
40
|
-
readonly id: string;
|
|
41
|
-
readonly provider: ProviderId;
|
|
42
|
-
/** App-side owner the customer belongs to (user / org / workspace). Opaque to this package. */
|
|
43
|
-
readonly referenceId: string;
|
|
44
|
-
}
|
|
45
|
-
interface PaymentSession {
|
|
46
|
-
readonly amount: Money;
|
|
47
|
-
readonly capturedAmount: Money;
|
|
48
|
-
readonly createdAt: number;
|
|
49
|
-
/** Provider-side payment / intent / session id. */
|
|
50
|
-
readonly id: string;
|
|
51
|
-
readonly provider: ProviderId;
|
|
52
|
-
readonly referenceId: string;
|
|
53
|
-
readonly refundedAmount: Money;
|
|
54
|
-
readonly state: PaymentState;
|
|
55
|
-
readonly updatedAt: number;
|
|
56
|
-
}
|
|
57
|
-
interface Subscription {
|
|
58
|
-
readonly cancelAtPeriodEnd: boolean;
|
|
59
|
-
readonly createdAt: number;
|
|
60
|
-
readonly currentPeriodEnd?: number;
|
|
61
|
-
/** Start of the current billing period — the window `check` sums metered usage over. */
|
|
62
|
-
readonly currentPeriodStart?: number;
|
|
63
|
-
readonly id: string;
|
|
64
|
-
readonly priceId: string;
|
|
65
|
-
readonly provider: ProviderId;
|
|
66
|
-
readonly quantity: number;
|
|
67
|
-
readonly referenceId: string;
|
|
68
|
-
readonly state: SubscriptionState;
|
|
69
|
-
readonly updatedAt: number;
|
|
70
|
-
}
|
|
71
|
-
interface CustomerRef {
|
|
72
|
-
readonly email?: string;
|
|
73
|
-
readonly metadata?: Record<string, string>;
|
|
74
|
-
readonly referenceId: string;
|
|
75
|
-
}
|
|
76
|
-
interface CheckoutInput {
|
|
77
|
-
readonly cancelUrl: string;
|
|
78
|
-
/** Existing provider customer id, if known. */
|
|
79
|
-
readonly customerId?: string;
|
|
80
|
-
/** Outbound idempotency key for the provider call; auto-derived when omitted. */
|
|
81
|
-
readonly idempotencyKey?: string;
|
|
82
|
-
readonly metadata?: Record<string, string>;
|
|
83
|
-
readonly mode: "payment" | "subscription";
|
|
84
|
-
readonly priceId: string;
|
|
85
|
-
readonly quantity?: number;
|
|
86
|
-
readonly referenceId: string;
|
|
87
|
-
readonly successUrl: string;
|
|
88
|
-
}
|
|
89
|
-
interface CheckoutResult {
|
|
90
|
-
readonly id: string;
|
|
91
|
-
readonly provider: ProviderId;
|
|
92
|
-
readonly url: string;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* `attach` input — subscribe a reference to a plan. A thin, plan-oriented skin over
|
|
96
|
-
* {@link CheckoutInput}: `mode` defaults to `"subscription"` (the common case), so callers pass
|
|
97
|
-
* just `{ referenceId, priceId, successUrl, cancelUrl }`.
|
|
98
|
-
*/
|
|
99
|
-
interface AttachInput extends Omit<CheckoutInput, "mode"> {
|
|
100
|
-
readonly mode?: CheckoutInput["mode"];
|
|
101
|
-
}
|
|
102
|
-
interface PortalInput {
|
|
103
|
-
readonly customerId: string;
|
|
104
|
-
readonly returnUrl: string;
|
|
105
|
-
}
|
|
106
|
-
/** A single durable usage record — one metered event for a `(referenceId, featureId)` pair. */
|
|
107
|
-
interface UsageEvent {
|
|
108
|
-
readonly createdAt: number;
|
|
109
|
-
readonly featureId: string;
|
|
110
|
-
/** Caller-stable dedupe key — recording the same key twice is a no-op (exactly-once `track`). */
|
|
111
|
-
readonly idempotencyKey: string;
|
|
112
|
-
readonly provider: ProviderId;
|
|
113
|
-
readonly quantity: number;
|
|
114
|
-
readonly referenceId: string;
|
|
115
|
-
/** Whether the event was successfully forwarded to the provider's metering API. */
|
|
116
|
-
readonly reportedToProvider: boolean;
|
|
117
|
-
}
|
|
118
|
-
/** `track` input — record metered usage for a reference's feature. */
|
|
119
|
-
interface TrackInput {
|
|
120
|
-
readonly featureId: string;
|
|
121
|
-
/** Caller-supplied dedupe key; a fresh one is generated when omitted (so each call records). */
|
|
122
|
-
readonly idempotencyKey?: string;
|
|
123
|
-
/** `"add"` (default) increments usage by `quantity`; `"set"` reconciles the period total to `quantity`. */
|
|
124
|
-
readonly mode?: "add" | "set";
|
|
125
|
-
/** Usage amount to add, or the absolute period total when `mode` is `"set"` (defaults to `1`). */
|
|
126
|
-
readonly quantity?: number;
|
|
127
|
-
readonly referenceId: string;
|
|
128
|
-
}
|
|
129
|
-
/** Result of a `track` call. */
|
|
130
|
-
interface TrackResult {
|
|
131
|
-
/** True when this call inserted a new usage event; false when deduplicated by idempotency key. */
|
|
132
|
-
readonly recorded: boolean;
|
|
133
|
-
/** True when the event was forwarded to the provider's metering API. */
|
|
134
|
-
readonly reportedToProvider: boolean;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* `check` input — is a reference allowed something right now? Pass `featureId` to check a feature
|
|
138
|
-
* grant/allowance, or `priceId` to check active access to a product (one of the two is required).
|
|
139
|
-
*/
|
|
140
|
-
interface CheckInput {
|
|
141
|
-
/** Feature to check a grant/allowance for. Provide this **or** `priceId`. */
|
|
142
|
-
readonly featureId?: string;
|
|
143
|
-
/** Provider price/product id to check active access for. Provide this **or** `featureId`. */
|
|
144
|
-
readonly priceId?: string;
|
|
145
|
-
/** Units the caller intends to consume; the check passes only when this many remain (default `1`). */
|
|
146
|
-
readonly quantity?: number;
|
|
147
|
-
readonly referenceId: string;
|
|
148
|
-
}
|
|
149
|
-
/** Result of a `check` call. */
|
|
150
|
-
interface CheckResult {
|
|
151
|
-
/** Whether the reference may consume `quantity` units of the feature right now. */
|
|
152
|
-
readonly allowed: boolean;
|
|
153
|
-
/** Remaining units this period (`limit - used`), for metered features only. */
|
|
154
|
-
readonly balance?: number;
|
|
155
|
-
/** The plan-granted cap, for metered features only. */
|
|
156
|
-
readonly limit?: number;
|
|
157
|
-
/** True for a boolean feature granted without a numeric cap. */
|
|
158
|
-
readonly unlimited: boolean;
|
|
159
|
-
/** Usage consumed this period, for metered features only. */
|
|
160
|
-
readonly used?: number;
|
|
161
|
-
}
|
|
162
|
-
/** One feature's resolved allowance for a reference — a {@link CheckResult} tagged with its feature. */
|
|
163
|
-
interface FeatureBalance extends CheckResult {
|
|
164
|
-
readonly featureId: string;
|
|
165
|
-
}
|
|
166
|
-
/** Input the adapter forwards to the provider's metering API (Stripe Meter Events / Polar ingestion). */
|
|
167
|
-
interface ReportUsageInput {
|
|
168
|
-
/** Provider customer id, when known (Stripe meter events key on it). */
|
|
169
|
-
readonly customerId?: string;
|
|
170
|
-
readonly featureId: string;
|
|
171
|
-
readonly idempotencyKey: string;
|
|
172
|
-
readonly quantity: number;
|
|
173
|
-
readonly referenceId: string;
|
|
174
|
-
/** Event time in epoch ms; defaults to now at the provider. */
|
|
175
|
-
readonly timestamp?: number;
|
|
176
|
-
}
|
|
177
|
-
interface CaptureInput {
|
|
178
|
-
/** Partial capture amount; full capture when omitted. */
|
|
179
|
-
readonly amount?: Money;
|
|
180
|
-
readonly idempotencyKey?: string;
|
|
181
|
-
readonly sessionId: string;
|
|
182
|
-
}
|
|
183
|
-
interface RefundInput {
|
|
184
|
-
/** Partial refund amount; full refund when omitted. */
|
|
185
|
-
readonly amount?: Money;
|
|
186
|
-
readonly idempotencyKey?: string;
|
|
187
|
-
readonly reason?: string;
|
|
188
|
-
readonly sessionId: string;
|
|
189
|
-
}
|
|
190
|
-
interface CancelSubscriptionOptions {
|
|
191
|
-
/** Cancel at period end instead of immediately. */
|
|
192
|
-
readonly atPeriodEnd?: boolean;
|
|
193
|
-
readonly idempotencyKey?: string;
|
|
194
|
-
}
|
|
195
|
-
interface SubscriptionPatch {
|
|
196
|
-
readonly priceId?: string;
|
|
197
|
-
readonly quantity?: number;
|
|
198
|
-
}
|
|
199
|
-
/** Normalized webhook outcome — the *core state transition* a provider event implies. */
|
|
200
|
-
type WebhookActionType = "payment.authorized" | "payment.captured" | "payment.failed" | "payment.refunded" | "subscription.active" | "subscription.canceled" | "subscription.past_due" | "subscription.paused" | "subscription.updated" | "unhandled";
|
|
201
|
-
/**
|
|
202
|
-
* How a refund action's {@link WebhookAction.amount} should be interpreted by the sync layer.
|
|
203
|
-
*
|
|
204
|
-
* `"delta"` is an incremental amount added to the running refunded total (Polar `refund.created`,
|
|
205
|
-
* and the historical default), so multiple events accumulate. `"absolute"` is the provider's
|
|
206
|
-
* cumulative refunded-to-date total (Stripe `charge.refunded` carries `amount_refunded`, which
|
|
207
|
-
* already sums all prior partial refunds); the sync layer sets the refunded total to this value
|
|
208
|
-
* rather than adding, so repeated partial-refund events do not over-count.
|
|
209
|
-
*
|
|
210
|
-
* Omitted means `"delta"`, preserving the original behavior for callers that predate this field.
|
|
211
|
-
*/
|
|
212
|
-
type RefundAmountKind = "absolute" | "delta";
|
|
213
|
-
interface WebhookAction {
|
|
214
|
-
readonly amount?: Money;
|
|
215
|
-
/**
|
|
216
|
-
* Interpretation of {@link WebhookAction.amount} for refund actions (`payment.refunded`).
|
|
217
|
-
* Defaults to `"delta"` when omitted. Ignored for non-refund actions.
|
|
218
|
-
*/
|
|
219
|
-
readonly amountKind?: RefundAmountKind;
|
|
220
|
-
readonly cancelAtPeriodEnd?: boolean;
|
|
221
|
-
readonly currentPeriodEnd?: number;
|
|
222
|
-
readonly currentPeriodStart?: number;
|
|
223
|
-
readonly customerId?: string;
|
|
224
|
-
/** Provider event id — the inbound idempotency key. */
|
|
225
|
-
readonly eventId: string;
|
|
226
|
-
readonly priceId?: string;
|
|
227
|
-
readonly provider: ProviderId;
|
|
228
|
-
readonly quantity?: number;
|
|
229
|
-
/** Raw provider event, retained for the events log / debugging. */
|
|
230
|
-
readonly raw?: unknown;
|
|
231
|
-
readonly referenceId?: string;
|
|
232
|
-
readonly sessionId?: string;
|
|
233
|
-
readonly subscriptionId?: string;
|
|
234
|
-
readonly type: WebhookActionType;
|
|
235
|
-
}
|
|
236
|
-
/** Result of applying a webhook action to the store. */
|
|
237
|
-
interface ApplyResult {
|
|
238
|
-
readonly applied: boolean;
|
|
239
|
-
readonly reason?: "duplicate" | "illegal_transition" | "invalid_refund_amount" | "ok" | "unhandled";
|
|
240
|
-
}
|
|
241
|
-
/** A read-only header bag; the platform `Headers` object satisfies it. */
|
|
242
|
-
interface WebhookHeaders {
|
|
243
|
-
get: (name: string) => null | string;
|
|
244
|
-
}
|
|
245
|
-
interface WebhookInput {
|
|
246
|
-
/** Request headers (signature schemes read provider-specific headers from here). */
|
|
247
|
-
readonly headers: WebhookHeaders;
|
|
248
|
-
/** Raw request body, exactly as received (required for signature verification). */
|
|
249
|
-
readonly payload: string;
|
|
250
|
-
}
|
|
251
|
-
/**
|
|
252
|
-
* A stateless translator between the provider API and Lunora's normalized vocabulary.
|
|
253
|
-
*
|
|
254
|
-
* Adapters never own state — they make provider calls and normalize provider events into a
|
|
255
|
-
* `WebhookAction`. All durable state lives in the payment store.
|
|
256
|
-
*/
|
|
257
|
-
interface PaymentAdapter {
|
|
258
|
-
cancelPayment: (sessionId: string, options?: {
|
|
259
|
-
idempotencyKey?: string;
|
|
260
|
-
}) => Promise<PaymentSession>;
|
|
261
|
-
cancelSubscription: (subscriptionId: string, options?: CancelSubscriptionOptions) => Promise<Subscription>;
|
|
262
|
-
readonly capabilities: ProviderCapabilities;
|
|
263
|
-
capturePayment: (input: CaptureInput) => Promise<PaymentSession>;
|
|
264
|
-
createCheckout: (input: CheckoutInput) => Promise<CheckoutResult>;
|
|
265
|
-
createPortalSession: (input: PortalInput) => Promise<{
|
|
266
|
-
url: string;
|
|
267
|
-
}>;
|
|
268
|
-
getOrCreateCustomer: (ref: CustomerRef) => Promise<Customer>;
|
|
269
|
-
/** Fetch the provider's current truth for a payment session — the basis for reconciliation. */
|
|
270
|
-
getPaymentStatus: (sessionId: string) => Promise<PaymentSession>;
|
|
271
|
-
/** Fetch the provider's current truth for a subscription — the basis for reconciliation. */
|
|
272
|
-
getSubscriptionStatus: (subscriptionId: string) => Promise<Subscription>;
|
|
273
|
-
/** Stable provider identifier (Medusa-style). */
|
|
274
|
-
readonly identifier: ProviderId;
|
|
275
|
-
/** Verify the signature over the raw body, then normalize the event. Throws on invalid signature. */
|
|
276
|
-
parseWebhook: (input: WebhookInput) => Promise<WebhookAction>;
|
|
277
|
-
refundPayment: (input: RefundInput) => Promise<PaymentSession>;
|
|
278
|
-
/**
|
|
279
|
-
* Forward metered usage to the provider's billing API. Optional — present only on providers
|
|
280
|
-
* whose `capabilities.usageMetering` is `true` and that expose an ingestion endpoint. When
|
|
281
|
-
* absent, `track` still records usage durably and `check` enforces limits locally.
|
|
282
|
-
*/
|
|
283
|
-
reportUsage?: (input: ReportUsageInput) => Promise<void>;
|
|
284
|
-
resumeSubscription: (subscriptionId: string) => Promise<Subscription>;
|
|
285
|
-
updateSubscription: (subscriptionId: string, patch: SubscriptionPatch) => Promise<Subscription>;
|
|
286
|
-
}
|
|
287
|
-
/** Registry of adapters keyed by provider id — supports dual-register during provider migration. */
|
|
288
|
-
interface AdapterRegistry {
|
|
289
|
-
all: () => PaymentAdapter[];
|
|
290
|
-
get: (provider: ProviderId) => PaymentAdapter;
|
|
291
|
-
has: (provider: ProviderId) => boolean;
|
|
292
|
-
}
|
|
293
|
-
declare const createAdapterRegistry: (adapters: ReadonlyArray<PaymentAdapter>) => AdapterRegistry;
|
|
294
5
|
interface PaymentStore {
|
|
295
6
|
getCustomerByReference: (provider: ProviderId, referenceId: string) => Promise<Customer | undefined>;
|
|
296
7
|
getPaymentSession: (provider: ProviderId, id: string) => Promise<PaymentSession | undefined>;
|
|
@@ -555,147 +266,6 @@ interface MoneyJSON {
|
|
|
555
266
|
}
|
|
556
267
|
declare const toMoneyJSON: (m: Money) => MoneyJSON;
|
|
557
268
|
declare const fromMoneyJSON: (json: MoneyJSON) => Money;
|
|
558
|
-
interface PolarSubscriptionLike {
|
|
559
|
-
readonly cancelAtPeriodEnd?: boolean;
|
|
560
|
-
readonly currentPeriodEnd?: null | string;
|
|
561
|
-
readonly currentPeriodStart?: null | string;
|
|
562
|
-
readonly customerId?: null | string;
|
|
563
|
-
readonly id: string;
|
|
564
|
-
readonly metadata?: Record<string, string>;
|
|
565
|
-
readonly productId?: string;
|
|
566
|
-
readonly status: string;
|
|
567
|
-
}
|
|
568
|
-
interface PolarOrderLike {
|
|
569
|
-
readonly amount?: number;
|
|
570
|
-
readonly currency?: string;
|
|
571
|
-
readonly id: string;
|
|
572
|
-
readonly status: string;
|
|
573
|
-
readonly totalAmount?: number;
|
|
574
|
-
}
|
|
575
|
-
interface PolarClientLike {
|
|
576
|
-
readonly checkouts: {
|
|
577
|
-
create: (parameters: Record<string, unknown>) => Promise<{
|
|
578
|
-
id: string;
|
|
579
|
-
url: string;
|
|
580
|
-
}>;
|
|
581
|
-
};
|
|
582
|
-
readonly customers: {
|
|
583
|
-
create: (parameters: Record<string, unknown>) => Promise<{
|
|
584
|
-
email: null | string;
|
|
585
|
-
id: string;
|
|
586
|
-
}>;
|
|
587
|
-
};
|
|
588
|
-
readonly customerSessions: {
|
|
589
|
-
create: (parameters: Record<string, unknown>) => Promise<{
|
|
590
|
-
customerPortalUrl: string;
|
|
591
|
-
}>;
|
|
592
|
-
};
|
|
593
|
-
readonly events: {
|
|
594
|
-
ingest: (parameters: Record<string, unknown>) => Promise<{
|
|
595
|
-
inserted?: number;
|
|
596
|
-
}>;
|
|
597
|
-
};
|
|
598
|
-
readonly orders: {
|
|
599
|
-
get: (parameters: Record<string, unknown>) => Promise<PolarOrderLike>;
|
|
600
|
-
};
|
|
601
|
-
readonly refunds: {
|
|
602
|
-
create: (parameters: Record<string, unknown>) => Promise<{
|
|
603
|
-
id: string;
|
|
604
|
-
}>;
|
|
605
|
-
};
|
|
606
|
-
readonly subscriptions: {
|
|
607
|
-
get: (parameters: Record<string, unknown>) => Promise<PolarSubscriptionLike>;
|
|
608
|
-
revoke: (parameters: Record<string, unknown>) => Promise<PolarSubscriptionLike>;
|
|
609
|
-
update: (parameters: Record<string, unknown>) => Promise<PolarSubscriptionLike>;
|
|
610
|
-
};
|
|
611
|
-
}
|
|
612
|
-
interface PolarAdapterOptions {
|
|
613
|
-
readonly client: PolarClientLike;
|
|
614
|
-
readonly webhookSecret: string;
|
|
615
|
-
readonly webhookToleranceSeconds?: number;
|
|
616
|
-
}
|
|
617
|
-
declare const createPolarAdapter: (options: PolarAdapterOptions) => PaymentAdapter;
|
|
618
|
-
interface StripeRequestOptions {
|
|
619
|
-
readonly idempotencyKey?: string;
|
|
620
|
-
}
|
|
621
|
-
interface StripePaymentIntentLike {
|
|
622
|
-
readonly amount: number;
|
|
623
|
-
readonly amount_received?: number;
|
|
624
|
-
readonly currency: string;
|
|
625
|
-
readonly customer?: null | string;
|
|
626
|
-
readonly id: string;
|
|
627
|
-
readonly metadata?: Record<string, string>;
|
|
628
|
-
readonly status: string;
|
|
629
|
-
}
|
|
630
|
-
interface StripeSubscriptionLike {
|
|
631
|
-
readonly cancel_at_period_end?: boolean;
|
|
632
|
-
readonly current_period_end?: number;
|
|
633
|
-
readonly current_period_start?: number;
|
|
634
|
-
readonly customer?: null | string;
|
|
635
|
-
readonly id: string;
|
|
636
|
-
readonly items?: {
|
|
637
|
-
data: ReadonlyArray<{
|
|
638
|
-
price?: {
|
|
639
|
-
id?: string;
|
|
640
|
-
};
|
|
641
|
-
quantity?: number;
|
|
642
|
-
}>;
|
|
643
|
-
};
|
|
644
|
-
readonly metadata?: Record<string, string>;
|
|
645
|
-
readonly status: string;
|
|
646
|
-
}
|
|
647
|
-
/** The subset of the Stripe SDK surface this adapter calls. A real `Stripe` instance satisfies it. */
|
|
648
|
-
interface StripeClientLike {
|
|
649
|
-
readonly billing: {
|
|
650
|
-
meterEvents: {
|
|
651
|
-
create: (parameters: Record<string, unknown>, options?: StripeRequestOptions) => Promise<{
|
|
652
|
-
identifier?: string;
|
|
653
|
-
}>;
|
|
654
|
-
};
|
|
655
|
-
};
|
|
656
|
-
readonly billingPortal: {
|
|
657
|
-
sessions: {
|
|
658
|
-
create: (parameters: Record<string, unknown>) => Promise<{
|
|
659
|
-
url: string;
|
|
660
|
-
}>;
|
|
661
|
-
};
|
|
662
|
-
};
|
|
663
|
-
readonly checkout: {
|
|
664
|
-
sessions: {
|
|
665
|
-
create: (parameters: Record<string, unknown>, options?: StripeRequestOptions) => Promise<{
|
|
666
|
-
id: string;
|
|
667
|
-
url: null | string;
|
|
668
|
-
}>;
|
|
669
|
-
};
|
|
670
|
-
};
|
|
671
|
-
readonly customers: {
|
|
672
|
-
create: (parameters: Record<string, unknown>, options?: StripeRequestOptions) => Promise<{
|
|
673
|
-
email: null | string;
|
|
674
|
-
id: string;
|
|
675
|
-
}>;
|
|
676
|
-
};
|
|
677
|
-
readonly paymentIntents: {
|
|
678
|
-
cancel: (id: string, parameters?: Record<string, unknown>, options?: StripeRequestOptions) => Promise<StripePaymentIntentLike>;
|
|
679
|
-
capture: (id: string, parameters?: Record<string, unknown>, options?: StripeRequestOptions) => Promise<StripePaymentIntentLike>;
|
|
680
|
-
retrieve: (id: string) => Promise<StripePaymentIntentLike>;
|
|
681
|
-
};
|
|
682
|
-
readonly refunds: {
|
|
683
|
-
create: (parameters: Record<string, unknown>, options?: StripeRequestOptions) => Promise<{
|
|
684
|
-
id: string;
|
|
685
|
-
}>;
|
|
686
|
-
};
|
|
687
|
-
readonly subscriptions: {
|
|
688
|
-
cancel: (id: string, parameters?: Record<string, unknown>, options?: StripeRequestOptions) => Promise<StripeSubscriptionLike>;
|
|
689
|
-
retrieve: (id: string) => Promise<StripeSubscriptionLike>;
|
|
690
|
-
update: (id: string, parameters: Record<string, unknown>, options?: StripeRequestOptions) => Promise<StripeSubscriptionLike>;
|
|
691
|
-
};
|
|
692
|
-
}
|
|
693
|
-
interface StripeAdapterOptions {
|
|
694
|
-
readonly client: StripeClientLike;
|
|
695
|
-
readonly webhookSecret: string;
|
|
696
|
-
readonly webhookToleranceSeconds?: number;
|
|
697
|
-
}
|
|
698
|
-
declare const createStripeAdapter: (options: StripeAdapterOptions) => PaymentAdapter;
|
|
699
269
|
interface ReconcileInput {
|
|
700
270
|
readonly adapter: PaymentAdapter;
|
|
701
271
|
/** Optional telemetry sink — fired per drifted row and once on completion. */
|
|
@@ -730,29 +300,6 @@ declare const applyWebhookAction: (store: PaymentStore, action: WebhookAction, o
|
|
|
730
300
|
/** Constant-time string comparison to avoid leaking byte positions via timing. */
|
|
731
301
|
declare const constantTimeEqual: (a: string, b: string) => boolean;
|
|
732
302
|
declare const hmacSha256Hex: (secret: string, payload: string) => Promise<string>;
|
|
733
|
-
interface StripeSignatureParts {
|
|
734
|
-
readonly signatures: string[];
|
|
735
|
-
readonly timestamp: number;
|
|
736
|
-
}
|
|
737
|
-
/** Parse a Stripe-style `t=...,v1=...,v1=...` signature header. */
|
|
738
|
-
declare const parseStripeSignatureHeader: (header: string) => StripeSignatureParts;
|
|
739
|
-
interface VerifyStripeSignatureInput {
|
|
740
|
-
/** Injectable clock (ms since epoch) for tests. */
|
|
741
|
-
readonly now?: number;
|
|
742
|
-
/** Raw request body, exactly as received. */
|
|
743
|
-
readonly payload: string;
|
|
744
|
-
readonly secret: string;
|
|
745
|
-
/** The `Stripe-Signature` header value. */
|
|
746
|
-
readonly signatureHeader: string;
|
|
747
|
-
/** Whole-second tolerance for the signed timestamp (default 300). */
|
|
748
|
-
readonly toleranceSeconds?: number;
|
|
749
|
-
}
|
|
750
|
-
/**
|
|
751
|
-
* Verify a Stripe-scheme webhook signature: `HMAC_SHA256(secret, "{t}.{payload}")` compared
|
|
752
|
-
* against the header's `v1` values, with a timestamp tolerance to reject replays. Throws a
|
|
753
|
-
* {@link LunoraPaymentError} on any failure.
|
|
754
|
-
*/
|
|
755
|
-
declare const verifyStripeSignature: (input: VerifyStripeSignatureInput) => Promise<void>;
|
|
756
303
|
interface VerifyStandardWebhookInput {
|
|
757
304
|
/** Injectable clock (ms since epoch) for tests. */
|
|
758
305
|
readonly now?: number;
|
|
@@ -775,4 +322,18 @@ interface VerifyStandardWebhookInput {
|
|
|
775
322
|
* entries, with a replay-window check. Throws a {@link LunoraPaymentError} on any failure.
|
|
776
323
|
*/
|
|
777
324
|
declare const verifyStandardWebhook: (input: VerifyStandardWebhookInput) => Promise<void>;
|
|
778
|
-
|
|
325
|
+
interface VerifyCreemSignatureInput {
|
|
326
|
+
/** Raw request body, exactly as received. */
|
|
327
|
+
readonly payload: string;
|
|
328
|
+
/** Creem webhook signing secret. */
|
|
329
|
+
readonly secret: string;
|
|
330
|
+
/** The `creem-signature` header value. */
|
|
331
|
+
readonly signature: string;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Verify a Creem webhook signature: `hex(HMAC_SHA256(secret, rawBody))` compared against the
|
|
335
|
+
* `creem-signature` header. Creem's scheme signs the raw body with no timestamp, so there is no
|
|
336
|
+
* replay-window check. Throws a {@link LunoraPaymentError} on any failure.
|
|
337
|
+
*/
|
|
338
|
+
declare const verifyCreemSignature: (input: VerifyCreemSignatureInput) => Promise<void>;
|
|
339
|
+
export { type ApplyResult, type AttachInput, type AuthorizeReference, type CancelSubscriptionOptions, type CheckInput, type CheckResult, type CheckoutInput, type CheckoutResult, type CreatePaymentOptions, type CurrencyCode, type Customer, type Entitlements, type EntitlementsConfig, type FeatureBalance, type LunoraDatabaseLike, type LunoraPayment, LunoraPaymentError, MemoryPaymentStore, type Money, type MoneyJSON, PAYMENT_TERMINAL_STATES, type PaymentAction, type PaymentAdapter, type PaymentContextLike, type PaymentDatabase, type PaymentErrorCode, type PaymentEvent, type PaymentObserver, type PaymentRow, type PaymentSession, type PaymentState, type PaymentStore, type PaymentsFromContextOptions, type PlanDefinition, type ProviderId, type ReconcileInput, type ReconcileResult, SUBSCRIPTION_TERMINAL_STATES, type Subscription, type SubscriptionAction, type SubscriptionState, type TrackInput, type TrackResult, type UsageEvent, type WebhookAction, type WebhookActionType, addMoney, allocateMoney, applyWebhookAction, canTransitionPayment, canTransitionSubscription, compareMoney, constantTimeEqual, createDatabasePaymentStore, createPayment, entitlementsForReference, featureNames, formatMoney, fromMoneyJSON, hasActivePrice, hmacSha256Hex, idempotencyKey, isZeroDecimalCurrency, isZeroMoney, lunoraDatabaseToPaymentDatabase, money, nextPaymentState, nextSubscriptionState, paymentTables, paymentsFromContext, reconcile, resolveEntitlements, subtractMoney, toMoneyJSON, usagePeriodStart, verifyCreemSignature, verifyStandardWebhook, zeroMoney };
|