@happyvertical/smrt-commerce 0.51.33 → 0.51.34

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 (37) hide show
  1. package/AGENTS.md +17 -0
  2. package/README.md +88 -0
  3. package/dist/__tests__/helpers/crypto-rail.d.ts +69 -0
  4. package/dist/__tests__/helpers/crypto-rail.d.ts.map +1 -0
  5. package/dist/__tests__/helpers/fake-stripe.d.ts +1 -0
  6. package/dist/__tests__/helpers/fake-stripe.d.ts.map +1 -1
  7. package/dist/billing/btcpay.d.ts +40 -0
  8. package/dist/billing/btcpay.d.ts.map +1 -0
  9. package/dist/billing/credits.d.ts +6 -1
  10. package/dist/billing/credits.d.ts.map +1 -1
  11. package/dist/billing/crypto.d.ts +32 -0
  12. package/dist/billing/crypto.d.ts.map +1 -0
  13. package/dist/billing/events.d.ts +10 -1
  14. package/dist/billing/events.d.ts.map +1 -1
  15. package/dist/billing/index.d.ts +5 -1
  16. package/dist/billing/index.d.ts.map +1 -1
  17. package/dist/billing/invoice-payments.d.ts +29 -0
  18. package/dist/billing/invoice-payments.d.ts.map +1 -0
  19. package/dist/billing/payment-attempts.d.ts +143 -0
  20. package/dist/billing/payment-attempts.d.ts.map +1 -0
  21. package/dist/billing/provider.d.ts +97 -1
  22. package/dist/billing/provider.d.ts.map +1 -1
  23. package/dist/billing/runtime.d.ts +107 -4
  24. package/dist/billing/runtime.d.ts.map +1 -1
  25. package/dist/billing/stripe.d.ts +5 -0
  26. package/dist/billing/stripe.d.ts.map +1 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +4055 -2859
  30. package/dist/index.js.map +1 -1
  31. package/dist/manifest.json +920 -91
  32. package/dist/models/billing.d.ts +103 -0
  33. package/dist/models/billing.d.ts.map +1 -1
  34. package/dist/models/index.d.ts +1 -1
  35. package/dist/models/index.d.ts.map +1 -1
  36. package/dist/smrt-knowledge.json +319 -8
  37. package/package.json +10 -9
package/AGENTS.md CHANGED
@@ -100,6 +100,23 @@ for usage.
100
100
  `WRITTEN_OFF` (a later payment is recorded; the status stays).
101
101
  - **`Invoice.providerTaxAmount`** is added to line-item tax; it is
102
102
  server-managed (not API-writable). `toAccountingInput()` emits major units.
103
+ - **Payment rails (#3138).** A runtime has one issuing `provider` and any
104
+ number of `paymentProviders` (unique names, one inbox namespace each; a
105
+ provider with `capabilities.issuesInvoices === false` can never issue).
106
+ `observe()` resolves the provider from the delivery namespace, never the
107
+ payload. Crypto rails implement the port over `@happyvertical/payments`'
108
+ `CryptoCheckoutGateway`; never call BTCPay (or any gateway) from here.
109
+ Settlement is decided by the pure `decideAttempt()` from gateway state and
110
+ `paymentPolicy` — the gateway's `settled` is authoritative and nothing here
111
+ counts confirmations. A `BillingPaymentAttempt` (`(provider, checkout_id)`
112
+ deterministic id) records every state and settles once; grants and payments
113
+ are keyed by checkout id. Invoice payments close the issuer's invoice out of
114
+ band in `observe()` (idempotent) before `project()` records the payment, and
115
+ `settlePaidInvoice` skips (records nothing for) a `paidOutOfBand` invoice
116
+ the rail latched with `outOfBandRequestedAt`; other out-of-band closes are
117
+ recorded as `OTHER` payments. Rails never save cards or charge tax: a taxed
118
+ credit purchase on a rail needs an explicit `automaticTax: false`. Exceptions are flags for operators;
119
+ nothing reverses or refunds automatically.
103
120
  - **Known limits**: write-offs post no bad-debt journal (AR stays until paid
104
121
  or journaled by an operator); discounts still reach Stripe as negative lines (the SDK's
105
122
  line `discount` would change the lines a replayed push reconciles, so it
package/README.md CHANGED
@@ -373,6 +373,94 @@ const evaluator = await SpendingPolicyEvaluator.create({
373
373
  `automaticTax: false` to keep them untaxed), and Stripe customers are
374
374
  created idempotently.
375
375
 
376
+ ### Payment rails: BTC and other crypto (#3138)
377
+
378
+ A seller runtime can take payments on more than one **rail**. The issuing
379
+ `provider` (Stripe) still issues, taxes, and emails every invoice; extra rails
380
+ in `paymentProviders` let a payer choose, per payment, to pay an invoice or buy
381
+ prepaid credit another way. The crypto rail runs short-lived, fiat-priced
382
+ checkouts through `@happyvertical/payments`' provider-neutral
383
+ `CryptoCheckoutGateway` — BTCPay Server at launch — so another gateway can
384
+ replace BTCPay without changing this package or its consumers.
385
+
386
+ ```ts
387
+ import {
388
+ BillingRuntime,
389
+ createBtcPayBillingProvider,
390
+ createStripeBillingProvider,
391
+ } from '@happyvertical/smrt-commerce';
392
+
393
+ const btcpay = createBtcPayBillingProvider({
394
+ baseUrl, apiKey, storeId, // one BTCPay store per seller entity
395
+ webhookSecret, metadataSecret, // from the host's secret store, by name
396
+ speedPolicy: 'LowMediumSpeed', // settle after 2 confirmations (BTCPay offers 0/1/2/6)
397
+ rateSource: 'kraken',
398
+ minimumAmount: { CAD: 500, USD: 500 },
399
+ });
400
+ const billing = await BillingRuntime.create({
401
+ db, sellerTenantId, kind: 'provider',
402
+ provider: createStripeBillingProvider({ stripe, webhookSecret }),
403
+ paymentProviders: [btcpay],
404
+ paymentPolicy: { latePaymentPolicy: 'review', refundBasis: 'original_native' },
405
+ billingRelationships,
406
+ ledger: { ...ledger, cryptoHoldingsAccountId, fxGainLossAccountId, feesAccountId },
407
+ });
408
+
409
+ // Prepaid credit or an issued invoice, paid with BTC:
410
+ await billing.createCreditCheckout({ ...purchase, provider: 'btcpay' });
411
+ await billing.createInvoicePayment({ invoiceId, provider: 'btcpay', purchaseId, successUrl, cancelUrl });
412
+
413
+ // Webhook route for the rail (BTCPay signs with its own header):
414
+ await billing.acceptWebhook(rawBody, '', { provider: 'btcpay', headers: request.headers });
415
+ await billing.processEvents();
416
+ ```
417
+
418
+ - **Settlement is the gateway's.** Credit is granted and invoices are paid
419
+ only when the gateway reports `settled` under its own confirmation policy;
420
+ this package never counts confirmations. BTCPay offers 0, 1, 2 or 6
421
+ confirmations; the default is `LowMediumSpeed` (2 confirmations).
422
+ - **Payment attempts.** Every rail checkout is a `BillingPaymentAttempt`
423
+ recording the locked fiat price, fiat and native amounts received, rate and
424
+ rate source, each payment's txid, rail and fee, a timeline of status changes,
425
+ and what settlement produced. `listPaymentAttempts()` feeds "payment
426
+ confirming" displays and operator queues; `refreshPaymentAttempts()` is the
427
+ polling fallback for missed webhooks.
428
+ - **Dunning pauses** for an invoice while a payment for it is confirming
429
+ (0-conf seen); if the payment then expires or is invalidated the payer's
430
+ standing is re-applied.
431
+ - **Invoices paid on a rail** are closed at the issuer with
432
+ `markInvoicePaidOutOfBand` (Stripe `paid_out_of_band`), so Stripe stops
433
+ collecting; Stripe's own `paid` event then records nothing more.
434
+ `createInvoicePayment` refuses when the issuing provider cannot do that.
435
+ - **Exceptions never auto-refund.** Underpaid, overpaid, late, manually marked
436
+ (at the gateway), invalidated-after-settlement, and paid-twice attempts are
437
+ flagged for an operator (`resolvePaymentAttempt`). Per-seller
438
+ `paymentPolicy` sets under/overpayment tolerances (basis points), late
439
+ payments (`review` | `accept`), manually marked checkouts, hold vs convert
440
+ (`conversionHandler`), and the refund basis.
441
+ - **Ledger.** Receipts are booked at the locked fiat amount into
442
+ `cryptoHoldingsAccountId` (default `cashAccountId`); money received above
443
+ the price is booked as customer credit (prepaid-credit liability).
444
+ `recordManualRefund()` refunds from that excess first, then from purchased
445
+ credit (or an invoice payment kept as credit because the invoice was paid
446
+ elsewhere) — capped cumulatively, once per reference; an invoice payment
447
+ applied to its invoice is reversed at the issuer, not here.
448
+ `recordCryptoConversion()` posts a conversion with FX gain/loss.
449
+ - **Upgrading.** Additive schema: `_smrt_billing_payment_attempts` (run
450
+ `smrt db:migrate`). A runtime without `paymentProviders` never reads it.
451
+ - **One live payment per invoice.** The issuer's own `paid` event for an
452
+ invoice a rail closed out of band records nothing (the rail records it); an
453
+ out-of-band close made by someone else (wire, cheque) is recorded as an
454
+ `OTHER`-method payment; a real card payment made while a rail payment
455
+ confirms is recorded and the rail money is flagged `invoice_already_paid`.
456
+ An issuer close whose rail payment never settles is flagged
457
+ `out_of_band_without_settlement`: reopen the invoice at the issuer, then
458
+ `resolvePaymentAttempt()` it, after which a later out-of-band close is
459
+ recorded normally.
460
+ - **Entities.** Each legal entity is its own seller runtime with its own
461
+ store, keys, and ledger. Inter-entity resale is ordinary reseller billing
462
+ between two sellers, payable on any rail the selling entity offers.
463
+
376
464
  See [`AGENTS.md`](./AGENTS.md#billing-period-close-3060) for invariants and
377
465
  known limits.
378
466
 
@@ -0,0 +1,69 @@
1
+ /**
2
+ * A crypto payment rail world for #3138: the billing fixture's Stripe
3
+ * issuing provider plus an in-memory `CryptoCheckoutGateway`, wired into one
4
+ * seller runtime. Shared by the SQLite suite and the PostgreSQL lane.
5
+ */
6
+ import { type CreateCryptoCheckoutInput, type CryptoCheckout, type CryptoCheckoutException, type CryptoCheckoutGateway, type CryptoCheckoutPayment, type CryptoCheckoutStatus } from '@happyvertical/payments';
7
+ import type { DatabaseInterface } from '@happyvertical/smrt-core/migrations';
8
+ import type { BillingPaymentPolicy } from '../../billing/payment-attempts.js';
9
+ import type { BillingProvider } from '../../billing/provider.js';
10
+ import { type BillingLedgerAccounts, BillingRuntime } from '../../billing/runtime.js';
11
+ import { type BillingWorld } from './billing-fixture.js';
12
+ export declare const RAIL_METADATA_SECRET = "rail-metadata-secret";
13
+ export declare const RAIL_SIGNATURE = "fake-rail-ok";
14
+ interface FakeCheckout {
15
+ id: string;
16
+ orderId: string;
17
+ amount: number;
18
+ currency: string;
19
+ metadata: Record<string, string>;
20
+ status: CryptoCheckoutStatus;
21
+ exception: CryptoCheckoutException;
22
+ amountPaid: number;
23
+ payments: CryptoCheckoutPayment[];
24
+ owned: boolean;
25
+ /** Settlement asset override (default BTC). */
26
+ asset?: string;
27
+ }
28
+ /** An in-memory gateway: tests move checkouts through their states. */
29
+ export declare class FakeCryptoGateway implements CryptoCheckoutGateway {
30
+ readonly id = "btcpay";
31
+ readonly checkouts: Map<string, FakeCheckout>;
32
+ created: number;
33
+ private counter;
34
+ createCheckout(input: CreateCryptoCheckoutInput): Promise<CryptoCheckout>;
35
+ getCheckout(checkoutId: string): Promise<CryptoCheckout>;
36
+ listCheckouts(input: {
37
+ orderId: string;
38
+ }): Promise<CryptoCheckout[]>;
39
+ verifyWebhook(rawBody: string, headers: Headers | Record<string, string | undefined>): {
40
+ eventId: string;
41
+ checkoutId: string | null;
42
+ type: string;
43
+ redelivery: boolean;
44
+ };
45
+ /** Move a checkout: `paid` is fiat minor units received. */
46
+ set(checkoutId: string, status: CryptoCheckoutStatus, options?: {
47
+ exception?: CryptoCheckoutException;
48
+ paid?: number;
49
+ paymentStatus?: CryptoCheckoutPayment['status'];
50
+ }): void;
51
+ private view;
52
+ }
53
+ export interface RailWorld extends BillingWorld {
54
+ gateway: FakeCryptoGateway;
55
+ rail: BillingProvider;
56
+ runtime: BillingRuntime;
57
+ railLedger: BillingLedgerAccounts;
58
+ /** Provider invoice ids closed as paid out of band. */
59
+ outOfBand: string[];
60
+ /** Deliver a signed rail webhook for a checkout and process events. */
61
+ railEvent(checkoutId: string, eventId?: string): Promise<void>;
62
+ }
63
+ export declare function createRailWorld(db: DatabaseInterface, options?: {
64
+ paymentPolicy?: Partial<BillingPaymentPolicy>;
65
+ /** Give Stripe the out-of-band method (default true). */
66
+ outOfBand?: boolean;
67
+ }): Promise<RailWorld>;
68
+ export {};
69
+ //# sourceMappingURL=crypto-rail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto-rail.d.ts","sourceRoot":"","sources":["../../../src/__tests__/helpers/crypto-rail.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAE1B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAE1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAI7E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,KAAK,EACV,eAAe,EAEhB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,KAAK,qBAAqB,EAC1B,cAAc,EACf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,KAAK,YAAY,EAGlB,MAAM,sBAAsB,CAAC;AAG9B,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAC3D,eAAO,MAAM,cAAc,iBAAiB,CAAC;AAG7C,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,SAAS,EAAE,uBAAuB,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,qBAAqB,EAAE,CAAC;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,uEAAuE;AACvE,qBAAa,iBAAkB,YAAW,qBAAqB;IAC7D,QAAQ,CAAC,EAAE,YAAY;IACvB,QAAQ,CAAC,SAAS,4BAAmC;IACrD,OAAO,SAAK;IACZ,OAAO,CAAC,OAAO,CAAK;IAEd,cAAc,CAClB,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,cAAc,CAAC;IAyBpB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAOxD,aAAa,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAM1E,aAAa,CACX,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;;;;;;IAsBvD,4DAA4D;IAC5D,GAAG,CACD,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,oBAAoB,EAC5B,OAAO,GAAE;QACP,SAAS,CAAC,EAAE,uBAAuB,CAAC;QACpC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,aAAa,CAAC,EAAE,qBAAqB,CAAC,QAAQ,CAAC,CAAC;KAC5C,GACL,IAAI;IA6BP,OAAO,CAAC,IAAI;CAsBb;AAED,MAAM,WAAW,SAAU,SAAQ,YAAY;IAC7C,OAAO,EAAE,iBAAiB,CAAC;IAC3B,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,qBAAqB,CAAC;IAClC,uDAAuD;IACvD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,uEAAuE;IACvE,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChE;AAID,wBAAsB,eAAe,CACnC,EAAE,EAAE,iBAAiB,EACrB,OAAO,GAAE;IACP,aAAa,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC9C,yDAAyD;IACzD,SAAS,CAAC,EAAE,OAAO,CAAC;CAChB,GACL,OAAO,CAAC,SAAS,CAAC,CAmFpB"}
@@ -39,6 +39,7 @@ interface FakeInvoice {
39
39
  amount_remaining: number;
40
40
  metadata: Record<string, string>;
41
41
  sent: number;
42
+ paid_out_of_band?: boolean;
42
43
  }
43
44
  interface FakeSession {
44
45
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"fake-stripe.d.ts","sourceRoot":"","sources":["../../../src/__tests__/helpers/fake-stripe.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAG1E,eAAO,MAAM,cAAc,uBAAuB,CAAC;AAEnD,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,UAAU,eAAe;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,eAAe,CAAC;IAC7D,iBAAiB,EAAE,cAAc,GAAG,sBAAsB,CAAC;IAC3D,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IACxC,cAAc,EAAE,MAAM,GAAG,QAAQ,GAAG,qBAAqB,CAAC;IAC1D,aAAa,EAAE,OAAO,CAAC;IACvB,uBAAuB,EAAE,OAAO,CAAC;IACjC,0BAA0B,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,gEAAgE;AAChE,MAAM,MAAM,gBAAgB,GACxB,SAAS,GACT,YAAY,GACZ,SAAS,GACT,yBAAyB,CAAC;AAE9B,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,gBAAgB,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAClD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AA4CD,qBAAa,UAAU;IACrB,QAAQ,CAAC,SAAS,4BAAmC;IACrD,QAAQ,CAAC,YAAY,+BAAsC;IAC3D,QAAQ,CAAC,QAAQ,2BAAkC;IACnD,QAAQ,CAAC,QAAQ,2BAAkC;IACnD,QAAQ,CAAC,cAAc,iCAAwC;IAC/D,4DAA4D;IAC5D,UAAU,UAAQ;IAClB,iEAAiE;IACjE,QAAQ,CAAC,KAAK,gCAAuC;IACrD,QAAQ,CAAC,aAAa,uCAA8C;IACpE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAM;IAC9E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAGvB;IACJ,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,OAAO,CAAK;IAEpB,OAAO,CAAC,MAAM;IAKd,8CAA8C;IAC9C,IAAI,CACF,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,QAAQ,GAAG,OAAkB,EACnC,KAAK,SAAI,GACR,IAAI;IAIP,QAAQ,IAAI,OAAO,CAAC,wBAAwB,CAAC;IAW7C,QAAQ,CAAC,KAAK,GACZ,OAAO,MAAM,GAAG,GAAG,GAAG,OAAO,EAC7B,OAAO,WAAW,KACjB,OAAO,CAAC,QAAQ,CAAC,CA+ClB;IAEF,OAAO,CAAC,KAAK;IAkPb,OAAO,CAAC,aAAa;IAwBrB,OAAO,CAAC,WAAW;IAgBnB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,IAAI;IAqBZ,6CAA6C;IAC7C,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAQ5B;;;OAGG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ;IAkB7C;;;;;OAKG;IACH,eAAe,CACb,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAO,GACzE,WAAW;IA2Bd,OAAO,CAAC,mBAAmB;IA8C3B,wEAAwE;IACxE,mBAAmB,CACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,WAAW,GAAG,QAAQ,GAC7B,iBAAiB;IAWpB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,IAAI;IAMxE,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,EAAE;CAMlD;AAED,oDAAoD;AACpD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,CAOA;AAID,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE;IACP,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,EACD,aAAa,SAAS,EACtB,IAAI,SAA+B,GAClC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAmBzB;AAED,qEAAqE;AACrE,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM,GACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB"}
1
+ {"version":3,"file":"fake-stripe.d.ts","sourceRoot":"","sources":["../../../src/__tests__/helpers/fake-stripe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * BTCPay Server as a crypto payment rail (#3138): sugar over
3
+ * {@link createCryptoBillingProvider} with the SDK's BTCPay checkout gateway.
4
+ * One BTCPay store per seller; keys and secrets come from the host's secret
5
+ * store, never from this package.
6
+ */
7
+ import { type BtcpayClientOptions, type BtcpaySpeedPolicy } from '@happyvertical/payments/btcpay';
8
+ import type { BillingProvider } from './provider.js';
9
+ export interface BtcPayBillingProviderOptions {
10
+ /** Server origin, for example `https://btcpay.example.com`. */
11
+ baseUrl: string;
12
+ /** Store-scoped key: `canviewinvoices` + `cancreateinvoice` suffice. */
13
+ apiKey: string;
14
+ storeId: string;
15
+ /** The store webhook's secret. */
16
+ webhookSecret: string;
17
+ /** Secret signing the `smrt_*` checkout metadata. */
18
+ metadataSecret: string;
19
+ /**
20
+ * Confirmations before BTCPay settles on-chain: `HighSpeed` 0,
21
+ * `MediumSpeed` 1, `LowMediumSpeed` 2 (default, the owner's settlement
22
+ * policy), `LowSpeed` 6.
23
+ */
24
+ speedPolicy?: BtcpaySpeedPolicy;
25
+ /** Default `['BTC-CHAIN']`; add `BTC-LN` once the store has Lightning. */
26
+ paymentMethods?: string[];
27
+ expirationMinutes?: number;
28
+ monitoringMinutes?: number;
29
+ /** BTCPay's own underpayment tolerance, percent (default 0). */
30
+ paymentTolerance?: number;
31
+ /** Label of the store's rate source, recorded on every payment. */
32
+ rateSource?: string;
33
+ /** Minimum checkout per currency, minor units. */
34
+ minimumAmount?: Record<string, number>;
35
+ /** Provider name (default `btcpay`). */
36
+ name?: string;
37
+ fetch?: BtcpayClientOptions['fetch'];
38
+ }
39
+ export declare function createBtcPayBillingProvider(options: BtcPayBillingProviderOptions): BillingProvider;
40
+ //# sourceMappingURL=btcpay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"btcpay.d.ts","sourceRoot":"","sources":["../../src/billing/btcpay.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EAEvB,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,MAAM,WAAW,4BAA4B;IAC3C,+DAA+D;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,cAAc,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,mBAAmB,CAAC,OAAO,CAAC,CAAC;CACtC;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,4BAA4B,GACpC,eAAe,CAsBjB"}
@@ -1,4 +1,4 @@
1
- import type { BillingProviderCheckoutSession } from './provider.js';
1
+ import { type BillingProviderCheckoutSession } from './provider.js';
2
2
  import type { BillingRuntime } from './runtime.js';
3
3
  export declare const CREDIT_PURCHASE_PURPOSE = "credit_purchase";
4
4
  export interface CreateCreditCheckoutInput {
@@ -27,6 +27,11 @@ export interface CreateCreditCheckoutInput {
27
27
  * automatically charged invoices (#3139).
28
28
  */
29
29
  savePaymentMethod?: boolean;
30
+ /**
31
+ * The payment rail to pay with (a provider name from the runtime's
32
+ * `provider` or `paymentProviders`; default the issuing provider, #3138).
33
+ */
34
+ provider?: string;
30
35
  }
31
36
  /** The checkout metadata a completed purchase is settled from. */
32
37
  export interface CreditPurchaseMetadata {
@@ -1 +1 @@
1
- {"version":3,"file":"credits.d.ts","sourceRoot":"","sources":["../../src/billing/credits.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAQnD,eAAO,MAAM,uBAAuB,oBAAoB,CAAC;AAEzD,MAAM,WAAW,yBAAyB;IACxC,yDAAyD;IACzD,gBAAgB,EAAE,MAAM,CAAC;IACzB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,kEAAkE;AAClE,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAuBD,uEAAuE;AACvE,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1B,sBAAsB,GAAG,IAAI,CAwB/B;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,8BAA8B,CAAC,CA4FzC"}
1
+ {"version":3,"file":"credits.d.ts","sourceRoot":"","sources":["../../src/billing/credits.ts"],"names":[],"mappings":"AAkBA,OAAO,EACL,KAAK,8BAA8B,EAEpC,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAQnD,eAAO,MAAM,uBAAuB,oBAAoB,CAAC;AAEzD,MAAM,WAAW,yBAAyB;IACxC,yDAAyD;IACzD,gBAAgB,EAAE,MAAM,CAAC;IACzB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,kEAAkE;AAClE,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAuBD,uEAAuE;AACvE,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1B,sBAAsB,GAAG,IAAI,CAwB/B;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,8BAA8B,CAAC,CAwHzC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * A crypto payment rail for the {@link BillingProvider} port (#3138).
3
+ *
4
+ * The rail runs short-lived, fiat-priced checkouts through a
5
+ * `CryptoCheckoutGateway` from `@happyvertical/payments` — BTCPay at launch,
6
+ * any other implementation of the port later. It never issues invoices: the
7
+ * runtime's issuing provider (Stripe) does, and this rail pays them or buys
8
+ * prepaid credit. Settlement is the gateway's decision (its confirmation
9
+ * policy); this package never counts confirmations.
10
+ */
11
+ import { type CryptoCheckoutGateway } from '@happyvertical/payments';
12
+ import { type BillingProvider } from './provider.js';
13
+ export interface CryptoBillingProviderOptions {
14
+ /** A checkout gateway, for example `createBtcpayCheckoutGateway()`. */
15
+ gateway: CryptoCheckoutGateway;
16
+ /**
17
+ * Secret the `smrt_*` checkout metadata is signed with. Rotating it
18
+ * strands checkouts created before the rotation.
19
+ */
20
+ metadataSecret: string;
21
+ /** Provider name on local rows and in the inbox (default the gateway id). */
22
+ name?: string;
23
+ /**
24
+ * Smallest checkout accepted, per currency, in minor units (fee and dust
25
+ * economics). A currency without an entry has no minimum.
26
+ */
27
+ minimumAmount?: Record<string, number>;
28
+ }
29
+ export declare function createCryptoBillingProvider(options: CryptoBillingProviderOptions): BillingProvider;
30
+ /** Exact decimal string → integer atomic units; rejects excess precision. */
31
+ export declare function decimalToAtomic(value: string, exponent: number): number;
32
+ //# sourceMappingURL=crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/billing/crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAEL,KAAK,qBAAqB,EAG3B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAGL,KAAK,eAAe,EAMrB,MAAM,eAAe,CAAC;AASvB,MAAM,WAAW,4BAA4B;IAC3C,uEAAuE;IACvE,OAAO,EAAE,qBAAqB,CAAC;IAC/B;;;OAGG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAKD,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,4BAA4B,GACpC,eAAe,CAqHjB;AAkED,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAYvE"}
@@ -10,7 +10,8 @@
10
10
  */
11
11
  import { type ForgeProjector } from '@happyvertical/smrt-jobs';
12
12
  import { type SavedCard } from './cards.js';
13
- import type { BillingProviderCheckoutState, BillingProviderEvent, BillingProviderInvoiceState, BillingProviderSubscriptionState } from './provider.js';
13
+ import { type AttemptTarget } from './payment-attempts.js';
14
+ import type { BillingPaymentAttemptState, BillingProviderCheckoutState, BillingProviderEvent, BillingProviderInvoiceState, BillingProviderSubscriptionState } from './provider.js';
14
15
  import type { BillingRuntime } from './runtime.js';
15
16
  type InvoiceEvent = Extract<BillingProviderEvent, {
16
17
  kind: 'invoice';
@@ -24,6 +25,9 @@ type CheckoutEvent = Extract<BillingProviderEvent, {
24
25
  type PaymentEvent = Extract<BillingProviderEvent, {
25
26
  kind: 'payment';
26
27
  }>;
28
+ type AttemptEvent = Extract<BillingProviderEvent, {
29
+ kind: 'payment_attempt';
30
+ }>;
27
31
  type ObservedEvent = {
28
32
  event: InvoiceEvent;
29
33
  invoice: BillingProviderInvoiceState;
@@ -39,6 +43,11 @@ type ObservedEvent = {
39
43
  } | {
40
44
  event: PaymentEvent;
41
45
  paymentId: string;
46
+ } | {
47
+ event: AttemptEvent;
48
+ providerName: string;
49
+ attempt: BillingPaymentAttemptState;
50
+ target: AttemptTarget;
42
51
  };
43
52
  /** Apply up to `limit` queued events for a runtime; returns how many ran. */
44
53
  export declare function processBillingEvents(runtime: BillingRuntime, limit: number): Promise<number>;
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/billing/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,0BAA0B,CAAC;AAoBlC,OAAO,EAKL,KAAK,SAAS,EAEf,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EACV,4BAA4B,EAC5B,oBAAoB,EACpB,2BAA2B,EAC3B,gCAAgC,EACjC,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAInD,KAAK,YAAY,GAAG,OAAO,CAAC,oBAAoB,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AACvE,KAAK,iBAAiB,GAAG,OAAO,CAC9B,oBAAoB,EACpB;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,CACzB,CAAC;AACF,KAAK,aAAa,GAAG,OAAO,CAC1B,oBAAoB,EACpB;IAAE,IAAI,EAAE,oBAAoB,CAAA;CAAE,CAC/B,CAAC;AACF,KAAK,YAAY,GAAG,OAAO,CAAC,oBAAoB,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AAEvE,KAAK,aAAa,GACd;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,2BAA2B,CAAA;CAAE,GAC7D;IACE,KAAK,EAAE,iBAAiB,CAAC;IACzB,YAAY,EAAE,gCAAgC,CAAC;CAChD,GACD;IACE,KAAK,EAAE,aAAa,CAAC;IACrB,6DAA6D;IAC7D,QAAQ,EAAE,4BAA4B,GAAG,IAAI,CAAC;IAC9C,8DAA8D;IAC9D,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;CACxB,GACD;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAI/C,6EAA6E;AAC7E,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAkBjB;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,cAAc,GACtB,cAAc,CAAC,aAAa,CAAC,CAiF/B"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/billing/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,0BAA0B,CAAC;AAqBlC,OAAO,EAKL,KAAK,SAAS,EAEf,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,KAAK,aAAa,EAInB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACV,0BAA0B,EAE1B,4BAA4B,EAC5B,oBAAoB,EACpB,2BAA2B,EAC3B,gCAAgC,EACjC,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAInD,KAAK,YAAY,GAAG,OAAO,CAAC,oBAAoB,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AACvE,KAAK,iBAAiB,GAAG,OAAO,CAC9B,oBAAoB,EACpB;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,CACzB,CAAC;AACF,KAAK,aAAa,GAAG,OAAO,CAC1B,oBAAoB,EACpB;IAAE,IAAI,EAAE,oBAAoB,CAAA;CAAE,CAC/B,CAAC;AACF,KAAK,YAAY,GAAG,OAAO,CAAC,oBAAoB,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AACvE,KAAK,YAAY,GAAG,OAAO,CAAC,oBAAoB,EAAE;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,CAAC,CAAC;AAE/E,KAAK,aAAa,GACd;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,2BAA2B,CAAA;CAAE,GAC7D;IACE,KAAK,EAAE,iBAAiB,CAAC;IACzB,YAAY,EAAE,gCAAgC,CAAC;CAChD,GACD;IACE,KAAK,EAAE,aAAa,CAAC;IACrB,6DAA6D;IAC7D,QAAQ,EAAE,4BAA4B,GAAG,IAAI,CAAC;IAC9C,8DAA8D;IAC9D,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;CACxB,GACD;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC1C;IACE,KAAK,EAAE,YAAY,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,0BAA0B,CAAC;IACpC,MAAM,EAAE,aAAa,CAAC;CACvB,CAAC;AAIN,6EAA6E;AAC7E,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAkBjB;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,cAAc,GACtB,cAAc,CAAC,aAAa,CAAC,CAqG/B"}
@@ -3,12 +3,16 @@
3
3
  * card on file, and automatic top-ups (#3139).
4
4
  * @packageDocumentation
5
5
  */
6
+ export { type BtcPayBillingProviderOptions, createBtcPayBillingProvider, } from './btcpay.js';
6
7
  export type { CreateCardSetupCheckoutInput } from './cards.js';
7
8
  export type { CreateCreditCheckoutInput } from './credits.js';
9
+ export { type CryptoBillingProviderOptions, createCryptoBillingProvider, } from './crypto.js';
8
10
  export { addBillingMonths, billingPeriodContaining, lastEndedBillingPeriod, prorateMinorUnits, type ScheduledBillingPeriod, } from './cycles.js';
11
+ export { type CreateInvoicePaymentInput, INVOICE_PAYMENT_PURPOSE, } from './invoice-payments.js';
9
12
  export { type EnqueueBillingJobOptions, enqueueBillingEvents, enqueueBillingPeriodClose, getBillingRuntime, registerBillingRuntime, unregisterBillingRuntime, } from './jobs.js';
13
+ export { type BillingPaymentPolicy, type CryptoConversionInput, type CryptoSettlement, decideAttempt, type ManualRefundInput, type ManualRefundResult, } from './payment-attempts.js';
10
14
  export { type BillingPeriod, BillingPeriodCloseError, type ClosePeriodInput, type PeriodCloseGroupResult, type PeriodCloseOutcome, type PeriodCloseResult, previousCalendarMonth, } from './period-close.js';
11
- export { type BillingChargeStatus, type BillingCollectionMethod, type BillingInvoiceEventType, type BillingProvider, type BillingProviderChargeInput, type BillingProviderChargeResult, type BillingProviderCheckoutInput, type BillingProviderCheckoutSession, type BillingProviderCheckoutState, type BillingProviderCustomerInput, type BillingProviderEvent, type BillingProviderInvoiceInput, type BillingProviderInvoiceLine, type BillingProviderInvoiceState, type BillingProviderInvoiceStatus, type BillingProviderSetupCheckoutInput, type BillingProviderSubscriptionState, BillingWebhookVerificationError, } from './provider.js';
15
+ export { type BillingChargeStatus, type BillingCollectionMethod, type BillingInvoiceEventType, type BillingPaymentAttemptException, type BillingPaymentAttemptPayment, type BillingPaymentAttemptState, type BillingPaymentAttemptStatus, type BillingProvider, type BillingProviderCapabilities, type BillingProviderChargeInput, type BillingProviderChargeResult, type BillingProviderCheckoutInput, type BillingProviderCheckoutSession, type BillingProviderCheckoutState, type BillingProviderCustomerInput, type BillingProviderEvent, type BillingProviderInvoiceInput, type BillingProviderInvoiceLine, type BillingProviderInvoiceState, type BillingProviderInvoiceStatus, type BillingProviderSetupCheckoutInput, type BillingProviderSubscriptionState, BillingProviderUnsupportedError, BillingWebhookVerificationError, providerCapabilities, } from './provider.js';
12
16
  export { type BillingLedgerAccounts, BillingRuntime, type BillingRuntimeOptions, type EnsureProviderCustomerOptions, type PayerStandingChange, type PayerStandingHook, type SyncedBillingAccount, type UpsertBillingAccountInput, } from './runtime.js';
13
17
  export { createStripeBillingProvider, type StripeBillingProviderOptions, } from './stripe.js';
14
18
  export type { AutoTopUpFailure, AutoTopUpFailureHook, AutoTopUpHookOptions, } from './top-up.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/billing/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,YAAY,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAC/D,YAAY,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,sBAAsB,EACtB,iBAAiB,EACjB,KAAK,sBAAsB,GAC5B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,wBAAwB,EAC7B,oBAAoB,EACpB,yBAAyB,EACzB,iBAAiB,EACjB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,KAAK,aAAa,EAClB,uBAAuB,EACvB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,8BAA8B,EACnC,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,EACjC,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,iCAAiC,EACtC,KAAK,gCAAgC,EACrC,+BAA+B,GAChC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,KAAK,qBAAqB,EAC1B,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,6BAA6B,EAClC,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,GAC/B,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,2BAA2B,EAC3B,KAAK,4BAA4B,GAClC,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/billing/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,KAAK,4BAA4B,EACjC,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAC/D,YAAY,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,KAAK,4BAA4B,EACjC,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,sBAAsB,EACtB,iBAAiB,EACjB,KAAK,sBAAsB,GAC5B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,yBAAyB,EAC9B,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,KAAK,wBAAwB,EAC7B,oBAAoB,EACpB,yBAAyB,EACzB,iBAAiB,EACjB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,aAAa,EACb,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,KAAK,aAAa,EAClB,uBAAuB,EACvB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,8BAA8B,EACnC,KAAK,4BAA4B,EACjC,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,eAAe,EACpB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,8BAA8B,EACnC,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,EACjC,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,iCAAiC,EACtC,KAAK,gCAAgC,EACrC,+BAA+B,EAC/B,+BAA+B,EAC/B,oBAAoB,GACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,KAAK,qBAAqB,EAC1B,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,6BAA6B,EAClC,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,GAC/B,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,2BAA2B,EAC3B,KAAK,4BAA4B,GAClC,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { type BillingProviderCheckoutSession } from './provider.js';
2
+ import type { BillingRuntime } from './runtime.js';
3
+ export declare const INVOICE_PAYMENT_PURPOSE = "invoice_payment";
4
+ export interface CreateInvoicePaymentInput {
5
+ invoiceId: string;
6
+ /** The payment rail (a provider name from `paymentProviders`). */
7
+ provider: string;
8
+ /**
9
+ * Caller-owned id for this attempt; a retry with the same id (and the same
10
+ * amount due) returns the same checkout.
11
+ */
12
+ purchaseId: string;
13
+ successUrl: string;
14
+ cancelUrl: string;
15
+ description?: string;
16
+ }
17
+ export interface InvoicePaymentMetadata {
18
+ purpose: string;
19
+ sellerTenantId: string;
20
+ payerTenantId: string;
21
+ billingAccountId: string;
22
+ invoiceId: string;
23
+ amount: number;
24
+ currency: string;
25
+ }
26
+ /** Parse checkout metadata written by {@link createInvoicePayment}. */
27
+ export declare function invoicePaymentMetadata(raw: Record<string, string>): InvoicePaymentMetadata | null;
28
+ export declare function createInvoicePayment(runtime: BillingRuntime, input: CreateInvoicePaymentInput): Promise<BillingProviderCheckoutSession>;
29
+ //# sourceMappingURL=invoice-payments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoice-payments.d.ts","sourceRoot":"","sources":["../../src/billing/invoice-payments.ts"],"names":[],"mappings":"AAkBA,OAAO,EACL,KAAK,8BAA8B,EAEpC,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGnD,eAAO,MAAM,uBAAuB,oBAAoB,CAAC;AAUzD,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,uEAAuE;AACvE,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1B,sBAAsB,GAAG,IAAI,CAuB/B;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,8BAA8B,CAAC,CA2HzC"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Payment-rail attempts (#3138): per-seller policy, settlement of a rail
3
+ * checkout into credit or an invoice payment, and operator refund and
4
+ * conversion journals.
5
+ *
6
+ * The rail's gateway decides when a checkout is settled (its confirmation
7
+ * policy); this module never counts confirmations. It records everything the
8
+ * rail reports on a `BillingPaymentAttempt` and settles at most once, keyed by
9
+ * the checkout id.
10
+ */
11
+ import type { DatabaseInterface } from '@happyvertical/smrt-core/migrations';
12
+ import { type BillingPaymentAttempt, type BillingPaymentAttemptFlag, type BillingPaymentAttemptPurpose } from '../models/billing.js';
13
+ import type { BillingPaymentAttemptState } from './provider.js';
14
+ import type { BillingRuntime } from './runtime.js';
15
+ /** Per-seller rules for rail payments. Every default is conservative. */
16
+ export interface BillingPaymentPolicy {
17
+ /**
18
+ * Underpayment accepted as payment in full, in basis points of the price
19
+ * (default 0). The shortfall is not written off in the ledger.
20
+ */
21
+ underpaymentToleranceBps: number;
22
+ /** Overpayment not flagged for an operator, in basis points (default 0). */
23
+ overpaymentToleranceBps: number;
24
+ /**
25
+ * A payment received after the rate lock expired: `review` (default)
26
+ * flags it and settles nothing; `accept` settles when it covers the price.
27
+ */
28
+ latePaymentPolicy: 'review' | 'accept';
29
+ /** Settle checkouts an operator marked paid at the rail (default false). */
30
+ acceptManuallyMarked: boolean;
31
+ /** Hold received crypto (default) or hand it to `conversionHandler`. */
32
+ cryptoTreatment: 'hold' | 'convert';
33
+ /**
34
+ * Called after a settlement when `cryptoTreatment` is `convert`. It runs
35
+ * inside the event transaction and may run again on retry: enqueue work
36
+ * (for example a job) rather than calling an exchange directly.
37
+ */
38
+ conversionHandler?: (settlement: CryptoSettlement) => void | Promise<void>;
39
+ /** Refund basis recorded when a refund does not name one. */
40
+ refundBasis: 'original_native' | 'fiat_at_refund';
41
+ }
42
+ export interface CryptoSettlement {
43
+ sellerTenantId: string;
44
+ attemptId: string;
45
+ paymentId: string;
46
+ provider: string;
47
+ amount: number;
48
+ currency: string;
49
+ nativeCurrency: string;
50
+ nativeAmount: number;
51
+ db: DatabaseInterface;
52
+ }
53
+ export declare function normalizePaymentPolicy(input?: Partial<BillingPaymentPolicy>): BillingPaymentPolicy;
54
+ export type AttemptDecision = {
55
+ action: 'settle';
56
+ flag: BillingPaymentAttemptFlag;
57
+ } | {
58
+ action: 'none';
59
+ flag: BillingPaymentAttemptFlag;
60
+ };
61
+ /**
62
+ * What a rail checkout's state means for billing. Pure: the same state and
63
+ * policy always decide the same way, so `observe()` and `project()` agree.
64
+ */
65
+ export declare function decideAttempt(state: BillingPaymentAttemptState, policy: BillingPaymentPolicy, expected: {
66
+ amount: number;
67
+ currency: string;
68
+ }): AttemptDecision;
69
+ /** The purpose and settlement target an attempt's verified metadata names. */
70
+ export interface AttemptTarget {
71
+ purpose: BillingPaymentAttemptPurpose;
72
+ payerTenantId: string;
73
+ billingAccountId: string;
74
+ amount: number;
75
+ currency: string;
76
+ invoiceId: string;
77
+ spendingPolicyId: string;
78
+ grantedByTenantId: string;
79
+ /**
80
+ * The issuer reported the invoice paid by its own collection (for example
81
+ * a card charge whose event has not been applied yet): the rail's money is
82
+ * kept as customer credit, never allocated to the invoice.
83
+ */
84
+ issuerCollected?: boolean;
85
+ }
86
+ /** Read the target from verified metadata; null when not this seller's. */
87
+ export declare function attemptTarget(runtime: BillingRuntime, metadata: Record<string, string>): AttemptTarget | null;
88
+ export interface AttemptOutcome {
89
+ attempt: BillingPaymentAttempt;
90
+ /** The attempt left `confirming` without settling. */
91
+ endedUnsettled: boolean;
92
+ /** This application settled it. */
93
+ settled: boolean;
94
+ }
95
+ /**
96
+ * Record the rail's current state on the attempt and settle it once when the
97
+ * decision says so. `invoiceHook` applies standing for invoice payments.
98
+ */
99
+ export declare function applyPaymentAttempt(runtime: BillingRuntime, db: DatabaseInterface, providerName: string, state: BillingPaymentAttemptState, target: AttemptTarget, source: 'webhook' | 'poll'): Promise<AttemptOutcome>;
100
+ export interface ManualRefundInput {
101
+ /** The settled rail `Payment` refunded. */
102
+ paymentId: string;
103
+ /** Fiat value of the refund, minor units of the payment currency. */
104
+ fiatAmount: number;
105
+ /** Native amount sent back (satoshis), when known. */
106
+ nativeAmount?: number;
107
+ /** Default: the seller's `paymentPolicy.refundBasis`. */
108
+ basis?: 'original_native' | 'fiat_at_refund';
109
+ /** The operator's refund reference (for example the refund txid). */
110
+ reference: string;
111
+ reason: string;
112
+ }
113
+ export interface ManualRefundResult {
114
+ journalId: string;
115
+ creditGrantId: string;
116
+ }
117
+ /**
118
+ * Record a refund an operator made outside billing. Refunds come from what
119
+ * the payer is owed: first any overpayment, then — for a credit purchase, or
120
+ * an invoice payment kept as credit because the invoice was paid elsewhere —
121
+ * the price. An invoice payment applied to its invoice is not refundable
122
+ * here (reverse the invoice at the issuer first). Refunds are capped
123
+ * cumulatively per payment and are idempotent by `reference`.
124
+ */
125
+ export declare function recordManualRefund(runtime: BillingRuntime, input: ManualRefundInput): Promise<ManualRefundResult>;
126
+ export interface CryptoConversionInput {
127
+ /** Operator reference (for example the exchange trade id). */
128
+ reference: string;
129
+ currency: string;
130
+ nativeCurrency: string;
131
+ /** Native amount converted (satoshis). */
132
+ nativeAmount: number;
133
+ /** Book value of the converted holdings, minor units of `currency`. */
134
+ carryingValue: number;
135
+ /** Cash received, minor units. */
136
+ proceeds: number;
137
+ /** Fees paid, minor units (default 0). */
138
+ fees?: number;
139
+ }
140
+ export declare function recordCryptoConversion(runtime: BillingRuntime, input: CryptoConversionInput): Promise<{
141
+ journalId: string;
142
+ }>;
143
+ //# sourceMappingURL=payment-attempts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payment-attempts.d.ts","sourceRoot":"","sources":["../../src/billing/payment-attempts.ts"],"names":[],"mappings":"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"}