@classytic/revenue 2.4.0 → 2.6.0

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/CHANGELOG.md CHANGED
@@ -3,6 +3,47 @@
3
3
  Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
4
4
  adhering to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
5
 
6
+ ## [2.6.0]
7
+
8
+ ### Added — generalized settlement rollups (`summary` + `breakdownByRecipient`)
9
+
10
+ `recipientBalance` only rolled up ONE recipient, forcing hosts to hand-roll raw
11
+ aggregations for platform-wide / per-recipient / cross-org views. Two reusable
12
+ primitives now cover all of them (the `recipientBalance` status+due bucketing,
13
+ generalized — one tenant-scoped `aggregatePipeline`, never a raw `Model.aggregate`):
14
+
15
+ - **`summary(filter = {}, ctx)` → `SettlementSummary`** — the money-state
16
+ (`held / available / processing / paidOut / pending / failed / lifetime /
17
+ currency`) for an ARBITRARY filter: a recipient, an org, or the whole platform
18
+ (pass `_bypassTenant` in ctx). Backs platform reconciliation + cross-org
19
+ earnings.
20
+ - **`breakdownByRecipient(filter = {}, ctx)` → `RecipientBreakdown[]`** — one
21
+ rollup per distinct `(recipientId, recipientType)` (plus first-seen `role`),
22
+ for a "who is owed what" platform view.
23
+
24
+ `recipientBalance` is now a thin wrapper over `summary({ recipientId, … })`.
25
+ Exported types: `SettlementSummary`, `RecipientBreakdown`. No migration; no
26
+ breaking change to `recipientBalance`'s shape.
27
+
28
+ ## [2.5.0]
29
+
30
+ ### Added — `SettlementRepository.recipientBalance()` (the seller/creator "wallet")
31
+
32
+ `recipientBalance(recipientId, { recipientType?, currency? }, ctx)` returns a
33
+ recipient's payout balance bucketed by settlement status —
34
+ `{ pending, held, available, processing, paidOut, failed, lifetime, currency }`
35
+ in minor units. `pending` splits into `held` (escrowed — `scheduledAt` in the
36
+ future) and `available` (cleared — due now), so a marketplace can show "in
37
+ clearance" vs "ready to pay". One tenant-scoped `aggregatePipeline` over the
38
+ `{ recipientId, status }` index, so hosts stop hand-rolling a raw
39
+ `Model.aggregate` (which bypasses multi-tenant scope).
40
+
41
+ ### Added — `processPending({ recipientId })` filter
42
+
43
+ `processPending` now accepts an optional `recipientId` so a host can pay out a
44
+ single seller/participant (gating each via their own KYC/eligibility check)
45
+ instead of only by organization.
46
+
6
47
  ## [2.4.0] - 2026-06-14
7
48
 
8
49
  ### Added — `settled` bank-feed/manual status + `settle()` / `unsettle()` verbs
@@ -60,6 +60,7 @@ interface SplitInfo {
60
60
  }
61
61
  declare function calculateSplits(amount: number, rules: SplitRule[], gatewayFeeRate?: number): SplitInfo[];
62
62
  declare function calculateOrganizationPayout(amount: number, splits: SplitInfo[]): number;
63
+ declare function reverseSplits(originalSplits: SplitInfo[], originalAmount: number, refundAmount: number): SplitInfo[];
63
64
  //#endregion
64
65
  //#region src/shared/formatters/money.d.ts
65
66
  /**
@@ -86,4 +87,4 @@ declare function getLastStateChange(doc: {
86
87
  metadata?: Record<string, unknown>;
87
88
  }): StateChangeEvent | undefined;
88
89
  //#endregion
89
- export { SplitInfo as A, validateTaxCalculation as B, multiplyMoney as C, toCurrencyCode as D, sumMoney as E, TaxConfig as F, calculateCommission as H, TaxType as I, calculateTax as L, calculateOrganizationPayout as M, calculateSplits as N, toMajor$1 as O, TaxCalculation as P, getTaxType as R, money$1 as S, subtractMoney as T, reverseCommission as U, CommissionInfo as V, isMoney as _, CurrencyCode as a, isZeroMoney as b, Money as c, addMoney as d, compareMoney as f, isCurrencyCode as g, fromSmallestUnit as h, CURRENCIES as i, SplitRule as j, toSmallestUnit as k, MoneyValue as l, fromMajor$1 as m, getAuditTrail as n, CurrencyMismatchError as o, equalsMoney as p, getLastStateChange as r, MINOR_UNIT_FACTOR as s, appendAuditEvent as t, absMoney as u, isNegativeMoney as v, negateMoney as w, minorUnitFactor as x, isPositiveMoney as y, reverseTax as z };
90
+ export { SplitInfo as A, reverseTax as B, multiplyMoney as C, toCurrencyCode as D, sumMoney as E, TaxCalculation as F, CommissionInfo as H, TaxConfig as I, TaxType as L, calculateOrganizationPayout as M, calculateSplits as N, toMajor$1 as O, reverseSplits as P, calculateTax as R, money$1 as S, subtractMoney as T, calculateCommission as U, validateTaxCalculation as V, reverseCommission as W, isMoney as _, CurrencyCode as a, isZeroMoney as b, Money as c, addMoney as d, compareMoney as f, isCurrencyCode as g, fromSmallestUnit as h, CURRENCIES as i, SplitRule as j, toSmallestUnit as k, MoneyValue as l, fromMajor$1 as m, getAuditTrail as n, CurrencyMismatchError as o, equalsMoney as p, getLastStateChange as r, MINOR_UNIT_FACTOR as s, appendAuditEvent as t, absMoney as u, isNegativeMoney as v, negateMoney as w, minorUnitFactor as x, isPositiveMoney as y, getTaxType as z };
@@ -922,6 +922,42 @@ interface SettlementProcessingError {
922
922
  settlementId: SettlementDocument['_id'];
923
923
  error: unknown;
924
924
  }
925
+ /**
926
+ * A recipient's payout balance — the amounts the platform has scheduled,
927
+ * is processing, has paid, or failed to pay, in minor units. The "wallet"
928
+ * view a marketplace shows a seller/creator. Derived from settlement status;
929
+ * tenant-scoped.
930
+ */
931
+ interface RecipientBalance {
932
+ recipientId: string;
933
+ currency: string | null;
934
+ /** Scheduled, awaiting payout (status: pending) = held + available. */
935
+ pending: number;
936
+ /** Pending but still in the clearance window (`scheduledAt` in the future) — escrowed, not yet payable. */
937
+ held: number;
938
+ /** Pending and due (`scheduledAt <= now`) — cleared, ready to pay out. */
939
+ available: number;
940
+ /** Payout in flight (status: processing). */
941
+ processing: number;
942
+ /** Paid out, lifetime (status: completed). */
943
+ paidOut: number;
944
+ /** Failed payouts (status: failed). */
945
+ failed: number;
946
+ /** pending + processing + paidOut — the total the platform has committed to this recipient. */
947
+ lifetime: number;
948
+ }
949
+ /**
950
+ * Settlement money-state for an arbitrary filter (a recipient, an org, or the
951
+ * whole platform) — the same status+due rollup as {@link RecipientBalance} but
952
+ * not tied to a single recipient. The reusable shape behind `summary`.
953
+ */
954
+ type SettlementSummary = Omit<RecipientBalance, 'recipientId'>;
955
+ /** One row of {@link SettlementRepository.breakdownByRecipient}. */
956
+ interface RecipientBreakdown extends RecipientBalance {
957
+ recipientType: string;
958
+ /** First-seen settlement role (creator_earning | co_instructor | referrer | …). */
959
+ role: string | null;
960
+ }
925
961
  /**
926
962
  * SettlementRepository — payouts to recipients (organizations, vendors,
927
963
  * affiliates).
@@ -962,7 +998,8 @@ declare class SettlementRepository extends RevenueRepositoryBase<SettlementDocum
962
998
  processPending(options?: {
963
999
  limit?: number;
964
1000
  organizationId?: string;
965
- payoutMethod?: string;
1001
+ payoutMethod?: string; /** Restrict the sweep to a single recipient — pay one seller/participant. */
1002
+ recipientId?: string;
966
1003
  dryRun?: boolean;
967
1004
  }, ctx?: RevenueContext): Promise<{
968
1005
  processed: number;
@@ -982,6 +1019,26 @@ declare class SettlementRepository extends RevenueRepositoryBase<SettlementDocum
982
1019
  code?: string;
983
1020
  retry?: boolean;
984
1021
  }, ctx?: RevenueContext): Promise<SettlementDocument>;
1022
+ /**
1023
+ * Settlement money-state for an ARBITRARY filter — a recipient, an org, or
1024
+ * the whole platform (pass `_bypassTenant` in ctx to span every org). One
1025
+ * tenant-scoped `aggregatePipeline` (the `{ recipientId, status }` index backs
1026
+ * the `$match`), never a raw `Model.aggregate`. The reusable rollup behind
1027
+ * `recipientBalance`, platform reconciliation, and cross-org earnings.
1028
+ */
1029
+ summary(filter?: Record<string, unknown>, ctx?: RevenueContext): Promise<SettlementSummary>;
1030
+ /**
1031
+ * Per-recipient settlement rollup — one {@link RecipientBreakdown} per
1032
+ * distinct (recipientId, recipientType) matching `filter`. The reusable list
1033
+ * behind a platform "who is owed what" view; pass `_bypassTenant` to span all
1034
+ * orgs.
1035
+ */
1036
+ breakdownByRecipient(filter?: Record<string, unknown>, ctx?: RevenueContext): Promise<RecipientBreakdown[]>;
1037
+ /** One recipient's wallet — a thin `summary` over `{ recipientId, … }`. */
1038
+ recipientBalance(recipientId: string, options?: {
1039
+ recipientType?: string;
1040
+ currency?: string;
1041
+ }, ctx?: RevenueContext): Promise<RecipientBalance>;
985
1042
  }
986
1043
  //#endregion
987
1044
  //#region src/engine/engine-types.d.ts
@@ -1236,4 +1293,4 @@ interface RevenueEngine {
1236
1293
  destroy(): Promise<void>;
1237
1294
  }
1238
1295
  //#endregion
1239
- export { RevenueConfig as a, SubscriptionRepository as c, RevenueSchemaOptions as d, SettlementDocument as f, RetryConfig as i, TransactionRepository as l, TransactionDocument as m, BankFeedModuleConfig as n, RevenueEngine as o, SubscriptionDocument as p, CommissionConfig as r, SettlementRepository as s, BankFeedIndexConfig as t, RevenueModels as u };
1296
+ export { TransactionDocument as _, RevenueConfig as a, RecipientBreakdown as c, SubscriptionRepository as d, TransactionRepository as f, SubscriptionDocument as g, SettlementDocument as h, RetryConfig as i, SettlementRepository as l, RevenueSchemaOptions as m, BankFeedModuleConfig as n, RevenueEngine as o, RevenueModels as p, CommissionConfig as r, RecipientBalance as s, BankFeedIndexConfig as t, SettlementSummary as u };
@@ -110,29 +110,10 @@ declare const transactionBaseSchema: z.ZodObject<{
110
110
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
111
111
  }, z.core.$strip>;
112
112
  declare const transactionCreateSchema: z.ZodObject<{
113
- organizationId: z.ZodOptional<z.ZodString>;
114
- customerId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
113
+ status: z.ZodDefault<z.ZodString>;
115
114
  type: z.ZodString;
116
- flow: z.ZodEnum<{
117
- inflow: "inflow";
118
- outflow: "outflow";
119
- }>;
120
- tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
121
115
  amount: z.ZodNumber;
122
116
  currency: z.ZodString;
123
- fee: z.ZodDefault<z.ZodNumber>;
124
- tax: z.ZodDefault<z.ZodNumber>;
125
- net: z.ZodDefault<z.ZodNumber>;
126
- taxDetails: z.ZodOptional<z.ZodObject<{
127
- type: z.ZodOptional<z.ZodEnum<{
128
- sales_tax: "sales_tax";
129
- vat: "vat";
130
- none: "none";
131
- }>>;
132
- rate: z.ZodOptional<z.ZodNumber>;
133
- isInclusive: z.ZodOptional<z.ZodBoolean>;
134
- }, z.core.$strip>>;
135
- method: z.ZodString;
136
117
  methodKind: z.ZodEnum<{
137
118
  manual: "manual";
138
119
  bank_transfer: "bank_transfer";
@@ -148,8 +129,39 @@ declare const transactionCreateSchema: z.ZodObject<{
148
129
  cheque: "cheque";
149
130
  other: "other";
150
131
  }>;
151
- status: z.ZodDefault<z.ZodString>;
152
132
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
133
+ customerId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
134
+ splits: z.ZodOptional<z.ZodArray<z.ZodObject<{
135
+ type: z.ZodString;
136
+ recipientId: z.ZodString;
137
+ recipientType: z.ZodString;
138
+ rate: z.ZodNumber;
139
+ grossAmount: z.ZodNumber;
140
+ gatewayFeeRate: z.ZodNumber;
141
+ gatewayFeeAmount: z.ZodNumber;
142
+ netAmount: z.ZodNumber;
143
+ status: z.ZodString;
144
+ }, z.core.$strip>>>;
145
+ relatedTransactionId: z.ZodOptional<z.ZodString>;
146
+ organizationId: z.ZodOptional<z.ZodString>;
147
+ flow: z.ZodEnum<{
148
+ inflow: "inflow";
149
+ outflow: "outflow";
150
+ }>;
151
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
152
+ fee: z.ZodDefault<z.ZodNumber>;
153
+ tax: z.ZodDefault<z.ZodNumber>;
154
+ net: z.ZodDefault<z.ZodNumber>;
155
+ taxDetails: z.ZodOptional<z.ZodObject<{
156
+ type: z.ZodOptional<z.ZodEnum<{
157
+ sales_tax: "sales_tax";
158
+ vat: "vat";
159
+ none: "none";
160
+ }>>;
161
+ rate: z.ZodOptional<z.ZodNumber>;
162
+ isInclusive: z.ZodOptional<z.ZodBoolean>;
163
+ }, z.core.$strip>>;
164
+ method: z.ZodString;
153
165
  gateway: z.ZodOptional<z.ZodObject<{
154
166
  type: z.ZodString;
155
167
  sessionId: z.ZodOptional<z.ZodString>;
@@ -167,17 +179,6 @@ declare const transactionCreateSchema: z.ZodObject<{
167
179
  netAmount: z.ZodNumber;
168
180
  status: z.ZodString;
169
181
  }, z.core.$strip>>;
170
- splits: z.ZodOptional<z.ZodArray<z.ZodObject<{
171
- type: z.ZodString;
172
- recipientId: z.ZodString;
173
- recipientType: z.ZodString;
174
- rate: z.ZodNumber;
175
- grossAmount: z.ZodNumber;
176
- gatewayFeeRate: z.ZodNumber;
177
- gatewayFeeAmount: z.ZodNumber;
178
- netAmount: z.ZodNumber;
179
- status: z.ZodString;
180
- }, z.core.$strip>>>;
181
182
  hold: z.ZodOptional<z.ZodObject<{
182
183
  status: z.ZodString;
183
184
  heldAmount: z.ZodNumber;
@@ -200,7 +201,6 @@ declare const transactionCreateSchema: z.ZodObject<{
200
201
  }, z.core.$strip>>;
201
202
  sourceId: z.ZodOptional<z.ZodString>;
202
203
  sourceModel: z.ZodOptional<z.ZodString>;
203
- relatedTransactionId: z.ZodOptional<z.ZodString>;
204
204
  idempotencyKey: z.ZodOptional<z.ZodString>;
205
205
  }, z.core.$strip>;
206
206
  declare const transactionUpdateSchema: z.ZodObject<{
@@ -360,12 +360,12 @@ declare const subscriptionBaseSchema: z.ZodObject<{
360
360
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
361
361
  }, z.core.$strip>;
362
362
  declare const subscriptionCreateSchema: z.ZodObject<{
363
- organizationId: z.ZodOptional<z.ZodString>;
364
- customerId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
365
363
  amount: z.ZodNumber;
366
364
  currency: z.ZodOptional<z.ZodString>;
367
- paymentIntentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
368
365
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
366
+ customerId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
367
+ organizationId: z.ZodOptional<z.ZodString>;
368
+ paymentIntentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
369
369
  planKey: z.ZodString;
370
370
  transactionId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
371
371
  startDate: z.ZodOptional<z.ZodCoercedDate<unknown>>;
@@ -478,7 +478,6 @@ declare const settlementBaseSchema: z.ZodObject<{
478
478
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
479
479
  }, z.core.$strip>;
480
480
  declare const settlementCreateSchema: z.ZodObject<{
481
- organizationId: z.ZodString;
482
481
  type: z.ZodEnum<{
483
482
  split_payout: "split_payout";
484
483
  platform_withdrawal: "platform_withdrawal";
@@ -504,6 +503,9 @@ declare const settlementCreateSchema: z.ZodObject<{
504
503
  crypto: "crypto";
505
504
  check: "check";
506
505
  }>;
506
+ scheduledAt: z.ZodDefault<z.ZodCoercedDate<unknown>>;
507
+ notes: z.ZodOptional<z.ZodString>;
508
+ organizationId: z.ZodString;
507
509
  sourceTransactionIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
508
510
  sourceSplitIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
509
511
  bankTransferDetails: z.ZodOptional<z.ZodObject<{
@@ -529,8 +531,6 @@ declare const settlementCreateSchema: z.ZodObject<{
529
531
  transactionHash: z.ZodOptional<z.ZodString>;
530
532
  transferredAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
531
533
  }, z.core.$strip>>;
532
- scheduledAt: z.ZodDefault<z.ZodCoercedDate<unknown>>;
533
- notes: z.ZodOptional<z.ZodString>;
534
534
  }, z.core.$strip>;
535
535
  declare const settlementUpdateSchema: z.ZodObject<{
536
536
  publicId: z.ZodOptional<z.ZodOptional<z.ZodString>>;
package/dist/index.d.mts CHANGED
@@ -6,10 +6,10 @@ import { BANK_FEED_STATE_MACHINE, HOLD_STATE_MACHINE, MANUAL_STATE_MACHINE, PAYM
6
6
  import { a as isMonetizationType, c as PAYMENT_STATUS, d as PaymentGatewayTypeValue, f as PaymentStatus, h as isPaymentStatus, i as MonetizationTypes, l as PAYMENT_STATUS_VALUES, m as isPaymentGatewayType, n as MONETIZATION_TYPE_VALUES, o as PAYMENT_GATEWAY_TYPE, p as PaymentStatusValue, r as MonetizationTypeValue, s as PAYMENT_GATEWAY_TYPE_VALUES, t as MONETIZATION_TYPES, u as PaymentGatewayType } from "./monetization.enums-DzAI4sT7.mjs";
7
7
  import { D as RevenueEventSchema, E as RevenueEventPayloadOf, T as RevenueEventDefinition, _t as InProcessRevenueBusOptions, ft as revenueEventDefinitions, gt as InProcessRevenueBus, ht as createEvent, mt as RevenueEventName, pt as REVENUE_EVENTS } from "./revenue-event-catalog-BU_KYN2-.mjs";
8
8
  import { a as BankFeedProviderRegistry, c as ParseUploadParams, d as PaymentProvider, i as BankFeedProviderCapabilities, l as ParseUploadResult, n as createProviderRegistry, o as FetchTransactionsParams, r as BankFeedProvider, s as FetchTransactionsResult, t as ProviderRegistry, u as createBankFeedProviderRegistry } from "./registry-DSG7x-Cl.mjs";
9
- import { a as RevenueConfig, c as SubscriptionRepository, d as RevenueSchemaOptions, f as SettlementDocument, i as RetryConfig, l as TransactionRepository, m as TransactionDocument, n as BankFeedModuleConfig, o as RevenueEngine, p as SubscriptionDocument, r as CommissionConfig, s as SettlementRepository, t as BankFeedIndexConfig, u as RevenueModels } from "./engine-types-BU8kkttr.mjs";
9
+ import { _ as TransactionDocument, a as RevenueConfig, c as RecipientBreakdown, d as SubscriptionRepository, f as TransactionRepository, g as SubscriptionDocument, h as SettlementDocument, i as RetryConfig, l as SettlementRepository, m as RevenueSchemaOptions, n as BankFeedModuleConfig, o as RevenueEngine, p as RevenueModels, r as CommissionConfig, s as RecipientBalance, t as BankFeedIndexConfig, u as SettlementSummary } from "./engine-types-D6ijamqA.mjs";
10
10
  import { RepositoryPluginBundle, RevenueRepositories } from "./repositories/create-repositories.mjs";
11
- import { A as transactionBaseSchema, C as subscriptionBaseSchema, D as TransactionCreateInput, E as subscriptionUpdateSchema, M as transactionListFilterSchema, N as transactionUpdateSchema, O as TransactionListFilter, S as SubscriptionUpdateInput, T as subscriptionListFilterSchema, _ as settlementCreateSchema, a as escrowReleaseSchema, b as SubscriptionCreateInput, c as PaymentVerifyInput, d as paymentVerifySchema, f as refundSchema, g as settlementBaseSchema, h as SettlementUpdateInput, i as escrowHoldSchema, j as transactionCreateSchema, k as TransactionUpdateInput, l as RefundInput, m as SettlementListFilter, n as EscrowReleaseInput, o as splitRuleSchema, p as SettlementCreateInput, r as SplitRuleInput, s as PaymentIntentInput, t as EscrowHoldInput, u as paymentIntentSchema, v as settlementListFilterSchema, w as subscriptionCreateSchema, x as SubscriptionListFilter, y as settlementUpdateSchema } from "./escrow.schema-Cklvlywy.mjs";
12
- import { A as SplitInfo, B as validateTaxCalculation, C as multiplyMoney, D as toCurrencyCode, E as sumMoney, F as TaxConfig, H as calculateCommission, I as TaxType, L as calculateTax, M as calculateOrganizationPayout, N as calculateSplits, O as toMajor, P as TaxCalculation, R as getTaxType, S as money, T as subtractMoney, U as reverseCommission, V as CommissionInfo, _ as isMoney, a as CurrencyCode, b as isZeroMoney, c as Money, d as addMoney, f as compareMoney, g as isCurrencyCode, h as fromSmallestUnit, i as CURRENCIES, j as SplitRule, k as toSmallestUnit, l as MoneyValue, m as fromMajor, n as getAuditTrail, o as CurrencyMismatchError, p as equalsMoney, r as getLastStateChange, s as MINOR_UNIT_FACTOR, t as appendAuditEvent, u as absMoney, v as isNegativeMoney, w as negateMoney, x as minorUnitFactor, y as isPositiveMoney, z as reverseTax } from "./audit-DRKuLBFO.mjs";
11
+ import { A as transactionBaseSchema, C as subscriptionBaseSchema, D as TransactionCreateInput, E as subscriptionUpdateSchema, M as transactionListFilterSchema, N as transactionUpdateSchema, O as TransactionListFilter, S as SubscriptionUpdateInput, T as subscriptionListFilterSchema, _ as settlementCreateSchema, a as escrowReleaseSchema, b as SubscriptionCreateInput, c as PaymentVerifyInput, d as paymentVerifySchema, f as refundSchema, g as settlementBaseSchema, h as SettlementUpdateInput, i as escrowHoldSchema, j as transactionCreateSchema, k as TransactionUpdateInput, l as RefundInput, m as SettlementListFilter, n as EscrowReleaseInput, o as splitRuleSchema, p as SettlementCreateInput, r as SplitRuleInput, s as PaymentIntentInput, t as EscrowHoldInput, u as paymentIntentSchema, v as settlementListFilterSchema, w as subscriptionCreateSchema, x as SubscriptionListFilter, y as settlementUpdateSchema } from "./escrow.schema-DSx7EywJ.mjs";
12
+ import { A as SplitInfo, B as reverseTax, C as multiplyMoney, D as toCurrencyCode, E as sumMoney, F as TaxCalculation, H as CommissionInfo, I as TaxConfig, L as TaxType, M as calculateOrganizationPayout, N as calculateSplits, O as toMajor, R as calculateTax, S as money, T as subtractMoney, U as calculateCommission, V as validateTaxCalculation, W as reverseCommission, _ as isMoney, a as CurrencyCode, b as isZeroMoney, c as Money, d as addMoney, f as compareMoney, g as isCurrencyCode, h as fromSmallestUnit, i as CURRENCIES, j as SplitRule, k as toSmallestUnit, l as MoneyValue, m as fromMajor, n as getAuditTrail, o as CurrencyMismatchError, p as equalsMoney, r as getLastStateChange, s as MINOR_UNIT_FACTOR, t as appendAuditEvent, u as absMoney, v as isNegativeMoney, w as negateMoney, x as minorUnitFactor, y as isPositiveMoney, z as getTaxType } from "./audit-BkDdPSed.mjs";
13
13
  import { HookHandler, PluginContext, PluginManager, RevenuePluginDefinition } from "./plugins/plugin.interface.mjs";
14
14
  import { DomainEvent, DomainEvent as DomainEvent$1, EventHandler, EventTransport } from "@classytic/primitives/events";
15
15
  import { InvalidOutboxEventError, OutboxAcknowledgeOptions, OutboxAcknowledgeOptions as OutboxAcknowledgeOptions$1, OutboxClaimOptions, OutboxErrorInfo, OutboxFailOptions, OutboxFailureContext, OutboxFailureDecision, OutboxFailurePolicy, OutboxOwnershipError, OutboxStore, OutboxStore as OutboxStore$1, OutboxWriteOptions, OutboxWriteOptions as OutboxWriteOptions$1 } from "@classytic/primitives/outbox";
@@ -115,4 +115,4 @@ declare class BankFeedProviderNotFoundError extends RevenueError {
115
115
  constructor(providerName: string);
116
116
  }
117
117
  //#endregion
118
- export { AlreadyVerifiedError, type AnalyticsBridge, BANK_FEED_SOURCE, BANK_FEED_SOURCE_VALUES, BANK_FEED_STATE_MACHINE, BANK_FEED_STATUS, BANK_FEED_STATUS_VALUES, BankFeedImportError, type BankFeedIndexConfig, type BankFeedModuleConfig, BankFeedProvider, type BankFeedProviderCapabilities, BankFeedProviderNotFoundError, BankFeedProviderRegistry, BankFeedSourceValue, BankFeedStatusValue, CURRENCIES, type CommissionConfig, type CommissionInfo, ConfigurationError, type CurrencyBridge, type CurrencyCode, CurrencyMismatchError, type CustomerBridge, type DomainEvent, EscrowHoldInput, EscrowReleaseInput, type EventHandler, type EventTransport, type FetchTransactionsParams, type FetchTransactionsResult, HOLD_REASON, HOLD_REASON_VALUES, HOLD_STATE_MACHINE, HOLD_STATUS, HOLD_STATUS_VALUES, HoldReason, HoldReasonValue, HoldStatus, HoldStatusValue, type HookHandler, InProcessRevenueBus, type InProcessRevenueBusOptions, InvalidOutboxEventError, InvalidStateTransitionError, LIBRARY_CATEGORIES, LIBRARY_CATEGORY_VALUES, type LedgerBridge, LibraryCategories, LibraryCategoryValue, MANUAL_STATE_MACHINE, MINOR_UNIT_FACTOR, MONETIZATION_TYPES, MONETIZATION_TYPE_VALUES, MemoryOutboxStore, MethodKindLockedError, MonetizationTypeValue, MonetizationTypes, type Money, type MoneyValue, type NotificationBridge, type OutboxAcknowledgeOptions, type OutboxClaimOptions, type OutboxErrorInfo, type OutboxFailOptions, type OutboxFailureContext, type OutboxFailureDecision, type OutboxFailurePolicy, OutboxOwnershipError, type OutboxStore, type OutboxWriteOptions, PAYMENT_FLOW_STATE_MACHINE, PAYMENT_GATEWAY_TYPE, PAYMENT_GATEWAY_TYPE_VALUES, PAYMENT_STATUS, PAYMENT_STATUS_VALUES, PAYOUT_METHOD, PAYOUT_METHOD_VALUES, PLAN_KEYS, PLAN_KEY_VALUES, type ParseUploadParams, type ParseUploadResult, PaymentGatewayType, PaymentGatewayTypeValue, PaymentIntentCreationError, PaymentIntentInput, PaymentProvider, PaymentStatus, PaymentStatusValue, PaymentVerificationError, PaymentVerifyInput, PayoutMethod, PayoutMethodValue, PlanKeyValue, PlanKeys, type PluginContext, PluginManager, ProviderCapabilityError, ProviderNotFoundError, ProviderRegistry, RELEASE_REASON, RELEASE_REASON_VALUES, REVENUE_EVENTS, RefundInput, RefundNotSupportedError, ReleaseReason, ReleaseReasonValue, type RepositoryPluginBundle, type Result, type RetryConfig, type RevenueBridges, type RevenueConfig, type RevenueContext, type RevenueEngine, RevenueError, type RevenueEventDefinition, type RevenueEventName, type RevenueEventPayloadOf, type RevenueEventSchema, type RevenueModels, type RevenuePluginDefinition, type RevenueRepositories, type RevenueSchemaOptions, SETTLEMENT_STATE_MACHINE, SETTLEMENT_STATUS, SETTLEMENT_STATUS_VALUES, SETTLEMENT_TYPE, SETTLEMENT_TYPE_VALUES, SPLIT_STATE_MACHINE, SPLIT_STATUS, SPLIT_STATUS_VALUES, SPLIT_TYPE, SPLIT_TYPE_VALUES, SUBSCRIPTION_STATE_MACHINE, SUBSCRIPTION_STATUS, SUBSCRIPTION_STATUS_VALUES, SettlementCreateInput, type SettlementDocument, SettlementListFilter, SettlementNotFoundError, SettlementRepository, SettlementStatus, SettlementStatusValue, SettlementType, SettlementTypeValue, SettlementUpdateInput, type SplitInfo, type SplitRule, SplitRuleInput, SplitStatus, SplitStatusValue, SplitType, SplitTypeValue, type StateChangeEvent, StateMachine, SubscriptionCreateInput, type SubscriptionDocument, SubscriptionListFilter, SubscriptionNotFoundError, SubscriptionRepository, SubscriptionStatus, SubscriptionStatusValue, SubscriptionUpdateInput, TRANSACTION_FLOW, TRANSACTION_FLOW_VALUES, TRANSACTION_KIND, TRANSACTION_KIND_VALUES, TRANSACTION_STATE_MACHINE, TRANSACTION_STATUS, TRANSACTION_STATUS_VALUES, type TaxBridge, type TaxCalculation, type TaxConfig, type TaxType, TransactionCreateInput, type TransactionDocument, TransactionFlow, TransactionFlowValue, TransactionKind, TransactionKindValue, TransactionListFilter, TransactionNotFoundError, TransactionRepository, TransactionStatus, TransactionStatusValue, TransactionUpdateInput, ValidationError, WrongTransactionKindError, absMoney, addMoney, appendAuditEvent, calculateCommission, calculateOrganizationPayout, calculateSplits, calculateTax, compareMoney, createBankFeedProviderRegistry, createEvent, createProviderRegistry, createRevenue, equalsMoney, err, escrowHoldSchema, escrowReleaseSchema, fromMajor, fromSmallestUnit, getAuditTrail, getLastStateChange, getTaxType, initialStatusFor, isBankFeedSource, isBankFeedStatus, isCurrencyCode, isErr, isHoldReason, isHoldStatus, isLibraryCategory, isMonetizationType, isMoney, isNegativeMoney, isOk, isPaymentGatewayType, isPaymentStatus, isPayoutMethod, isPlanKey, isPositiveMoney, isReleaseReason, isSettlementStatus, isSettlementType, isSplitStatus, isSplitType, isStatusValidForKind, isSubscriptionStatus, isTransactionFlow, isTransactionKind, isTransactionStatus, isZeroMoney, minorUnitFactor, money, multiplyMoney, negateMoney, ok, paymentIntentSchema, paymentVerifySchema, refundSchema, revenueEventDefinitions, reverseCommission, reverseTax, settlementBaseSchema, settlementCreateSchema, settlementListFilterSchema, settlementUpdateSchema, smFor, splitRuleSchema, statusesForKind, subscriptionBaseSchema, subscriptionCreateSchema, subscriptionListFilterSchema, subscriptionUpdateSchema, subtractMoney, sumMoney, toCurrencyCode, toMajor, toSmallestUnit, transactionBaseSchema, transactionCreateSchema, transactionListFilterSchema, transactionUpdateSchema, validateTaxCalculation };
118
+ export { AlreadyVerifiedError, type AnalyticsBridge, BANK_FEED_SOURCE, BANK_FEED_SOURCE_VALUES, BANK_FEED_STATE_MACHINE, BANK_FEED_STATUS, BANK_FEED_STATUS_VALUES, BankFeedImportError, type BankFeedIndexConfig, type BankFeedModuleConfig, BankFeedProvider, type BankFeedProviderCapabilities, BankFeedProviderNotFoundError, BankFeedProviderRegistry, BankFeedSourceValue, BankFeedStatusValue, CURRENCIES, type CommissionConfig, type CommissionInfo, ConfigurationError, type CurrencyBridge, type CurrencyCode, CurrencyMismatchError, type CustomerBridge, type DomainEvent, EscrowHoldInput, EscrowReleaseInput, type EventHandler, type EventTransport, type FetchTransactionsParams, type FetchTransactionsResult, HOLD_REASON, HOLD_REASON_VALUES, HOLD_STATE_MACHINE, HOLD_STATUS, HOLD_STATUS_VALUES, HoldReason, HoldReasonValue, HoldStatus, HoldStatusValue, type HookHandler, InProcessRevenueBus, type InProcessRevenueBusOptions, InvalidOutboxEventError, InvalidStateTransitionError, LIBRARY_CATEGORIES, LIBRARY_CATEGORY_VALUES, type LedgerBridge, LibraryCategories, LibraryCategoryValue, MANUAL_STATE_MACHINE, MINOR_UNIT_FACTOR, MONETIZATION_TYPES, MONETIZATION_TYPE_VALUES, MemoryOutboxStore, MethodKindLockedError, MonetizationTypeValue, MonetizationTypes, type Money, type MoneyValue, type NotificationBridge, type OutboxAcknowledgeOptions, type OutboxClaimOptions, type OutboxErrorInfo, type OutboxFailOptions, type OutboxFailureContext, type OutboxFailureDecision, type OutboxFailurePolicy, OutboxOwnershipError, type OutboxStore, type OutboxWriteOptions, PAYMENT_FLOW_STATE_MACHINE, PAYMENT_GATEWAY_TYPE, PAYMENT_GATEWAY_TYPE_VALUES, PAYMENT_STATUS, PAYMENT_STATUS_VALUES, PAYOUT_METHOD, PAYOUT_METHOD_VALUES, PLAN_KEYS, PLAN_KEY_VALUES, type ParseUploadParams, type ParseUploadResult, PaymentGatewayType, PaymentGatewayTypeValue, PaymentIntentCreationError, PaymentIntentInput, PaymentProvider, PaymentStatus, PaymentStatusValue, PaymentVerificationError, PaymentVerifyInput, PayoutMethod, PayoutMethodValue, PlanKeyValue, PlanKeys, type PluginContext, PluginManager, ProviderCapabilityError, ProviderNotFoundError, ProviderRegistry, RELEASE_REASON, RELEASE_REASON_VALUES, REVENUE_EVENTS, type RecipientBalance, type RecipientBreakdown, RefundInput, RefundNotSupportedError, ReleaseReason, ReleaseReasonValue, type RepositoryPluginBundle, type Result, type RetryConfig, type RevenueBridges, type RevenueConfig, type RevenueContext, type RevenueEngine, RevenueError, type RevenueEventDefinition, type RevenueEventName, type RevenueEventPayloadOf, type RevenueEventSchema, type RevenueModels, type RevenuePluginDefinition, type RevenueRepositories, type RevenueSchemaOptions, SETTLEMENT_STATE_MACHINE, SETTLEMENT_STATUS, SETTLEMENT_STATUS_VALUES, SETTLEMENT_TYPE, SETTLEMENT_TYPE_VALUES, SPLIT_STATE_MACHINE, SPLIT_STATUS, SPLIT_STATUS_VALUES, SPLIT_TYPE, SPLIT_TYPE_VALUES, SUBSCRIPTION_STATE_MACHINE, SUBSCRIPTION_STATUS, SUBSCRIPTION_STATUS_VALUES, SettlementCreateInput, type SettlementDocument, SettlementListFilter, SettlementNotFoundError, SettlementRepository, SettlementStatus, SettlementStatusValue, type SettlementSummary, SettlementType, SettlementTypeValue, SettlementUpdateInput, type SplitInfo, type SplitRule, SplitRuleInput, SplitStatus, SplitStatusValue, SplitType, SplitTypeValue, type StateChangeEvent, StateMachine, SubscriptionCreateInput, type SubscriptionDocument, SubscriptionListFilter, SubscriptionNotFoundError, SubscriptionRepository, SubscriptionStatus, SubscriptionStatusValue, SubscriptionUpdateInput, TRANSACTION_FLOW, TRANSACTION_FLOW_VALUES, TRANSACTION_KIND, TRANSACTION_KIND_VALUES, TRANSACTION_STATE_MACHINE, TRANSACTION_STATUS, TRANSACTION_STATUS_VALUES, type TaxBridge, type TaxCalculation, type TaxConfig, type TaxType, TransactionCreateInput, type TransactionDocument, TransactionFlow, TransactionFlowValue, TransactionKind, TransactionKindValue, TransactionListFilter, TransactionNotFoundError, TransactionRepository, TransactionStatus, TransactionStatusValue, TransactionUpdateInput, ValidationError, WrongTransactionKindError, absMoney, addMoney, appendAuditEvent, calculateCommission, calculateOrganizationPayout, calculateSplits, calculateTax, compareMoney, createBankFeedProviderRegistry, createEvent, createProviderRegistry, createRevenue, equalsMoney, err, escrowHoldSchema, escrowReleaseSchema, fromMajor, fromSmallestUnit, getAuditTrail, getLastStateChange, getTaxType, initialStatusFor, isBankFeedSource, isBankFeedStatus, isCurrencyCode, isErr, isHoldReason, isHoldStatus, isLibraryCategory, isMonetizationType, isMoney, isNegativeMoney, isOk, isPaymentGatewayType, isPaymentStatus, isPayoutMethod, isPlanKey, isPositiveMoney, isReleaseReason, isSettlementStatus, isSettlementType, isSplitStatus, isSplitType, isStatusValidForKind, isSubscriptionStatus, isTransactionFlow, isTransactionKind, isTransactionStatus, isZeroMoney, minorUnitFactor, money, multiplyMoney, negateMoney, ok, paymentIntentSchema, paymentVerifySchema, refundSchema, revenueEventDefinitions, reverseCommission, reverseTax, settlementBaseSchema, settlementCreateSchema, settlementListFilterSchema, settlementUpdateSchema, smFor, splitRuleSchema, statusesForKind, subscriptionBaseSchema, subscriptionCreateSchema, subscriptionListFilterSchema, subscriptionUpdateSchema, subtractMoney, sumMoney, toCurrencyCode, toMajor, toSmallestUnit, transactionBaseSchema, transactionCreateSchema, transactionListFilterSchema, transactionUpdateSchema, validateTaxCalculation };
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  import { _ as TRANSACTION_STATUS, a as TRANSACTION_KIND, b as isTransactionFlow, c as isBankFeedSource, d as isTransactionKind, f as statusesForKind, g as TRANSACTION_FLOW_VALUES, h as TRANSACTION_FLOW, i as BANK_FEED_STATUS_VALUES, l as isBankFeedStatus, m as LIBRARY_CATEGORY_VALUES, n as BANK_FEED_SOURCE_VALUES, o as TRANSACTION_KIND_VALUES, p as LIBRARY_CATEGORIES, r as BANK_FEED_STATUS, s as initialStatusFor, t as BANK_FEED_SOURCE, u as isStatusValidForKind, v as TRANSACTION_STATUS_VALUES, x as isTransactionStatus, y as isLibraryCategory } from "./bank-feed.enums-ByS3mjX0.mjs";
2
- import { n as SubscriptionRepository, r as TransactionRepository, t as SettlementRepository } from "./settlement.repository-DtLSBDIk.mjs";
2
+ import { n as SubscriptionRepository, r as TransactionRepository, t as SettlementRepository } from "./settlement.repository-oypYDjKq.mjs";
3
3
  import { n as createEvent, t as REVENUE_EVENTS } from "./event-constants-DM_-A57b.mjs";
4
4
  import { A as isReleaseReason, C as HOLD_REASON_VALUES, D as RELEASE_REASON_VALUES, E as RELEASE_REASON, O as isHoldReason, S as HOLD_REASON, T as HOLD_STATUS_VALUES, _ as SETTLEMENT_STATUS_VALUES, a as isPlanKey, b as isSettlementStatus, c as PAYOUT_METHOD_VALUES, d as SPLIT_TYPE, f as SPLIT_TYPE_VALUES, g as SETTLEMENT_STATUS, h as isSplitType, i as SUBSCRIPTION_STATUS_VALUES, k as isHoldStatus, l as SPLIT_STATUS, m as isSplitStatus, n as PLAN_KEY_VALUES, o as isSubscriptionStatus, p as isPayoutMethod, r as SUBSCRIPTION_STATUS, s as PAYOUT_METHOD, t as PLAN_KEYS, u as SPLIT_STATUS_VALUES, v as SETTLEMENT_TYPE, w as HOLD_STATUS, x as isSettlementType, y as SETTLEMENT_TYPE_VALUES } from "./subscription.enums-95othr0i.mjs";
5
5
  import { _ as WrongTransactionKindError, a as InvalidStateTransitionError, c as PaymentVerificationError, d as RefundNotSupportedError, f as RevenueError, g as ValidationError, h as TransactionNotFoundError, i as ConfigurationError, l as ProviderCapabilityError, m as SubscriptionNotFoundError, n as BankFeedImportError, o as MethodKindLockedError, p as SettlementNotFoundError, r as BankFeedProviderNotFoundError, s as PaymentIntentCreationError, t as AlreadyVerifiedError, u as ProviderNotFoundError } from "./errors-Bt5NRVMq.mjs";
6
6
  import { BANK_FEED_STATE_MACHINE, HOLD_STATE_MACHINE, MANUAL_STATE_MACHINE, PAYMENT_FLOW_STATE_MACHINE, SETTLEMENT_STATE_MACHINE, SPLIT_STATE_MACHINE, SUBSCRIPTION_STATE_MACHINE, StateMachine, TRANSACTION_STATE_MACHINE, smFor } from "./core/state-machines.mjs";
7
- import { a as reverseTax, c as reverseCommission, i as getTaxType, n as calculateSplits, o as validateTaxCalculation, r as calculateTax, s as calculateCommission, t as calculateOrganizationPayout } from "./splits-CNfQj92L.mjs";
7
+ import { a as getTaxType, c as calculateCommission, i as calculateTax, l as reverseCommission, n as calculateSplits, o as reverseTax, s as validateTaxCalculation, t as calculateOrganizationPayout } from "./splits-CEdZN6OT.mjs";
8
8
  import { createRevenueRepositories } from "./repositories/create-repositories.mjs";
9
9
  import { a as createProviderRegistry, i as ProviderRegistry, n as BankFeedProviderRegistry, o as PaymentProvider, r as createBankFeedProviderRegistry, t as BankFeedProvider } from "./bank-feed-ClxNob_I.mjs";
10
10
  import { M as revenueEventDefinitions, N as InProcessRevenueBus } from "./revenue-event-catalog-B9aZmNpL.mjs";
@@ -1,4 +1,4 @@
1
- import { c as SubscriptionRepository, l as TransactionRepository, s as SettlementRepository, u as RevenueModels } from "../engine-types-BU8kkttr.mjs";
1
+ import { d as SubscriptionRepository, f as TransactionRepository, l as SettlementRepository, p as RevenueModels } from "../engine-types-D6ijamqA.mjs";
2
2
  import { PluginType } from "@classytic/mongokit";
3
3
 
4
4
  //#region src/repositories/create-repositories.d.ts
@@ -1,4 +1,4 @@
1
- import { n as SubscriptionRepository, r as TransactionRepository, t as SettlementRepository } from "../settlement.repository-DtLSBDIk.mjs";
1
+ import { n as SubscriptionRepository, r as TransactionRepository, t as SettlementRepository } from "../settlement.repository-oypYDjKq.mjs";
2
2
 
3
3
  //#region src/repositories/create-repositories.ts
4
4
  function createRevenueRepositories(models, builtInPlugins, hostPlugins = {}) {
@@ -3,7 +3,7 @@ import { n as createEvent, t as REVENUE_EVENTS } from "./event-constants-DM_-A57
3
3
  import { g as SETTLEMENT_STATUS, r as SUBSCRIPTION_STATUS, w as HOLD_STATUS } from "./subscription.enums-95othr0i.mjs";
4
4
  import { _ as WrongTransactionKindError, g as ValidationError, h as TransactionNotFoundError, m as SubscriptionNotFoundError, n as BankFeedImportError, o as MethodKindLockedError, p as SettlementNotFoundError } from "./errors-Bt5NRVMq.mjs";
5
5
  import { SETTLEMENT_STATE_MACHINE, SUBSCRIPTION_STATE_MACHINE, TRANSACTION_STATE_MACHINE, smFor } from "./core/state-machines.mjs";
6
- import { a as reverseTax, c as reverseCommission, n as calculateSplits, s as calculateCommission, t as calculateOrganizationPayout } from "./splits-CNfQj92L.mjs";
6
+ import { c as calculateCommission, l as reverseCommission, n as calculateSplits, o as reverseTax, t as calculateOrganizationPayout } from "./splits-CEdZN6OT.mjs";
7
7
  import { Repository, repoOptionsFromCtx, withTransaction } from "@classytic/mongokit";
8
8
 
9
9
  //#region src/repositories/base.repository.ts
@@ -1402,6 +1402,38 @@ var SubscriptionRepository = class extends RevenueRepositoryBase {
1402
1402
 
1403
1403
  //#endregion
1404
1404
  //#region src/repositories/settlement.repository.ts
1405
+ function emptySettlementSummary() {
1406
+ return {
1407
+ currency: null,
1408
+ pending: 0,
1409
+ held: 0,
1410
+ available: 0,
1411
+ processing: 0,
1412
+ paidOut: 0,
1413
+ failed: 0,
1414
+ lifetime: 0
1415
+ };
1416
+ }
1417
+ /** Bucket one aggregated (status, due, total) row into a running summary. */
1418
+ function foldSettlementStatus(s, status, due, total) {
1419
+ switch (status) {
1420
+ case SETTLEMENT_STATUS.PENDING:
1421
+ s.pending += total;
1422
+ if (due) s.available += total;
1423
+ else s.held += total;
1424
+ break;
1425
+ case SETTLEMENT_STATUS.PROCESSING:
1426
+ s.processing += total;
1427
+ break;
1428
+ case SETTLEMENT_STATUS.COMPLETED:
1429
+ s.paidOut += total;
1430
+ break;
1431
+ case SETTLEMENT_STATUS.FAILED:
1432
+ s.failed += total;
1433
+ break;
1434
+ default: break;
1435
+ }
1436
+ }
1405
1437
  /**
1406
1438
  * SettlementRepository — payouts to recipients (organizations, vendors,
1407
1439
  * affiliates).
@@ -1447,6 +1479,7 @@ var SettlementRepository = class extends RevenueRepositoryBase {
1447
1479
  };
1448
1480
  if (options.organizationId) query.organizationId = options.organizationId;
1449
1481
  if (options.payoutMethod) query.payoutMethod = options.payoutMethod;
1482
+ if (options.recipientId) query.recipientId = options.recipientId;
1450
1483
  const pending = (await this.getAll({
1451
1484
  filters: query,
1452
1485
  limit: options.limit ?? 50,
@@ -1562,6 +1595,82 @@ var SettlementRepository = class extends RevenueRepositoryBase {
1562
1595
  }), ctx);
1563
1596
  return updated;
1564
1597
  }
1598
+ /**
1599
+ * Settlement money-state for an ARBITRARY filter — a recipient, an org, or
1600
+ * the whole platform (pass `_bypassTenant` in ctx to span every org). One
1601
+ * tenant-scoped `aggregatePipeline` (the `{ recipientId, status }` index backs
1602
+ * the `$match`), never a raw `Model.aggregate`. The reusable rollup behind
1603
+ * `recipientBalance`, platform reconciliation, and cross-org earnings.
1604
+ */
1605
+ async summary(filter = {}, ctx = {}) {
1606
+ const now = /* @__PURE__ */ new Date();
1607
+ const rows = await this.aggregatePipeline([{ $match: filter }, { $group: {
1608
+ _id: {
1609
+ status: "$status",
1610
+ due: { $lte: ["$scheduledAt", now] }
1611
+ },
1612
+ total: { $sum: "$amount" },
1613
+ currency: { $first: "$currency" }
1614
+ } }], this.optsFromCtx(ctx));
1615
+ const out = emptySettlementSummary();
1616
+ for (const row of rows) {
1617
+ foldSettlementStatus(out, row._id.status, row._id.due, row.total);
1618
+ if (row.currency && !out.currency) out.currency = row.currency;
1619
+ }
1620
+ out.lifetime = out.pending + out.processing + out.paidOut;
1621
+ return out;
1622
+ }
1623
+ /**
1624
+ * Per-recipient settlement rollup — one {@link RecipientBreakdown} per
1625
+ * distinct (recipientId, recipientType) matching `filter`. The reusable list
1626
+ * behind a platform "who is owed what" view; pass `_bypassTenant` to span all
1627
+ * orgs.
1628
+ */
1629
+ async breakdownByRecipient(filter = {}, ctx = {}) {
1630
+ const now = /* @__PURE__ */ new Date();
1631
+ const rows = await this.aggregatePipeline([{ $match: filter }, { $group: {
1632
+ _id: {
1633
+ recipientId: "$recipientId",
1634
+ recipientType: "$recipientType",
1635
+ status: "$status",
1636
+ due: { $lte: ["$scheduledAt", now] }
1637
+ },
1638
+ total: { $sum: "$amount" },
1639
+ currency: { $first: "$currency" },
1640
+ role: { $first: "$metadata.role" }
1641
+ } }], this.optsFromCtx(ctx));
1642
+ const byKey = /* @__PURE__ */ new Map();
1643
+ for (const row of rows) {
1644
+ const key = `${row._id.recipientType}:${row._id.recipientId}`;
1645
+ let r = byKey.get(key);
1646
+ if (!r) {
1647
+ r = {
1648
+ recipientId: row._id.recipientId,
1649
+ recipientType: row._id.recipientType,
1650
+ role: row.role ?? null,
1651
+ ...emptySettlementSummary()
1652
+ };
1653
+ byKey.set(key, r);
1654
+ }
1655
+ foldSettlementStatus(r, row._id.status, row._id.due, row.total);
1656
+ if (row.role && !r.role) r.role = row.role;
1657
+ if (row.currency && !r.currency) r.currency = row.currency;
1658
+ }
1659
+ for (const r of byKey.values()) r.lifetime = r.pending + r.processing + r.paidOut;
1660
+ return [...byKey.values()];
1661
+ }
1662
+ /** One recipient's wallet — a thin `summary` over `{ recipientId, … }`. */
1663
+ async recipientBalance(recipientId, options = {}, ctx = {}) {
1664
+ const filter = { recipientId };
1665
+ if (options.recipientType !== void 0) filter.recipientType = options.recipientType;
1666
+ if (options.currency !== void 0) filter.currency = options.currency;
1667
+ const s = await this.summary(filter, ctx);
1668
+ return {
1669
+ recipientId,
1670
+ ...s,
1671
+ currency: options.currency ?? s.currency
1672
+ };
1673
+ }
1565
1674
  };
1566
1675
 
1567
1676
  //#endregion
@@ -1,2 +1,2 @@
1
- import { A as SplitInfo, B as validateTaxCalculation, C as multiplyMoney, D as toCurrencyCode, E as sumMoney, F as TaxConfig, H as calculateCommission, I as TaxType, L as calculateTax, M as calculateOrganizationPayout, N as calculateSplits, O as toMajor, P as TaxCalculation, R as getTaxType, S as money, T as subtractMoney, U as reverseCommission, V as CommissionInfo, _ as isMoney, a as CurrencyCode, b as isZeroMoney, c as Money, d as addMoney, f as compareMoney, g as isCurrencyCode, h as fromSmallestUnit, i as CURRENCIES, j as SplitRule, k as toSmallestUnit, l as MoneyValue, m as fromMajor, n as getAuditTrail, o as CurrencyMismatchError, p as equalsMoney, r as getLastStateChange, s as MINOR_UNIT_FACTOR, t as appendAuditEvent, u as absMoney, v as isNegativeMoney, w as negateMoney, x as minorUnitFactor, y as isPositiveMoney, z as reverseTax } from "../audit-DRKuLBFO.mjs";
2
- export { CURRENCIES, CommissionInfo, type CurrencyCode, CurrencyMismatchError, MINOR_UNIT_FACTOR, type Money, type MoneyValue, SplitInfo, SplitRule, TaxCalculation, TaxConfig, TaxType, absMoney, addMoney, appendAuditEvent, calculateCommission, calculateOrganizationPayout, calculateSplits, calculateTax, compareMoney, equalsMoney, fromMajor, fromSmallestUnit, getAuditTrail, getLastStateChange, getTaxType, isCurrencyCode, isMoney, isNegativeMoney, isPositiveMoney, isZeroMoney, minorUnitFactor, money, multiplyMoney, negateMoney, reverseCommission, reverseTax, subtractMoney, sumMoney, toCurrencyCode, toMajor, toSmallestUnit, validateTaxCalculation };
1
+ import { A as SplitInfo, B as reverseTax, C as multiplyMoney, D as toCurrencyCode, E as sumMoney, F as TaxCalculation, H as CommissionInfo, I as TaxConfig, L as TaxType, M as calculateOrganizationPayout, N as calculateSplits, O as toMajor, P as reverseSplits, R as calculateTax, S as money, T as subtractMoney, U as calculateCommission, V as validateTaxCalculation, W as reverseCommission, _ as isMoney, a as CurrencyCode, b as isZeroMoney, c as Money, d as addMoney, f as compareMoney, g as isCurrencyCode, h as fromSmallestUnit, i as CURRENCIES, j as SplitRule, k as toSmallestUnit, l as MoneyValue, m as fromMajor, n as getAuditTrail, o as CurrencyMismatchError, p as equalsMoney, r as getLastStateChange, s as MINOR_UNIT_FACTOR, t as appendAuditEvent, u as absMoney, v as isNegativeMoney, w as negateMoney, x as minorUnitFactor, y as isPositiveMoney, z as getTaxType } from "../audit-BkDdPSed.mjs";
2
+ export { CURRENCIES, CommissionInfo, type CurrencyCode, CurrencyMismatchError, MINOR_UNIT_FACTOR, type Money, type MoneyValue, SplitInfo, SplitRule, TaxCalculation, TaxConfig, TaxType, absMoney, addMoney, appendAuditEvent, calculateCommission, calculateOrganizationPayout, calculateSplits, calculateTax, compareMoney, equalsMoney, fromMajor, fromSmallestUnit, getAuditTrail, getLastStateChange, getTaxType, isCurrencyCode, isMoney, isNegativeMoney, isPositiveMoney, isZeroMoney, minorUnitFactor, money, multiplyMoney, negateMoney, reverseCommission, reverseSplits, reverseTax, subtractMoney, sumMoney, toCurrencyCode, toMajor, toSmallestUnit, validateTaxCalculation };
@@ -1,4 +1,4 @@
1
- import { a as reverseTax, c as reverseCommission, i as getTaxType, n as calculateSplits, o as validateTaxCalculation, r as calculateTax, s as calculateCommission, t as calculateOrganizationPayout } from "../splits-CNfQj92L.mjs";
1
+ import { a as getTaxType, c as calculateCommission, i as calculateTax, l as reverseCommission, n as calculateSplits, o as reverseTax, r as reverseSplits, s as validateTaxCalculation, t as calculateOrganizationPayout } from "../splits-CEdZN6OT.mjs";
2
2
  import { C as sumMoney, E as toSmallestUnit, S as subtractMoney, T as toMajor, _ as isZeroMoney, a as CurrencyMismatchError, b as multiplyMoney, c as addMoney, d as fromMajor, f as fromSmallestUnit, g as isPositiveMoney, h as isNegativeMoney, i as CURRENCIES, l as compareMoney, m as isMoney, n as getAuditTrail, o as MINOR_UNIT_FACTOR, p as isCurrencyCode, r as getLastStateChange, s as absMoney, t as appendAuditEvent, u as equalsMoney, v as minorUnitFactor, w as toCurrencyCode, x as negateMoney, y as money } from "../audit-Ba2XB2C4.mjs";
3
3
 
4
- export { CURRENCIES, CurrencyMismatchError, MINOR_UNIT_FACTOR, absMoney, addMoney, appendAuditEvent, calculateCommission, calculateOrganizationPayout, calculateSplits, calculateTax, compareMoney, equalsMoney, fromMajor, fromSmallestUnit, getAuditTrail, getLastStateChange, getTaxType, isCurrencyCode, isMoney, isNegativeMoney, isPositiveMoney, isZeroMoney, minorUnitFactor, money, multiplyMoney, negateMoney, reverseCommission, reverseTax, subtractMoney, sumMoney, toCurrencyCode, toMajor, toSmallestUnit, validateTaxCalculation };
4
+ export { CURRENCIES, CurrencyMismatchError, MINOR_UNIT_FACTOR, absMoney, addMoney, appendAuditEvent, calculateCommission, calculateOrganizationPayout, calculateSplits, calculateTax, compareMoney, equalsMoney, fromMajor, fromSmallestUnit, getAuditTrail, getLastStateChange, getTaxType, isCurrencyCode, isMoney, isNegativeMoney, isPositiveMoney, isZeroMoney, minorUnitFactor, money, multiplyMoney, negateMoney, reverseCommission, reverseSplits, reverseTax, subtractMoney, sumMoney, toCurrencyCode, toMajor, toSmallestUnit, validateTaxCalculation };
@@ -1,3 +1,5 @@
1
+ import { g as ValidationError } from "./errors-Bt5NRVMq.mjs";
2
+
1
3
  //#region src/shared/calculators/commission.ts
2
4
  function calculateCommission(amount, commissionRate, gatewayFeeRate = 0) {
3
5
  if (!commissionRate || commissionRate <= 0) return null;
@@ -17,9 +19,9 @@ function calculateCommission(amount, commissionRate, gatewayFeeRate = 0) {
17
19
  }
18
20
  function reverseCommission(originalCommission, originalAmount, refundAmount) {
19
21
  if (!originalCommission?.netAmount) return null;
20
- if (!originalAmount || originalAmount <= 0) throw new Error("Original amount must be greater than 0");
21
- if (refundAmount < 0) throw new Error("Refund amount cannot be negative");
22
- if (refundAmount > originalAmount) throw new Error("Refund amount exceeds original amount");
22
+ if (!originalAmount || originalAmount <= 0) throw new ValidationError("Original amount must be greater than 0");
23
+ if (refundAmount < 0) throw new ValidationError("Refund amount cannot be negative");
24
+ if (refundAmount > originalAmount) throw new ValidationError("Refund amount exceeds original amount");
23
25
  const refundRatio = refundAmount / originalAmount;
24
26
  return {
25
27
  rate: originalCommission.rate,
@@ -74,9 +76,9 @@ function reverseTax(originalTax, originalAmount, refundAmount) {
74
76
  totalAmount: refundAmount,
75
77
  pricesIncludeTax: false
76
78
  };
77
- if (!originalAmount || originalAmount <= 0) throw new Error("Original amount must be greater than 0");
78
- if (refundAmount < 0) throw new Error("Refund amount cannot be negative");
79
- if (refundAmount > originalAmount) throw new Error("Refund amount exceeds original amount");
79
+ if (!originalAmount || originalAmount <= 0) throw new ValidationError("Original amount must be greater than 0");
80
+ if (refundAmount < 0) throw new ValidationError("Refund amount cannot be negative");
81
+ if (refundAmount > originalAmount) throw new ValidationError("Refund amount exceeds original amount");
80
82
  const refundRatio = refundAmount / originalAmount;
81
83
  const reversedType = originalTax.type ? originalTax.type === "collected" ? "paid" : originalTax.type === "paid" ? "collected" : "exempt" : void 0;
82
84
  return {
@@ -118,6 +120,19 @@ function calculateSplits(amount, rules, gatewayFeeRate = 0) {
118
120
  function calculateOrganizationPayout(amount, splits) {
119
121
  return amount - splits.reduce((sum, s) => sum + s.grossAmount, 0);
120
122
  }
123
+ function reverseSplits(originalSplits, originalAmount, refundAmount) {
124
+ if (!originalAmount || originalAmount <= 0) throw new ValidationError("Original amount must be greater than 0");
125
+ if (refundAmount < 0) throw new ValidationError("Refund amount cannot be negative");
126
+ if (refundAmount > originalAmount) throw new ValidationError("Refund amount exceeds original amount");
127
+ const refundRatio = refundAmount / originalAmount;
128
+ return originalSplits.map((s) => ({
129
+ ...s,
130
+ grossAmount: Math.round(s.grossAmount * refundRatio),
131
+ gatewayFeeAmount: Math.round(s.gatewayFeeAmount * refundRatio),
132
+ netAmount: Math.round(s.netAmount * refundRatio),
133
+ status: "waived"
134
+ }));
135
+ }
121
136
 
122
137
  //#endregion
123
- export { reverseTax as a, reverseCommission as c, getTaxType as i, calculateSplits as n, validateTaxCalculation as o, calculateTax as r, calculateCommission as s, calculateOrganizationPayout as t };
138
+ export { getTaxType as a, calculateCommission as c, calculateTax as i, reverseCommission as l, calculateSplits as n, reverseTax as o, reverseSplits as r, validateTaxCalculation as s, calculateOrganizationPayout as t };
@@ -1,4 +1,4 @@
1
- import { A as transactionBaseSchema, C as subscriptionBaseSchema, D as TransactionCreateInput, E as subscriptionUpdateSchema, M as transactionListFilterSchema, N as transactionUpdateSchema, O as TransactionListFilter, S as SubscriptionUpdateInput, T as subscriptionListFilterSchema, _ as settlementCreateSchema, a as escrowReleaseSchema, b as SubscriptionCreateInput, c as PaymentVerifyInput, d as paymentVerifySchema, f as refundSchema, g as settlementBaseSchema, h as SettlementUpdateInput, i as escrowHoldSchema, j as transactionCreateSchema, k as TransactionUpdateInput, l as RefundInput, m as SettlementListFilter, n as EscrowReleaseInput, o as splitRuleSchema, p as SettlementCreateInput, r as SplitRuleInput, s as PaymentIntentInput, t as EscrowHoldInput, u as paymentIntentSchema, v as settlementListFilterSchema, w as subscriptionCreateSchema, x as SubscriptionListFilter, y as settlementUpdateSchema } from "../escrow.schema-Cklvlywy.mjs";
1
+ import { A as transactionBaseSchema, C as subscriptionBaseSchema, D as TransactionCreateInput, E as subscriptionUpdateSchema, M as transactionListFilterSchema, N as transactionUpdateSchema, O as TransactionListFilter, S as SubscriptionUpdateInput, T as subscriptionListFilterSchema, _ as settlementCreateSchema, a as escrowReleaseSchema, b as SubscriptionCreateInput, c as PaymentVerifyInput, d as paymentVerifySchema, f as refundSchema, g as settlementBaseSchema, h as SettlementUpdateInput, i as escrowHoldSchema, j as transactionCreateSchema, k as TransactionUpdateInput, l as RefundInput, m as SettlementListFilter, n as EscrowReleaseInput, o as splitRuleSchema, p as SettlementCreateInput, r as SplitRuleInput, s as PaymentIntentInput, t as EscrowHoldInput, u as paymentIntentSchema, v as settlementListFilterSchema, w as subscriptionCreateSchema, x as SubscriptionListFilter, y as settlementUpdateSchema } from "../escrow.schema-DSx7EywJ.mjs";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region src/validators/bank-feed.schema.d.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classytic/revenue",
3
- "version": "2.4.0",
3
+ "version": "2.6.0",
4
4
  "description": "Payment lifecycle engine — transactions, subscriptions, escrow, settlements, commissions. MongoKit-powered, Arc-compatible, framework-agnostic.",
5
5
  "type": "module",
6
6
  "sideEffects": false,