@fantastic.dev/better-stripe 0.20.1 → 0.22.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.
Files changed (73) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +16 -5
  3. package/dist/client/connect/payoutExecution.d.ts +34 -0
  4. package/dist/client/connect/payoutExecution.d.ts.map +1 -0
  5. package/dist/client/connect/payoutExecution.js +189 -0
  6. package/dist/client/connect/payoutExecution.js.map +1 -0
  7. package/dist/client/connect/payoutHistory.d.ts +22 -0
  8. package/dist/client/connect/payoutHistory.d.ts.map +1 -0
  9. package/dist/client/connect/payoutHistory.js +122 -0
  10. package/dist/client/connect/payoutHistory.js.map +1 -0
  11. package/dist/client/connect/payoutReceipt.d.ts +53 -0
  12. package/dist/client/connect/payoutReceipt.d.ts.map +1 -0
  13. package/dist/client/connect/payoutReceipt.js +185 -0
  14. package/dist/client/connect/payoutReceipt.js.map +1 -0
  15. package/dist/client/connect/payoutReconciliation.d.ts +38 -0
  16. package/dist/client/connect/payoutReconciliation.d.ts.map +1 -0
  17. package/dist/client/connect/payoutReconciliation.js +112 -0
  18. package/dist/client/connect/payoutReconciliation.js.map +1 -0
  19. package/dist/client/payoutPolicy.d.ts +9 -0
  20. package/dist/client/payoutPolicy.d.ts.map +1 -1
  21. package/dist/client/payoutPolicy.js +12 -0
  22. package/dist/client/payoutPolicy.js.map +1 -1
  23. package/dist/component/_generated/component.d.ts +112 -0
  24. package/dist/component/_generated/component.d.ts.map +1 -1
  25. package/dist/component/earnings/triggers.d.ts +52 -2
  26. package/dist/component/earnings/triggers.d.ts.map +1 -1
  27. package/dist/component/payoutRelease/allocation.d.ts +1 -0
  28. package/dist/component/payoutRelease/allocation.d.ts.map +1 -1
  29. package/dist/component/payoutRelease/allocation.js +3 -0
  30. package/dist/component/payoutRelease/allocation.js.map +1 -1
  31. package/dist/component/payoutRelease/fees.d.ts +22 -0
  32. package/dist/component/payoutRelease/fees.d.ts.map +1 -0
  33. package/dist/component/payoutRelease/fees.js +73 -0
  34. package/dist/component/payoutRelease/fees.js.map +1 -0
  35. package/dist/component/payoutRelease/helpers.d.ts +5 -0
  36. package/dist/component/payoutRelease/helpers.d.ts.map +1 -1
  37. package/dist/component/payoutRelease/mutations.d.ts +29 -0
  38. package/dist/component/payoutRelease/mutations.d.ts.map +1 -1
  39. package/dist/component/payoutRelease/mutations.js +24 -1
  40. package/dist/component/payoutRelease/mutations.js.map +1 -1
  41. package/dist/component/payoutRelease/queries.d.ts +87 -0
  42. package/dist/component/payoutRelease/queries.d.ts.map +1 -1
  43. package/dist/component/payoutRelease/queries.js +39 -0
  44. package/dist/component/payoutRelease/queries.js.map +1 -1
  45. package/dist/component/payoutRelease/schema.d.ts +43 -2
  46. package/dist/component/payoutRelease/schema.d.ts.map +1 -1
  47. package/dist/component/payoutRelease/schema.js +12 -0
  48. package/dist/component/payoutRelease/schema.js.map +1 -1
  49. package/dist/component/schema.d.ts +27 -1
  50. package/dist/component/schema.js +2 -1
  51. package/dist/component/schema.js.map +1 -1
  52. package/docs/settlement.md +134 -3
  53. package/package.json +1 -1
  54. package/src/client/connect/payoutAllocation.test.ts +36 -3
  55. package/src/client/connect/payoutExecution.test.ts +504 -0
  56. package/src/client/connect/payoutExecution.ts +265 -0
  57. package/src/client/connect/payoutHistory.test.ts +145 -0
  58. package/src/client/connect/payoutHistory.ts +149 -0
  59. package/src/client/connect/payoutReceipt.test.ts +312 -0
  60. package/src/client/connect/payoutReceipt.ts +287 -0
  61. package/src/client/connect/payoutReconciliation.test.ts +398 -0
  62. package/src/client/connect/payoutReconciliation.ts +178 -0
  63. package/src/client/payoutPolicy.ts +30 -0
  64. package/src/component/_generated/api.ts +2 -0
  65. package/src/component/_generated/component.ts +118 -0
  66. package/src/component/payout-fees.test.ts +224 -0
  67. package/src/component/payout-release-snapshot.test.ts +57 -0
  68. package/src/component/payoutRelease/allocation.ts +6 -0
  69. package/src/component/payoutRelease/fees.ts +93 -0
  70. package/src/component/payoutRelease/mutations.ts +26 -1
  71. package/src/component/payoutRelease/queries.ts +46 -0
  72. package/src/component/payoutRelease/schema.ts +13 -0
  73. package/src/component/schema.ts +2 -0
package/CHANGELOG.md CHANGED
@@ -14,6 +14,18 @@
14
14
  - Remove internal tracker references from public documentation and add a
15
15
  regression check that prevents their reintroduction.
16
16
 
17
+ ## [0.22.0](https://github.com/FantasticDevHQ/better-stripe/compare/v0.21.0...v0.22.0) (2026-10-15)
18
+
19
+ ### Features
20
+
21
+ - **payouts:** qualify and execute combined recipient releases ([#189](https://github.com/FantasticDevHQ/better-stripe/issues/189)) ([08f4cec](https://github.com/FantasticDevHQ/better-stripe/commit/08f4cecf004635caa42255d4171206e35bda181c))
22
+
23
+ ## [0.21.0](https://github.com/FantasticDevHQ/better-stripe/compare/v0.20.1...v0.21.0) (2026-10-15)
24
+
25
+ ### Features
26
+
27
+ - **payouts:** reconcile verified payout outcomes and fees ([#187](https://github.com/FantasticDevHQ/better-stripe/issues/187)) ([7f14edb](https://github.com/FantasticDevHQ/better-stripe/commit/7f14edb93dcc2c7808f1e3e3f3a8dbe2ff84ad3d))
28
+
17
29
  ## [0.20.1](https://github.com/FantasticDevHQ/better-stripe/compare/v0.20.0...v0.20.1) (2026-10-15)
18
30
 
19
31
  ### Documentation
package/README.md CHANGED
@@ -42,14 +42,18 @@ deadline-expiry API. See [policy setup and limits](docs/settlement.md#recipient-
42
42
  A [recipient funding reader](docs/settlement.md#verified-recipient-funding-receipts)
43
43
  verifies original and reversal receipts, maturity, and exact settlement amounts;
44
44
  received credit is kept distinct from still-unpaid entitlement.
45
- The component also has an internal transactional claim ledger for reservations
46
- and paid allocations. Automatic combined release and adoption of existing
47
- balances still require the separate release boundary; schedule controls and
48
- claim primitives alone do not enforce a minimum.
45
+ A [payout receipt and reconciliation API](docs/settlement.md#verified-payout-receipts-and-reconciliation)
46
+ verifies actual bank-payout debits and returns, adopts an attempted claim's
47
+ provider outcome, and books its net payout fees once.
48
+ The [combined release API](docs/settlement.md#combined-recipient-release) verifies
49
+ complete source and payout history, reserves mature unpaid funds, and creates an
50
+ idempotent bank payout. Install a host job to invoke it and expire due policies.
51
+ Existing unallocated balances, larger histories and other debit allocations still
52
+ require migration; schedule controls alone do not enforce a minimum.
49
53
 
50
54
  ## Status
51
55
 
52
- **Version**: `0.20.1` <!-- x-release-please-version --> (pre-1.0). API may change between minor versions until 1.0.
56
+ **Version**: `0.22.0` <!-- x-release-please-version --> (pre-1.0). API may change between minor versions until 1.0.
53
57
 
54
58
  Used in production by its authors. Webhook pipeline is covered by unit tests and a live E2E harness (`npm run e2e:webhooks`) that fires real Stripe-signed events and asserts the ledger.
55
59
 
@@ -131,6 +135,13 @@ existing integration to this API version.
131
135
 
132
136
  The component ships committed Convex codegen output at `src/component/_generated/{api,component,dataModel,server}.ts` — consumers reach the bindings via the `./_generated/component` subpath export. The example app also commits its own codegen at `example/convex/_generated/`. Running `pnpm dev` (which wraps `convex dev`) regenerates these automatically when the schema or function definitions change, but only against the live dev deployment and only while the dev server is watching.
133
137
 
138
+ The example resolves the workspace package through `dist/`. After changing
139
+ component source, regenerate library bindings with `pnpm codegen:lib`, run
140
+ `pnpm build`, then deploy the rebuilt component from the example directory with
141
+ `pnpm exec convex dev --once`. Run `pnpm codegen:example` afterward. Code generation
142
+ alone does not prove that a newly added function is mounted; invoke a representative
143
+ query or action against the development deployment before running financial tests.
144
+
134
145
  If you add, remove, or rename a query/mutation/action on a branch without the dev server watching — or after a rebase — regenerate explicitly before committing:
135
146
 
136
147
  ```bash
@@ -0,0 +1,34 @@
1
+ import type Stripe from "stripe";
2
+ import type { Infer } from "convex/values";
3
+ import type { Component, RunCtx } from "../helpers.js";
4
+ import type { policyDoc } from "../../component/payoutPolicy/schema.js";
5
+ import { type PayoutReconciliation } from "./payoutReconciliation.js";
6
+ type Policy = Infer<typeof policyDoc>;
7
+ export type PayoutReleaseOptions = {
8
+ accountId: string;
9
+ ownerKey: string;
10
+ operationKey: string;
11
+ currency: string;
12
+ /** Host supplies all authorized off-provider debts/reserves, without double counting provider receipt debits. */
13
+ independentLiabilities: number;
14
+ maxPages?: number;
15
+ };
16
+ type Held = {
17
+ status: "held";
18
+ reason: string;
19
+ };
20
+ export type PayoutReleaseResult = PayoutReconciliation | Held;
21
+ /**
22
+ * Complete receipt qualification followed by an atomic claim and one immutable
23
+ * provider request. Host authorizes the recipient, policy, operation and known
24
+ * off-provider liabilities. Attempted operations only reconcile on subsequent
25
+ * calls; they are never blindly recreated after an unknown provider outcome.
26
+ */
27
+ export declare function releaseRecipientPayout(stripe: Stripe, component: Component, ctx: RunCtx, opts: PayoutReleaseOptions, verify: () => Promise<{
28
+ status: "verified";
29
+ policy: Policy;
30
+ } | {
31
+ status: string;
32
+ }>): Promise<PayoutReleaseResult>;
33
+ export {};
34
+ //# sourceMappingURL=payoutExecution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payoutExecution.d.ts","sourceRoot":"","sources":["../../../src/client/connect/payoutExecution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAKvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAUxE,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,2BAA2B,CAAC;AAEnC,KAAK,MAAM,GAAG,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AACtC,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,iHAAiH;IACjH,sBAAsB,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AACF,KAAK,IAAI,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/C,MAAM,MAAM,mBAAmB,GAAG,oBAAoB,GAAG,IAAI,CAAC;AAQ9D;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACpB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,oBAAoB,EAC1B,MAAM,EAAE,MAAM,OAAO,CACnB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAC5D,GACA,OAAO,CAAC,mBAAmB,CAAC,CAiN9B"}
@@ -0,0 +1,189 @@
1
+ import { runMutationOrThrow } from "../helpers.js";
2
+ import { componentRef } from "../webhooks/helpers.js";
3
+ import { transferFingerprint, validateIdentity, } from "../../component/payoutRelease/helpers.js";
4
+ import { getTransferFundingReceipt, } from "./transferReceipt.js";
5
+ import { verifyPayoutHistory } from "./payoutHistory.js";
6
+ import { reconcileRecipientPayout, } from "./payoutReconciliation.js";
7
+ /**
8
+ * Complete receipt qualification followed by an atomic claim and one immutable
9
+ * provider request. Host authorizes the recipient, policy, operation and known
10
+ * off-provider liabilities. Attempted operations only reconcile on subsequent
11
+ * calls; they are never blindly recreated after an unknown provider outcome.
12
+ */
13
+ export async function releaseRecipientPayout(stripe, component, ctx, opts, verify) {
14
+ validateIdentity(opts);
15
+ if (!/^[a-z]{3}$/.test(opts.currency) ||
16
+ !Number.isSafeInteger(opts.independentLiabilities) ||
17
+ opts.independentLiabilities < 0)
18
+ throw new Error("Invalid payout currency or independent liabilities.");
19
+ const maxPages = opts.maxPages ?? 10;
20
+ if (!Number.isInteger(maxPages) || maxPages < 1 || maxPages > 100)
21
+ throw new Error("Payout page budget must be between 1 and 100.");
22
+ if (!ctx.runMutation)
23
+ throw new Error("Payout release requires runMutation.");
24
+ const identity = {
25
+ accountId: opts.accountId,
26
+ ownerKey: opts.ownerKey,
27
+ operationKey: opts.operationKey,
28
+ };
29
+ const existing = (await ctx.runQuery(componentRef(component, "payoutRelease/queries/get"), identity));
30
+ if (existing) {
31
+ if (existing.currency !== opts.currency)
32
+ throw new Error("Payout claim currency cannot be changed.");
33
+ if (existing.attemptedAt !== undefined || existing.status !== "reserved")
34
+ return reconcileRecipientPayout(stripe, component, ctx, {
35
+ ...identity,
36
+ maxPages,
37
+ });
38
+ // A crash before the attempt has no provider side effect. Release its exact
39
+ // reservations; the next scheduled operation must collect fresh receipts.
40
+ const claim = (await runMutationOrThrow(ctx, componentRef(component, "payoutRelease/mutations/cancelUnattempted"), identity));
41
+ return { status: "terminal", claim };
42
+ }
43
+ const controls = await verify();
44
+ if (controls.status !== "verified" || !("policy" in controls))
45
+ return { status: "held", reason: controls.status };
46
+ const snapshot = (await ctx.runQuery(componentRef(component, "payoutRelease/queries/snapshot"), { accountId: opts.accountId, ownerKey: opts.ownerKey }));
47
+ if (snapshot.status !== "ready")
48
+ return snapshot;
49
+ const banks = [];
50
+ let bankCursor;
51
+ for (let page = 0;; page++) {
52
+ if (page >= maxPages)
53
+ return { status: "held", reason: "bank_history_incomplete" };
54
+ const batch = await stripe.accounts.listExternalAccounts(opts.accountId, {
55
+ object: "bank_account",
56
+ limit: 100,
57
+ ...(bankCursor ? { starting_after: bankCursor } : {}),
58
+ });
59
+ for (const bank of batch.data)
60
+ if (bank.object === "bank_account" &&
61
+ bank.currency === opts.currency &&
62
+ bank.default_for_currency &&
63
+ bank.status !== "errored")
64
+ banks.push(bank.id);
65
+ if (!batch.has_more)
66
+ break;
67
+ const next = batch.data[batch.data.length - 1]?.id;
68
+ if (!next || next === bankCursor)
69
+ return { status: "held", reason: "bank_history_incomplete" };
70
+ bankCursor = next;
71
+ }
72
+ if (banks.length !== 1 || !/^ba_\w+$/.test(banks[0]))
73
+ return { status: "held", reason: "bank_destination_unavailable" };
74
+ const destinationId = banks[0];
75
+ const transactions = [];
76
+ for (const claim of snapshot.claims) {
77
+ if (claim.currency !== opts.currency ||
78
+ claim.status === "canceled" ||
79
+ claim.status === "rejected")
80
+ continue;
81
+ if (claim.attemptedAt === undefined)
82
+ return { status: "held", reason: "pending_claim" };
83
+ const result = await reconcileRecipientPayout(stripe, component, ctx, {
84
+ accountId: opts.accountId,
85
+ ownerKey: opts.ownerKey,
86
+ operationKey: claim.operationKey,
87
+ maxPages,
88
+ });
89
+ if (result.status !== "updated")
90
+ return result;
91
+ for (const t of [result.receipt.debit, result.receipt.credit])
92
+ if (t)
93
+ transactions.push({ ...t, sourceId: result.receipt.stripePayoutId });
94
+ }
95
+ const observations = [];
96
+ for (const row of snapshot.transfers) {
97
+ const receipt = await getTransferFundingReceipt(stripe, component, ctx, {
98
+ accountId: opts.accountId,
99
+ stripeTransferId: row.stripeTransferId,
100
+ });
101
+ if (receipt.status !== "ready")
102
+ return { status: "held", reason: receipt.reason };
103
+ observations.push({
104
+ stripeTransferId: row.stripeTransferId,
105
+ currency: receipt.settlementCurrency,
106
+ matureNet: receipt.matureNet,
107
+ pendingCredits: receipt.pendingCredits,
108
+ ledgerFingerprint: transferFingerprint(row),
109
+ observedAt: receipt.observedAt,
110
+ transactionIds: receipt.transactions.map((t) => t.id),
111
+ });
112
+ if (receipt.settlementCurrency === opts.currency)
113
+ transactions.push(...receipt.transactions);
114
+ }
115
+ const history = await verifyPayoutHistory(stripe, {
116
+ accountId: opts.accountId,
117
+ currency: opts.currency,
118
+ transactions,
119
+ maxPages,
120
+ });
121
+ if (history.status !== "verified")
122
+ return history;
123
+ const claim = (await runMutationOrThrow(ctx, componentRef(component, "payoutRelease/mutations/claim"), {
124
+ ...identity,
125
+ expectedRevision: controls.policy.revision,
126
+ currency: opts.currency,
127
+ destinationId,
128
+ providerAvailable: history.providerAvailable,
129
+ independentLiabilities: opts.independentLiabilities,
130
+ observations,
131
+ }));
132
+ if (claim.status === "held")
133
+ return claim;
134
+ // Another caller can win this operation while receipts were being collected.
135
+ if (claim.attemptedAt !== undefined || claim.status !== "reserved")
136
+ return reconcileRecipientPayout(stripe, component, ctx, {
137
+ ...identity,
138
+ maxPages,
139
+ });
140
+ const latest = await verify();
141
+ if (latest.status !== "verified" ||
142
+ !("policy" in latest) ||
143
+ latest.policy.revision !== controls.policy.revision) {
144
+ await runMutationOrThrow(ctx, componentRef(component, "payoutRelease/mutations/cancelUnattempted"), identity);
145
+ return {
146
+ status: "held",
147
+ reason: latest.status === "verified" ? "policy_changed" : latest.status,
148
+ };
149
+ }
150
+ await runMutationOrThrow(ctx, componentRef(component, "payoutRelease/mutations/beginAttempt"), identity);
151
+ let payout;
152
+ try {
153
+ payout = await stripe.payouts.create({
154
+ amount: claim.amount,
155
+ currency: claim.currency,
156
+ destination: claim.destinationId,
157
+ method: "standard",
158
+ source_type: "card",
159
+ metadata: { bsPayoutClaim: claim.operationKey },
160
+ }, {
161
+ stripeAccount: claim.accountId,
162
+ idempotencyKey: `bs:payout-release:${claim.operationKey}`,
163
+ });
164
+ }
165
+ catch (error) {
166
+ if (error instanceof Error &&
167
+ "type" in error &&
168
+ error.type === "StripeInvalidRequestError" &&
169
+ "code" in error &&
170
+ ["balance_insufficient", "amount_too_small"].includes(String(error.code)) &&
171
+ "requestId" in error &&
172
+ typeof error.requestId === "string" &&
173
+ /^req_\w+$/.test(error.requestId)) {
174
+ const saved = (await runMutationOrThrow(ctx, componentRef(component, "payoutRelease/mutations/recordRejection"), {
175
+ ...identity,
176
+ requestId: error.requestId,
177
+ code: error.code,
178
+ }));
179
+ return { status: "terminal", claim: saved };
180
+ }
181
+ throw error;
182
+ }
183
+ return reconcileRecipientPayout(stripe, component, ctx, {
184
+ ...identity,
185
+ stripePayoutId: payout.id,
186
+ maxPages,
187
+ });
188
+ }
189
+ //# sourceMappingURL=payoutExecution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payoutExecution.js","sourceRoot":"","sources":["../../../src/client/connect/payoutExecution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type Stripe from "stripe";
2
+ import type { TransferReceiptTransaction } from "./transferReceipt.js";
3
+ export type PayoutHistoryVerification = {
4
+ status: "verified";
5
+ providerAvailable: number;
6
+ observedAt: number;
7
+ } | {
8
+ status: "held";
9
+ reason: "unallocated_history" | "history_changed" | "history_incomplete" | "balance_changed";
10
+ };
11
+ /**
12
+ * Verify a complete currency history against independently verified transfer and
13
+ * payout receipts. Unknown debits AND credits require explicit allocation. A
14
+ * current balance alone never establishes still-unpaid source ownership.
15
+ */
16
+ export declare function verifyPayoutHistory(stripe: Stripe, opts: {
17
+ accountId: string;
18
+ currency: string;
19
+ transactions: TransferReceiptTransaction[];
20
+ maxPages?: number;
21
+ }): Promise<PayoutHistoryVerification>;
22
+ //# sourceMappingURL=payoutHistory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payoutHistory.d.ts","sourceRoot":"","sources":["../../../src/client/connect/payoutHistory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAEvE,MAAM,MAAM,yBAAyB,GACjC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACrE;IACE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EACF,qBAAqB,GACrB,iBAAiB,GACjB,oBAAoB,GACpB,iBAAiB,CAAC;CACvB,CAAC;AA+BN;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IACJ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,0BAA0B,EAAE,CAAC;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,OAAO,CAAC,yBAAyB,CAAC,CA4FpC"}
@@ -0,0 +1,122 @@
1
+ import { addSummaryAmounts as add } from "../../component/earnings/arithmetic.js";
2
+ function fingerprint(t) {
3
+ return JSON.stringify([
4
+ t.id,
5
+ t.sourceId,
6
+ t.amount,
7
+ t.fee,
8
+ t.net,
9
+ t.currency,
10
+ t.created,
11
+ t.availableOn,
12
+ t.status,
13
+ t.type,
14
+ ]);
15
+ }
16
+ function normalize(t) {
17
+ if (t.status !== "available" && t.status !== "pending")
18
+ throw new Error("Invalid provider receipt status.");
19
+ return {
20
+ id: t.id,
21
+ sourceId: typeof t.source === "string" ? t.source : (t.source?.id ?? ""),
22
+ amount: t.amount,
23
+ fee: t.fee,
24
+ net: t.net,
25
+ currency: t.currency,
26
+ created: t.created,
27
+ availableOn: t.available_on,
28
+ status: t.status,
29
+ type: t.type,
30
+ };
31
+ }
32
+ /**
33
+ * Verify a complete currency history against independently verified transfer and
34
+ * payout receipts. Unknown debits AND credits require explicit allocation. A
35
+ * current balance alone never establishes still-unpaid source ownership.
36
+ */
37
+ export async function verifyPayoutHistory(stripe, opts) {
38
+ const maxPages = opts.maxPages ?? 10;
39
+ if (!Number.isInteger(maxPages) || maxPages < 1 || maxPages > 100)
40
+ throw new Error("History page budget must be between 1 and 100.");
41
+ if (!/^acct_\w+$/.test(opts.accountId) || !/^[a-z]{3}$/.test(opts.currency))
42
+ throw new Error("Invalid payout history scope.");
43
+ const expected = new Map();
44
+ for (const t of opts.transactions) {
45
+ if (expected.has(t.id))
46
+ throw new Error("Duplicate payout history receipt.");
47
+ if (t.currency !== opts.currency ||
48
+ !/^txn_\w+$/.test(t.id) ||
49
+ !t.sourceId ||
50
+ [t.amount, t.fee, t.net, t.created, t.availableOn].some((n) => !Number.isSafeInteger(n)) ||
51
+ t.net !== add(t.amount, -t.fee))
52
+ throw new Error("Invalid payout history receipt.");
53
+ expected.set(t.id, fingerprint(t));
54
+ }
55
+ const scope = { stripeAccount: opts.accountId };
56
+ const seen = new Set();
57
+ let cursor, head;
58
+ let available = 0, pending = 0, complete = false;
59
+ const held = (reason) => ({ status: "held", reason });
60
+ for (let page = 0; page < maxPages; page++) {
61
+ const batch = await stripe.balanceTransactions.list({
62
+ currency: opts.currency,
63
+ limit: 100,
64
+ ...(cursor ? { starting_after: cursor } : {}),
65
+ }, scope);
66
+ if (page === 0 && batch.data[0])
67
+ head = fingerprint(normalize(batch.data[0]));
68
+ for (const raw of batch.data) {
69
+ const t = normalize(raw);
70
+ if (seen.has(t.id))
71
+ return held("history_incomplete");
72
+ seen.add(t.id);
73
+ if (!expected.has(t.id))
74
+ return held("unallocated_history");
75
+ if (fingerprint(t) !== expected.get(t.id))
76
+ return held("history_changed");
77
+ if (t.status === "available")
78
+ available = add(available, t.net);
79
+ else if (t.status === "pending")
80
+ pending = add(pending, t.net);
81
+ else
82
+ return held("history_changed");
83
+ }
84
+ if (!batch.has_more) {
85
+ complete = true;
86
+ break;
87
+ }
88
+ const next = batch.data[batch.data.length - 1]?.id;
89
+ if (!next || next === cursor)
90
+ return held("history_incomplete");
91
+ cursor = next;
92
+ }
93
+ if (!complete)
94
+ return held("history_incomplete");
95
+ if (seen.size !== expected.size)
96
+ return held("history_changed");
97
+ const balance = await stripe.balance.retrieve(undefined, scope);
98
+ const latest = await stripe.balanceTransactions.list({ currency: opts.currency, limit: 1 }, scope);
99
+ const latestHead = latest.data[0]
100
+ ? fingerprint(normalize(latest.data[0]))
101
+ : undefined;
102
+ if (latestHead !== head)
103
+ return held("history_changed");
104
+ const entries = (rows) => rows.filter((t) => t.currency === opts.currency);
105
+ const a = entries(balance.available), p = entries(balance.pending);
106
+ if (a.length > 1 ||
107
+ p.length > 1 ||
108
+ (a[0]?.amount ?? 0) !== available ||
109
+ (p[0]?.amount ?? 0) !== pending)
110
+ return held("balance_changed");
111
+ // The durable payout request explicitly draws from card balance. Other rails
112
+ // cannot increase this cap even if they contribute to aggregate availability.
113
+ const card = a[0]?.source_types?.card ?? 0;
114
+ if (!Number.isSafeInteger(card))
115
+ throw new Error("Invalid provider card balance.");
116
+ return {
117
+ status: "verified",
118
+ providerAvailable: Math.min(available, card),
119
+ observedAt: Date.now(),
120
+ };
121
+ }
122
+ //# sourceMappingURL=payoutHistory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payoutHistory.js","sourceRoot":"","sources":["../../../src/client/connect/payoutHistory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type Stripe from "stripe";
2
+ import type { PayoutStatus } from "../../component/connect/validators.js";
3
+ export type RecipientPayoutReceiptOptions = {
4
+ accountId: string;
5
+ stripePayoutId: string;
6
+ /** Required when adopting a provider payout into a previously attempted claim. */
7
+ operationKey?: string;
8
+ };
9
+ export type PayoutReceiptTransaction = {
10
+ id: string;
11
+ amount: number;
12
+ fee: number;
13
+ net: number;
14
+ currency: string;
15
+ status: "available" | "pending";
16
+ created: number;
17
+ availableOn: number;
18
+ type: string;
19
+ };
20
+ export type RecipientPayoutReceipt = {
21
+ status: "not_ready";
22
+ accountId: string;
23
+ stripePayoutId: string;
24
+ reason: "debit_unavailable" | "debit_pending" | "return_unavailable" | "return_pending" | "provider_changed" | "reversal_allocation_required" | "currency_allocation_required";
25
+ } | {
26
+ status: "ready";
27
+ accountId: string;
28
+ stripePayoutId: string;
29
+ operationKey?: string;
30
+ amount: number;
31
+ currency: string;
32
+ providerStatus: PayoutStatus;
33
+ automatic: boolean;
34
+ method: string;
35
+ type: string;
36
+ sourceType: string;
37
+ destinationId: string;
38
+ created: number;
39
+ arrivalDate: number;
40
+ debit: PayoutReceiptTransaction;
41
+ credit?: PayoutReceiptTransaction;
42
+ returnedPrincipal: number;
43
+ returnedNet: number;
44
+ observedAt: number;
45
+ };
46
+ /**
47
+ * Read-only provider receipts, not unpaid entitlement or authorization to release
48
+ * a reservation. Fees remain separate from principal and must be accounted for
49
+ * by the payout/recovery ledger. Manual payout receipts do not identify the
50
+ * original transfers that funded them. Host authorizes access to this account.
51
+ */
52
+ export declare function getRecipientPayoutReceipt(stripe: Stripe, options: RecipientPayoutReceiptOptions): Promise<RecipientPayoutReceipt>;
53
+ //# sourceMappingURL=payoutReceipt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payoutReceipt.d.ts","sourceRoot":"","sources":["../../../src/client/connect/payoutReceipt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,MAAM,MAAM,6BAA6B,GAAG;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,kFAAkF;IAClF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AACF,MAAM,MAAM,wBAAwB,GAAG;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AACF,MAAM,MAAM,sBAAsB,GAC9B;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EACF,mBAAmB,GACnB,eAAe,GACf,oBAAoB,GACpB,gBAAgB,GAChB,kBAAkB,GAClB,8BAA8B,GAC9B,8BAA8B,CAAC;CACpC,GACD;IACE,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,YAAY,CAAC;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,wBAAwB,CAAC;IAChC,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAClC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAqFN;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,sBAAsB,CAAC,CA2IjC"}