@owlmeans/server-payment 0.1.18-rc.20 → 0.1.18-rc.21

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.
Files changed (144) hide show
  1. package/README.md +1 -1
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/server-payment/SKILL.md +402 -260
  4. package/build/config.d.ts +15 -1
  5. package/build/config.d.ts.map +1 -1
  6. package/build/config.js +99 -3
  7. package/build/config.js.map +1 -1
  8. package/build/consts.d.ts +27 -0
  9. package/build/consts.d.ts.map +1 -1
  10. package/build/consts.js +27 -0
  11. package/build/consts.js.map +1 -1
  12. package/build/consumer/capture.d.ts +74 -0
  13. package/build/consumer/capture.d.ts.map +1 -0
  14. package/build/consumer/capture.js +291 -0
  15. package/build/consumer/capture.js.map +1 -0
  16. package/build/consumer/format.d.ts +27 -0
  17. package/build/consumer/format.d.ts.map +1 -0
  18. package/build/consumer/format.js +81 -0
  19. package/build/consumer/format.js.map +1 -0
  20. package/build/consumer/handlers.d.ts +28 -0
  21. package/build/consumer/handlers.d.ts.map +1 -0
  22. package/build/consumer/handlers.js +173 -0
  23. package/build/consumer/handlers.js.map +1 -0
  24. package/build/consumer/index.d.ts +7 -0
  25. package/build/consumer/index.d.ts.map +1 -0
  26. package/build/consumer/index.js +6 -0
  27. package/build/consumer/index.js.map +1 -0
  28. package/build/consumer/mail.d.ts +27 -0
  29. package/build/consumer/mail.d.ts.map +1 -0
  30. package/build/consumer/mail.js +314 -0
  31. package/build/consumer/mail.js.map +1 -0
  32. package/build/consumer/origin.d.ts +14 -0
  33. package/build/consumer/origin.d.ts.map +1 -0
  34. package/build/consumer/origin.js +47 -0
  35. package/build/consumer/origin.js.map +1 -0
  36. package/build/consumer/reconcile.d.ts +12 -0
  37. package/build/consumer/reconcile.d.ts.map +1 -0
  38. package/build/consumer/reconcile.js +317 -0
  39. package/build/consumer/reconcile.js.map +1 -0
  40. package/build/consumer/records.d.ts +78 -0
  41. package/build/consumer/records.d.ts.map +1 -0
  42. package/build/consumer/records.js +296 -0
  43. package/build/consumer/records.js.map +1 -0
  44. package/build/consumer/service.d.ts +51 -0
  45. package/build/consumer/service.d.ts.map +1 -0
  46. package/build/consumer/service.js +760 -0
  47. package/build/consumer/service.js.map +1 -0
  48. package/build/consumer/withdrawal.d.ts +57 -0
  49. package/build/consumer/withdrawal.d.ts.map +1 -0
  50. package/build/consumer/withdrawal.js +247 -0
  51. package/build/consumer/withdrawal.js.map +1 -0
  52. package/build/index.d.ts +4 -2
  53. package/build/index.d.ts.map +1 -1
  54. package/build/index.js +4 -2
  55. package/build/index.js.map +1 -1
  56. package/build/model.d.ts +6 -1
  57. package/build/model.d.ts.map +1 -1
  58. package/build/model.js +134 -4
  59. package/build/model.js.map +1 -1
  60. package/build/observer.d.ts +4 -0
  61. package/build/observer.d.ts.map +1 -1
  62. package/build/observer.js +13 -0
  63. package/build/observer.js.map +1 -1
  64. package/build/plugins/checkout-plugins.d.ts +49 -0
  65. package/build/plugins/checkout-plugins.d.ts.map +1 -0
  66. package/build/plugins/checkout-plugins.js +124 -0
  67. package/build/plugins/checkout-plugins.js.map +1 -0
  68. package/build/plugins/estimate.d.ts.map +1 -1
  69. package/build/plugins/estimate.js +41 -8
  70. package/build/plugins/estimate.js.map +1 -1
  71. package/build/plugins/events.d.ts +2 -0
  72. package/build/plugins/events.d.ts.map +1 -1
  73. package/build/plugins/events.js +126 -9
  74. package/build/plugins/events.js.map +1 -1
  75. package/build/plugins/fx.d.ts +5 -0
  76. package/build/plugins/fx.d.ts.map +1 -1
  77. package/build/plugins/fx.js +25 -0
  78. package/build/plugins/fx.js.map +1 -1
  79. package/build/plugins/portal.d.ts.map +1 -1
  80. package/build/plugins/portal.js +11 -1
  81. package/build/plugins/portal.js.map +1 -1
  82. package/build/plugins/stripe.d.ts +21 -2
  83. package/build/plugins/stripe.d.ts.map +1 -1
  84. package/build/plugins/stripe.js +397 -61
  85. package/build/plugins/stripe.js.map +1 -1
  86. package/build/resource.d.ts +8 -1
  87. package/build/resource.d.ts.map +1 -1
  88. package/build/resource.js +59 -2
  89. package/build/resource.js.map +1 -1
  90. package/build/service.d.ts +2 -1
  91. package/build/service.d.ts.map +1 -1
  92. package/build/service.js +28 -5
  93. package/build/service.js.map +1 -1
  94. package/build/subscription.d.ts +6 -0
  95. package/build/subscription.d.ts.map +1 -1
  96. package/build/subscription.js +1 -0
  97. package/build/subscription.js.map +1 -1
  98. package/build/sync.d.ts +7 -0
  99. package/build/sync.d.ts.map +1 -1
  100. package/build/sync.js +108 -15
  101. package/build/sync.js.map +1 -1
  102. package/build/types.d.ts +707 -4
  103. package/build/types.d.ts.map +1 -1
  104. package/build/utils.d.ts +22 -1
  105. package/build/utils.d.ts.map +1 -1
  106. package/build/utils.js +27 -1
  107. package/build/utils.js.map +1 -1
  108. package/package.json +14 -13
  109. package/src/config.ts +111 -7
  110. package/src/consts.ts +34 -0
  111. package/src/consumer/capture.ts +362 -0
  112. package/src/consumer/format.ts +90 -0
  113. package/src/consumer/handlers.ts +211 -0
  114. package/src/consumer/index.ts +6 -0
  115. package/src/consumer/mail.ts +368 -0
  116. package/src/consumer/origin.ts +63 -0
  117. package/src/consumer/reconcile.ts +329 -0
  118. package/src/consumer/records.ts +374 -0
  119. package/src/consumer/service.ts +868 -0
  120. package/src/consumer/withdrawal.ts +302 -0
  121. package/src/index.ts +6 -4
  122. package/src/model.ts +148 -6
  123. package/src/observer.ts +15 -2
  124. package/src/plugins/checkout-plugins.ts +155 -0
  125. package/src/plugins/estimate.ts +49 -9
  126. package/src/plugins/events.ts +135 -11
  127. package/src/plugins/fx.ts +29 -0
  128. package/src/plugins/portal.ts +11 -1
  129. package/src/plugins/stripe.ts +476 -60
  130. package/src/resource.ts +87 -4
  131. package/src/service.ts +28 -6
  132. package/src/subscription.ts +7 -0
  133. package/src/sync.ts +124 -17
  134. package/src/types.ts +756 -6
  135. package/src/utils.ts +56 -7
  136. package/tests/checkout-consumer.spec.ts +348 -0
  137. package/tests/checkout-plugins.spec.ts +164 -0
  138. package/tests/consumer-events.spec.ts +218 -0
  139. package/tests/consumer-fixtures.ts +132 -0
  140. package/tests/consumer-ops.spec.ts +351 -0
  141. package/tests/consumer-rights.integration.spec.ts +150 -0
  142. package/tests/consumer-rights.spec.ts +501 -0
  143. package/tests/context.ts +20 -2
  144. package/tests/fake-stripe.ts +188 -18
package/build/types.d.ts CHANGED
@@ -1,10 +1,13 @@
1
+ import type Stripe from 'stripe';
1
2
  import type { InitializedService, LazyService } from '@owlmeans/context';
2
3
  import type { ResourceRecord } from '@owlmeans/resource';
3
4
  import type { MongoResource } from '@owlmeans/mongo-resource';
4
5
  import type { PluginConfig } from '@owlmeans/config';
5
6
  import type { PermissionSet } from '@owlmeans/auth';
7
+ import type { AbstractRequest } from '@owlmeans/entrypoint';
8
+ import type { MailMessage } from '@owlmeans/mailer';
6
9
  import type { Config as ApiConfig, Context as ApiContext } from '@owlmeans/server-api';
7
- import type { AmountCheckoutPolicy, CheckoutPricingMode, EntitlementView, LimitDeclaration, LimitView, PlanCapability, PlanDuration, PortalFlow, PriceEstimate, PricingPolicy, Product, ProductPlan, ProductType, QuantityCheckoutPolicy, SubscriptionStatus } from '@owlmeans/payment';
10
+ import type { AmountCheckoutPolicy, AmountNarrowing, AmountPolicyView, BillingProfileView, CancellationBody, CancellationKind, CancellationReceipt, CancellationStatus, CheckoutPricingMode, ConsentKind, ConsumerRegion, ConsumerRightsDeclaration, ConsumerRightsLinks, ConsumerRightsPolicy, DeclarationChannel, DeclarationKind, EntitlementView, LimitDeclaration, LimitView, PerformanceConsentBody, PerformanceConsentResponse, PerformanceConsentView, PlanCapability, PlanDuration, PlanPriceView, PlanWithdrawalComponent, PortalFlow, PriceEstimate, PricingPolicy, Product, ProductPlan, ProductType, PurchaseKind, PurchaseView, QuantityCheckoutPolicy, SubscriptionStartBody, SubscriptionStartResponse, SubscriptionStartView, SubscriptionStatus, WithdrawalBody, WithdrawalCandidateList, WithdrawalReceipt, WithdrawalStatus } from '@owlmeans/payment';
8
11
  export interface Config extends ApiConfig {
9
12
  }
10
13
  export interface Context<C extends Config = Config> extends ApiContext<C> {
@@ -23,6 +26,11 @@ export interface PaymentPlan extends ProductPlan {
23
26
  pricingMode?: CheckoutPricingMode;
24
27
  amountPolicy?: AmountCheckoutPolicy;
25
28
  quantityPolicy?: QuantityCheckoutPolicy;
29
+ /**
30
+ * Exact prices in further currencies, major units by lowercase ISO 4217 code (`{ usd: 20 }`).
31
+ * Synced as the reusable Price's `currency_options`, never converted.
32
+ */
33
+ currencyPrices?: Record<string, number>;
26
34
  }
27
35
  export interface PaymentProductDef {
28
36
  sku: string;
@@ -65,6 +73,19 @@ export interface PaymentPlanDef {
65
73
  minQuantity?: number;
66
74
  maxQuantity?: number;
67
75
  defaultQuantity?: number;
76
+ /**
77
+ * Exact prices in further currencies, major units by ISO 4217 code (`{ usd: 20 }`): a recurring
78
+ * or quantity plan's synced Price carries each as a `currency_options` entry at exactly this
79
+ * amount, while its default currency (the settlement currency) is converted as before.
80
+ */
81
+ currencyPrices?: Record<string, number>;
82
+ /**
83
+ * The separately priced parts of a subscription for a withdrawal (CJEU C-641/19): their
84
+ * `shareMinor` sum to `round(price × 100)`. Absent: the whole price is one `time` component.
85
+ */
86
+ withdrawal?: {
87
+ components: PlanWithdrawalComponent[];
88
+ };
68
89
  }
69
90
  /** File paths (or values) of the Stripe secrets. The webhook secret is an optional override. */
70
91
  export interface StripeSecretsDef {
@@ -100,6 +121,36 @@ export interface StripePricingPluginConfig extends PluginConfig, StripePricingDe
100
121
  export interface PricingDef extends PricingPolicy {
101
122
  stripe?: StripePricingDef;
102
123
  }
124
+ /**
125
+ * The business the consumer contracts with — backend only, never advertised. `name` is what the
126
+ * express statements say (`{{trader}}` in a consent or start request); the mails' identity line,
127
+ * the withdrawal information and the model form ("To: …") say `legalName`, `address` and `email`.
128
+ */
129
+ export type TraderDef = {
130
+ name: string;
131
+ legalName: string;
132
+ /** Postal address; without it (or `email`) the mails render without it and the boot warns. */
133
+ address?: string;
134
+ email?: string;
135
+ website?: string;
136
+ };
137
+ /** The consumer-rights mail options — backend only, never advertised. */
138
+ export interface ConsumerMailDef {
139
+ /** The mailer service alias. Default `MAILER_SERVICE`. */
140
+ alias?: string;
141
+ from?: string;
142
+ replyTo?: string;
143
+ /** Evidence archive addresses: each receives its own copy of every consumer-rights mail. */
144
+ bcc?: string[];
145
+ }
146
+ export interface ConsumerMailPluginConfig extends PluginConfig, ConsumerMailDef {
147
+ trader?: TraderDef;
148
+ }
149
+ /** `declareConsumerRights`'s argument: the advertised policy plus the backend-only trader and mail options. */
150
+ export type ConsumerRightsDef = ConsumerRightsDeclaration & {
151
+ trader?: TraderDef;
152
+ mail?: ConsumerMailDef;
153
+ };
103
154
  /** What the managed customer portal configuration shows. */
104
155
  export interface PortalBrandingDef {
105
156
  headline?: string;
@@ -120,10 +171,104 @@ export interface CreateLinkParams {
120
171
  amountMinor?: number;
121
172
  /** Stripe Checkout and future paid-invoice language. Caller supplies a Stripe-supported locale. */
122
173
  locale?: string;
123
- /** Trusted application copy shown beside the Checkout confirmation button. */
124
- submitText?: string;
174
+ /**
175
+ * Trusted application copy shown beside the Checkout confirmation button — never caller-provided
176
+ * text. A function receives the charge currency and the price the session charges.
177
+ */
178
+ submitText?: string | ((context: CheckoutTextContext) => string);
125
179
  successUrl?: string;
126
180
  cancelUrl?: string;
181
+ /** The billing country the buyer declared (ISO 3166-1 alpha-2). A locked profile overrides it. */
182
+ country?: string;
183
+ /** The subscription start request recorded right before a subscription checkout. */
184
+ startRequestId?: string;
185
+ /** The language the buyer is shown legal copy in; default: the billing country's. */
186
+ consumerLanguage?: string;
187
+ /** The request's geolocated country (`cf-ipcountry`) — second location evidence, stored at lock. */
188
+ ipCountry?: string;
189
+ }
190
+ /** What a submit-text function is told about the session it labels. */
191
+ export interface CheckoutTextContext {
192
+ language: string;
193
+ /** The charge currency, lowercase. */
194
+ currency: string;
195
+ /** A subscription's unit price in the charge currency; an amount checkout's pre-tax charge. */
196
+ unitAmountMinor?: number;
197
+ interval?: 'month' | 'year';
198
+ region: ConsumerRegion | null;
199
+ country?: string;
200
+ }
201
+ /** What a plugin narrows: one entity's amount checkout of one plan, at one instant. */
202
+ export interface CheckoutNarrowInput {
203
+ entityId: string;
204
+ productSku: string;
205
+ planSku?: string;
206
+ /** The plan's own amount policy — the same for everyone. */
207
+ base: AmountCheckoutPolicy;
208
+ at: Date;
209
+ }
210
+ /** A checkout about to be created — what `admit` may veto. */
211
+ export interface CheckoutAttempt {
212
+ entityId: string;
213
+ productSku: string;
214
+ planSku?: string;
215
+ mode: 'amount' | 'quantity' | 'subscription';
216
+ /** Amount mode: the net value bought, in the amount policy's currency. */
217
+ amountMinor?: number;
218
+ /** The amount policy's currency (amount mode), else the charge currency. */
219
+ amountCurrency?: string;
220
+ /** Amount mode: the pre-tax charge in `currency`. */
221
+ chargeMinor?: number;
222
+ currency: string;
223
+ /** The session lifetime the gateway will set; absent: Stripe's default (24 h). */
224
+ sessionTtlSeconds?: number;
225
+ expiresAt?: Date;
226
+ at: Date;
227
+ }
228
+ /** A plugin's admission: an optional reservation it binds to the session in `created`. */
229
+ export interface CheckoutAdmission {
230
+ reservationId?: string;
231
+ }
232
+ /** The session a checkout became. */
233
+ export interface CheckoutCreated extends CheckoutAttempt {
234
+ sessionId: string;
235
+ url: string;
236
+ /** What this plugin's own `admit` answered. */
237
+ reservationId?: string;
238
+ }
239
+ export type CheckoutOutcome = 'paid' | 'expired' | 'failed';
240
+ /**
241
+ * How a checkout ended: `paid` (completed and paid), `expired`, or `failed` — an asynchronous
242
+ * payment failure, or a session that never became usable (a later plugin vetoed, Stripe refused,
243
+ * a `created` threw; then `sessionId` may be absent and `reservationId` names the hold to release).
244
+ */
245
+ export interface CheckoutSettled {
246
+ entityId: string;
247
+ productSku?: string;
248
+ planSku?: string;
249
+ sessionId?: string;
250
+ reservationId?: string;
251
+ outcome: CheckoutOutcome;
252
+ amountMinor?: number;
253
+ at: Date;
254
+ }
255
+ /**
256
+ * A seam around amount and subscription checkout, registered with `gateway(ctx).use(plugin)` (a
257
+ * plugin with an `alias` registered twice replaces the first). Errors from `narrow` and `admit`
258
+ * propagate — a plugin fails closed; `settled` errors are logged, since holds carry their own TTL.
259
+ */
260
+ export interface CheckoutPlugin {
261
+ alias?: string;
262
+ /** Lower what this entity may buy now; `null` for no opinion. */
263
+ narrow?: (ctx: ApiContext, input: CheckoutNarrowInput) => Promise<AmountNarrowing | null>;
264
+ /** Veto (throw, e.g. `CheckoutLimitExceeded`) or hold a reservation for the session. */
265
+ admit?: (ctx: ApiContext, attempt: CheckoutAttempt) => Promise<CheckoutAdmission | void>;
266
+ /** The session exists — bind the reservation. A throw expires the session and rethrows. */
267
+ created?: (ctx: ApiContext, created: CheckoutCreated) => Promise<void>;
268
+ /** From the webhook (paid, expired, failed) or from a checkout that never became usable. */
269
+ settled?: (ctx: ApiContext, settled: CheckoutSettled) => Promise<void>;
270
+ /** The longest a session may stay open; the gateway uses the smallest, clamped to 30 min–24 h. */
271
+ sessionTtlSeconds?: number;
127
272
  }
128
273
  export interface PortalLinkOptions {
129
274
  flow: PortalFlow;
@@ -165,6 +310,17 @@ export interface GatewayService extends InitializedService {
165
310
  scanned: number;
166
311
  updated: number;
167
312
  }>;
313
+ /** Register a checkout plugin; one with an `alias` already registered replaces it. */
314
+ use: (plugin: CheckoutPlugin) => void;
315
+ /** The registered checkout plugins, in registration order. */
316
+ checkoutPlugins: () => readonly CheckoutPlugin[];
317
+ /**
318
+ * The entity's amount policy of an amount plan as narrowed NOW — the very computation
319
+ * `createLink` enforces. Mongo and plugins only; works unmanaged.
320
+ */
321
+ amountPolicy: (ctx: ApiContext, entityId: string, productSku: string, planSku?: string) => Promise<AmountPolicyView>;
322
+ /** The synced prices of a product's plans, per currency — stored rows, no Stripe call. */
323
+ planPrices: (ctx: ApiContext, productSku: string) => Promise<PlanPriceView[]>;
168
324
  }
169
325
  export interface PaymentGatewayOptions {
170
326
  dbAlias?: string;
@@ -175,6 +331,8 @@ export interface PaymentGatewayOptions {
175
331
  */
176
332
  manage?: boolean;
177
333
  }
334
+ /** A Stripe client for one context — the default reads the configured secret. */
335
+ export type StripeFactory = (ctx: ApiContext) => Promise<Stripe>;
178
336
  /** @deprecated use `PaymentGatewayOptions` */
179
337
  export type PaymentResourceOptions = PaymentGatewayOptions;
180
338
  interface TopUpBase {
@@ -262,6 +420,14 @@ export interface RefundEvent {
262
420
  netAmountMinor?: number;
263
421
  /** Fulfillment targets: the pre-tax subtotal charged at checkout. */
264
422
  chargeAmountMinor?: number;
423
+ /** The refund's own metadata. */
424
+ metadata?: Record<string, string>;
425
+ /**
426
+ * Set when the refund executes a withdrawal (`refund.metadata.withdrawalId`): the `onWithdrawal`
427
+ * observer takes back exactly the unused units — an `onRefund` observer must skip its own
428
+ * claw-back for such a refund, or the units are taken back twice.
429
+ */
430
+ withdrawalId?: string;
265
431
  }
266
432
  export type DisputePhase = 'opened' | 'funds-withdrawn' | 'funds-reinstated' | 'closed';
267
433
  export interface DisputeEvent {
@@ -292,6 +458,64 @@ export interface PaymentFailedEvent {
292
458
  nextAttemptAt?: Date;
293
459
  eventKey: string;
294
460
  }
461
+ /** A consumer's express request was recorded (performance consent or subscription start). */
462
+ export interface ConsentEvent {
463
+ kind: ConsentKind;
464
+ consentId: string;
465
+ entityId: string;
466
+ profileId?: string;
467
+ /** The purchases the consent covers (none for a start request, which precedes its purchase). */
468
+ purchaseIds: string[];
469
+ planSku?: string;
470
+ textVersion: string;
471
+ language: string;
472
+ decidedAt: Date;
473
+ expiresAt?: Date;
474
+ /** `consent:<consentId>`. */
475
+ eventKey: string;
476
+ }
477
+ /** A withdrawal executed (`refunded`) or left to an operator (`review`). */
478
+ export interface WithdrawalEvent {
479
+ withdrawalId: string;
480
+ /** `withdrawal:<withdrawalId>`. */
481
+ eventKey: string;
482
+ entityId: string;
483
+ channel: DeclarationChannel;
484
+ purchase: PurchaseRef;
485
+ declaredAt: Date;
486
+ status: WithdrawalStatus;
487
+ refund: {
488
+ amountMinor: number;
489
+ currency: string;
490
+ netMinor?: number;
491
+ refundId?: string;
492
+ creditNoteId?: string;
493
+ };
494
+ /**
495
+ * The purchase's units as the usage meter read them: `returned` is what the application takes
496
+ * back (`granted − used`), `null` without a meter.
497
+ */
498
+ units: {
499
+ granted: number;
500
+ used: number;
501
+ returned: number;
502
+ } | null;
503
+ subscriptionCanceled: boolean;
504
+ }
505
+ /** A cancellation was declared (matched to a subscription or not). */
506
+ export interface CancellationEvent {
507
+ cancellationId: string;
508
+ /** `cancellation:<cancellationId>`. */
509
+ eventKey: string;
510
+ entityId?: string;
511
+ matched: boolean;
512
+ channel: DeclarationChannel;
513
+ kind: CancellationKind;
514
+ status: CancellationStatus;
515
+ subscriptionId?: string;
516
+ effectiveAt?: Date;
517
+ declaredAt: Date;
518
+ }
295
519
  export interface TopUpCallback {
296
520
  (completion: TopUpCompletion, ctx: ApiContext): Promise<void>;
297
521
  }
@@ -307,18 +531,37 @@ export interface DisputeCallback {
307
531
  export interface PaymentFailedCallback {
308
532
  (event: PaymentFailedEvent, ctx: ApiContext): Promise<void>;
309
533
  }
310
- /** Callbacks run sequentially and are awaited; a throw escapes so the paygate retries. */
534
+ export interface ConsentCallback {
535
+ (event: ConsentEvent, ctx: ApiContext): Promise<void>;
536
+ }
537
+ export interface WithdrawalCallback {
538
+ (event: WithdrawalEvent, ctx: ApiContext): Promise<void>;
539
+ }
540
+ export interface CancellationCallback {
541
+ (event: CancellationEvent, ctx: ApiContext): Promise<void>;
542
+ }
543
+ /**
544
+ * Callbacks run sequentially and are awaited. A paygate callback's throw escapes so the paygate
545
+ * retries; a consumer-rights callback (`onConsent`, `onWithdrawal`, `onCancellation`) runs AFTER
546
+ * the records and the paygate steps, and its throw is recorded and retried by `reconcile()`.
547
+ */
311
548
  export interface CompletionObserver extends LazyService {
312
549
  onTopUp: (cb: TopUpCallback) => void;
313
550
  onSubscription: (cb: SubscriptionCallback) => void;
314
551
  onRefund: (cb: RefundCallback) => void;
315
552
  onDispute: (cb: DisputeCallback) => void;
316
553
  onPaymentFailed: (cb: PaymentFailedCallback) => void;
554
+ onConsent: (cb: ConsentCallback) => void;
555
+ onWithdrawal: (cb: WithdrawalCallback) => void;
556
+ onCancellation: (cb: CancellationCallback) => void;
317
557
  propagateTopUp: (completion: TopUpCompletion, ctx: ApiContext) => Promise<void>;
318
558
  propagateSubscription: (event: SubscriptionEvent, ctx: ApiContext) => Promise<void>;
319
559
  propagateRefund: (event: RefundEvent, ctx: ApiContext) => Promise<void>;
320
560
  propagateDispute: (event: DisputeEvent, ctx: ApiContext) => Promise<void>;
321
561
  propagatePaymentFailed: (event: PaymentFailedEvent, ctx: ApiContext) => Promise<void>;
562
+ propagateConsent: (event: ConsentEvent, ctx: ApiContext) => Promise<void>;
563
+ propagateWithdrawal: (event: WithdrawalEvent, ctx: ApiContext) => Promise<void>;
564
+ propagateCancellation: (event: CancellationEvent, ctx: ApiContext) => Promise<void>;
322
565
  }
323
566
  export interface PaygateCustomerRecord extends ResourceRecord {
324
567
  paygate: string;
@@ -328,6 +571,10 @@ export interface PaygateCustomerRecord extends ResourceRecord {
328
571
  email?: string;
329
572
  name?: string;
330
573
  taxId?: string;
574
+ /** The paygate customer's billing address country, as its last webhook stated it. */
575
+ country?: string;
576
+ /** The paygate customer's own currency (set by its first subscription or invoice). */
577
+ currency?: string;
331
578
  deletedAt?: Date;
332
579
  }
333
580
  export interface PaygateCustomerResource extends MongoResource<PaygateCustomerRecord> {
@@ -375,6 +622,18 @@ export interface PaymentSubscriptionRecord extends ResourceRecord {
375
622
  lastEventId?: string;
376
623
  initialPropagatedAt?: Date;
377
624
  propagated?: PropagatedState;
625
+ /** The subscription's currency (lowercase). */
626
+ currency?: string;
627
+ checkoutSessionId?: string;
628
+ purchaseId?: string;
629
+ firstInvoiceId?: string;
630
+ country?: string;
631
+ email?: string;
632
+ amountTotalMinor?: number;
633
+ amountTaxMinor?: number;
634
+ termsAccepted?: boolean;
635
+ startRequestId?: string;
636
+ withdrawnAt?: Date;
378
637
  }
379
638
  export interface PaymentSubscriptionResource extends MongoResource<PaymentSubscriptionRecord> {
380
639
  byExternalId: (externalId: string, paygate: string) => Promise<PaymentSubscriptionRecord | null>;
@@ -405,6 +664,13 @@ export interface PaymentFulfillmentRecord extends ResourceRecord {
405
664
  refundedAt?: Date;
406
665
  disputedAt?: Date;
407
666
  disputeStatus?: string;
667
+ country?: string;
668
+ email?: string;
669
+ profileId?: string;
670
+ amountTotalMinor?: number;
671
+ amountTaxMinor?: number;
672
+ termsAccepted?: boolean;
673
+ purchaseId?: string;
408
674
  }
409
675
  export interface PaymentFulfillmentResource extends MongoResource<PaymentFulfillmentRecord> {
410
676
  byExternalId: (externalId: string, paygate: string) => Promise<PaymentFulfillmentRecord | null>;
@@ -455,12 +721,35 @@ export interface PaymentUsageCounterRecord extends ResourceRecord {
455
721
  }
456
722
  export interface PaymentUsageCounterResource extends MongoResource<PaymentUsageCounterRecord> {
457
723
  }
724
+ /** One currency option of a synced price. */
725
+ export interface SyncedPriceOption {
726
+ currency: string;
727
+ unitAmount: number;
728
+ }
729
+ /** A reusable price as the last sync left it — what `planPrices` and checkout read without Stripe. */
730
+ export interface SyncedPrice {
731
+ planSku: string;
732
+ priceId: string;
733
+ lookupKey: string;
734
+ /** The default currency and its amount. */
735
+ currency: string;
736
+ unitAmount: number;
737
+ /** `currency_options` besides the default currency. */
738
+ options: SyncedPriceOption[];
739
+ taxBehavior?: string;
740
+ interval?: 'month' | 'year';
741
+ sourceUnitAmount: number;
742
+ sourceCurrency: string;
743
+ syncedAt: Date;
744
+ }
458
745
  export interface FingerprintRecord extends ResourceRecord {
459
746
  sku: string;
460
747
  hash: string;
461
748
  productId?: string;
462
749
  /** The paygate object the fingerprint describes (a portal configuration id). */
463
750
  externalId?: string;
751
+ /** A product's synced reusable prices. */
752
+ prices?: SyncedPrice[];
464
753
  updatedAt: Date;
465
754
  }
466
755
  export interface FingerprintResource extends MongoResource<FingerprintRecord> {
@@ -561,5 +850,419 @@ export interface ReconcileAllResult {
561
850
  repaired: number;
562
851
  failed: number;
563
852
  }
853
+ /** Where a billing profile's country came from. */
854
+ export type BillingProfileSource = 'checkout' | 'customer' | 'manual';
855
+ /** One per organization: the billing country fixed at the first purchase (first write wins). */
856
+ export interface BillingProfileRecord extends ResourceRecord {
857
+ entityId: string;
858
+ country: string;
859
+ region: ConsumerRegion;
860
+ /** The charge currency, fixed with the country. */
861
+ currency: string;
862
+ /** The language of the legal copy. */
863
+ language: string;
864
+ source: BillingProfileSource;
865
+ paygate: string;
866
+ customerId?: string;
867
+ sessionId?: string;
868
+ /** The geolocated country of the request that started the locking checkout — VAT evidence. */
869
+ ipCountry?: string;
870
+ email?: string;
871
+ name?: string;
872
+ /** A business tax id was given at the locking checkout. */
873
+ business?: boolean;
874
+ lockedAt: Date;
875
+ createdAt: Date;
876
+ updatedAt?: Date;
877
+ }
878
+ export interface BillingProfileResource extends MongoResource<BillingProfileRecord> {
879
+ byEntity: (entityId: string) => Promise<BillingProfileRecord | null>;
880
+ }
881
+ /**
882
+ * One purchase — a contract and its withdrawal window: a paid one-time checkout (`top-up`) or a
883
+ * subscription's first invoice (`subscription`). Renewals are not purchases.
884
+ */
885
+ export interface PurchaseRecord extends ResourceRecord {
886
+ /** `stripe:<session id>` (one-time) or `stripe:<subscription id>`. */
887
+ purchaseId: string;
888
+ /** `CR-YYMMDD-XXXXXX` — what a consumer quotes. */
889
+ contractRef: string;
890
+ entityId: string;
891
+ kind: PurchaseKind;
892
+ paygate: string;
893
+ sessionId?: string;
894
+ subscriptionId?: string;
895
+ paymentIntentId?: string;
896
+ invoiceId?: string;
897
+ invoiceNumber?: string;
898
+ invoiceLineId?: string;
899
+ productSku: string;
900
+ planSku?: string;
901
+ profileId?: string;
902
+ country?: string;
903
+ region?: ConsumerRegion;
904
+ ipCountry?: string;
905
+ inScope: boolean;
906
+ language: string;
907
+ email?: string;
908
+ name?: string;
909
+ business?: boolean;
910
+ /** The charge currency. */
911
+ currency: string;
912
+ amountSubtotalMinor: number;
913
+ amountTaxMinor: number;
914
+ amountTotalMinor: number;
915
+ presentmentCurrency?: string;
916
+ presentmentAmountMinor?: number;
917
+ /** Amount checkout: the net value credited, in `amountCurrency`. */
918
+ netAmountMinor?: number;
919
+ amountCurrency?: string;
920
+ /** Quantity checkout: the units bought. */
921
+ units?: number;
922
+ taxBehavior?: string;
923
+ /**
924
+ * Stripe's own `consent.terms_of_service` of the checkout — absent when the session did not
925
+ * collect it (the policy's `checkoutTerms` off, or the fallback of a Dashboard without a terms URL).
926
+ */
927
+ termsAccepted?: boolean;
928
+ textVersion?: string;
929
+ copyVersion?: string;
930
+ startRequestId?: string;
931
+ /** When the consumer expressly requested the services (the start request) — time deductions count from here. */
932
+ servicesStartedAt?: Date;
933
+ /** When the confirmation mail was claimed — one claim per purchase, whatever the outcome of the send. */
934
+ confirmationMailAt?: Date;
935
+ purchasedAt: Date;
936
+ /** Exclusive end of the withdrawal window; absent outside the consumer-rights territories. */
937
+ deadline?: Date;
938
+ consentId?: string;
939
+ consentedAt?: Date;
940
+ withdrawalId?: string;
941
+ withdrawnAt?: Date;
942
+ /** Refunded so far on this purchase's payment, tax included. */
943
+ refundedMinor?: number;
944
+ /** Set once the whole payment is refunded — the window closes. */
945
+ refundedAt?: Date;
946
+ cancellationId?: string;
947
+ cancelEffectiveAt?: Date;
948
+ createdAt: Date;
949
+ updatedAt?: Date;
950
+ }
951
+ export interface PurchaseResource extends MongoResource<PurchaseRecord> {
952
+ byPurchaseId: (purchaseId: string) => Promise<PurchaseRecord | null>;
953
+ }
954
+ /** The request evidence a consumer act is recorded with (`requestOriginOf`). */
955
+ export interface RequestOrigin {
956
+ /** `cf-connecting-ip`, else the LAST `x-forwarded-for` entry, else `x-real-ip`, else the socket. */
957
+ ip?: string;
958
+ /** The raw `x-forwarded-for` header. */
959
+ forwardedFor?: string;
960
+ /** `user-agent`, at most 512 characters. */
961
+ userAgent?: string;
962
+ /** `cf-ipcountry`. */
963
+ ipCountry?: string;
964
+ acceptLanguage?: string;
965
+ /** The channel the request came through (`http`, `mcp`, …), when the application knows. */
966
+ via?: string;
967
+ }
968
+ /** Append-only: one express request — a performance consent or a subscription start request. */
969
+ export interface ConsumerConsentRecord extends ResourceRecord, RequestOrigin {
970
+ kind: ConsentKind;
971
+ entityId: string;
972
+ profileId?: string;
973
+ /** The person who gave it — the confirmation is mailed here. */
974
+ name?: string;
975
+ email?: string;
976
+ purchaseIds: string[];
977
+ planSku?: string;
978
+ /** The plan's name as the statement said it (`{{plan}}`). */
979
+ planName?: string;
980
+ textVersion: string;
981
+ copyVersion: string;
982
+ /** The language the statement was shown in. */
983
+ language: string;
984
+ uiLanguage?: string;
985
+ trader: string;
986
+ /** The statement exactly as rendered and recorded. */
987
+ text: {
988
+ request: string;
989
+ acknowledgement: string;
990
+ checkbox: string;
991
+ };
992
+ links: ConsumerRightsLinks;
993
+ /** The latest deadline among the covered purchases. */
994
+ deadline?: Date;
995
+ decidedAt: Date;
996
+ /** A start request stops being usable at this instant. */
997
+ expiresAt?: Date;
998
+ }
999
+ export interface ConsumerConsentResource extends MongoResource<ConsumerConsentRecord> {
1000
+ }
1001
+ /** Append-only: one withdrawal or cancellation declaration, matched to a contract or not. */
1002
+ export interface ConsumerDeclarationRecord extends ResourceRecord, RequestOrigin {
1003
+ kind: DeclarationKind;
1004
+ channel: DeclarationChannel;
1005
+ entityId?: string;
1006
+ purchaseId?: string;
1007
+ subscriptionId?: string;
1008
+ /** The contract as the consumer named it. */
1009
+ contractRef?: string;
1010
+ name: string;
1011
+ email: string;
1012
+ cancellationKind?: CancellationKind;
1013
+ reason?: string;
1014
+ effective?: 'earliest' | 'date';
1015
+ requestedDate?: string;
1016
+ language: string;
1017
+ textVersion?: string;
1018
+ copyVersion: string;
1019
+ receivedAt: Date;
1020
+ matched: boolean;
1021
+ profileId?: string;
1022
+ /** A repeated declaration of a contract already withdrawn from: the original's id. */
1023
+ duplicateOf?: string;
1024
+ /** The status decided on receipt (`WithdrawalStatus` / `CancellationStatus`); execution steps are events. */
1025
+ status: string;
1026
+ refundMinor?: number;
1027
+ currency?: string;
1028
+ effectiveAt?: Date;
1029
+ }
1030
+ export interface ConsumerDeclarationResource extends MongoResource<ConsumerDeclarationRecord> {
1031
+ }
1032
+ export type ConsumerEventAction = 'mail' | 'computed' | 'meter' | 'refund' | 'credit-note' | 'subscription-cancel' | 'cancel-scheduled' | 'observers' | 'lock' | 'lock-mismatch' | 'relock' | 'unlock' | 'duplicate' | 'checkout-terms-fallback';
1033
+ export type ConsumerRecordKind = 'purchase' | 'consent' | 'declaration' | 'profile' | 'checkout';
1034
+ /** Append-only: one execution or audit step. */
1035
+ export interface ConsumerEventRecord extends ResourceRecord {
1036
+ /** The purchase id, consent id, declaration id, or the entity id of a profile or a checkout. */
1037
+ recordId: string;
1038
+ recordKind: ConsumerRecordKind;
1039
+ entityId?: string;
1040
+ action: ConsumerEventAction;
1041
+ /** The mail kind of a `mail` event; the observer family of an `observers` one. */
1042
+ step?: string;
1043
+ ok: boolean;
1044
+ /** A mail deliberately not sent (a reserved domain, a renderer that suppressed it). */
1045
+ skipped?: boolean;
1046
+ externalId?: string;
1047
+ amountMinor?: number;
1048
+ currency?: string;
1049
+ /** JSON. */
1050
+ detail?: string;
1051
+ error?: string;
1052
+ at: Date;
1053
+ }
1054
+ export interface ConsumerEventResource extends MongoResource<ConsumerEventRecord> {
1055
+ }
1056
+ /** What a usage meter is told about the purchase it reads. */
1057
+ export interface PurchaseRef {
1058
+ purchaseId: string;
1059
+ kind: PurchaseKind;
1060
+ entityId: string;
1061
+ contractRef: string;
1062
+ productSku: string;
1063
+ planSku?: string;
1064
+ /** One-time purchases: the checkout session id. */
1065
+ sessionId?: string;
1066
+ /** Subscription purchases: the paygate subscription id. */
1067
+ subscriptionId?: string;
1068
+ invoiceId?: string;
1069
+ purchasedAt: Date;
1070
+ }
1071
+ export interface UsageQuery {
1072
+ entityId: string;
1073
+ purchase: PurchaseRef;
1074
+ /** The purchase's consent — before it the consumer bears no cost; absent: nothing is deductible. */
1075
+ after?: Date;
1076
+ at: Date;
1077
+ }
1078
+ export interface UsageReading {
1079
+ /** Units the purchase granted. */
1080
+ granted: number;
1081
+ /** Units of it used so far. */
1082
+ used: number;
1083
+ /** Units of it used strictly after `after` (0 without `after`). */
1084
+ usedAfter: number;
1085
+ /** Units of it that paid off an earlier overdraft when it was granted. */
1086
+ settled?: number;
1087
+ /** Units of it already taken back by an earlier (money) refund. */
1088
+ clawed?: number;
1089
+ remaining?: number;
1090
+ }
1091
+ /**
1092
+ * The application's reading of how much of one purchase was used — for a withdrawal's refund.
1093
+ * The deduction is `usedAfter + settled + clawed`.
1094
+ */
1095
+ export interface UsageMeter {
1096
+ used: (ctx: ApiContext, query: UsageQuery) => Promise<UsageReading>;
1097
+ }
1098
+ /** Who acts: the organization, and the person's prefill. */
1099
+ export interface ConsumerSubject {
1100
+ entityId: string;
1101
+ profileId?: string;
1102
+ name?: string;
1103
+ email?: string;
1104
+ /** `public` when an application matched a public declaration to this organization itself. */
1105
+ channel?: DeclarationChannel;
1106
+ }
1107
+ export type ConsumerMailKind = 'purchase' | 'consent' | 'start' | 'withdrawal' | 'cancellation';
1108
+ /** What a consumer-rights mail is rendered from. */
1109
+ export interface ConsumerMailData {
1110
+ kind: ConsumerMailKind;
1111
+ /** The purchase id, consent id or declaration id. */
1112
+ recordId: string;
1113
+ entityId?: string;
1114
+ language: string;
1115
+ to: string;
1116
+ name?: string;
1117
+ trader: TraderDef;
1118
+ links: ConsumerRightsLinks;
1119
+ purchase?: PurchaseRecord;
1120
+ purchases?: PurchaseRecord[];
1121
+ consent?: ConsumerConsentRecord;
1122
+ declaration?: ConsumerDeclarationRecord;
1123
+ }
1124
+ /**
1125
+ * Replace or suppress a consumer-rights mail: answer a message to send it instead, `null` to send
1126
+ * nothing (recorded as skipped), `undefined` to send the rendered one.
1127
+ */
1128
+ export type ConsumerMailRenderer = (kind: ConsumerMailKind, data: ConsumerMailData, rendered: MailMessage) => MailMessage | null | undefined | Promise<MailMessage | null | undefined>;
1129
+ export interface LockOptions {
1130
+ customerId?: string;
1131
+ sessionId?: string;
1132
+ ipCountry?: string;
1133
+ email?: string;
1134
+ name?: string;
1135
+ business?: boolean;
1136
+ /** The charge currency; default: an active subscription's, else the region's. */
1137
+ currency?: string;
1138
+ language?: string;
1139
+ /** `manual` only: replace an existing lock (audited as a `relock` event). */
1140
+ force?: boolean;
1141
+ by?: string;
1142
+ reason?: string;
1143
+ }
1144
+ /** Who removes a lock, and why — kept on the `unlock` event. */
1145
+ export interface UnlockOptions {
1146
+ by?: string;
1147
+ reason?: string;
1148
+ }
1149
+ export interface ConsumerReconcileOptions {
1150
+ /** How far back declarations, mails and observers are retried. Default 30 days. */
1151
+ since?: Date;
1152
+ /** The most items per step. Default 50. */
1153
+ limit?: number;
1154
+ }
1155
+ export interface ConsumerReconcileResult {
1156
+ retried: number;
1157
+ mailed: number;
1158
+ observed: number;
1159
+ backfilled: number;
1160
+ locked: number;
1161
+ failed: number;
1162
+ }
1163
+ /**
1164
+ * Lazy: reachable while the application is still being wired (`useMeter`, `useMailRenderer` before
1165
+ * the context initializes); the gateway's initialization initializes it at boot.
1166
+ */
1167
+ export interface ConsumerRightsService extends LazyService {
1168
+ /**
1169
+ * `false`: every paygate-calling method (`withdraw`, `cancel`, `reconcile`'s paygate steps) refuses.
1170
+ * An explicit `manage` of `appendConsumerRights` wins over the gateway's, whatever the order.
1171
+ */
1172
+ readonly managed: boolean;
1173
+ policy: () => Promise<ConsumerRightsPolicy | null>;
1174
+ /** The locked billing profile, or `null`. */
1175
+ profile: (entityId: string) => Promise<BillingProfileView | null>;
1176
+ /** Lock the billing country; the first write wins unless a `manual` lock is `force`d. */
1177
+ lock: (entityId: string, country: string, source: BillingProfileSource, opts?: LockOptions) => Promise<BillingProfileView>;
1178
+ /**
1179
+ * An operator removes the lock: the profile is deleted and an `unlock` event keeps it. No lazy lock
1180
+ * from the paygate customer follows (checkout, reconcile); the next completed purchase locks again.
1181
+ * @returns the profile as it was, or `null` when nothing was locked
1182
+ */
1183
+ unlock: (entityId: string, opts?: UnlockOptions) => Promise<BillingProfileView | null>;
1184
+ purchases: (entityId: string, opts?: {
1185
+ open?: boolean;
1186
+ at?: Date;
1187
+ }) => Promise<PurchaseView[]>;
1188
+ consentView: (entityId: string, at?: Date) => Promise<PerformanceConsentView>;
1189
+ /** @throws PerformanceConsentRequired (428) for a stale text version */
1190
+ recordConsent: (subject: ConsumerSubject, body: PerformanceConsentBody, origin?: RequestOrigin) => Promise<PerformanceConsentResponse>;
1191
+ /** @throws PerformanceConsentRequired while an open in-scope window has no consent */
1192
+ assertConsent: (entityId: string, at?: Date) => Promise<void>;
1193
+ startView: (entityId: string, planSku: string, opts?: {
1194
+ language?: string;
1195
+ }) => Promise<SubscriptionStartView>;
1196
+ /** @throws SubscriptionStartRequired (428) for a stale text version */
1197
+ /** `plan`: the plan's short name the statement says (default: its localized catalogue title). */
1198
+ recordStartRequest: (subject: ConsumerSubject, body: SubscriptionStartBody, origin?: RequestOrigin, opts?: {
1199
+ plan?: string;
1200
+ }) => Promise<SubscriptionStartResponse>;
1201
+ /**
1202
+ * The fresh start request bound to this entity and plan, or `null` when none is required.
1203
+ * @throws SubscriptionStartRequired
1204
+ */
1205
+ assertStartRequest: (entityId: string, planSku: string, startRequestId?: string) => Promise<ConsumerConsentRecord | null>;
1206
+ withdrawalCandidates: (entityId: string, subject?: Partial<ConsumerSubject>) => Promise<WithdrawalCandidateList>;
1207
+ /** `subject: null` — the public function: matched by contract reference and e-mail, never disclosed. */
1208
+ withdraw: (subject: ConsumerSubject | null, body: WithdrawalBody, origin?: RequestOrigin) => Promise<WithdrawalReceipt>;
1209
+ cancel: (subject: ConsumerSubject | null, body: CancellationBody, origin?: RequestOrigin) => Promise<CancellationReceipt>;
1210
+ useMeter: (meter: UsageMeter | null) => void;
1211
+ useMailRenderer: (renderer: ConsumerMailRenderer | null) => void;
1212
+ usageMeter: () => UsageMeter | null;
1213
+ mailRenderer: () => ConsumerMailRenderer | null;
1214
+ /** Retry refunds, credit notes, cancellations, mails and observers; backfill purchases and legacy locks. */
1215
+ reconcile: (opts?: ConsumerReconcileOptions) => Promise<ConsumerReconcileResult>;
1216
+ }
1217
+ /**
1218
+ * `appendConsumerRights` options. `manage`, `usage` and `stripe` apply to the service whenever the
1219
+ * call comes — before or after the gateway registered it; the resources' `dbAlias` / `serviceAlias`
1220
+ * are those of the first registration.
1221
+ */
1222
+ export interface ConsumerRightsOptions {
1223
+ /**
1224
+ * `false` in a process that never talks to the paygate (reads and consent asserts only). Absent:
1225
+ * the gateway's `manage`, else managed.
1226
+ */
1227
+ manage?: boolean;
1228
+ /** The application's usage meter; without one a withdrawal is left to an operator (`review`). */
1229
+ usage?: UsageMeter;
1230
+ alias?: string;
1231
+ /** The paygate client; default: the configured Stripe secret. */
1232
+ stripe?: StripeFactory;
1233
+ dbAlias?: string;
1234
+ serviceAlias?: string;
1235
+ }
1236
+ /** What a public declaration is throttled by. */
1237
+ export interface ConsumerThrottleKey {
1238
+ action: 'withdrawal' | 'cancellation';
1239
+ email: string;
1240
+ ip?: string;
1241
+ }
1242
+ /**
1243
+ * The hooks of `consumerRightsEntrypoints`. Every hook gets the request's context last, so an
1244
+ * application keeps its counters and lookups on the context, never in module state.
1245
+ */
1246
+ export interface ConsumerRightsHandlerOptions {
1247
+ /** The organization a signed-in request acts for. Default: `req.entity.id`. */
1248
+ resolveEntity?: (req: AbstractRequest, ctx: ApiContext) => string | null | undefined;
1249
+ /** The person's profile id and prefill. */
1250
+ subjectOf?: (req: AbstractRequest, ctx: ApiContext) => Partial<ConsumerSubject> | Promise<Partial<ConsumerSubject>>;
1251
+ /** Refuse a money-moving act (consent, start, withdraw, cancel) — e.g. an API-key request. */
1252
+ guardMoney?: (req: AbstractRequest, action: string, ctx: ApiContext) => void | Promise<void>;
1253
+ /** REQUIRED when the public subtree is bound: throw (e.g. 429) to refuse a public declaration. */
1254
+ throttle?: (req: AbstractRequest, key: ConsumerThrottleKey, ctx: ApiContext) => void | Promise<void>;
1255
+ /** The request evidence; default `requestOriginOf`. */
1256
+ metaOf?: (req: AbstractRequest, ctx: ApiContext) => RequestOrigin;
1257
+ /** The least time a public declaration takes to answer, matched or not. Default 1000 ms. */
1258
+ publicMinMs?: number;
1259
+ /** The plan's short name a start request's statement says (default: its localized catalogue title). */
1260
+ planNameOf?: (planSku: string, language: string, req: AbstractRequest, ctx: ApiContext) => string | undefined | Promise<string | undefined>;
1261
+ serviceAlias?: string;
1262
+ }
1263
+ export interface CheckoutReadHandlerOptions {
1264
+ resolveEntity?: (req: AbstractRequest, ctx: ApiContext) => string | null | undefined;
1265
+ gatewayAlias?: string;
1266
+ }
564
1267
  export {};
565
1268
  //# sourceMappingURL=types.d.ts.map