@saasicat/core 1.0.0-rc.21 → 1.0.0-rc.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/.build-stamp CHANGED
@@ -1 +1 @@
1
- 369e8bc186ed4a646394a1f9b7c7dcc8605204b4bae0e8c40edc4f3b5dd5e378
1
+ 91754758b2193699e34b267e3d43034f1ffa6d651baee667fbdf3456d23db8b2
package/dist/index.cjs CHANGED
@@ -54,6 +54,7 @@ __export(index_exports, {
54
54
  REGISTRATION_STEP_BY_STATUS: () => REGISTRATION_STEP_BY_STATUS,
55
55
  SETTINGS_ERROR_CODES: () => SETTINGS_ERROR_CODES,
56
56
  SETUP_ERROR_CODES: () => SETUP_ERROR_CODES,
57
+ SUBSCRIBER_ACCOUNT_CAPABILITY: () => SUBSCRIBER_ACCOUNT_CAPABILITY,
57
58
  SUBSCRIBER_ERROR_CODES: () => SUBSCRIBER_ERROR_CODES,
58
59
  applyPromo: () => applyPromo,
59
60
  assertPersistenceCapabilities: () => assertPersistenceCapabilities,
@@ -98,6 +99,7 @@ __export(index_exports, {
98
99
  selectChargeableBundles: () => selectChargeableBundles,
99
100
  settingsSubtreeOf: () => settingsSubtreeOf,
100
101
  startOfUtcDay: () => startOfUtcDay,
102
+ subscriberChargeColumns: () => subscriberChargeColumns,
101
103
  subscriberFromRegistration: () => subscriberFromRegistration,
102
104
  subscriberPaymentMethodColumns: () => subscriberPaymentMethodColumns,
103
105
  toBundleStemRow: () => toBundleStemRow,
@@ -105,9 +107,11 @@ __export(index_exports, {
105
107
  toPlanRow: () => toPlanRow,
106
108
  toPlanVersionRow: () => toPlanVersionRow,
107
109
  toRunningContractIssuer: () => toRunningContractIssuer,
110
+ toSubscriberChargeRecord: () => toSubscriberChargeRecord,
108
111
  toSubscriberCorrectionRecord: () => toSubscriberCorrectionRecord,
109
112
  toSubscriberPaymentMethodRecord: () => toSubscriberPaymentMethodRecord,
110
113
  toSubscriberRecord: () => toSubscriberRecord,
114
+ toSubscriptionBundleRecord: () => toSubscriptionBundleRecord,
111
115
  toSubscriptionContractRecord: () => toSubscriptionContractRecord
112
116
  });
113
117
  module.exports = __toCommonJS(index_exports);
@@ -825,7 +829,14 @@ var PAYMENT_ERROR_CODES = {
825
829
  * A success or cancel URL at an origin `config/saas.yaml#payments.returnUrlOrigins`
826
830
  * does not name. Carries `field`.
827
831
  */
828
- PAYMENT_RETURN_URL_NOT_ALLOWED: "PAYMENT_RETURN_URL_NOT_ALLOWED"
832
+ PAYMENT_RETURN_URL_NOT_ALLOWED: "PAYMENT_RETURN_URL_NOT_ALLOWED",
833
+ /**
834
+ * The gateway failed — unreachable, refusing the account's keys, or
835
+ * answering with an error — while opening its form or reading a callback
836
+ * back. Answered with 502; what the gateway answered stays in the server
837
+ * log.
838
+ */
839
+ PAYMENT_GATEWAY_FAILED: "PAYMENT_GATEWAY_FAILED"
829
840
  };
830
841
  var SETTINGS_ERROR_CODES = {
831
842
  /** No recorded change has this id, or the installation keeps no record at all. */
@@ -1091,6 +1102,83 @@ function textOrNull(value) {
1091
1102
  return trimmed === "" ? null : trimmed;
1092
1103
  }
1093
1104
 
1105
+ // src/closed-value.ts
1106
+ function oneOf(allowed, value, source) {
1107
+ const match = allowed.find((entry) => entry === value);
1108
+ if (match === void 0) {
1109
+ throw new Error(
1110
+ `${source.table} row '${source.id}' holds ${source.column} '${value}', which is none of ${allowed.join(", ")}.`
1111
+ );
1112
+ }
1113
+ return match;
1114
+ }
1115
+
1116
+ // src/subscriber-ledger-mapping.ts
1117
+ var ORIGINS = {
1118
+ activation: true,
1119
+ renewal: true,
1120
+ planChange: true,
1121
+ bundleBooking: true,
1122
+ credit: true,
1123
+ correction: true
1124
+ };
1125
+ var SOURCES = {
1126
+ plan: true,
1127
+ bundle: true,
1128
+ discount: true
1129
+ };
1130
+ var TABLE = "subscriber_ledger_entries";
1131
+ var CENT_TOLERANCE = 1e-6;
1132
+ function toSubscriberChargeRecord(row) {
1133
+ const where = (column) => ({ table: TABLE, column, id: row.id });
1134
+ return {
1135
+ id: row.id,
1136
+ subscriberId: row.subscriberId,
1137
+ tenantId: row.tenantId,
1138
+ subscriptionId: row.subscriptionId,
1139
+ contractId: row.contractId,
1140
+ contractLineItemId: row.contractLineItemId,
1141
+ origin: oneOf(keysOf(ORIGINS), row.origin, where("origin")),
1142
+ source: oneOf(keysOf(SOURCES), row.source, where("source")),
1143
+ sourceRef: row.sourceRef,
1144
+ periodStart: row.periodStart,
1145
+ periodEnd: row.periodEnd,
1146
+ currency: row.currency,
1147
+ amountNet: Number(row.amountNet),
1148
+ bookedAt: row.bookedAt,
1149
+ createdAt: row.createdAt
1150
+ };
1151
+ }
1152
+ function subscriberChargeColumns(charge) {
1153
+ const cents = charge.amountNet * 100;
1154
+ if (!Number.isFinite(cents) || Math.abs(cents - Math.round(cents)) > CENT_TOLERANCE) {
1155
+ throw new Error(
1156
+ `A charge of ${charge.amountNet} is not a whole number of cents; round it once where it is derived, before it is written.`
1157
+ );
1158
+ }
1159
+ return {
1160
+ subscriberId: charge.subscriberId,
1161
+ tenantId: charge.tenantId,
1162
+ subscriptionId: charge.subscriptionId,
1163
+ contractId: charge.contractId,
1164
+ contractLineItemId: charge.contractLineItemId,
1165
+ origin: charge.origin,
1166
+ source: charge.source,
1167
+ sourceRef: charge.sourceRef,
1168
+ periodStart: charge.periodStart,
1169
+ periodEnd: charge.periodEnd,
1170
+ currency: charge.currency,
1171
+ amountNet: charge.amountNet.toFixed(2),
1172
+ bookedAt: charge.bookedAt
1173
+ };
1174
+ }
1175
+ function keysOf(record) {
1176
+ return Object.keys(record);
1177
+ }
1178
+
1179
+ // src/subscriber-ledger.types.ts
1180
+ var SUBSCRIBER_ACCOUNT_CAPABILITY = "charges.read";
1181
+
1094
1182
  // src/subscriber-mapping.ts
1095
1183
  function formatCustomerNumber(prefix, sequence) {
1096
1184
  return `${prefix}${sequence}`;
@@ -1206,6 +1294,7 @@ function toIdentityValues(value) {
1206
1294
  // src/subscriber-payment-method-mapping.ts
1207
1295
  var PAYMENT_METHOD_TYPES = ["card", "sepa_debit"];
1208
1296
  var STATUSES = ["ACTIVE", "REPLACED"];
1297
+ var TABLE2 = "subscriber_payment_methods";
1209
1298
  function toSubscriberPaymentMethodRecord(row) {
1210
1299
  return {
1211
1300
  id: row.id,
@@ -1214,7 +1303,7 @@ function toSubscriberPaymentMethodRecord(row) {
1214
1303
  provider: row.provider,
1215
1304
  customerRef: row.customerRef,
1216
1305
  paymentMethodRef: row.paymentMethodRef,
1217
- type: oneOf(PAYMENT_METHOD_TYPES, row.type, "type", row.id),
1306
+ type: oneOf(PAYMENT_METHOD_TYPES, row.type, { table: TABLE2, column: "type", id: row.id }),
1218
1307
  brand: row.brand,
1219
1308
  last4: row.last4,
1220
1309
  expiryMonth: row.expiryMonth,
@@ -1222,7 +1311,7 @@ function toSubscriberPaymentMethodRecord(row) {
1222
1311
  country: row.country,
1223
1312
  bankCode: row.bankCode,
1224
1313
  mandateReference: row.mandateReference,
1225
- status: oneOf(STATUSES, row.status, "status", row.id),
1314
+ status: oneOf(STATUSES, row.status, { table: TABLE2, column: "status", id: row.id }),
1226
1315
  confirmedAt: row.confirmedAt,
1227
1316
  replacedAt: row.replacedAt,
1228
1317
  createdAt: row.createdAt
@@ -1246,15 +1335,6 @@ function subscriberPaymentMethodColumns(data) {
1246
1335
  confirmedAt: data.confirmedAt
1247
1336
  };
1248
1337
  }
1249
- function oneOf(allowed, value, column, id) {
1250
- const match = allowed.find((entry) => entry === value);
1251
- if (match === void 0) {
1252
- throw new Error(
1253
- `subscriber_payment_methods row '${id}' holds ${column} '${value}', which is none of ${allowed.join(", ")}.`
1254
- );
1255
- }
1256
- return match;
1257
- }
1258
1338
  var FOREIGN_PAYMENT_METHOD_REFERENCE = "FOREIGN_PAYMENT_METHOD_REFERENCE";
1259
1339
  var ForeignPaymentMethodReferenceError = class extends Error {
1260
1340
  constructor(gatewayAccount, paymentMethodRef) {
@@ -1280,6 +1360,30 @@ function refuseForeignPaymentMethodReference(recorded, subscriberId) {
1280
1360
  );
1281
1361
  }
1282
1362
 
1363
+ // src/subscription-bundle-mapping.ts
1364
+ var BILLING_CYCLES = ["MONTHLY", "YEARLY"];
1365
+ function toSubscriptionBundleRecord(row) {
1366
+ const billingCycle = row.billingCycle ?? null;
1367
+ return {
1368
+ id: row.id,
1369
+ subscriptionId: row.subscriptionId,
1370
+ bundleVersionId: row.bundleVersionId,
1371
+ startedAt: row.startedAt,
1372
+ minimumTermEndsAt: row.minimumTermEndsAt,
1373
+ billingCycle: billingCycle === null ? null : oneOf(BILLING_CYCLES, billingCycle, {
1374
+ table: "subscription_bundles",
1375
+ column: "billingCycle",
1376
+ id: row.id
1377
+ }),
1378
+ currentPeriodStart: row.currentPeriodStart ?? null,
1379
+ currentPeriodEnd: row.currentPeriodEnd ?? null,
1380
+ canceledAt: row.canceledAt,
1381
+ canceledEffectiveAt: row.canceledEffectiveAt,
1382
+ createdAt: row.createdAt,
1383
+ updatedAt: row.updatedAt
1384
+ };
1385
+ }
1386
+
1283
1387
  // src/subscription-contract-mapping.ts
1284
1388
  function toSubscriptionContractRecord(row, lineItems) {
1285
1389
  return {
@@ -1615,6 +1719,7 @@ var ERROR_MESSAGES_EN = {
1615
1719
  PAYMENT_GATEWAY_ACCOUNT_UNKNOWN: "No payment gateway account is configured under '{account}'.",
1616
1720
  PAYMENT_CALLBACK_REJECTED: "The payment callback could not be verified.",
1617
1721
  PAYMENT_RETURN_URL_NOT_ALLOWED: "The {field} leads to a site this installation does not return to.",
1722
+ PAYMENT_GATEWAY_FAILED: "The payment provider did not answer as expected. Please try again in a few minutes.",
1618
1723
  // ── entitlement (code lives in upsell.types.ts) ──
1619
1724
  [FEATURE_NOT_LICENSED]: "Feature {featureKeys} is not included in the current plan.",
1620
1725
  // ── settings ──
@@ -1825,6 +1930,7 @@ var ERROR_MESSAGES_DE = {
1825
1930
  PAYMENT_GATEWAY_ACCOUNT_UNKNOWN: "Unter '{account}' ist kein Konto eines Zahlungsanbieters eingerichtet.",
1826
1931
  PAYMENT_CALLBACK_REJECTED: "Die R\xFCckmeldung des Zahlungsanbieters lie\xDF sich nicht pr\xFCfen.",
1827
1932
  PAYMENT_RETURN_URL_NOT_ALLOWED: "Die {field} f\xFChrt auf eine Seite, zu der diese Installation nicht zur\xFCckleitet.",
1933
+ PAYMENT_GATEWAY_FAILED: "Der Zahlungsanbieter hat nicht wie erwartet geantwortet. Bitte versuche es in ein paar Minuten noch einmal.",
1828
1934
  // ── entitlement (code lives in upsell.types.ts) ──
1829
1935
  [FEATURE_NOT_LICENSED]: "Das Feature {featureKeys} ist im aktuellen Plan nicht enthalten.",
1830
1936
  // ── settings ──
@@ -1866,6 +1972,7 @@ var ERROR_MESSAGES_DE = {
1866
1972
  REGISTRATION_STEP_BY_STATUS,
1867
1973
  SETTINGS_ERROR_CODES,
1868
1974
  SETUP_ERROR_CODES,
1975
+ SUBSCRIBER_ACCOUNT_CAPABILITY,
1869
1976
  SUBSCRIBER_ERROR_CODES,
1870
1977
  applyPromo,
1871
1978
  assertPersistenceCapabilities,
@@ -1910,6 +2017,7 @@ var ERROR_MESSAGES_DE = {
1910
2017
  selectChargeableBundles,
1911
2018
  settingsSubtreeOf,
1912
2019
  startOfUtcDay,
2020
+ subscriberChargeColumns,
1913
2021
  subscriberFromRegistration,
1914
2022
  subscriberPaymentMethodColumns,
1915
2023
  toBundleStemRow,
@@ -1917,8 +2025,10 @@ var ERROR_MESSAGES_DE = {
1917
2025
  toPlanRow,
1918
2026
  toPlanVersionRow,
1919
2027
  toRunningContractIssuer,
2028
+ toSubscriberChargeRecord,
1920
2029
  toSubscriberCorrectionRecord,
1921
2030
  toSubscriberPaymentMethodRecord,
1922
2031
  toSubscriberRecord,
2032
+ toSubscriptionBundleRecord,
1923
2033
  toSubscriptionContractRecord
1924
2034
  });
package/dist/index.d.cts CHANGED
@@ -643,12 +643,19 @@ interface PaymentGateway {
643
643
  /**
644
644
  * Opens the gateway's form for a payment method. Nothing is confirmed until
645
645
  * the gateway says so through `readCallback`.
646
+ *
647
+ * A failure is thrown as the provider reported it: the platform answers the
648
+ * person with `PAYMENT_GATEWAY_FAILED` and keeps what the error carries —
649
+ * its kind, code, status and request id — in the server log.
646
650
  */
647
651
  startPaymentMethodSetup(input: StartPaymentMethodSetupInput): Promise<PaymentMethodSetupSession>;
648
652
  /**
649
653
  * Verifies a callback with the account's secret and translates it.
650
654
  * Throws `PaymentCallbackRejectedError` for anything the gateway did not
651
- * send, before a single field of it is trusted.
655
+ * send, before a single field of it is trusted. Any other failure is
656
+ * answered with `PAYMENT_GATEWAY_FAILED` and 502, like one of
657
+ * `startPaymentMethodSetup` — to the gateway's webhook, or to the person
658
+ * an `immediateCallback` is read for.
652
659
  */
653
660
  readCallback(callback: PaymentGatewayCallback): Promise<PaymentGatewayEvent>;
654
661
  }
@@ -1103,7 +1110,7 @@ interface SubscriptionBundleRecord {
1103
1110
  * or on one whose plan has no period; readers fall back to the plan's
1104
1111
  * cycle, which is what every booking used before.
1105
1112
  */
1106
- billingCycle: string | null;
1113
+ billingCycle: BillingCycle | null;
1107
1114
  currentPeriodStart: Date | null;
1108
1115
  currentPeriodEnd: Date | null;
1109
1116
  createdAt: Date;
@@ -1137,7 +1144,7 @@ interface CreateSubscriptionBundleData {
1137
1144
  /** Null unless a commitment was configured or asked for. */
1138
1145
  minimumTermEndsAt?: Date | null;
1139
1146
  /** The rhythm and window worked out above this port. */
1140
- billingCycle?: string | null;
1147
+ billingCycle?: BillingCycle | null;
1141
1148
  currentPeriodStart?: Date | null;
1142
1149
  currentPeriodEnd?: Date | null;
1143
1150
  }
@@ -2206,6 +2213,16 @@ interface EffectiveLimitsSnapshot {
2206
2213
  plan: string;
2207
2214
  quotas: Record<string, number>;
2208
2215
  features: string[];
2216
+ /**
2217
+ * The add-ons a contract left out of these entitlements because their
2218
+ * cancellation was already declared when it was written. Each is granted by
2219
+ * its booking until its effective date, and by this snapshot never.
2220
+ *
2221
+ * Absent where nothing was left out — and on a snapshot written by an
2222
+ * application, or before the platform left anything out, which then counts
2223
+ * every add-on it names as its own.
2224
+ */
2225
+ leftOutBundleVersionIds?: string[];
2209
2226
  }
2210
2227
 
2211
2228
  interface FeatureUiMeta {
@@ -3511,6 +3528,128 @@ interface SubscriberCorrectionResult {
3511
3528
  correction: SubscriberCorrectionRecord | null;
3512
3529
  }
3513
3530
 
3531
+ /**
3532
+ * What made the charge arise. activation: the first period of a subscription. renewal: a later period. planChange: what an immediate plan change adds. bundleBooking: the first, short period of an add-on. credit: a decision that reduces what is owed. correction: a counter-entry reversing an earlier charge, which is how the append-only journal answers a mistake.
3533
+ */
3534
+ type SubscriberChargeOrigin = 'activation' | 'renewal' | 'planChange' | 'bundleBooking' | 'credit' | 'correction';
3535
+ /**
3536
+ * Which kind of contract line the charge realises.
3537
+ */
3538
+ type SubscriberChargeSource = 'plan' | 'bundle' | 'discount';
3539
+ /**
3540
+ * One charge in a subscriber's account: an amount that became due for a period, derived from a line of the contract in force. The journal is append-only — a charge is never updated, and a mistake is answered with a counter-entry rather than an edit, so the account says what happened rather than what somebody thinks today. A charge is net: the tax is decided by the tax adapter when the charge is invoiced, from the subscriber's origin on that day, and computed once per rate on the invoice.
3541
+ */
3542
+ interface SubscriberCharge {
3543
+ /**
3544
+ * The charge's own identifier. Never shown to a customer as an invoice number: invoice numbering is sequential, gapless and legally constrained per country, and an identifier somebody has already seen on a screen cannot become one later without confusion.
3545
+ */
3546
+ id: string;
3547
+ /**
3548
+ * The party the contract is concluded with, whose account this is. It outlives the tenant.
3549
+ */
3550
+ subscriberId: string;
3551
+ /**
3552
+ * The tenant the subscription belonged to when the charge arose.
3553
+ */
3554
+ tenantId: string;
3555
+ /**
3556
+ * The subscription the charge arose on. Part of the natural key.
3557
+ */
3558
+ subscriptionId: string;
3559
+ /**
3560
+ * The contract whose line the charge realises.
3561
+ */
3562
+ contractId: string;
3563
+ /**
3564
+ * The contract line the charge came from, so that every invoice line can be traced back to what was agreed.
3565
+ */
3566
+ contractLineItemId: string;
3567
+ origin: SubscriberChargeOrigin;
3568
+ source: SubscriberChargeSource;
3569
+ /**
3570
+ * Which thing of its source the charge is for, stable across contracts: the subscription id for the plan, the booking id for an add-on, the discount's key for a discount. Part of the natural key (subscriptionId, source, sourceRef, periodStart, origin), which is unique — a charge derived twice is written once.
3571
+ */
3572
+ sourceRef: string;
3573
+ /**
3574
+ * The start of the period the charge belongs to — the grouping key for an invoice.
3575
+ */
3576
+ periodStart: string;
3577
+ periodEnd: string;
3578
+ /**
3579
+ * ISO 4217, as the contract line records it — recorded per charge so that a charge written in 2026 still means what it meant after the configured currency changes.
3580
+ */
3581
+ currency: string;
3582
+ /**
3583
+ * Net, rounded to the currency's decimal places once, when the charge is written; the written figure is the truth from then on. Negative for a discount.
3584
+ */
3585
+ amountNet: number;
3586
+ /**
3587
+ * When the amount became due. The account is ordered by this, not by when the row was written.
3588
+ */
3589
+ bookedAt: string;
3590
+ createdAt: string;
3591
+ }
3592
+
3593
+ /** A charge as a store reads it back: the wire format, with its dates as dates. */
3594
+ interface SubscriberChargeRecord {
3595
+ id: string;
3596
+ subscriberId: string;
3597
+ tenantId: string;
3598
+ subscriptionId: string;
3599
+ contractId: string;
3600
+ contractLineItemId: string;
3601
+ origin: SubscriberChargeOrigin;
3602
+ source: SubscriberChargeSource;
3603
+ /** The subscription id for the plan, the booking id for an add-on, the discount's key. */
3604
+ sourceRef: string;
3605
+ periodStart: Date;
3606
+ periodEnd: Date;
3607
+ currency: string;
3608
+ /** Net, rounded to the cent when written. Negative for a discount. */
3609
+ amountNet: number;
3610
+ /** When the amount became due. */
3611
+ bookedAt: Date;
3612
+ createdAt: Date;
3613
+ }
3614
+ /** A charge to write: everything but what the store assigns. */
3615
+ type NewSubscriberCharge = Omit<SubscriberChargeRecord, 'id' | 'createdAt'>;
3616
+ /**
3617
+ * The manifest capability that announces the operator's view of an account.
3618
+ * The platform sets it where it serves the view, and the admin UI shows the
3619
+ * view only where it is set.
3620
+ */
3621
+ declare const SUBSCRIBER_ACCOUNT_CAPABILITY = "charges.read";
3622
+ /** Whose account it is, as the operator is shown it. */
3623
+ interface AdminAccountHolder {
3624
+ id: string;
3625
+ /** What the customer quotes, and what an invoice will carry. */
3626
+ customerNumber: string;
3627
+ legalName: string;
3628
+ }
3629
+ /** One charge of an account, with the name its contract line gives it. */
3630
+ interface AdminAccountEntry {
3631
+ /** The charge as the journal holds it. */
3632
+ charge: SubscriberCharge;
3633
+ /**
3634
+ * The contract line's own title, as it was when the contract was
3635
+ * concluded, or `null` where that line cannot be read.
3636
+ */
3637
+ title: string | null;
3638
+ }
3639
+ /**
3640
+ * A tenant's account as the operator reads it: the charges of the subscription
3641
+ * it holds, newest first — by when each became due, then by its period, then
3642
+ * the plan before its add-ons before its discounts.
3643
+ *
3644
+ * No total: without invoices and payments, a sum would be what was charged so
3645
+ * far, and it would be read as what is owed.
3646
+ */
3647
+ interface AdminSubscriberAccount {
3648
+ /** `null` for a tenant that has no subscriber. */
3649
+ holder: AdminAccountHolder | null;
3650
+ entries: AdminAccountEntry[];
3651
+ }
3652
+
3514
3653
  /**
3515
3654
  * Snapshot form of a `Subscription` row for the EntitlementService
3516
3655
  * computation. The consumer maps its Prisma structure onto this form.
@@ -3758,6 +3897,27 @@ interface SubscriberRepository {
3758
3897
  /** Every correction of this subscriber, the latest first. */
3759
3898
  listCorrections(subscriberId: string): Promise<SubscriberCorrectionRecord[]>;
3760
3899
  }
3900
+ /**
3901
+ * The subscriber's account: the charges that became due, one per contract line
3902
+ * and period. Append-only — nothing here updates or deletes a charge, and a
3903
+ * mistake is answered with a counter-entry (`SC-PRIC-020`).
3904
+ *
3905
+ * Owned by the subscriber rather than the tenant, so that it outlives the
3906
+ * tenant it arose for (ADR 0012).
3907
+ */
3908
+ interface SubscriberLedgerRepository {
3909
+ /**
3910
+ * Writes the charges that are not there yet and returns them.
3911
+ *
3912
+ * A charge whose natural key — subscription, source, source reference,
3913
+ * period start and origin — is already written is left as it is and not
3914
+ * returned, however often it is derived and whoever derives it at the same
3915
+ * time: the unique index decides, not a read before the write.
3916
+ */
3917
+ recordCharges(charges: readonly NewSubscriberCharge[], tx?: TransactionContext): Promise<SubscriberChargeRecord[]>;
3918
+ /** Every charge of one subscription, oldest period first. */
3919
+ listBySubscription(subscriptionId: string, tx?: TransactionContext): Promise<SubscriberChargeRecord[]>;
3920
+ }
3761
3921
  /**
3762
3922
  * Display form of a subscription for the tenant self-service UI.
3763
3923
  * Richer than `SubscriptionRecord` (which is only the aggregation form); contains
@@ -5085,6 +5245,8 @@ interface SaaSiCatPersistenceEntitlement {
5085
5245
  subscriptionContractRepository?: PersistenceProvider<SubscriptionContractRepository>;
5086
5246
  /** The parties contracts are concluded with; required wherever contracts are written. */
5087
5247
  subscriberRepository?: PersistenceProvider<SubscriberRepository>;
5248
+ /** The charges a subscriber's contracts give rise to (`tenantBilling.chargeJournal`). */
5249
+ subscriberLedgerRepository?: PersistenceProvider<SubscriberLedgerRepository>;
5088
5250
  subscriptionBundleRepository?: PersistenceProvider<SubscriptionBundleRepository>;
5089
5251
  bundleRepository?: PersistenceProvider<BundleRepository>;
5090
5252
  }
@@ -5530,6 +5692,13 @@ declare const PAYMENT_ERROR_CODES: {
5530
5692
  * does not name. Carries `field`.
5531
5693
  */
5532
5694
  readonly PAYMENT_RETURN_URL_NOT_ALLOWED: "PAYMENT_RETURN_URL_NOT_ALLOWED";
5695
+ /**
5696
+ * The gateway failed — unreachable, refusing the account's keys, or
5697
+ * answering with an error — while opening its form or reading a callback
5698
+ * back. Answered with 502; what the gateway answered stays in the server
5699
+ * log.
5700
+ */
5701
+ readonly PAYMENT_GATEWAY_FAILED: "PAYMENT_GATEWAY_FAILED";
5533
5702
  };
5534
5703
  type PaymentErrorCode = (typeof PAYMENT_ERROR_CODES)[keyof typeof PAYMENT_ERROR_CODES];
5535
5704
  /** Codes of the settings record (`GET /admin/settings`, the acknowledgement). */
@@ -5562,6 +5731,13 @@ declare const PLATFORM_ERROR_CODES: {
5562
5731
  * does not name. Carries `field`.
5563
5732
  */
5564
5733
  readonly PAYMENT_RETURN_URL_NOT_ALLOWED: "PAYMENT_RETURN_URL_NOT_ALLOWED";
5734
+ /**
5735
+ * The gateway failed — unreachable, refusing the account's keys, or
5736
+ * answering with an error — while opening its form or reading a callback
5737
+ * back. Answered with 502; what the gateway answered stays in the server
5738
+ * log.
5739
+ */
5740
+ readonly PAYMENT_GATEWAY_FAILED: "PAYMENT_GATEWAY_FAILED";
5565
5741
  readonly PENDING_REGISTRATION_NOT_FOUND: "PENDING_REGISTRATION_NOT_FOUND";
5566
5742
  readonly PENDING_REGISTRATION_EXPIRED: "PENDING_REGISTRATION_EXPIRED";
5567
5743
  readonly INVALID_REGISTRATION_STATE: "INVALID_REGISTRATION_STATE";
@@ -6779,6 +6955,47 @@ type IssuerIdentityChange =
6779
6955
  */
6780
6956
  declare function classifyIssuerChange(recorded: LegalIdentity | null, issuer: PlanCatalogIssuer | undefined): IssuerIdentityChange;
6781
6957
 
6958
+ /**
6959
+ * A `subscriber_ledger_entries` row as either adapter reads it back. The amount
6960
+ * is `unknown` because a Prisma row carries a `Decimal` where a Drizzle row
6961
+ * carries a numeric string.
6962
+ */
6963
+ interface CanonicalSubscriberChargeRow {
6964
+ id: string;
6965
+ subscriberId: string;
6966
+ tenantId: string;
6967
+ subscriptionId: string;
6968
+ contractId: string;
6969
+ contractLineItemId: string;
6970
+ origin: string;
6971
+ source: string;
6972
+ sourceRef: string;
6973
+ periodStart: Date;
6974
+ periodEnd: Date;
6975
+ currency: string;
6976
+ amountNet: unknown;
6977
+ bookedAt: Date;
6978
+ createdAt: Date;
6979
+ }
6980
+ /**
6981
+ * Reads a row back as a record. The origin and the source are checked rather
6982
+ * than cast: a value written by hand or by a later release would otherwise
6983
+ * reach an invoice as a charge nobody knows how to read.
6984
+ */
6985
+ declare function toSubscriberChargeRecord(row: CanonicalSubscriberChargeRow): SubscriberChargeRecord;
6986
+ /**
6987
+ * The columns a charge is written with. The amount goes as a decimal string of
6988
+ * two places, which both a Prisma `Decimal` and a PostgreSQL `numeric` take
6989
+ * exactly — a JavaScript number on its way to either is where a cent is lost.
6990
+ *
6991
+ * An amount that is not already a whole number of cents is refused rather than
6992
+ * rounded: a charge is rounded once, where it is derived, and a second rounding
6993
+ * here would make the written figure differ from the one that was computed.
6994
+ */
6995
+ declare function subscriberChargeColumns(charge: NewSubscriberCharge): Omit<CanonicalSubscriberChargeRow, 'id' | 'createdAt' | 'amountNet'> & {
6996
+ amountNet: string;
6997
+ };
6998
+
6782
6999
  /** A `subscribers` row as either adapter reads it back. */
6783
7000
  interface CanonicalSubscriberRow {
6784
7001
  id: string;
@@ -6907,6 +7124,37 @@ declare function isForeignPaymentMethodReferenceError(error: unknown): error is
6907
7124
  */
6908
7125
  declare function refuseForeignPaymentMethodReference(recorded: Pick<CanonicalSubscriberPaymentMethodRow, 'subscriberId' | 'gatewayAccount' | 'paymentMethodRef'>, subscriberId: string): void;
6909
7126
 
7127
+ /**
7128
+ * A `subscription_bundles` row as either adapter reads it back.
7129
+ *
7130
+ * The three billing columns are optional because a Prisma client generated from
7131
+ * a schema that predates them returns a row without them; an absent column
7132
+ * reads as null, the same as a booking made before they existed.
7133
+ */
7134
+ interface CanonicalSubscriptionBundleRow {
7135
+ id: string;
7136
+ subscriptionId: string;
7137
+ bundleVersionId: string;
7138
+ startedAt: Date;
7139
+ minimumTermEndsAt: Date | null;
7140
+ billingCycle?: string | null;
7141
+ currentPeriodStart?: Date | null;
7142
+ currentPeriodEnd?: Date | null;
7143
+ canceledAt: Date | null;
7144
+ canceledEffectiveAt: Date | null;
7145
+ createdAt: Date;
7146
+ updatedAt: Date;
7147
+ }
7148
+ /**
7149
+ * Reads a row back as a record.
7150
+ *
7151
+ * `billingCycle` is a text column the platform only ever writes as `MONTHLY` or
7152
+ * `YEARLY`, and a price is chosen by asking whether it is `YEARLY` — so any
7153
+ * other value would be billed monthly without a word. It is checked rather than
7154
+ * cast, and a value outside the two stops the read.
7155
+ */
7156
+ declare function toSubscriptionBundleRecord(row: CanonicalSubscriptionBundleRow): SubscriptionBundleRecord;
7157
+
6910
7158
  /** A `subscription_contracts` row as either adapter reads it back. */
6911
7159
  interface CanonicalContractRow {
6912
7160
  id: string;
@@ -7050,4 +7298,4 @@ declare function resolveErrorMessage(body: ResolvableErrorBody, overrides?: Part
7050
7298
 
7051
7299
  declare const ERROR_MESSAGES_DE: Record<PlatformErrorCode, string>;
7052
7300
 
7053
- export { ACTIVE_SUBSCRIPTION_CONTRACT_STATUSES, AUTH_ERROR_CODES, type ActionKey, type ActivationOrchestrator, type ActivePlanVersionWhere, type ActivePlanVersionWhereWithEndsAt, type ActiveVersionWhere, type ActiveVersionWhereWithEndsAt, type ActorTag, type AdminActor, type AdminAuditListFilter, type AdminManifest, type AdminResourcesPort, type AdminSubscriptionListRow, type AdminTenantDetail, type AdminTenantListFilter, type AdminTenantListRow, type AdminTenantStateResult, type AdminUserListFilter, type AdminUserListRow, type AppliedSettingsPort, type AppliedSettingsRecord, type AppliedSettingsValues, type ApplyOnboardingSelectionInput, type ApplyOnboardingSelectionResult, type ApprovedCatalogKeys, type AuditActionDef, type AuditEntry, type AuditPort, type AuditQuery, type AuditQueryPort, type AuditStatsPort, type AuditStatsSnapshot, type AuthErrorCode, BILLING_ERROR_CODES, BUNDLE_PRICE_LOOKUP_LIMIT, type BillingCycle, type BillingErrorCode, type BundleAvailabilityState, type BundleCompatibility, type BundleFeatureShape, type BundleListFilter, type BundlePricingOverride, type BundleRepository, type BundleRow, type BundleVersionFields, type BundleVersionMutationResult, type BundleVersionRow, CATALOGUE_KEYS, CATALOG_ERROR_CODES, CONTRACT_ERROR_CODES, type CancelSubscriptionBundleData, type CancelSubscriptionInput, type CancelSubscriptionResult, type CancellationNoticePeriods, type CanonicalContractLineItemRow, type CanonicalContractRow, type CanonicalPlanRow, type CanonicalPlanVersionRow, type CanonicalRunningContractRow, type CanonicalSubscriberCorrectionRow, type CanonicalSubscriberPaymentMethodRow, type CanonicalSubscriberRow, type CapabilityCatalogEntryRow, type CapabilityCodeStatus, type CapabilityKey, type CapabilityKind, type CatalogEntryFilter, type CatalogEntryI18n, type CatalogEntryI18nFields, type CatalogEntryRepository, type CatalogErrorCode, type ChangeDirection, type CheckoutOfferFilter, type CheckoutOfferLineItem, type CheckoutOfferLineItemKind, type CheckoutOfferPriceBreakdown, type CheckoutOfferPromoCodeSnapshot, type CheckoutOfferPromotionSnapshot, type CheckoutOfferRepository, type CheckoutOfferRow, type CheckoutOfferSelection, type CheckoutOfferSelectionUpdate, type CheckoutOfferStatus, type CleanupResult, type CliUserRow, type ComponentKey, type ConfiguratorCatalog, type ConfiguratorMarketingProvider, type ConfiguratorModel, type ConfiguratorPlanMarketing, type ConfiguratorPlanVersionRow, type ConfiguratorPriceBreakdown, type ConfiguratorSourcesLookup, type ConfirmedPaymentMethod, type ContractErrorCode, type ContractIssuerParty, type ContractLineItemKind, type ContractLineItemRecord, type ContractSubscriberParty, type CreateBundleData, type CreateBundleVersionDraftData, type CreateCheckoutOfferData, type CreateMarketingProjectionData, type CreatePlanData, type CreatePlanVersionDraftData, type CreatePromoCodeData, type CreatePromoCodeRequest, type CreatePromotionData, type CreateSubscriberData, type CreateSubscriptionBundleData, type CreateSubscriptionContractData, type CreateSuperAdminCliInput, type CreateTenantInput, type DiffResult, type DiscoveredCapability, type DiscoveredFeature, type DiscoveredQuota, type DiscoveredQuotaPolicy, type DiscoveryCodeStatus, type DiscoverySnapshot, type DiscoveryStatus, ERROR_MESSAGES_DE, ERROR_MESSAGES_EN, type EffectiveLimitsSnapshot, type EmailPort, type ErrorMessageParams, FEATURE_NOT_LICENSED, type FeatureCatalogEntryRow, type FeatureDef, type FeatureKey, type FeatureNotLicensedBody, type FeatureRequiresIndex, type FeatureTier, type FeatureUiMeta, type FeatureUiRegistry, type FinalActivationResult, type FirstTimeCustomerCheck, ForeignPaymentMethodReferenceError, type ImmediatePlanChangeInput, type InvoiceLineItemSnapshot, type IssuerCorrectionFault, type IssuerIdentityChange, type KpiCardDef, type KpiDisplayHint, LEGAL_IDENTITY_FIELDS, type LegalIdentity, type LegalIdentityField, MARKETING_PRIORITY_MAX, MARKETING_PRIORITY_MIN, type ManifestAccessPort, type ManifestContribution, type MarketingProjectionFilter, type MarketingProjectionRepository, type MarketingProjectionRow, type MarketingSettingsRepository, type MarketingSettingsRow, type MarketingTargetType, type MarketingTopFeature, type MaskedPaymentMethod, type MfaPort, type NewContractLineItemData, type NewSettingsChange, type NewSubscriberDetails, type NewSubscriptionContractData, OTP_RATE_LIMIT_MAX_SENDS, OTP_RATE_LIMIT_WINDOW_MINUTES, OTP_TTL_MINUTES, OTP_VERIFY_MAX_ATTEMPTS, type OnboardingPromoRedemption, type OnboardingSelectionRequest, type OnboardingSelectionResponse, PASSWORD_RESET_TTL_MINUTES, PAYMENT_ERROR_CODES, PAYMENT_METHOD_TYPES, PENDING_CHECKOUT_TTL_DAYS, PENDING_EMAIL_TTL_HOURS, PENDING_ONBOARDING_TTL_DAYS, PLATFORM_ERROR_CODES, PROMO_ERROR_CODES, type Paginated, type PartyAddress, type PasswordHasher, type PasswordResetCliResult, PaymentCallbackRejectedError, type PaymentErrorCode, type PaymentEventClaim, type PaymentEventLog, type PaymentGateway, type PaymentGatewayCallback, type PaymentGatewayEvent, type PaymentMethodHolder, type PaymentMethodSetupSession, type PaymentMethodSetupSubject, type PaymentMethodType, type PendingRegistration, type PendingRegistrationCreateInput, type PendingRegistrationRepository, type PendingRegistrationSnapshot, type PendingRegistrationUpdateInput, type PersistenceCapabilities, PersistenceCapabilityError, type PersistenceClassRef, type PersistenceInjectionToken, type PersistenceProvider, type PlanCatalog, type PlanCatalogApp, type PlanCatalogImportReport, type PlanCatalogImportSink, type PlanCatalogIssuer, type PlanCatalogIssuerCorrection, type PlanCatalogLookup, type PlanCatalogMarketing, type PlanCatalogNotifications, type PlanCatalogPaymentAccount, type PlanCatalogPayments, type PlanCatalogReadSink, type PlanCatalogReadSnapshot, type PlanCatalogSettings, type PlanCatalogSubscribers, type PlanCatalogTenantBilling, type PlanDef, type PlanId, type PlanListFilter, type PlanRepository, type PlanRow, type PlanVersion, type PlanVersionFields, type PlanVersionMappingFields, type PlanVersionMutationResult, type PlanVersionRecord, type PlanVersionRepository, type PlanVersionRow, type PlatformErrorBody, type PlatformErrorCode, type PlatformRole, type PlatformUserDto, PlatformUserExistsError, type ProjectPageDef, type PromoCode, type PromoCodeDurationType, type PromoCodeFilter, type PromoCodeHoldRecord, type PromoCodeHoldRepository, type PromoCodeHoldTaken, type PromoCodeRecord, type PromoCodeRedemption, type PromoCodeRedemptionListItem, type PromoCodeRedemptionRecord, type PromoCodeRedemptionRepository, type PromoCodeRedemptionStatus, type PromoCodeRepository, type PromoCodeStatsPort, type PromoCodeStatsSnapshot, type PromoCodeStatus, type PromoCodeValidationLog, type PromoCodeValidationLogRepository, type PromoCodeValidationResult, type PromoCodeValueType, type PromoErrorCode, type PromoPreviewInvalidReason, type PromoPreviewRequest, type PromoPreviewResponse, type PromoPreviewValidResponse, type PromoRevenueDeductionAggregator, type PromoSubscriptionLookup, type PromotionBillingCycle, type PromotionI18n, type PromotionI18nFields, type PromotionOnPrice, type PromotionRepository, type PromotionResult, type PromotionRow, type PromotionStatus, type PromotionTargetType, type PromotionType, type PromotionValue, type PublicBootResponse, type PublicComparisonRow, type PublicMarketingBundle, type PublicMarketingCatalogResponse, type PublicMarketingPlan, type PublicMarketingPromo, type PublicNewPaymentMethods, type PublicSignupPlan, type PublishBundleVersionData, type PublishBundleVersionMeta, type PublishPlanVersionData, type QuotaCatalogEntryRow, type QuotaEnforcementMode, type QuotaKey, type QuotaProvider, REGISTRATION_ERROR_CODES, REGISTRATION_RESUME_TTL_MINUTES, REGISTRATION_STEP_BY_STATUS, type ReassignTenantAdminCliResult, type RecommendablePlan, type RecordSubscriberPaymentMethodData, type RecordSubscriberPaymentMethodOutcome, type RecordSubscriberPaymentMethodResult, type RedeemPromoInTransactionCallback, type RegistrationActivation, type RegistrationAuditContext, type RegistrationAuditEvent, type RegistrationAuditEventType, type RegistrationAuditLogger, type RegistrationBillingDetails, type RegistrationConfigSelection, type RegistrationConfiguratorLookup, type RegistrationErrorCode, type RegistrationOtpDelivery, type RegistrationPromoPreview, type RegistrationResumeDelivery, type RegistrationResumeTokenSigner, type RegistrationStatus, type RegistrationStep, type RequiredCapabilities, type ResolvableErrorBody, type ResumeRegistrationInput, type ResumeRegistrationResult, type ReviewCatalogEntryData, type RlsBypassPort, type RunningContractIssuer, type RunningContractIssuers, SETTINGS_ERROR_CODES, SETUP_ERROR_CODES, SUBSCRIBER_ERROR_CODES, type SaaSiCatPersistenceAdapter, type SaaSiCatPersistenceAdminResources, type SaaSiCatPersistenceCatalog, type SaaSiCatPersistenceCore, type SaaSiCatPersistenceEntitlement, type SaaSiCatPersistencePayments, type SaaSiCatPersistencePromo, type SaaSiCatPersistenceTenantBilling, type SaveRegistrationConfigInput, type SaveRegistrationConfigResult, type ScheduledPlanChangeInput, type SelectPlanInput, type SelectPlanResult, type SelectableBundleShape, type SelfServiceBlockedPlans, type SetCatalogEntryReviewData, type SettingsChangeFilter, type SettingsChangeRecord, type SettingsDifference, type SettingsErrorCode, type SetupConfirmMfaRequest, type SetupConfirmMfaResponse, type SetupErrorCode, type SetupRequest, type SetupResult, type SetupStatusResponse, type SlugAvailabilityCheck, type StandardPageDef, type StandardPageKey, type StartCheckoutInput, type StartCheckoutResult, type StartPaymentMethodSetupInput, type StartRegistrationInput, type StartRegistrationResult, type StoredBundleStem, type StrictModeWarning, type StrictModeWarningCode, type SubscriberContact, type SubscriberContactChange, type SubscriberCorrectionData, type SubscriberCorrectionRecord, type SubscriberCorrectionResult, type SubscriberDetails, type SubscriberErrorCode, type SubscriberIdentityCorrection, type SubscriberIdentityDelta, type SubscriberIdentityValues, type SubscriberPaymentMethodRecord, type SubscriberPaymentMethodReference, type SubscriberPaymentMethodRepository, type SubscriberPaymentMethodSetupData, type SubscriberPaymentMethodSetupMatch, type SubscriberPaymentMethodStatus, type SubscriberRecord, type SubscriberRepository, type Subscription, type SubscriptionBundleRecord, type SubscriptionBundleRepository, type SubscriptionBundleView, type SubscriptionContractFilter, type SubscriptionContractInvoiceSnapshot, type SubscriptionContractParties, type SubscriptionContractPriceSnapshot, type SubscriptionContractRecord, type SubscriptionContractRepository, type SubscriptionContractStatus, type SubscriptionRecord, type SubscriptionRepository, type SubscriptionStatsPort, type SubscriptionStatsSnapshot, type SubscriptionStatus, type SubscriptionUsagePort, type SubscriptionUsageRecord, type SuperAdminProvisioningPort, type SyncDiscoveryResult, type TenantActionDef, type TenantColumnDef, type TenantDto, type TenantListFilter, type TenantPort, type TenantSubscriptionWritePort, type TerminateSubscriptionContractData, type TopPromoCode, type TransactionContext, type TransactionRunner, type UpdateBundleData, type UpdateBundleVersionDraftData, type UpdateCatalogEntryBaseData, type UpdateCatalogEntryI18nData, type UpdateCheckoutOfferData, type UpdateMarketingProjectionData, type UpdateMarketingSettingsData, type UpdatePlanData, type UpdatePlanVersionDraftData, type UpdatePromoCodeData, type UpdatePromoCodeRequest, type UpdatePromotionData, type UpsellOffer, type UpsellOfferResolver, type UpsertCapabilityEntryData, type UpsertFeatureCatalogEntryInput, type UpsertFeatureEntryData, type UpsertPlanInput, type UpsertPlanVersionInput, type UpsertQuotaEntryData, type UpsertResult, type UsageSnapshotPort, type UserAccountLookup, type UserListFilter, type UserManagementPort, type UserPort, type VerifyRegistrationOtpResult, type VersionChange, type VersionChangeDirection, type VersionEditability, type VersionEditableReason, type VersionedEntityBase, applyPromo, assertPersistenceCapabilities, buildActivePlanVersionWhere, buildActiveVersionWhere, buildFeatureRequiresIndex, bundleDraftDefaults, bundleStemDefaults, canonicalJson, classifyBundleVersionDiff, classifyIssuerChange, classifyPlanDiff, collectUnsatisfiedRequires, contractPartiesOf, coverageExcludingSelf, definedFields, diffSettings, formatCustomerNumber, formatErrorMessage, identityCorrectionDelta, isBundleRedundant, isForeignPaymentMethodReferenceError, isPaymentCallbackRejectedError, isPlatformUserExistsError, isVersionEditable, issuerIdentityOf, keepOneRecommended, missingRequiresFor, movedIdentityFields, pickActivePromo, planCatalogSettingsOf, previousUtcDay, promoStatus, promotionOnPrice, readQuotaRecord, readQuotaValue, recordedIssuerIdentity, refuseForeignPaymentMethodReference, resolveBundleAvailability, resolveErrorMessage, sameLegalIdentity, selectChargeableBundles, settingsSubtreeOf, startOfUtcDay, subscriberFromRegistration, subscriberPaymentMethodColumns, toBundleStemRow, toContractLineItemRecord, toPlanRow, toPlanVersionRow, toRunningContractIssuer, toSubscriberCorrectionRecord, toSubscriberPaymentMethodRecord, toSubscriberRecord, toSubscriptionContractRecord };
7301
+ export { ACTIVE_SUBSCRIPTION_CONTRACT_STATUSES, AUTH_ERROR_CODES, type ActionKey, type ActivationOrchestrator, type ActivePlanVersionWhere, type ActivePlanVersionWhereWithEndsAt, type ActiveVersionWhere, type ActiveVersionWhereWithEndsAt, type ActorTag, type AdminAccountEntry, type AdminAccountHolder, type AdminActor, type AdminAuditListFilter, type AdminManifest, type AdminResourcesPort, type AdminSubscriberAccount, type AdminSubscriptionListRow, type AdminTenantDetail, type AdminTenantListFilter, type AdminTenantListRow, type AdminTenantStateResult, type AdminUserListFilter, type AdminUserListRow, type AppliedSettingsPort, type AppliedSettingsRecord, type AppliedSettingsValues, type ApplyOnboardingSelectionInput, type ApplyOnboardingSelectionResult, type ApprovedCatalogKeys, type AuditActionDef, type AuditEntry, type AuditPort, type AuditQuery, type AuditQueryPort, type AuditStatsPort, type AuditStatsSnapshot, type AuthErrorCode, BILLING_ERROR_CODES, BUNDLE_PRICE_LOOKUP_LIMIT, type BillingCycle, type BillingErrorCode, type BundleAvailabilityState, type BundleCompatibility, type BundleFeatureShape, type BundleListFilter, type BundlePricingOverride, type BundleRepository, type BundleRow, type BundleVersionFields, type BundleVersionMutationResult, type BundleVersionRow, CATALOGUE_KEYS, CATALOG_ERROR_CODES, CONTRACT_ERROR_CODES, type CancelSubscriptionBundleData, type CancelSubscriptionInput, type CancelSubscriptionResult, type CancellationNoticePeriods, type CanonicalContractLineItemRow, type CanonicalContractRow, type CanonicalPlanRow, type CanonicalPlanVersionRow, type CanonicalRunningContractRow, type CanonicalSubscriberChargeRow, type CanonicalSubscriberCorrectionRow, type CanonicalSubscriberPaymentMethodRow, type CanonicalSubscriberRow, type CanonicalSubscriptionBundleRow, type CapabilityCatalogEntryRow, type CapabilityCodeStatus, type CapabilityKey, type CapabilityKind, type CatalogEntryFilter, type CatalogEntryI18n, type CatalogEntryI18nFields, type CatalogEntryRepository, type CatalogErrorCode, type ChangeDirection, type CheckoutOfferFilter, type CheckoutOfferLineItem, type CheckoutOfferLineItemKind, type CheckoutOfferPriceBreakdown, type CheckoutOfferPromoCodeSnapshot, type CheckoutOfferPromotionSnapshot, type CheckoutOfferRepository, type CheckoutOfferRow, type CheckoutOfferSelection, type CheckoutOfferSelectionUpdate, type CheckoutOfferStatus, type CleanupResult, type CliUserRow, type ComponentKey, type ConfiguratorCatalog, type ConfiguratorMarketingProvider, type ConfiguratorModel, type ConfiguratorPlanMarketing, type ConfiguratorPlanVersionRow, type ConfiguratorPriceBreakdown, type ConfiguratorSourcesLookup, type ConfirmedPaymentMethod, type ContractErrorCode, type ContractIssuerParty, type ContractLineItemKind, type ContractLineItemRecord, type ContractSubscriberParty, type CreateBundleData, type CreateBundleVersionDraftData, type CreateCheckoutOfferData, type CreateMarketingProjectionData, type CreatePlanData, type CreatePlanVersionDraftData, type CreatePromoCodeData, type CreatePromoCodeRequest, type CreatePromotionData, type CreateSubscriberData, type CreateSubscriptionBundleData, type CreateSubscriptionContractData, type CreateSuperAdminCliInput, type CreateTenantInput, type DiffResult, type DiscoveredCapability, type DiscoveredFeature, type DiscoveredQuota, type DiscoveredQuotaPolicy, type DiscoveryCodeStatus, type DiscoverySnapshot, type DiscoveryStatus, ERROR_MESSAGES_DE, ERROR_MESSAGES_EN, type EffectiveLimitsSnapshot, type EmailPort, type ErrorMessageParams, FEATURE_NOT_LICENSED, type FeatureCatalogEntryRow, type FeatureDef, type FeatureKey, type FeatureNotLicensedBody, type FeatureRequiresIndex, type FeatureTier, type FeatureUiMeta, type FeatureUiRegistry, type FinalActivationResult, type FirstTimeCustomerCheck, ForeignPaymentMethodReferenceError, type ImmediatePlanChangeInput, type InvoiceLineItemSnapshot, type IssuerCorrectionFault, type IssuerIdentityChange, type KpiCardDef, type KpiDisplayHint, LEGAL_IDENTITY_FIELDS, type LegalIdentity, type LegalIdentityField, MARKETING_PRIORITY_MAX, MARKETING_PRIORITY_MIN, type ManifestAccessPort, type ManifestContribution, type MarketingProjectionFilter, type MarketingProjectionRepository, type MarketingProjectionRow, type MarketingSettingsRepository, type MarketingSettingsRow, type MarketingTargetType, type MarketingTopFeature, type MaskedPaymentMethod, type MfaPort, type NewContractLineItemData, type NewSettingsChange, type NewSubscriberCharge, type NewSubscriberDetails, type NewSubscriptionContractData, OTP_RATE_LIMIT_MAX_SENDS, OTP_RATE_LIMIT_WINDOW_MINUTES, OTP_TTL_MINUTES, OTP_VERIFY_MAX_ATTEMPTS, type OnboardingPromoRedemption, type OnboardingSelectionRequest, type OnboardingSelectionResponse, PASSWORD_RESET_TTL_MINUTES, PAYMENT_ERROR_CODES, PAYMENT_METHOD_TYPES, PENDING_CHECKOUT_TTL_DAYS, PENDING_EMAIL_TTL_HOURS, PENDING_ONBOARDING_TTL_DAYS, PLATFORM_ERROR_CODES, PROMO_ERROR_CODES, type Paginated, type PartyAddress, type PasswordHasher, type PasswordResetCliResult, PaymentCallbackRejectedError, type PaymentErrorCode, type PaymentEventClaim, type PaymentEventLog, type PaymentGateway, type PaymentGatewayCallback, type PaymentGatewayEvent, type PaymentMethodHolder, type PaymentMethodSetupSession, type PaymentMethodSetupSubject, type PaymentMethodType, type PendingRegistration, type PendingRegistrationCreateInput, type PendingRegistrationRepository, type PendingRegistrationSnapshot, type PendingRegistrationUpdateInput, type PersistenceCapabilities, PersistenceCapabilityError, type PersistenceClassRef, type PersistenceInjectionToken, type PersistenceProvider, type PlanCatalog, type PlanCatalogApp, type PlanCatalogImportReport, type PlanCatalogImportSink, type PlanCatalogIssuer, type PlanCatalogIssuerCorrection, type PlanCatalogLookup, type PlanCatalogMarketing, type PlanCatalogNotifications, type PlanCatalogPaymentAccount, type PlanCatalogPayments, type PlanCatalogReadSink, type PlanCatalogReadSnapshot, type PlanCatalogSettings, type PlanCatalogSubscribers, type PlanCatalogTenantBilling, type PlanDef, type PlanId, type PlanListFilter, type PlanRepository, type PlanRow, type PlanVersion, type PlanVersionFields, type PlanVersionMappingFields, type PlanVersionMutationResult, type PlanVersionRecord, type PlanVersionRepository, type PlanVersionRow, type PlatformErrorBody, type PlatformErrorCode, type PlatformRole, type PlatformUserDto, PlatformUserExistsError, type ProjectPageDef, type PromoCode, type PromoCodeDurationType, type PromoCodeFilter, type PromoCodeHoldRecord, type PromoCodeHoldRepository, type PromoCodeHoldTaken, type PromoCodeRecord, type PromoCodeRedemption, type PromoCodeRedemptionListItem, type PromoCodeRedemptionRecord, type PromoCodeRedemptionRepository, type PromoCodeRedemptionStatus, type PromoCodeRepository, type PromoCodeStatsPort, type PromoCodeStatsSnapshot, type PromoCodeStatus, type PromoCodeValidationLog, type PromoCodeValidationLogRepository, type PromoCodeValidationResult, type PromoCodeValueType, type PromoErrorCode, type PromoPreviewInvalidReason, type PromoPreviewRequest, type PromoPreviewResponse, type PromoPreviewValidResponse, type PromoRevenueDeductionAggregator, type PromoSubscriptionLookup, type PromotionBillingCycle, type PromotionI18n, type PromotionI18nFields, type PromotionOnPrice, type PromotionRepository, type PromotionResult, type PromotionRow, type PromotionStatus, type PromotionTargetType, type PromotionType, type PromotionValue, type PublicBootResponse, type PublicComparisonRow, type PublicMarketingBundle, type PublicMarketingCatalogResponse, type PublicMarketingPlan, type PublicMarketingPromo, type PublicNewPaymentMethods, type PublicSignupPlan, type PublishBundleVersionData, type PublishBundleVersionMeta, type PublishPlanVersionData, type QuotaCatalogEntryRow, type QuotaEnforcementMode, type QuotaKey, type QuotaProvider, REGISTRATION_ERROR_CODES, REGISTRATION_RESUME_TTL_MINUTES, REGISTRATION_STEP_BY_STATUS, type ReassignTenantAdminCliResult, type RecommendablePlan, type RecordSubscriberPaymentMethodData, type RecordSubscriberPaymentMethodOutcome, type RecordSubscriberPaymentMethodResult, type RedeemPromoInTransactionCallback, type RegistrationActivation, type RegistrationAuditContext, type RegistrationAuditEvent, type RegistrationAuditEventType, type RegistrationAuditLogger, type RegistrationBillingDetails, type RegistrationConfigSelection, type RegistrationConfiguratorLookup, type RegistrationErrorCode, type RegistrationOtpDelivery, type RegistrationPromoPreview, type RegistrationResumeDelivery, type RegistrationResumeTokenSigner, type RegistrationStatus, type RegistrationStep, type RequiredCapabilities, type ResolvableErrorBody, type ResumeRegistrationInput, type ResumeRegistrationResult, type ReviewCatalogEntryData, type RlsBypassPort, type RunningContractIssuer, type RunningContractIssuers, SETTINGS_ERROR_CODES, SETUP_ERROR_CODES, SUBSCRIBER_ACCOUNT_CAPABILITY, SUBSCRIBER_ERROR_CODES, type SaaSiCatPersistenceAdapter, type SaaSiCatPersistenceAdminResources, type SaaSiCatPersistenceCatalog, type SaaSiCatPersistenceCore, type SaaSiCatPersistenceEntitlement, type SaaSiCatPersistencePayments, type SaaSiCatPersistencePromo, type SaaSiCatPersistenceTenantBilling, type SaveRegistrationConfigInput, type SaveRegistrationConfigResult, type ScheduledPlanChangeInput, type SelectPlanInput, type SelectPlanResult, type SelectableBundleShape, type SelfServiceBlockedPlans, type SetCatalogEntryReviewData, type SettingsChangeFilter, type SettingsChangeRecord, type SettingsDifference, type SettingsErrorCode, type SetupConfirmMfaRequest, type SetupConfirmMfaResponse, type SetupErrorCode, type SetupRequest, type SetupResult, type SetupStatusResponse, type SlugAvailabilityCheck, type StandardPageDef, type StandardPageKey, type StartCheckoutInput, type StartCheckoutResult, type StartPaymentMethodSetupInput, type StartRegistrationInput, type StartRegistrationResult, type StoredBundleStem, type StrictModeWarning, type StrictModeWarningCode, type SubscriberCharge, type SubscriberChargeOrigin, type SubscriberChargeRecord, type SubscriberChargeSource, type SubscriberContact, type SubscriberContactChange, type SubscriberCorrectionData, type SubscriberCorrectionRecord, type SubscriberCorrectionResult, type SubscriberDetails, type SubscriberErrorCode, type SubscriberIdentityCorrection, type SubscriberIdentityDelta, type SubscriberIdentityValues, type SubscriberLedgerRepository, type SubscriberPaymentMethodRecord, type SubscriberPaymentMethodReference, type SubscriberPaymentMethodRepository, type SubscriberPaymentMethodSetupData, type SubscriberPaymentMethodSetupMatch, type SubscriberPaymentMethodStatus, type SubscriberRecord, type SubscriberRepository, type Subscription, type SubscriptionBundleRecord, type SubscriptionBundleRepository, type SubscriptionBundleView, type SubscriptionContractFilter, type SubscriptionContractInvoiceSnapshot, type SubscriptionContractParties, type SubscriptionContractPriceSnapshot, type SubscriptionContractRecord, type SubscriptionContractRepository, type SubscriptionContractStatus, type SubscriptionRecord, type SubscriptionRepository, type SubscriptionStatsPort, type SubscriptionStatsSnapshot, type SubscriptionStatus, type SubscriptionUsagePort, type SubscriptionUsageRecord, type SuperAdminProvisioningPort, type SyncDiscoveryResult, type TenantActionDef, type TenantColumnDef, type TenantDto, type TenantListFilter, type TenantPort, type TenantSubscriptionWritePort, type TerminateSubscriptionContractData, type TopPromoCode, type TransactionContext, type TransactionRunner, type UpdateBundleData, type UpdateBundleVersionDraftData, type UpdateCatalogEntryBaseData, type UpdateCatalogEntryI18nData, type UpdateCheckoutOfferData, type UpdateMarketingProjectionData, type UpdateMarketingSettingsData, type UpdatePlanData, type UpdatePlanVersionDraftData, type UpdatePromoCodeData, type UpdatePromoCodeRequest, type UpdatePromotionData, type UpsellOffer, type UpsellOfferResolver, type UpsertCapabilityEntryData, type UpsertFeatureCatalogEntryInput, type UpsertFeatureEntryData, type UpsertPlanInput, type UpsertPlanVersionInput, type UpsertQuotaEntryData, type UpsertResult, type UsageSnapshotPort, type UserAccountLookup, type UserListFilter, type UserManagementPort, type UserPort, type VerifyRegistrationOtpResult, type VersionChange, type VersionChangeDirection, type VersionEditability, type VersionEditableReason, type VersionedEntityBase, applyPromo, assertPersistenceCapabilities, buildActivePlanVersionWhere, buildActiveVersionWhere, buildFeatureRequiresIndex, bundleDraftDefaults, bundleStemDefaults, canonicalJson, classifyBundleVersionDiff, classifyIssuerChange, classifyPlanDiff, collectUnsatisfiedRequires, contractPartiesOf, coverageExcludingSelf, definedFields, diffSettings, formatCustomerNumber, formatErrorMessage, identityCorrectionDelta, isBundleRedundant, isForeignPaymentMethodReferenceError, isPaymentCallbackRejectedError, isPlatformUserExistsError, isVersionEditable, issuerIdentityOf, keepOneRecommended, missingRequiresFor, movedIdentityFields, pickActivePromo, planCatalogSettingsOf, previousUtcDay, promoStatus, promotionOnPrice, readQuotaRecord, readQuotaValue, recordedIssuerIdentity, refuseForeignPaymentMethodReference, resolveBundleAvailability, resolveErrorMessage, sameLegalIdentity, selectChargeableBundles, settingsSubtreeOf, startOfUtcDay, subscriberChargeColumns, subscriberFromRegistration, subscriberPaymentMethodColumns, toBundleStemRow, toContractLineItemRecord, toPlanRow, toPlanVersionRow, toRunningContractIssuer, toSubscriberChargeRecord, toSubscriberCorrectionRecord, toSubscriberPaymentMethodRecord, toSubscriberRecord, toSubscriptionBundleRecord, toSubscriptionContractRecord };
package/dist/index.d.ts CHANGED
@@ -643,12 +643,19 @@ interface PaymentGateway {
643
643
  /**
644
644
  * Opens the gateway's form for a payment method. Nothing is confirmed until
645
645
  * the gateway says so through `readCallback`.
646
+ *
647
+ * A failure is thrown as the provider reported it: the platform answers the
648
+ * person with `PAYMENT_GATEWAY_FAILED` and keeps what the error carries —
649
+ * its kind, code, status and request id — in the server log.
646
650
  */
647
651
  startPaymentMethodSetup(input: StartPaymentMethodSetupInput): Promise<PaymentMethodSetupSession>;
648
652
  /**
649
653
  * Verifies a callback with the account's secret and translates it.
650
654
  * Throws `PaymentCallbackRejectedError` for anything the gateway did not
651
- * send, before a single field of it is trusted.
655
+ * send, before a single field of it is trusted. Any other failure is
656
+ * answered with `PAYMENT_GATEWAY_FAILED` and 502, like one of
657
+ * `startPaymentMethodSetup` — to the gateway's webhook, or to the person
658
+ * an `immediateCallback` is read for.
652
659
  */
653
660
  readCallback(callback: PaymentGatewayCallback): Promise<PaymentGatewayEvent>;
654
661
  }
@@ -1103,7 +1110,7 @@ interface SubscriptionBundleRecord {
1103
1110
  * or on one whose plan has no period; readers fall back to the plan's
1104
1111
  * cycle, which is what every booking used before.
1105
1112
  */
1106
- billingCycle: string | null;
1113
+ billingCycle: BillingCycle | null;
1107
1114
  currentPeriodStart: Date | null;
1108
1115
  currentPeriodEnd: Date | null;
1109
1116
  createdAt: Date;
@@ -1137,7 +1144,7 @@ interface CreateSubscriptionBundleData {
1137
1144
  /** Null unless a commitment was configured or asked for. */
1138
1145
  minimumTermEndsAt?: Date | null;
1139
1146
  /** The rhythm and window worked out above this port. */
1140
- billingCycle?: string | null;
1147
+ billingCycle?: BillingCycle | null;
1141
1148
  currentPeriodStart?: Date | null;
1142
1149
  currentPeriodEnd?: Date | null;
1143
1150
  }
@@ -2206,6 +2213,16 @@ interface EffectiveLimitsSnapshot {
2206
2213
  plan: string;
2207
2214
  quotas: Record<string, number>;
2208
2215
  features: string[];
2216
+ /**
2217
+ * The add-ons a contract left out of these entitlements because their
2218
+ * cancellation was already declared when it was written. Each is granted by
2219
+ * its booking until its effective date, and by this snapshot never.
2220
+ *
2221
+ * Absent where nothing was left out — and on a snapshot written by an
2222
+ * application, or before the platform left anything out, which then counts
2223
+ * every add-on it names as its own.
2224
+ */
2225
+ leftOutBundleVersionIds?: string[];
2209
2226
  }
2210
2227
 
2211
2228
  interface FeatureUiMeta {
@@ -3511,6 +3528,128 @@ interface SubscriberCorrectionResult {
3511
3528
  correction: SubscriberCorrectionRecord | null;
3512
3529
  }
3513
3530
 
3531
+ /**
3532
+ * What made the charge arise. activation: the first period of a subscription. renewal: a later period. planChange: what an immediate plan change adds. bundleBooking: the first, short period of an add-on. credit: a decision that reduces what is owed. correction: a counter-entry reversing an earlier charge, which is how the append-only journal answers a mistake.
3533
+ */
3534
+ type SubscriberChargeOrigin = 'activation' | 'renewal' | 'planChange' | 'bundleBooking' | 'credit' | 'correction';
3535
+ /**
3536
+ * Which kind of contract line the charge realises.
3537
+ */
3538
+ type SubscriberChargeSource = 'plan' | 'bundle' | 'discount';
3539
+ /**
3540
+ * One charge in a subscriber's account: an amount that became due for a period, derived from a line of the contract in force. The journal is append-only — a charge is never updated, and a mistake is answered with a counter-entry rather than an edit, so the account says what happened rather than what somebody thinks today. A charge is net: the tax is decided by the tax adapter when the charge is invoiced, from the subscriber's origin on that day, and computed once per rate on the invoice.
3541
+ */
3542
+ interface SubscriberCharge {
3543
+ /**
3544
+ * The charge's own identifier. Never shown to a customer as an invoice number: invoice numbering is sequential, gapless and legally constrained per country, and an identifier somebody has already seen on a screen cannot become one later without confusion.
3545
+ */
3546
+ id: string;
3547
+ /**
3548
+ * The party the contract is concluded with, whose account this is. It outlives the tenant.
3549
+ */
3550
+ subscriberId: string;
3551
+ /**
3552
+ * The tenant the subscription belonged to when the charge arose.
3553
+ */
3554
+ tenantId: string;
3555
+ /**
3556
+ * The subscription the charge arose on. Part of the natural key.
3557
+ */
3558
+ subscriptionId: string;
3559
+ /**
3560
+ * The contract whose line the charge realises.
3561
+ */
3562
+ contractId: string;
3563
+ /**
3564
+ * The contract line the charge came from, so that every invoice line can be traced back to what was agreed.
3565
+ */
3566
+ contractLineItemId: string;
3567
+ origin: SubscriberChargeOrigin;
3568
+ source: SubscriberChargeSource;
3569
+ /**
3570
+ * Which thing of its source the charge is for, stable across contracts: the subscription id for the plan, the booking id for an add-on, the discount's key for a discount. Part of the natural key (subscriptionId, source, sourceRef, periodStart, origin), which is unique — a charge derived twice is written once.
3571
+ */
3572
+ sourceRef: string;
3573
+ /**
3574
+ * The start of the period the charge belongs to — the grouping key for an invoice.
3575
+ */
3576
+ periodStart: string;
3577
+ periodEnd: string;
3578
+ /**
3579
+ * ISO 4217, as the contract line records it — recorded per charge so that a charge written in 2026 still means what it meant after the configured currency changes.
3580
+ */
3581
+ currency: string;
3582
+ /**
3583
+ * Net, rounded to the currency's decimal places once, when the charge is written; the written figure is the truth from then on. Negative for a discount.
3584
+ */
3585
+ amountNet: number;
3586
+ /**
3587
+ * When the amount became due. The account is ordered by this, not by when the row was written.
3588
+ */
3589
+ bookedAt: string;
3590
+ createdAt: string;
3591
+ }
3592
+
3593
+ /** A charge as a store reads it back: the wire format, with its dates as dates. */
3594
+ interface SubscriberChargeRecord {
3595
+ id: string;
3596
+ subscriberId: string;
3597
+ tenantId: string;
3598
+ subscriptionId: string;
3599
+ contractId: string;
3600
+ contractLineItemId: string;
3601
+ origin: SubscriberChargeOrigin;
3602
+ source: SubscriberChargeSource;
3603
+ /** The subscription id for the plan, the booking id for an add-on, the discount's key. */
3604
+ sourceRef: string;
3605
+ periodStart: Date;
3606
+ periodEnd: Date;
3607
+ currency: string;
3608
+ /** Net, rounded to the cent when written. Negative for a discount. */
3609
+ amountNet: number;
3610
+ /** When the amount became due. */
3611
+ bookedAt: Date;
3612
+ createdAt: Date;
3613
+ }
3614
+ /** A charge to write: everything but what the store assigns. */
3615
+ type NewSubscriberCharge = Omit<SubscriberChargeRecord, 'id' | 'createdAt'>;
3616
+ /**
3617
+ * The manifest capability that announces the operator's view of an account.
3618
+ * The platform sets it where it serves the view, and the admin UI shows the
3619
+ * view only where it is set.
3620
+ */
3621
+ declare const SUBSCRIBER_ACCOUNT_CAPABILITY = "charges.read";
3622
+ /** Whose account it is, as the operator is shown it. */
3623
+ interface AdminAccountHolder {
3624
+ id: string;
3625
+ /** What the customer quotes, and what an invoice will carry. */
3626
+ customerNumber: string;
3627
+ legalName: string;
3628
+ }
3629
+ /** One charge of an account, with the name its contract line gives it. */
3630
+ interface AdminAccountEntry {
3631
+ /** The charge as the journal holds it. */
3632
+ charge: SubscriberCharge;
3633
+ /**
3634
+ * The contract line's own title, as it was when the contract was
3635
+ * concluded, or `null` where that line cannot be read.
3636
+ */
3637
+ title: string | null;
3638
+ }
3639
+ /**
3640
+ * A tenant's account as the operator reads it: the charges of the subscription
3641
+ * it holds, newest first — by when each became due, then by its period, then
3642
+ * the plan before its add-ons before its discounts.
3643
+ *
3644
+ * No total: without invoices and payments, a sum would be what was charged so
3645
+ * far, and it would be read as what is owed.
3646
+ */
3647
+ interface AdminSubscriberAccount {
3648
+ /** `null` for a tenant that has no subscriber. */
3649
+ holder: AdminAccountHolder | null;
3650
+ entries: AdminAccountEntry[];
3651
+ }
3652
+
3514
3653
  /**
3515
3654
  * Snapshot form of a `Subscription` row for the EntitlementService
3516
3655
  * computation. The consumer maps its Prisma structure onto this form.
@@ -3758,6 +3897,27 @@ interface SubscriberRepository {
3758
3897
  /** Every correction of this subscriber, the latest first. */
3759
3898
  listCorrections(subscriberId: string): Promise<SubscriberCorrectionRecord[]>;
3760
3899
  }
3900
+ /**
3901
+ * The subscriber's account: the charges that became due, one per contract line
3902
+ * and period. Append-only — nothing here updates or deletes a charge, and a
3903
+ * mistake is answered with a counter-entry (`SC-PRIC-020`).
3904
+ *
3905
+ * Owned by the subscriber rather than the tenant, so that it outlives the
3906
+ * tenant it arose for (ADR 0012).
3907
+ */
3908
+ interface SubscriberLedgerRepository {
3909
+ /**
3910
+ * Writes the charges that are not there yet and returns them.
3911
+ *
3912
+ * A charge whose natural key — subscription, source, source reference,
3913
+ * period start and origin — is already written is left as it is and not
3914
+ * returned, however often it is derived and whoever derives it at the same
3915
+ * time: the unique index decides, not a read before the write.
3916
+ */
3917
+ recordCharges(charges: readonly NewSubscriberCharge[], tx?: TransactionContext): Promise<SubscriberChargeRecord[]>;
3918
+ /** Every charge of one subscription, oldest period first. */
3919
+ listBySubscription(subscriptionId: string, tx?: TransactionContext): Promise<SubscriberChargeRecord[]>;
3920
+ }
3761
3921
  /**
3762
3922
  * Display form of a subscription for the tenant self-service UI.
3763
3923
  * Richer than `SubscriptionRecord` (which is only the aggregation form); contains
@@ -5085,6 +5245,8 @@ interface SaaSiCatPersistenceEntitlement {
5085
5245
  subscriptionContractRepository?: PersistenceProvider<SubscriptionContractRepository>;
5086
5246
  /** The parties contracts are concluded with; required wherever contracts are written. */
5087
5247
  subscriberRepository?: PersistenceProvider<SubscriberRepository>;
5248
+ /** The charges a subscriber's contracts give rise to (`tenantBilling.chargeJournal`). */
5249
+ subscriberLedgerRepository?: PersistenceProvider<SubscriberLedgerRepository>;
5088
5250
  subscriptionBundleRepository?: PersistenceProvider<SubscriptionBundleRepository>;
5089
5251
  bundleRepository?: PersistenceProvider<BundleRepository>;
5090
5252
  }
@@ -5530,6 +5692,13 @@ declare const PAYMENT_ERROR_CODES: {
5530
5692
  * does not name. Carries `field`.
5531
5693
  */
5532
5694
  readonly PAYMENT_RETURN_URL_NOT_ALLOWED: "PAYMENT_RETURN_URL_NOT_ALLOWED";
5695
+ /**
5696
+ * The gateway failed — unreachable, refusing the account's keys, or
5697
+ * answering with an error — while opening its form or reading a callback
5698
+ * back. Answered with 502; what the gateway answered stays in the server
5699
+ * log.
5700
+ */
5701
+ readonly PAYMENT_GATEWAY_FAILED: "PAYMENT_GATEWAY_FAILED";
5533
5702
  };
5534
5703
  type PaymentErrorCode = (typeof PAYMENT_ERROR_CODES)[keyof typeof PAYMENT_ERROR_CODES];
5535
5704
  /** Codes of the settings record (`GET /admin/settings`, the acknowledgement). */
@@ -5562,6 +5731,13 @@ declare const PLATFORM_ERROR_CODES: {
5562
5731
  * does not name. Carries `field`.
5563
5732
  */
5564
5733
  readonly PAYMENT_RETURN_URL_NOT_ALLOWED: "PAYMENT_RETURN_URL_NOT_ALLOWED";
5734
+ /**
5735
+ * The gateway failed — unreachable, refusing the account's keys, or
5736
+ * answering with an error — while opening its form or reading a callback
5737
+ * back. Answered with 502; what the gateway answered stays in the server
5738
+ * log.
5739
+ */
5740
+ readonly PAYMENT_GATEWAY_FAILED: "PAYMENT_GATEWAY_FAILED";
5565
5741
  readonly PENDING_REGISTRATION_NOT_FOUND: "PENDING_REGISTRATION_NOT_FOUND";
5566
5742
  readonly PENDING_REGISTRATION_EXPIRED: "PENDING_REGISTRATION_EXPIRED";
5567
5743
  readonly INVALID_REGISTRATION_STATE: "INVALID_REGISTRATION_STATE";
@@ -6779,6 +6955,47 @@ type IssuerIdentityChange =
6779
6955
  */
6780
6956
  declare function classifyIssuerChange(recorded: LegalIdentity | null, issuer: PlanCatalogIssuer | undefined): IssuerIdentityChange;
6781
6957
 
6958
+ /**
6959
+ * A `subscriber_ledger_entries` row as either adapter reads it back. The amount
6960
+ * is `unknown` because a Prisma row carries a `Decimal` where a Drizzle row
6961
+ * carries a numeric string.
6962
+ */
6963
+ interface CanonicalSubscriberChargeRow {
6964
+ id: string;
6965
+ subscriberId: string;
6966
+ tenantId: string;
6967
+ subscriptionId: string;
6968
+ contractId: string;
6969
+ contractLineItemId: string;
6970
+ origin: string;
6971
+ source: string;
6972
+ sourceRef: string;
6973
+ periodStart: Date;
6974
+ periodEnd: Date;
6975
+ currency: string;
6976
+ amountNet: unknown;
6977
+ bookedAt: Date;
6978
+ createdAt: Date;
6979
+ }
6980
+ /**
6981
+ * Reads a row back as a record. The origin and the source are checked rather
6982
+ * than cast: a value written by hand or by a later release would otherwise
6983
+ * reach an invoice as a charge nobody knows how to read.
6984
+ */
6985
+ declare function toSubscriberChargeRecord(row: CanonicalSubscriberChargeRow): SubscriberChargeRecord;
6986
+ /**
6987
+ * The columns a charge is written with. The amount goes as a decimal string of
6988
+ * two places, which both a Prisma `Decimal` and a PostgreSQL `numeric` take
6989
+ * exactly — a JavaScript number on its way to either is where a cent is lost.
6990
+ *
6991
+ * An amount that is not already a whole number of cents is refused rather than
6992
+ * rounded: a charge is rounded once, where it is derived, and a second rounding
6993
+ * here would make the written figure differ from the one that was computed.
6994
+ */
6995
+ declare function subscriberChargeColumns(charge: NewSubscriberCharge): Omit<CanonicalSubscriberChargeRow, 'id' | 'createdAt' | 'amountNet'> & {
6996
+ amountNet: string;
6997
+ };
6998
+
6782
6999
  /** A `subscribers` row as either adapter reads it back. */
6783
7000
  interface CanonicalSubscriberRow {
6784
7001
  id: string;
@@ -6907,6 +7124,37 @@ declare function isForeignPaymentMethodReferenceError(error: unknown): error is
6907
7124
  */
6908
7125
  declare function refuseForeignPaymentMethodReference(recorded: Pick<CanonicalSubscriberPaymentMethodRow, 'subscriberId' | 'gatewayAccount' | 'paymentMethodRef'>, subscriberId: string): void;
6909
7126
 
7127
+ /**
7128
+ * A `subscription_bundles` row as either adapter reads it back.
7129
+ *
7130
+ * The three billing columns are optional because a Prisma client generated from
7131
+ * a schema that predates them returns a row without them; an absent column
7132
+ * reads as null, the same as a booking made before they existed.
7133
+ */
7134
+ interface CanonicalSubscriptionBundleRow {
7135
+ id: string;
7136
+ subscriptionId: string;
7137
+ bundleVersionId: string;
7138
+ startedAt: Date;
7139
+ minimumTermEndsAt: Date | null;
7140
+ billingCycle?: string | null;
7141
+ currentPeriodStart?: Date | null;
7142
+ currentPeriodEnd?: Date | null;
7143
+ canceledAt: Date | null;
7144
+ canceledEffectiveAt: Date | null;
7145
+ createdAt: Date;
7146
+ updatedAt: Date;
7147
+ }
7148
+ /**
7149
+ * Reads a row back as a record.
7150
+ *
7151
+ * `billingCycle` is a text column the platform only ever writes as `MONTHLY` or
7152
+ * `YEARLY`, and a price is chosen by asking whether it is `YEARLY` — so any
7153
+ * other value would be billed monthly without a word. It is checked rather than
7154
+ * cast, and a value outside the two stops the read.
7155
+ */
7156
+ declare function toSubscriptionBundleRecord(row: CanonicalSubscriptionBundleRow): SubscriptionBundleRecord;
7157
+
6910
7158
  /** A `subscription_contracts` row as either adapter reads it back. */
6911
7159
  interface CanonicalContractRow {
6912
7160
  id: string;
@@ -7050,4 +7298,4 @@ declare function resolveErrorMessage(body: ResolvableErrorBody, overrides?: Part
7050
7298
 
7051
7299
  declare const ERROR_MESSAGES_DE: Record<PlatformErrorCode, string>;
7052
7300
 
7053
- export { ACTIVE_SUBSCRIPTION_CONTRACT_STATUSES, AUTH_ERROR_CODES, type ActionKey, type ActivationOrchestrator, type ActivePlanVersionWhere, type ActivePlanVersionWhereWithEndsAt, type ActiveVersionWhere, type ActiveVersionWhereWithEndsAt, type ActorTag, type AdminActor, type AdminAuditListFilter, type AdminManifest, type AdminResourcesPort, type AdminSubscriptionListRow, type AdminTenantDetail, type AdminTenantListFilter, type AdminTenantListRow, type AdminTenantStateResult, type AdminUserListFilter, type AdminUserListRow, type AppliedSettingsPort, type AppliedSettingsRecord, type AppliedSettingsValues, type ApplyOnboardingSelectionInput, type ApplyOnboardingSelectionResult, type ApprovedCatalogKeys, type AuditActionDef, type AuditEntry, type AuditPort, type AuditQuery, type AuditQueryPort, type AuditStatsPort, type AuditStatsSnapshot, type AuthErrorCode, BILLING_ERROR_CODES, BUNDLE_PRICE_LOOKUP_LIMIT, type BillingCycle, type BillingErrorCode, type BundleAvailabilityState, type BundleCompatibility, type BundleFeatureShape, type BundleListFilter, type BundlePricingOverride, type BundleRepository, type BundleRow, type BundleVersionFields, type BundleVersionMutationResult, type BundleVersionRow, CATALOGUE_KEYS, CATALOG_ERROR_CODES, CONTRACT_ERROR_CODES, type CancelSubscriptionBundleData, type CancelSubscriptionInput, type CancelSubscriptionResult, type CancellationNoticePeriods, type CanonicalContractLineItemRow, type CanonicalContractRow, type CanonicalPlanRow, type CanonicalPlanVersionRow, type CanonicalRunningContractRow, type CanonicalSubscriberCorrectionRow, type CanonicalSubscriberPaymentMethodRow, type CanonicalSubscriberRow, type CapabilityCatalogEntryRow, type CapabilityCodeStatus, type CapabilityKey, type CapabilityKind, type CatalogEntryFilter, type CatalogEntryI18n, type CatalogEntryI18nFields, type CatalogEntryRepository, type CatalogErrorCode, type ChangeDirection, type CheckoutOfferFilter, type CheckoutOfferLineItem, type CheckoutOfferLineItemKind, type CheckoutOfferPriceBreakdown, type CheckoutOfferPromoCodeSnapshot, type CheckoutOfferPromotionSnapshot, type CheckoutOfferRepository, type CheckoutOfferRow, type CheckoutOfferSelection, type CheckoutOfferSelectionUpdate, type CheckoutOfferStatus, type CleanupResult, type CliUserRow, type ComponentKey, type ConfiguratorCatalog, type ConfiguratorMarketingProvider, type ConfiguratorModel, type ConfiguratorPlanMarketing, type ConfiguratorPlanVersionRow, type ConfiguratorPriceBreakdown, type ConfiguratorSourcesLookup, type ConfirmedPaymentMethod, type ContractErrorCode, type ContractIssuerParty, type ContractLineItemKind, type ContractLineItemRecord, type ContractSubscriberParty, type CreateBundleData, type CreateBundleVersionDraftData, type CreateCheckoutOfferData, type CreateMarketingProjectionData, type CreatePlanData, type CreatePlanVersionDraftData, type CreatePromoCodeData, type CreatePromoCodeRequest, type CreatePromotionData, type CreateSubscriberData, type CreateSubscriptionBundleData, type CreateSubscriptionContractData, type CreateSuperAdminCliInput, type CreateTenantInput, type DiffResult, type DiscoveredCapability, type DiscoveredFeature, type DiscoveredQuota, type DiscoveredQuotaPolicy, type DiscoveryCodeStatus, type DiscoverySnapshot, type DiscoveryStatus, ERROR_MESSAGES_DE, ERROR_MESSAGES_EN, type EffectiveLimitsSnapshot, type EmailPort, type ErrorMessageParams, FEATURE_NOT_LICENSED, type FeatureCatalogEntryRow, type FeatureDef, type FeatureKey, type FeatureNotLicensedBody, type FeatureRequiresIndex, type FeatureTier, type FeatureUiMeta, type FeatureUiRegistry, type FinalActivationResult, type FirstTimeCustomerCheck, ForeignPaymentMethodReferenceError, type ImmediatePlanChangeInput, type InvoiceLineItemSnapshot, type IssuerCorrectionFault, type IssuerIdentityChange, type KpiCardDef, type KpiDisplayHint, LEGAL_IDENTITY_FIELDS, type LegalIdentity, type LegalIdentityField, MARKETING_PRIORITY_MAX, MARKETING_PRIORITY_MIN, type ManifestAccessPort, type ManifestContribution, type MarketingProjectionFilter, type MarketingProjectionRepository, type MarketingProjectionRow, type MarketingSettingsRepository, type MarketingSettingsRow, type MarketingTargetType, type MarketingTopFeature, type MaskedPaymentMethod, type MfaPort, type NewContractLineItemData, type NewSettingsChange, type NewSubscriberDetails, type NewSubscriptionContractData, OTP_RATE_LIMIT_MAX_SENDS, OTP_RATE_LIMIT_WINDOW_MINUTES, OTP_TTL_MINUTES, OTP_VERIFY_MAX_ATTEMPTS, type OnboardingPromoRedemption, type OnboardingSelectionRequest, type OnboardingSelectionResponse, PASSWORD_RESET_TTL_MINUTES, PAYMENT_ERROR_CODES, PAYMENT_METHOD_TYPES, PENDING_CHECKOUT_TTL_DAYS, PENDING_EMAIL_TTL_HOURS, PENDING_ONBOARDING_TTL_DAYS, PLATFORM_ERROR_CODES, PROMO_ERROR_CODES, type Paginated, type PartyAddress, type PasswordHasher, type PasswordResetCliResult, PaymentCallbackRejectedError, type PaymentErrorCode, type PaymentEventClaim, type PaymentEventLog, type PaymentGateway, type PaymentGatewayCallback, type PaymentGatewayEvent, type PaymentMethodHolder, type PaymentMethodSetupSession, type PaymentMethodSetupSubject, type PaymentMethodType, type PendingRegistration, type PendingRegistrationCreateInput, type PendingRegistrationRepository, type PendingRegistrationSnapshot, type PendingRegistrationUpdateInput, type PersistenceCapabilities, PersistenceCapabilityError, type PersistenceClassRef, type PersistenceInjectionToken, type PersistenceProvider, type PlanCatalog, type PlanCatalogApp, type PlanCatalogImportReport, type PlanCatalogImportSink, type PlanCatalogIssuer, type PlanCatalogIssuerCorrection, type PlanCatalogLookup, type PlanCatalogMarketing, type PlanCatalogNotifications, type PlanCatalogPaymentAccount, type PlanCatalogPayments, type PlanCatalogReadSink, type PlanCatalogReadSnapshot, type PlanCatalogSettings, type PlanCatalogSubscribers, type PlanCatalogTenantBilling, type PlanDef, type PlanId, type PlanListFilter, type PlanRepository, type PlanRow, type PlanVersion, type PlanVersionFields, type PlanVersionMappingFields, type PlanVersionMutationResult, type PlanVersionRecord, type PlanVersionRepository, type PlanVersionRow, type PlatformErrorBody, type PlatformErrorCode, type PlatformRole, type PlatformUserDto, PlatformUserExistsError, type ProjectPageDef, type PromoCode, type PromoCodeDurationType, type PromoCodeFilter, type PromoCodeHoldRecord, type PromoCodeHoldRepository, type PromoCodeHoldTaken, type PromoCodeRecord, type PromoCodeRedemption, type PromoCodeRedemptionListItem, type PromoCodeRedemptionRecord, type PromoCodeRedemptionRepository, type PromoCodeRedemptionStatus, type PromoCodeRepository, type PromoCodeStatsPort, type PromoCodeStatsSnapshot, type PromoCodeStatus, type PromoCodeValidationLog, type PromoCodeValidationLogRepository, type PromoCodeValidationResult, type PromoCodeValueType, type PromoErrorCode, type PromoPreviewInvalidReason, type PromoPreviewRequest, type PromoPreviewResponse, type PromoPreviewValidResponse, type PromoRevenueDeductionAggregator, type PromoSubscriptionLookup, type PromotionBillingCycle, type PromotionI18n, type PromotionI18nFields, type PromotionOnPrice, type PromotionRepository, type PromotionResult, type PromotionRow, type PromotionStatus, type PromotionTargetType, type PromotionType, type PromotionValue, type PublicBootResponse, type PublicComparisonRow, type PublicMarketingBundle, type PublicMarketingCatalogResponse, type PublicMarketingPlan, type PublicMarketingPromo, type PublicNewPaymentMethods, type PublicSignupPlan, type PublishBundleVersionData, type PublishBundleVersionMeta, type PublishPlanVersionData, type QuotaCatalogEntryRow, type QuotaEnforcementMode, type QuotaKey, type QuotaProvider, REGISTRATION_ERROR_CODES, REGISTRATION_RESUME_TTL_MINUTES, REGISTRATION_STEP_BY_STATUS, type ReassignTenantAdminCliResult, type RecommendablePlan, type RecordSubscriberPaymentMethodData, type RecordSubscriberPaymentMethodOutcome, type RecordSubscriberPaymentMethodResult, type RedeemPromoInTransactionCallback, type RegistrationActivation, type RegistrationAuditContext, type RegistrationAuditEvent, type RegistrationAuditEventType, type RegistrationAuditLogger, type RegistrationBillingDetails, type RegistrationConfigSelection, type RegistrationConfiguratorLookup, type RegistrationErrorCode, type RegistrationOtpDelivery, type RegistrationPromoPreview, type RegistrationResumeDelivery, type RegistrationResumeTokenSigner, type RegistrationStatus, type RegistrationStep, type RequiredCapabilities, type ResolvableErrorBody, type ResumeRegistrationInput, type ResumeRegistrationResult, type ReviewCatalogEntryData, type RlsBypassPort, type RunningContractIssuer, type RunningContractIssuers, SETTINGS_ERROR_CODES, SETUP_ERROR_CODES, SUBSCRIBER_ERROR_CODES, type SaaSiCatPersistenceAdapter, type SaaSiCatPersistenceAdminResources, type SaaSiCatPersistenceCatalog, type SaaSiCatPersistenceCore, type SaaSiCatPersistenceEntitlement, type SaaSiCatPersistencePayments, type SaaSiCatPersistencePromo, type SaaSiCatPersistenceTenantBilling, type SaveRegistrationConfigInput, type SaveRegistrationConfigResult, type ScheduledPlanChangeInput, type SelectPlanInput, type SelectPlanResult, type SelectableBundleShape, type SelfServiceBlockedPlans, type SetCatalogEntryReviewData, type SettingsChangeFilter, type SettingsChangeRecord, type SettingsDifference, type SettingsErrorCode, type SetupConfirmMfaRequest, type SetupConfirmMfaResponse, type SetupErrorCode, type SetupRequest, type SetupResult, type SetupStatusResponse, type SlugAvailabilityCheck, type StandardPageDef, type StandardPageKey, type StartCheckoutInput, type StartCheckoutResult, type StartPaymentMethodSetupInput, type StartRegistrationInput, type StartRegistrationResult, type StoredBundleStem, type StrictModeWarning, type StrictModeWarningCode, type SubscriberContact, type SubscriberContactChange, type SubscriberCorrectionData, type SubscriberCorrectionRecord, type SubscriberCorrectionResult, type SubscriberDetails, type SubscriberErrorCode, type SubscriberIdentityCorrection, type SubscriberIdentityDelta, type SubscriberIdentityValues, type SubscriberPaymentMethodRecord, type SubscriberPaymentMethodReference, type SubscriberPaymentMethodRepository, type SubscriberPaymentMethodSetupData, type SubscriberPaymentMethodSetupMatch, type SubscriberPaymentMethodStatus, type SubscriberRecord, type SubscriberRepository, type Subscription, type SubscriptionBundleRecord, type SubscriptionBundleRepository, type SubscriptionBundleView, type SubscriptionContractFilter, type SubscriptionContractInvoiceSnapshot, type SubscriptionContractParties, type SubscriptionContractPriceSnapshot, type SubscriptionContractRecord, type SubscriptionContractRepository, type SubscriptionContractStatus, type SubscriptionRecord, type SubscriptionRepository, type SubscriptionStatsPort, type SubscriptionStatsSnapshot, type SubscriptionStatus, type SubscriptionUsagePort, type SubscriptionUsageRecord, type SuperAdminProvisioningPort, type SyncDiscoveryResult, type TenantActionDef, type TenantColumnDef, type TenantDto, type TenantListFilter, type TenantPort, type TenantSubscriptionWritePort, type TerminateSubscriptionContractData, type TopPromoCode, type TransactionContext, type TransactionRunner, type UpdateBundleData, type UpdateBundleVersionDraftData, type UpdateCatalogEntryBaseData, type UpdateCatalogEntryI18nData, type UpdateCheckoutOfferData, type UpdateMarketingProjectionData, type UpdateMarketingSettingsData, type UpdatePlanData, type UpdatePlanVersionDraftData, type UpdatePromoCodeData, type UpdatePromoCodeRequest, type UpdatePromotionData, type UpsellOffer, type UpsellOfferResolver, type UpsertCapabilityEntryData, type UpsertFeatureCatalogEntryInput, type UpsertFeatureEntryData, type UpsertPlanInput, type UpsertPlanVersionInput, type UpsertQuotaEntryData, type UpsertResult, type UsageSnapshotPort, type UserAccountLookup, type UserListFilter, type UserManagementPort, type UserPort, type VerifyRegistrationOtpResult, type VersionChange, type VersionChangeDirection, type VersionEditability, type VersionEditableReason, type VersionedEntityBase, applyPromo, assertPersistenceCapabilities, buildActivePlanVersionWhere, buildActiveVersionWhere, buildFeatureRequiresIndex, bundleDraftDefaults, bundleStemDefaults, canonicalJson, classifyBundleVersionDiff, classifyIssuerChange, classifyPlanDiff, collectUnsatisfiedRequires, contractPartiesOf, coverageExcludingSelf, definedFields, diffSettings, formatCustomerNumber, formatErrorMessage, identityCorrectionDelta, isBundleRedundant, isForeignPaymentMethodReferenceError, isPaymentCallbackRejectedError, isPlatformUserExistsError, isVersionEditable, issuerIdentityOf, keepOneRecommended, missingRequiresFor, movedIdentityFields, pickActivePromo, planCatalogSettingsOf, previousUtcDay, promoStatus, promotionOnPrice, readQuotaRecord, readQuotaValue, recordedIssuerIdentity, refuseForeignPaymentMethodReference, resolveBundleAvailability, resolveErrorMessage, sameLegalIdentity, selectChargeableBundles, settingsSubtreeOf, startOfUtcDay, subscriberFromRegistration, subscriberPaymentMethodColumns, toBundleStemRow, toContractLineItemRecord, toPlanRow, toPlanVersionRow, toRunningContractIssuer, toSubscriberCorrectionRecord, toSubscriberPaymentMethodRecord, toSubscriberRecord, toSubscriptionContractRecord };
7301
+ export { ACTIVE_SUBSCRIPTION_CONTRACT_STATUSES, AUTH_ERROR_CODES, type ActionKey, type ActivationOrchestrator, type ActivePlanVersionWhere, type ActivePlanVersionWhereWithEndsAt, type ActiveVersionWhere, type ActiveVersionWhereWithEndsAt, type ActorTag, type AdminAccountEntry, type AdminAccountHolder, type AdminActor, type AdminAuditListFilter, type AdminManifest, type AdminResourcesPort, type AdminSubscriberAccount, type AdminSubscriptionListRow, type AdminTenantDetail, type AdminTenantListFilter, type AdminTenantListRow, type AdminTenantStateResult, type AdminUserListFilter, type AdminUserListRow, type AppliedSettingsPort, type AppliedSettingsRecord, type AppliedSettingsValues, type ApplyOnboardingSelectionInput, type ApplyOnboardingSelectionResult, type ApprovedCatalogKeys, type AuditActionDef, type AuditEntry, type AuditPort, type AuditQuery, type AuditQueryPort, type AuditStatsPort, type AuditStatsSnapshot, type AuthErrorCode, BILLING_ERROR_CODES, BUNDLE_PRICE_LOOKUP_LIMIT, type BillingCycle, type BillingErrorCode, type BundleAvailabilityState, type BundleCompatibility, type BundleFeatureShape, type BundleListFilter, type BundlePricingOverride, type BundleRepository, type BundleRow, type BundleVersionFields, type BundleVersionMutationResult, type BundleVersionRow, CATALOGUE_KEYS, CATALOG_ERROR_CODES, CONTRACT_ERROR_CODES, type CancelSubscriptionBundleData, type CancelSubscriptionInput, type CancelSubscriptionResult, type CancellationNoticePeriods, type CanonicalContractLineItemRow, type CanonicalContractRow, type CanonicalPlanRow, type CanonicalPlanVersionRow, type CanonicalRunningContractRow, type CanonicalSubscriberChargeRow, type CanonicalSubscriberCorrectionRow, type CanonicalSubscriberPaymentMethodRow, type CanonicalSubscriberRow, type CanonicalSubscriptionBundleRow, type CapabilityCatalogEntryRow, type CapabilityCodeStatus, type CapabilityKey, type CapabilityKind, type CatalogEntryFilter, type CatalogEntryI18n, type CatalogEntryI18nFields, type CatalogEntryRepository, type CatalogErrorCode, type ChangeDirection, type CheckoutOfferFilter, type CheckoutOfferLineItem, type CheckoutOfferLineItemKind, type CheckoutOfferPriceBreakdown, type CheckoutOfferPromoCodeSnapshot, type CheckoutOfferPromotionSnapshot, type CheckoutOfferRepository, type CheckoutOfferRow, type CheckoutOfferSelection, type CheckoutOfferSelectionUpdate, type CheckoutOfferStatus, type CleanupResult, type CliUserRow, type ComponentKey, type ConfiguratorCatalog, type ConfiguratorMarketingProvider, type ConfiguratorModel, type ConfiguratorPlanMarketing, type ConfiguratorPlanVersionRow, type ConfiguratorPriceBreakdown, type ConfiguratorSourcesLookup, type ConfirmedPaymentMethod, type ContractErrorCode, type ContractIssuerParty, type ContractLineItemKind, type ContractLineItemRecord, type ContractSubscriberParty, type CreateBundleData, type CreateBundleVersionDraftData, type CreateCheckoutOfferData, type CreateMarketingProjectionData, type CreatePlanData, type CreatePlanVersionDraftData, type CreatePromoCodeData, type CreatePromoCodeRequest, type CreatePromotionData, type CreateSubscriberData, type CreateSubscriptionBundleData, type CreateSubscriptionContractData, type CreateSuperAdminCliInput, type CreateTenantInput, type DiffResult, type DiscoveredCapability, type DiscoveredFeature, type DiscoveredQuota, type DiscoveredQuotaPolicy, type DiscoveryCodeStatus, type DiscoverySnapshot, type DiscoveryStatus, ERROR_MESSAGES_DE, ERROR_MESSAGES_EN, type EffectiveLimitsSnapshot, type EmailPort, type ErrorMessageParams, FEATURE_NOT_LICENSED, type FeatureCatalogEntryRow, type FeatureDef, type FeatureKey, type FeatureNotLicensedBody, type FeatureRequiresIndex, type FeatureTier, type FeatureUiMeta, type FeatureUiRegistry, type FinalActivationResult, type FirstTimeCustomerCheck, ForeignPaymentMethodReferenceError, type ImmediatePlanChangeInput, type InvoiceLineItemSnapshot, type IssuerCorrectionFault, type IssuerIdentityChange, type KpiCardDef, type KpiDisplayHint, LEGAL_IDENTITY_FIELDS, type LegalIdentity, type LegalIdentityField, MARKETING_PRIORITY_MAX, MARKETING_PRIORITY_MIN, type ManifestAccessPort, type ManifestContribution, type MarketingProjectionFilter, type MarketingProjectionRepository, type MarketingProjectionRow, type MarketingSettingsRepository, type MarketingSettingsRow, type MarketingTargetType, type MarketingTopFeature, type MaskedPaymentMethod, type MfaPort, type NewContractLineItemData, type NewSettingsChange, type NewSubscriberCharge, type NewSubscriberDetails, type NewSubscriptionContractData, OTP_RATE_LIMIT_MAX_SENDS, OTP_RATE_LIMIT_WINDOW_MINUTES, OTP_TTL_MINUTES, OTP_VERIFY_MAX_ATTEMPTS, type OnboardingPromoRedemption, type OnboardingSelectionRequest, type OnboardingSelectionResponse, PASSWORD_RESET_TTL_MINUTES, PAYMENT_ERROR_CODES, PAYMENT_METHOD_TYPES, PENDING_CHECKOUT_TTL_DAYS, PENDING_EMAIL_TTL_HOURS, PENDING_ONBOARDING_TTL_DAYS, PLATFORM_ERROR_CODES, PROMO_ERROR_CODES, type Paginated, type PartyAddress, type PasswordHasher, type PasswordResetCliResult, PaymentCallbackRejectedError, type PaymentErrorCode, type PaymentEventClaim, type PaymentEventLog, type PaymentGateway, type PaymentGatewayCallback, type PaymentGatewayEvent, type PaymentMethodHolder, type PaymentMethodSetupSession, type PaymentMethodSetupSubject, type PaymentMethodType, type PendingRegistration, type PendingRegistrationCreateInput, type PendingRegistrationRepository, type PendingRegistrationSnapshot, type PendingRegistrationUpdateInput, type PersistenceCapabilities, PersistenceCapabilityError, type PersistenceClassRef, type PersistenceInjectionToken, type PersistenceProvider, type PlanCatalog, type PlanCatalogApp, type PlanCatalogImportReport, type PlanCatalogImportSink, type PlanCatalogIssuer, type PlanCatalogIssuerCorrection, type PlanCatalogLookup, type PlanCatalogMarketing, type PlanCatalogNotifications, type PlanCatalogPaymentAccount, type PlanCatalogPayments, type PlanCatalogReadSink, type PlanCatalogReadSnapshot, type PlanCatalogSettings, type PlanCatalogSubscribers, type PlanCatalogTenantBilling, type PlanDef, type PlanId, type PlanListFilter, type PlanRepository, type PlanRow, type PlanVersion, type PlanVersionFields, type PlanVersionMappingFields, type PlanVersionMutationResult, type PlanVersionRecord, type PlanVersionRepository, type PlanVersionRow, type PlatformErrorBody, type PlatformErrorCode, type PlatformRole, type PlatformUserDto, PlatformUserExistsError, type ProjectPageDef, type PromoCode, type PromoCodeDurationType, type PromoCodeFilter, type PromoCodeHoldRecord, type PromoCodeHoldRepository, type PromoCodeHoldTaken, type PromoCodeRecord, type PromoCodeRedemption, type PromoCodeRedemptionListItem, type PromoCodeRedemptionRecord, type PromoCodeRedemptionRepository, type PromoCodeRedemptionStatus, type PromoCodeRepository, type PromoCodeStatsPort, type PromoCodeStatsSnapshot, type PromoCodeStatus, type PromoCodeValidationLog, type PromoCodeValidationLogRepository, type PromoCodeValidationResult, type PromoCodeValueType, type PromoErrorCode, type PromoPreviewInvalidReason, type PromoPreviewRequest, type PromoPreviewResponse, type PromoPreviewValidResponse, type PromoRevenueDeductionAggregator, type PromoSubscriptionLookup, type PromotionBillingCycle, type PromotionI18n, type PromotionI18nFields, type PromotionOnPrice, type PromotionRepository, type PromotionResult, type PromotionRow, type PromotionStatus, type PromotionTargetType, type PromotionType, type PromotionValue, type PublicBootResponse, type PublicComparisonRow, type PublicMarketingBundle, type PublicMarketingCatalogResponse, type PublicMarketingPlan, type PublicMarketingPromo, type PublicNewPaymentMethods, type PublicSignupPlan, type PublishBundleVersionData, type PublishBundleVersionMeta, type PublishPlanVersionData, type QuotaCatalogEntryRow, type QuotaEnforcementMode, type QuotaKey, type QuotaProvider, REGISTRATION_ERROR_CODES, REGISTRATION_RESUME_TTL_MINUTES, REGISTRATION_STEP_BY_STATUS, type ReassignTenantAdminCliResult, type RecommendablePlan, type RecordSubscriberPaymentMethodData, type RecordSubscriberPaymentMethodOutcome, type RecordSubscriberPaymentMethodResult, type RedeemPromoInTransactionCallback, type RegistrationActivation, type RegistrationAuditContext, type RegistrationAuditEvent, type RegistrationAuditEventType, type RegistrationAuditLogger, type RegistrationBillingDetails, type RegistrationConfigSelection, type RegistrationConfiguratorLookup, type RegistrationErrorCode, type RegistrationOtpDelivery, type RegistrationPromoPreview, type RegistrationResumeDelivery, type RegistrationResumeTokenSigner, type RegistrationStatus, type RegistrationStep, type RequiredCapabilities, type ResolvableErrorBody, type ResumeRegistrationInput, type ResumeRegistrationResult, type ReviewCatalogEntryData, type RlsBypassPort, type RunningContractIssuer, type RunningContractIssuers, SETTINGS_ERROR_CODES, SETUP_ERROR_CODES, SUBSCRIBER_ACCOUNT_CAPABILITY, SUBSCRIBER_ERROR_CODES, type SaaSiCatPersistenceAdapter, type SaaSiCatPersistenceAdminResources, type SaaSiCatPersistenceCatalog, type SaaSiCatPersistenceCore, type SaaSiCatPersistenceEntitlement, type SaaSiCatPersistencePayments, type SaaSiCatPersistencePromo, type SaaSiCatPersistenceTenantBilling, type SaveRegistrationConfigInput, type SaveRegistrationConfigResult, type ScheduledPlanChangeInput, type SelectPlanInput, type SelectPlanResult, type SelectableBundleShape, type SelfServiceBlockedPlans, type SetCatalogEntryReviewData, type SettingsChangeFilter, type SettingsChangeRecord, type SettingsDifference, type SettingsErrorCode, type SetupConfirmMfaRequest, type SetupConfirmMfaResponse, type SetupErrorCode, type SetupRequest, type SetupResult, type SetupStatusResponse, type SlugAvailabilityCheck, type StandardPageDef, type StandardPageKey, type StartCheckoutInput, type StartCheckoutResult, type StartPaymentMethodSetupInput, type StartRegistrationInput, type StartRegistrationResult, type StoredBundleStem, type StrictModeWarning, type StrictModeWarningCode, type SubscriberCharge, type SubscriberChargeOrigin, type SubscriberChargeRecord, type SubscriberChargeSource, type SubscriberContact, type SubscriberContactChange, type SubscriberCorrectionData, type SubscriberCorrectionRecord, type SubscriberCorrectionResult, type SubscriberDetails, type SubscriberErrorCode, type SubscriberIdentityCorrection, type SubscriberIdentityDelta, type SubscriberIdentityValues, type SubscriberLedgerRepository, type SubscriberPaymentMethodRecord, type SubscriberPaymentMethodReference, type SubscriberPaymentMethodRepository, type SubscriberPaymentMethodSetupData, type SubscriberPaymentMethodSetupMatch, type SubscriberPaymentMethodStatus, type SubscriberRecord, type SubscriberRepository, type Subscription, type SubscriptionBundleRecord, type SubscriptionBundleRepository, type SubscriptionBundleView, type SubscriptionContractFilter, type SubscriptionContractInvoiceSnapshot, type SubscriptionContractParties, type SubscriptionContractPriceSnapshot, type SubscriptionContractRecord, type SubscriptionContractRepository, type SubscriptionContractStatus, type SubscriptionRecord, type SubscriptionRepository, type SubscriptionStatsPort, type SubscriptionStatsSnapshot, type SubscriptionStatus, type SubscriptionUsagePort, type SubscriptionUsageRecord, type SuperAdminProvisioningPort, type SyncDiscoveryResult, type TenantActionDef, type TenantColumnDef, type TenantDto, type TenantListFilter, type TenantPort, type TenantSubscriptionWritePort, type TerminateSubscriptionContractData, type TopPromoCode, type TransactionContext, type TransactionRunner, type UpdateBundleData, type UpdateBundleVersionDraftData, type UpdateCatalogEntryBaseData, type UpdateCatalogEntryI18nData, type UpdateCheckoutOfferData, type UpdateMarketingProjectionData, type UpdateMarketingSettingsData, type UpdatePlanData, type UpdatePlanVersionDraftData, type UpdatePromoCodeData, type UpdatePromoCodeRequest, type UpdatePromotionData, type UpsellOffer, type UpsellOfferResolver, type UpsertCapabilityEntryData, type UpsertFeatureCatalogEntryInput, type UpsertFeatureEntryData, type UpsertPlanInput, type UpsertPlanVersionInput, type UpsertQuotaEntryData, type UpsertResult, type UsageSnapshotPort, type UserAccountLookup, type UserListFilter, type UserManagementPort, type UserPort, type VerifyRegistrationOtpResult, type VersionChange, type VersionChangeDirection, type VersionEditability, type VersionEditableReason, type VersionedEntityBase, applyPromo, assertPersistenceCapabilities, buildActivePlanVersionWhere, buildActiveVersionWhere, buildFeatureRequiresIndex, bundleDraftDefaults, bundleStemDefaults, canonicalJson, classifyBundleVersionDiff, classifyIssuerChange, classifyPlanDiff, collectUnsatisfiedRequires, contractPartiesOf, coverageExcludingSelf, definedFields, diffSettings, formatCustomerNumber, formatErrorMessage, identityCorrectionDelta, isBundleRedundant, isForeignPaymentMethodReferenceError, isPaymentCallbackRejectedError, isPlatformUserExistsError, isVersionEditable, issuerIdentityOf, keepOneRecommended, missingRequiresFor, movedIdentityFields, pickActivePromo, planCatalogSettingsOf, previousUtcDay, promoStatus, promotionOnPrice, readQuotaRecord, readQuotaValue, recordedIssuerIdentity, refuseForeignPaymentMethodReference, resolveBundleAvailability, resolveErrorMessage, sameLegalIdentity, selectChargeableBundles, settingsSubtreeOf, startOfUtcDay, subscriberChargeColumns, subscriberFromRegistration, subscriberPaymentMethodColumns, toBundleStemRow, toContractLineItemRecord, toPlanRow, toPlanVersionRow, toRunningContractIssuer, toSubscriberChargeRecord, toSubscriberCorrectionRecord, toSubscriberPaymentMethodRecord, toSubscriberRecord, toSubscriptionBundleRecord, toSubscriptionContractRecord };
package/dist/index.js CHANGED
@@ -711,7 +711,14 @@ var PAYMENT_ERROR_CODES = {
711
711
  * A success or cancel URL at an origin `config/saas.yaml#payments.returnUrlOrigins`
712
712
  * does not name. Carries `field`.
713
713
  */
714
- PAYMENT_RETURN_URL_NOT_ALLOWED: "PAYMENT_RETURN_URL_NOT_ALLOWED"
714
+ PAYMENT_RETURN_URL_NOT_ALLOWED: "PAYMENT_RETURN_URL_NOT_ALLOWED",
715
+ /**
716
+ * The gateway failed — unreachable, refusing the account's keys, or
717
+ * answering with an error — while opening its form or reading a callback
718
+ * back. Answered with 502; what the gateway answered stays in the server
719
+ * log.
720
+ */
721
+ PAYMENT_GATEWAY_FAILED: "PAYMENT_GATEWAY_FAILED"
715
722
  };
716
723
  var SETTINGS_ERROR_CODES = {
717
724
  /** No recorded change has this id, or the installation keeps no record at all. */
@@ -977,6 +984,83 @@ function textOrNull(value) {
977
984
  return trimmed === "" ? null : trimmed;
978
985
  }
979
986
 
987
+ // src/closed-value.ts
988
+ function oneOf(allowed, value, source) {
989
+ const match = allowed.find((entry) => entry === value);
990
+ if (match === void 0) {
991
+ throw new Error(
992
+ `${source.table} row '${source.id}' holds ${source.column} '${value}', which is none of ${allowed.join(", ")}.`
993
+ );
994
+ }
995
+ return match;
996
+ }
997
+
998
+ // src/subscriber-ledger-mapping.ts
999
+ var ORIGINS = {
1000
+ activation: true,
1001
+ renewal: true,
1002
+ planChange: true,
1003
+ bundleBooking: true,
1004
+ credit: true,
1005
+ correction: true
1006
+ };
1007
+ var SOURCES = {
1008
+ plan: true,
1009
+ bundle: true,
1010
+ discount: true
1011
+ };
1012
+ var TABLE = "subscriber_ledger_entries";
1013
+ var CENT_TOLERANCE = 1e-6;
1014
+ function toSubscriberChargeRecord(row) {
1015
+ const where = (column) => ({ table: TABLE, column, id: row.id });
1016
+ return {
1017
+ id: row.id,
1018
+ subscriberId: row.subscriberId,
1019
+ tenantId: row.tenantId,
1020
+ subscriptionId: row.subscriptionId,
1021
+ contractId: row.contractId,
1022
+ contractLineItemId: row.contractLineItemId,
1023
+ origin: oneOf(keysOf(ORIGINS), row.origin, where("origin")),
1024
+ source: oneOf(keysOf(SOURCES), row.source, where("source")),
1025
+ sourceRef: row.sourceRef,
1026
+ periodStart: row.periodStart,
1027
+ periodEnd: row.periodEnd,
1028
+ currency: row.currency,
1029
+ amountNet: Number(row.amountNet),
1030
+ bookedAt: row.bookedAt,
1031
+ createdAt: row.createdAt
1032
+ };
1033
+ }
1034
+ function subscriberChargeColumns(charge) {
1035
+ const cents = charge.amountNet * 100;
1036
+ if (!Number.isFinite(cents) || Math.abs(cents - Math.round(cents)) > CENT_TOLERANCE) {
1037
+ throw new Error(
1038
+ `A charge of ${charge.amountNet} is not a whole number of cents; round it once where it is derived, before it is written.`
1039
+ );
1040
+ }
1041
+ return {
1042
+ subscriberId: charge.subscriberId,
1043
+ tenantId: charge.tenantId,
1044
+ subscriptionId: charge.subscriptionId,
1045
+ contractId: charge.contractId,
1046
+ contractLineItemId: charge.contractLineItemId,
1047
+ origin: charge.origin,
1048
+ source: charge.source,
1049
+ sourceRef: charge.sourceRef,
1050
+ periodStart: charge.periodStart,
1051
+ periodEnd: charge.periodEnd,
1052
+ currency: charge.currency,
1053
+ amountNet: charge.amountNet.toFixed(2),
1054
+ bookedAt: charge.bookedAt
1055
+ };
1056
+ }
1057
+ function keysOf(record) {
1058
+ return Object.keys(record);
1059
+ }
1060
+
1061
+ // src/subscriber-ledger.types.ts
1062
+ var SUBSCRIBER_ACCOUNT_CAPABILITY = "charges.read";
1063
+
980
1064
  // src/subscriber-mapping.ts
981
1065
  function formatCustomerNumber(prefix, sequence) {
982
1066
  return `${prefix}${sequence}`;
@@ -1092,6 +1176,7 @@ function toIdentityValues(value) {
1092
1176
  // src/subscriber-payment-method-mapping.ts
1093
1177
  var PAYMENT_METHOD_TYPES = ["card", "sepa_debit"];
1094
1178
  var STATUSES = ["ACTIVE", "REPLACED"];
1179
+ var TABLE2 = "subscriber_payment_methods";
1095
1180
  function toSubscriberPaymentMethodRecord(row) {
1096
1181
  return {
1097
1182
  id: row.id,
@@ -1100,7 +1185,7 @@ function toSubscriberPaymentMethodRecord(row) {
1100
1185
  provider: row.provider,
1101
1186
  customerRef: row.customerRef,
1102
1187
  paymentMethodRef: row.paymentMethodRef,
1103
- type: oneOf(PAYMENT_METHOD_TYPES, row.type, "type", row.id),
1188
+ type: oneOf(PAYMENT_METHOD_TYPES, row.type, { table: TABLE2, column: "type", id: row.id }),
1104
1189
  brand: row.brand,
1105
1190
  last4: row.last4,
1106
1191
  expiryMonth: row.expiryMonth,
@@ -1108,7 +1193,7 @@ function toSubscriberPaymentMethodRecord(row) {
1108
1193
  country: row.country,
1109
1194
  bankCode: row.bankCode,
1110
1195
  mandateReference: row.mandateReference,
1111
- status: oneOf(STATUSES, row.status, "status", row.id),
1196
+ status: oneOf(STATUSES, row.status, { table: TABLE2, column: "status", id: row.id }),
1112
1197
  confirmedAt: row.confirmedAt,
1113
1198
  replacedAt: row.replacedAt,
1114
1199
  createdAt: row.createdAt
@@ -1132,15 +1217,6 @@ function subscriberPaymentMethodColumns(data) {
1132
1217
  confirmedAt: data.confirmedAt
1133
1218
  };
1134
1219
  }
1135
- function oneOf(allowed, value, column, id) {
1136
- const match = allowed.find((entry) => entry === value);
1137
- if (match === void 0) {
1138
- throw new Error(
1139
- `subscriber_payment_methods row '${id}' holds ${column} '${value}', which is none of ${allowed.join(", ")}.`
1140
- );
1141
- }
1142
- return match;
1143
- }
1144
1220
  var FOREIGN_PAYMENT_METHOD_REFERENCE = "FOREIGN_PAYMENT_METHOD_REFERENCE";
1145
1221
  var ForeignPaymentMethodReferenceError = class extends Error {
1146
1222
  constructor(gatewayAccount, paymentMethodRef) {
@@ -1166,6 +1242,30 @@ function refuseForeignPaymentMethodReference(recorded, subscriberId) {
1166
1242
  );
1167
1243
  }
1168
1244
 
1245
+ // src/subscription-bundle-mapping.ts
1246
+ var BILLING_CYCLES = ["MONTHLY", "YEARLY"];
1247
+ function toSubscriptionBundleRecord(row) {
1248
+ const billingCycle = row.billingCycle ?? null;
1249
+ return {
1250
+ id: row.id,
1251
+ subscriptionId: row.subscriptionId,
1252
+ bundleVersionId: row.bundleVersionId,
1253
+ startedAt: row.startedAt,
1254
+ minimumTermEndsAt: row.minimumTermEndsAt,
1255
+ billingCycle: billingCycle === null ? null : oneOf(BILLING_CYCLES, billingCycle, {
1256
+ table: "subscription_bundles",
1257
+ column: "billingCycle",
1258
+ id: row.id
1259
+ }),
1260
+ currentPeriodStart: row.currentPeriodStart ?? null,
1261
+ currentPeriodEnd: row.currentPeriodEnd ?? null,
1262
+ canceledAt: row.canceledAt,
1263
+ canceledEffectiveAt: row.canceledEffectiveAt,
1264
+ createdAt: row.createdAt,
1265
+ updatedAt: row.updatedAt
1266
+ };
1267
+ }
1268
+
1169
1269
  // src/subscription-contract-mapping.ts
1170
1270
  function toSubscriptionContractRecord(row, lineItems) {
1171
1271
  return {
@@ -1501,6 +1601,7 @@ var ERROR_MESSAGES_EN = {
1501
1601
  PAYMENT_GATEWAY_ACCOUNT_UNKNOWN: "No payment gateway account is configured under '{account}'.",
1502
1602
  PAYMENT_CALLBACK_REJECTED: "The payment callback could not be verified.",
1503
1603
  PAYMENT_RETURN_URL_NOT_ALLOWED: "The {field} leads to a site this installation does not return to.",
1604
+ PAYMENT_GATEWAY_FAILED: "The payment provider did not answer as expected. Please try again in a few minutes.",
1504
1605
  // ── entitlement (code lives in upsell.types.ts) ──
1505
1606
  [FEATURE_NOT_LICENSED]: "Feature {featureKeys} is not included in the current plan.",
1506
1607
  // ── settings ──
@@ -1711,6 +1812,7 @@ var ERROR_MESSAGES_DE = {
1711
1812
  PAYMENT_GATEWAY_ACCOUNT_UNKNOWN: "Unter '{account}' ist kein Konto eines Zahlungsanbieters eingerichtet.",
1712
1813
  PAYMENT_CALLBACK_REJECTED: "Die R\xFCckmeldung des Zahlungsanbieters lie\xDF sich nicht pr\xFCfen.",
1713
1814
  PAYMENT_RETURN_URL_NOT_ALLOWED: "Die {field} f\xFChrt auf eine Seite, zu der diese Installation nicht zur\xFCckleitet.",
1815
+ PAYMENT_GATEWAY_FAILED: "Der Zahlungsanbieter hat nicht wie erwartet geantwortet. Bitte versuche es in ein paar Minuten noch einmal.",
1714
1816
  // ── entitlement (code lives in upsell.types.ts) ──
1715
1817
  [FEATURE_NOT_LICENSED]: "Das Feature {featureKeys} ist im aktuellen Plan nicht enthalten.",
1716
1818
  // ── settings ──
@@ -1751,6 +1853,7 @@ export {
1751
1853
  REGISTRATION_STEP_BY_STATUS,
1752
1854
  SETTINGS_ERROR_CODES,
1753
1855
  SETUP_ERROR_CODES,
1856
+ SUBSCRIBER_ACCOUNT_CAPABILITY,
1754
1857
  SUBSCRIBER_ERROR_CODES,
1755
1858
  applyPromo,
1756
1859
  assertPersistenceCapabilities,
@@ -1795,6 +1898,7 @@ export {
1795
1898
  selectChargeableBundles,
1796
1899
  settingsSubtreeOf,
1797
1900
  startOfUtcDay,
1901
+ subscriberChargeColumns,
1798
1902
  subscriberFromRegistration,
1799
1903
  subscriberPaymentMethodColumns,
1800
1904
  toBundleStemRow,
@@ -1802,8 +1906,10 @@ export {
1802
1906
  toPlanRow,
1803
1907
  toPlanVersionRow,
1804
1908
  toRunningContractIssuer,
1909
+ toSubscriberChargeRecord,
1805
1910
  toSubscriberCorrectionRecord,
1806
1911
  toSubscriberPaymentMethodRecord,
1807
1912
  toSubscriberRecord,
1913
+ toSubscriptionBundleRecord,
1808
1914
  toSubscriptionContractRecord
1809
1915
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saasicat/core",
3
- "version": "1.0.0-rc.21",
3
+ "version": "1.0.0-rc.22",
4
4
  "description": "TypeScript contracts for SaaSiCat — capabilities, catalogs, subscriptions, entitlements, admin manifests, persistence ports — and the pure domain logic both server and browser run: error catalogues, plan-diff classification, promo arithmetic, feature requirements.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",