@fantastic.dev/better-stripe 0.23.2 → 0.25.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 (358) hide show
  1. package/CHANGELOG.md +27 -2
  2. package/README.md +46 -5
  3. package/dist/client/affiliateRecovery/disputes.d.ts +18 -0
  4. package/dist/client/affiliateRecovery/disputes.d.ts.map +1 -0
  5. package/dist/client/affiliateRecovery/disputes.js +33 -0
  6. package/dist/client/affiliateRecovery/disputes.js.map +1 -0
  7. package/dist/client/affiliateRecovery/engine.d.ts +29 -0
  8. package/dist/client/affiliateRecovery/engine.d.ts.map +1 -0
  9. package/dist/client/affiliateRecovery/engine.js +116 -0
  10. package/dist/client/affiliateRecovery/engine.js.map +1 -0
  11. package/dist/client/affiliateRecovery/payoutGate.d.ts +24 -0
  12. package/dist/client/affiliateRecovery/payoutGate.d.ts.map +1 -0
  13. package/dist/client/affiliateRecovery/payoutGate.js +30 -0
  14. package/dist/client/affiliateRecovery/payoutGate.js.map +1 -0
  15. package/dist/client/affiliateRecovery/provider.d.ts +14 -0
  16. package/dist/client/affiliateRecovery/provider.d.ts.map +1 -0
  17. package/dist/client/affiliateRecovery/provider.js +96 -0
  18. package/dist/client/affiliateRecovery/provider.js.map +1 -0
  19. package/dist/client/affiliateRecovery/review.d.ts +28 -0
  20. package/dist/client/affiliateRecovery/review.d.ts.map +1 -0
  21. package/dist/client/affiliateRecovery/review.js +86 -0
  22. package/dist/client/affiliateRecovery/review.js.map +1 -0
  23. package/dist/client/affiliateRecovery/validators.d.ts +402 -0
  24. package/dist/client/affiliateRecovery/validators.d.ts.map +1 -0
  25. package/dist/client/affiliateRecovery/validators.js +27 -0
  26. package/dist/client/affiliateRecovery/validators.js.map +1 -0
  27. package/dist/client/affiliateRecovery.d.ts +131 -0
  28. package/dist/client/affiliateRecovery.d.ts.map +1 -0
  29. package/dist/client/affiliateRecovery.js +69 -0
  30. package/dist/client/affiliateRecovery.js.map +1 -0
  31. package/dist/client/billing/checkout.d.ts +3 -43
  32. package/dist/client/billing/checkout.d.ts.map +1 -1
  33. package/dist/client/billing/checkout.js +5 -260
  34. package/dist/client/billing/checkout.js.map +1 -1
  35. package/dist/client/billing/checkoutRequest.d.ts +129 -0
  36. package/dist/client/billing/checkoutRequest.d.ts.map +1 -0
  37. package/dist/client/billing/checkoutRequest.js +263 -0
  38. package/dist/client/billing/checkoutRequest.js.map +1 -0
  39. package/dist/client/billing/preparedCheckout.d.ts +22 -0
  40. package/dist/client/billing/preparedCheckout.d.ts.map +1 -0
  41. package/dist/client/billing/preparedCheckout.js +86 -0
  42. package/dist/client/billing/preparedCheckout.js.map +1 -0
  43. package/dist/client/checkoutRequests.d.ts +80 -0
  44. package/dist/client/checkoutRequests.d.ts.map +1 -0
  45. package/dist/client/checkoutRequests.js +28 -0
  46. package/dist/client/checkoutRequests.js.map +1 -0
  47. package/dist/client/connect/commissionReceipts.d.ts +4 -0
  48. package/dist/client/connect/commissionReceipts.d.ts.map +1 -0
  49. package/dist/client/connect/commissionReceipts.js +17 -0
  50. package/dist/client/connect/commissionReceipts.js.map +1 -0
  51. package/dist/client/connect/payoutAdoptionTestHelpers.d.ts +958 -2
  52. package/dist/client/connect/payoutAdoptionTestHelpers.d.ts.map +1 -1
  53. package/dist/client/connect/payoutCollection.d.ts +21 -0
  54. package/dist/client/connect/payoutCollection.d.ts.map +1 -0
  55. package/dist/client/connect/payoutCollection.js +47 -0
  56. package/dist/client/connect/payoutCollection.js.map +1 -0
  57. package/dist/client/connect/payoutExecutionTestHelpers.d.ts +1805 -0
  58. package/dist/client/connect/payoutExecutionTestHelpers.d.ts.map +1 -0
  59. package/dist/client/connect/payoutExecutionTestHelpers.js +194 -0
  60. package/dist/client/connect/payoutExecutionTestHelpers.js.map +1 -0
  61. package/dist/client/connect/payoutSyncTestHelpers.d.ts +479 -1
  62. package/dist/client/connect/payoutSyncTestHelpers.d.ts.map +1 -1
  63. package/dist/client/connect/payoutWorker.d.ts +48 -0
  64. package/dist/client/connect/payoutWorker.d.ts.map +1 -0
  65. package/dist/client/connect/payoutWorker.js +78 -0
  66. package/dist/client/connect/payoutWorker.js.map +1 -0
  67. package/dist/client/connect/payouts.d.ts +3 -1
  68. package/dist/client/connect/payouts.d.ts.map +1 -1
  69. package/dist/client/connect/payouts.js +45 -12
  70. package/dist/client/connect/payouts.js.map +1 -1
  71. package/dist/client/connect/refundPrincipal.d.ts +4 -0
  72. package/dist/client/connect/refundPrincipal.d.ts.map +1 -0
  73. package/dist/client/connect/refundPrincipal.js +21 -0
  74. package/dist/client/connect/refundPrincipal.js.map +1 -0
  75. package/dist/client/connect/reversalExecution.d.ts +47 -0
  76. package/dist/client/connect/reversalExecution.d.ts.map +1 -0
  77. package/dist/client/connect/reversalExecution.js +84 -0
  78. package/dist/client/connect/reversalExecution.js.map +1 -0
  79. package/dist/client/connect/transfers.d.ts +8 -4
  80. package/dist/client/connect/transfers.d.ts.map +1 -1
  81. package/dist/client/connect/transfers.js +52 -57
  82. package/dist/client/connect/transfers.js.map +1 -1
  83. package/dist/client/index.d.ts +7 -11
  84. package/dist/client/index.d.ts.map +1 -1
  85. package/dist/client/index.js +10 -10
  86. package/dist/client/index.js.map +1 -1
  87. package/dist/client/payoutPolicy.d.ts +67 -0
  88. package/dist/client/payoutPolicy.d.ts.map +1 -1
  89. package/dist/client/payoutPolicy.js +10 -0
  90. package/dist/client/payoutPolicy.js.map +1 -1
  91. package/dist/client/readContracts.d.ts +11 -1
  92. package/dist/client/readContracts.d.ts.map +1 -1
  93. package/dist/client/readContracts.js +10 -0
  94. package/dist/client/readContracts.js.map +1 -1
  95. package/dist/client/settlement/execution.d.ts.map +1 -1
  96. package/dist/client/settlement/execution.js +30 -3
  97. package/dist/client/settlement/execution.js.map +1 -1
  98. package/dist/client/settlement/reconciliation.d.ts.map +1 -1
  99. package/dist/client/settlement/reconciliation.js +16 -2
  100. package/dist/client/settlement/reconciliation.js.map +1 -1
  101. package/dist/client/webhooks/disputeRecovery.d.ts +4 -0
  102. package/dist/client/webhooks/disputeRecovery.d.ts.map +1 -0
  103. package/dist/client/webhooks/disputeRecovery.js +40 -0
  104. package/dist/client/webhooks/disputeRecovery.js.map +1 -0
  105. package/dist/client/webhooks/processors.d.ts.map +1 -1
  106. package/dist/client/webhooks/processors.js +14 -29
  107. package/dist/client/webhooks/processors.js.map +1 -1
  108. package/dist/component/_generated/component.d.ts +784 -0
  109. package/dist/component/_generated/component.d.ts.map +1 -1
  110. package/dist/component/affiliateEarnings/mutations.d.ts +22 -0
  111. package/dist/component/affiliateEarnings/mutations.d.ts.map +1 -0
  112. package/dist/component/affiliateEarnings/mutations.js +160 -0
  113. package/dist/component/affiliateEarnings/mutations.js.map +1 -0
  114. package/dist/component/affiliatePayouts/mutations.d.ts +25 -0
  115. package/dist/component/affiliatePayouts/mutations.d.ts.map +1 -0
  116. package/dist/component/affiliatePayouts/mutations.js +104 -0
  117. package/dist/component/affiliatePayouts/mutations.js.map +1 -0
  118. package/dist/component/affiliatePayouts/queries.d.ts +23 -0
  119. package/dist/component/affiliatePayouts/queries.d.ts.map +1 -0
  120. package/dist/component/affiliatePayouts/queries.js +23 -0
  121. package/dist/component/affiliatePayouts/queries.js.map +1 -0
  122. package/dist/component/affiliatePayouts/recipientGuard.d.ts +12 -0
  123. package/dist/component/affiliatePayouts/recipientGuard.d.ts.map +1 -0
  124. package/dist/component/affiliatePayouts/recipientGuard.js +26 -0
  125. package/dist/component/affiliatePayouts/recipientGuard.js.map +1 -0
  126. package/dist/component/affiliateRecovery/accounting.d.ts +28 -0
  127. package/dist/component/affiliateRecovery/accounting.d.ts.map +1 -0
  128. package/dist/component/affiliateRecovery/accounting.js +71 -0
  129. package/dist/component/affiliateRecovery/accounting.js.map +1 -0
  130. package/dist/component/affiliateRecovery/mutations.d.ts +65 -0
  131. package/dist/component/affiliateRecovery/mutations.d.ts.map +1 -0
  132. package/dist/component/affiliateRecovery/mutations.js +250 -0
  133. package/dist/component/affiliateRecovery/mutations.js.map +1 -0
  134. package/dist/component/affiliateRecovery/queries.d.ts +305 -0
  135. package/dist/component/affiliateRecovery/queries.d.ts.map +1 -0
  136. package/dist/component/affiliateRecovery/queries.js +113 -0
  137. package/dist/component/affiliateRecovery/queries.js.map +1 -0
  138. package/dist/component/affiliateRecovery/schema.d.ts +171 -0
  139. package/dist/component/affiliateRecovery/schema.d.ts.map +1 -0
  140. package/dist/component/affiliateRecovery/schema.js +71 -0
  141. package/dist/component/affiliateRecovery/schema.js.map +1 -0
  142. package/dist/component/connect/mutations.d.ts +36 -23
  143. package/dist/component/connect/mutations.d.ts.map +1 -1
  144. package/dist/component/connect/mutations.js +7 -124
  145. package/dist/component/connect/mutations.js.map +1 -1
  146. package/dist/component/connect/queries.d.ts +10 -0
  147. package/dist/component/connect/queries.d.ts.map +1 -1
  148. package/dist/component/connect/queries.js +3 -40
  149. package/dist/component/connect/queries.js.map +1 -1
  150. package/dist/component/connect/reversalClaims.d.ts +169 -0
  151. package/dist/component/connect/reversalClaims.d.ts.map +1 -0
  152. package/dist/component/connect/reversalClaims.js +176 -0
  153. package/dist/component/connect/reversalClaims.js.map +1 -0
  154. package/dist/component/connect/reversalDiagnostics.d.ts +59 -0
  155. package/dist/component/connect/reversalDiagnostics.d.ts.map +1 -0
  156. package/dist/component/connect/reversalDiagnostics.js +50 -0
  157. package/dist/component/connect/reversalDiagnostics.js.map +1 -0
  158. package/dist/component/connect/reversalReceipts.d.ts +27 -0
  159. package/dist/component/connect/reversalReceipts.d.ts.map +1 -0
  160. package/dist/component/connect/reversalReceipts.js +85 -0
  161. package/dist/component/connect/reversalReceipts.js.map +1 -0
  162. package/dist/component/connect/schema.d.ts +31 -1
  163. package/dist/component/connect/schema.d.ts.map +1 -1
  164. package/dist/component/connect/schema.js +3 -1
  165. package/dist/component/connect/schema.js.map +1 -1
  166. package/dist/component/connect/validators.d.ts +49 -1
  167. package/dist/component/connect/validators.d.ts.map +1 -1
  168. package/dist/component/connect/validators.js +2 -0
  169. package/dist/component/connect/validators.js.map +1 -1
  170. package/dist/component/core/mutations.d.ts.map +1 -1
  171. package/dist/component/core/mutations.js +2 -0
  172. package/dist/component/core/mutations.js.map +1 -1
  173. package/dist/component/core/resetSafety.d.ts +4 -0
  174. package/dist/component/core/resetSafety.d.ts.map +1 -0
  175. package/dist/component/core/resetSafety.js +54 -0
  176. package/dist/component/core/resetSafety.js.map +1 -0
  177. package/dist/component/earnings/triggers.d.ts +828 -2
  178. package/dist/component/earnings/triggers.d.ts.map +1 -1
  179. package/dist/component/earnings/triggers.js +2 -0
  180. package/dist/component/earnings/triggers.js.map +1 -1
  181. package/dist/component/payoutPolicy/schema.d.ts +2 -0
  182. package/dist/component/payoutPolicy/schema.d.ts.map +1 -1
  183. package/dist/component/payoutPolicy/schema.js +3 -1
  184. package/dist/component/payoutPolicy/schema.js.map +1 -1
  185. package/dist/component/payoutRelease/mutations.d.ts.map +1 -1
  186. package/dist/component/payoutRelease/mutations.js +7 -1
  187. package/dist/component/payoutRelease/mutations.js.map +1 -1
  188. package/dist/component/payoutRelease/queries.d.ts.map +1 -1
  189. package/dist/component/payoutRelease/queries.js +3 -1
  190. package/dist/component/payoutRelease/queries.js.map +1 -1
  191. package/dist/component/payoutRelease/schema.d.ts +1 -0
  192. package/dist/component/payoutRelease/schema.d.ts.map +1 -1
  193. package/dist/component/payoutRelease/schema.js +1 -0
  194. package/dist/component/payoutRelease/schema.js.map +1 -1
  195. package/dist/component/payoutSnapshots/localState.d.ts +89 -0
  196. package/dist/component/payoutSnapshots/localState.d.ts.map +1 -0
  197. package/dist/component/payoutSnapshots/localState.js +186 -0
  198. package/dist/component/payoutSnapshots/localState.js.map +1 -0
  199. package/dist/component/payoutSnapshots/mutations.d.ts +108 -0
  200. package/dist/component/payoutSnapshots/mutations.d.ts.map +1 -0
  201. package/dist/component/payoutSnapshots/mutations.js +263 -0
  202. package/dist/component/payoutSnapshots/mutations.js.map +1 -0
  203. package/dist/component/payoutSnapshots/revisions.d.ts +12 -0
  204. package/dist/component/payoutSnapshots/revisions.d.ts.map +1 -0
  205. package/dist/component/payoutSnapshots/revisions.js +173 -0
  206. package/dist/component/payoutSnapshots/revisions.js.map +1 -0
  207. package/dist/component/payoutSnapshots/schema.d.ts +285 -0
  208. package/dist/component/payoutSnapshots/schema.d.ts.map +1 -0
  209. package/dist/component/payoutSnapshots/schema.js +108 -0
  210. package/dist/component/payoutSnapshots/schema.js.map +1 -0
  211. package/dist/component/payoutSnapshots/scope.d.ts +7 -0
  212. package/dist/component/payoutSnapshots/scope.d.ts.map +1 -0
  213. package/dist/component/payoutSnapshots/scope.js +8 -0
  214. package/dist/component/payoutSnapshots/scope.js.map +1 -0
  215. package/dist/component/payoutWorker/helpers.d.ts +30 -0
  216. package/dist/component/payoutWorker/helpers.d.ts.map +1 -0
  217. package/dist/component/payoutWorker/helpers.js +21 -0
  218. package/dist/component/payoutWorker/helpers.js.map +1 -0
  219. package/dist/component/payoutWorker/mutations.d.ts +68 -0
  220. package/dist/component/payoutWorker/mutations.d.ts.map +1 -0
  221. package/dist/component/payoutWorker/mutations.js +161 -0
  222. package/dist/component/payoutWorker/mutations.js.map +1 -0
  223. package/dist/component/payoutWorker/queries.d.ts +123 -0
  224. package/dist/component/payoutWorker/queries.d.ts.map +1 -0
  225. package/dist/component/payoutWorker/queries.js +61 -0
  226. package/dist/component/payoutWorker/queries.js.map +1 -0
  227. package/dist/component/payoutWorker/schema.d.ts +91 -0
  228. package/dist/component/payoutWorker/schema.d.ts.map +1 -0
  229. package/dist/component/payoutWorker/schema.js +27 -0
  230. package/dist/component/payoutWorker/schema.js.map +1 -0
  231. package/dist/component/schema.d.ts +479 -1
  232. package/dist/component/schema.js +19 -0
  233. package/dist/component/schema.js.map +1 -1
  234. package/dist/component/settlement/clawbackSchema.d.ts +161 -0
  235. package/dist/component/settlement/clawbackSchema.d.ts.map +1 -0
  236. package/dist/component/settlement/clawbackSchema.js +73 -0
  237. package/dist/component/settlement/clawbackSchema.js.map +1 -0
  238. package/dist/component/settlement/clawbacks.d.ts +55 -0
  239. package/dist/component/settlement/clawbacks.d.ts.map +1 -0
  240. package/dist/component/settlement/clawbacks.js +146 -0
  241. package/dist/component/settlement/clawbacks.js.map +1 -0
  242. package/dist/component/settlement/mutations.d.ts +16 -0
  243. package/dist/component/settlement/mutations.d.ts.map +1 -1
  244. package/dist/component/settlement/mutations.js +48 -0
  245. package/dist/component/settlement/mutations.js.map +1 -1
  246. package/dist/component/settlement/queries.d.ts +53 -0
  247. package/dist/component/settlement/queries.d.ts.map +1 -1
  248. package/dist/component/settlement/queries.js +26 -0
  249. package/dist/component/settlement/queries.js.map +1 -1
  250. package/dist/react/workflows/AffiliateRecovery.d.ts +46 -0
  251. package/dist/react/workflows/AffiliateRecovery.d.ts.map +1 -0
  252. package/dist/react/workflows/AffiliateRecovery.js +84 -0
  253. package/dist/react/workflows/AffiliateRecovery.js.map +1 -0
  254. package/dist/react/workflows/index.d.ts +2 -0
  255. package/dist/react/workflows/index.d.ts.map +1 -1
  256. package/dist/react/workflows/index.js +1 -0
  257. package/dist/react/workflows/index.js.map +1 -1
  258. package/dist/testing/affiliate-recovery.d.ts +10 -0
  259. package/dist/testing/affiliate-recovery.d.ts.map +1 -0
  260. package/dist/testing/affiliate-recovery.js +126 -0
  261. package/dist/testing/affiliate-recovery.js.map +1 -0
  262. package/dist/testing/index.d.ts +2 -0
  263. package/dist/testing/index.d.ts.map +1 -1
  264. package/dist/testing/index.js +1 -0
  265. package/dist/testing/index.js.map +1 -1
  266. package/docs/affiliate-clawbacks.md +306 -0
  267. package/docs/read-contracts.md +48 -0
  268. package/docs/settlement.md +145 -1
  269. package/package.json +2 -1
  270. package/src/client/affiliateRecovery/disputes.ts +62 -0
  271. package/src/client/affiliateRecovery/engine.ts +196 -0
  272. package/src/client/affiliateRecovery/payoutGate.ts +65 -0
  273. package/src/client/affiliateRecovery/provider.ts +127 -0
  274. package/src/client/affiliateRecovery/review.ts +117 -0
  275. package/src/client/affiliateRecovery/validators.ts +38 -0
  276. package/src/client/affiliateRecovery.ts +173 -0
  277. package/src/client/billing/checkout.ts +11 -359
  278. package/src/client/billing/checkoutRequest.ts +362 -0
  279. package/src/client/billing/prepared-checkout.test.ts +430 -0
  280. package/src/client/billing/preparedCheckout.ts +143 -0
  281. package/src/client/checkoutRequests.ts +40 -0
  282. package/src/client/connect/commissionReceipts.test.ts +157 -0
  283. package/src/client/connect/commissionReceipts.ts +23 -0
  284. package/src/client/connect/payoutCollection.test.ts +74 -0
  285. package/src/client/connect/payoutCollection.ts +82 -0
  286. package/src/client/connect/payoutExecution.test.ts +1 -211
  287. package/src/client/connect/payoutExecutionTestHelpers.ts +213 -0
  288. package/src/client/connect/payoutWorker.test.ts +145 -0
  289. package/src/client/connect/payoutWorker.ts +144 -0
  290. package/src/client/connect/payouts.ts +75 -15
  291. package/src/client/connect/refundPrincipal.test.ts +46 -0
  292. package/src/client/connect/refundPrincipal.ts +26 -0
  293. package/src/client/connect/reversalExecution.ts +130 -0
  294. package/src/client/connect/transfers.test.ts +3 -3
  295. package/src/client/connect/transfers.ts +93 -92
  296. package/src/client/index.ts +16 -28
  297. package/src/client/payoutPolicy.ts +26 -1
  298. package/src/client/readContracts.ts +23 -0
  299. package/src/client/settlement/execution.test.ts +5 -0
  300. package/src/client/settlement/execution.ts +50 -3
  301. package/src/client/settlement/reconciliation.ts +20 -2
  302. package/src/client/webhooks/disputeRecovery.ts +74 -0
  303. package/src/client/webhooks/processors.test.ts +36 -53
  304. package/src/client/webhooks/processors.ts +18 -31
  305. package/src/component/_generated/api.ts +40 -0
  306. package/src/component/_generated/component.ts +975 -1
  307. package/src/component/affiliate-clawbacks.test.ts +370 -0
  308. package/src/component/affiliate-component-pagination.test.ts +83 -0
  309. package/src/component/affiliate-direct-payout.test.ts +160 -0
  310. package/src/component/affiliate-recovery-lifecycle.test.ts +587 -0
  311. package/src/component/affiliateEarnings/mutations.ts +196 -0
  312. package/src/component/affiliatePayouts/mutations.ts +121 -0
  313. package/src/component/affiliatePayouts/queries.ts +28 -0
  314. package/src/component/affiliatePayouts/recipientGuard.ts +42 -0
  315. package/src/component/affiliateRecovery/accounting.ts +111 -0
  316. package/src/component/affiliateRecovery/mutations.ts +275 -0
  317. package/src/component/affiliateRecovery/queries.ts +138 -0
  318. package/src/component/affiliateRecovery/schema.ts +86 -0
  319. package/src/component/connect/mutations.ts +9 -160
  320. package/src/component/connect/queries.ts +4 -47
  321. package/src/component/connect/reversalClaims.ts +232 -0
  322. package/src/component/connect/reversalDiagnostics.ts +61 -0
  323. package/src/component/connect/reversalReceipts.ts +147 -0
  324. package/src/component/connect/schema.ts +3 -3
  325. package/src/component/connect/validators.ts +2 -0
  326. package/src/component/core/mutations.ts +2 -0
  327. package/src/component/core/resetSafety.ts +67 -0
  328. package/src/component/earnings/triggers.ts +2 -0
  329. package/src/component/payout-recovery-integration.test.ts +172 -0
  330. package/src/component/payout-reset-safety.test.ts +148 -0
  331. package/src/component/payout-revisions.test.ts +125 -0
  332. package/src/component/payout-snapshots.test.ts +395 -0
  333. package/src/component/payout-worker.test.ts +165 -0
  334. package/src/component/payoutPolicy/schema.ts +3 -1
  335. package/src/component/payoutRelease/mutations.ts +10 -1
  336. package/src/component/payoutRelease/queries.ts +3 -1
  337. package/src/component/payoutRelease/schema.ts +1 -0
  338. package/src/component/payoutSnapshots/localState.ts +238 -0
  339. package/src/component/payoutSnapshots/mutations.ts +275 -0
  340. package/src/component/payoutSnapshots/revisions.ts +247 -0
  341. package/src/component/payoutSnapshots/schema.ts +125 -0
  342. package/src/component/payoutSnapshots/scope.ts +7 -0
  343. package/src/component/payoutWorker/helpers.ts +30 -0
  344. package/src/component/payoutWorker/mutations.ts +181 -0
  345. package/src/component/payoutWorker/queries.ts +64 -0
  346. package/src/component/payoutWorker/schema.ts +26 -0
  347. package/src/component/public.test.ts +2 -2
  348. package/src/component/schema.ts +36 -0
  349. package/src/component/settlement/clawbackSchema.ts +78 -0
  350. package/src/component/settlement/clawbacks.ts +233 -0
  351. package/src/component/settlement/mutations.ts +54 -0
  352. package/src/component/settlement/queries.ts +35 -0
  353. package/src/component/summary-arithmetic.test.ts +9 -4
  354. package/src/react/workflows/AffiliateRecovery.test.tsx +106 -0
  355. package/src/react/workflows/AffiliateRecovery.tsx +273 -0
  356. package/src/react/workflows/index.ts +9 -0
  357. package/src/testing/affiliate-recovery.ts +137 -0
  358. package/src/testing/index.ts +2 -0
@@ -0,0 +1,172 @@
1
+ // @vitest-environment edge-runtime
2
+ import { convexTest } from "convex-test";
3
+ import { makeFunctionReference } from "convex/server";
4
+ import { expect, it } from "vitest";
5
+ import schema from "./schema.js";
6
+ import { changeBalance } from "./affiliateRecovery/accounting.js";
7
+ import { transferFingerprint } from "./payoutRelease/helpers.js";
8
+ const modules = import.meta.glob("./**/*.*s");
9
+ const m = (name: string) =>
10
+ makeFunctionReference<"mutation">(`payoutRelease/mutations:${name}`);
11
+ const pm = (name: string) =>
12
+ makeFunctionReference<"mutation">(`payoutPolicy/mutations:${name}`);
13
+ const scope = { accountId: "acct_recipient", ownerKey: "user_1" };
14
+ const transfer = (
15
+ stripeTransferId: string,
16
+ amount: number,
17
+ role = "store",
18
+ ) => ({
19
+ stripeTransferId,
20
+ destinationAccountId: scope.accountId,
21
+ amount,
22
+ currency: "usd",
23
+ status: "paid",
24
+ role,
25
+ });
26
+ async function setup() {
27
+ const t = convexTest(schema, modules);
28
+ await t.mutation(pm("prepare"), {
29
+ ...scope,
30
+ operationKey: "enable",
31
+ expectedRevision: -1,
32
+ mode: "custom",
33
+ thresholds: [{ currency: "usd", amount: 1000 }],
34
+ country: "US",
35
+ observedSchedule: { interval: "daily" },
36
+ });
37
+ await t.mutation(pm("confirm"), {
38
+ ...scope,
39
+ operationKey: "enable",
40
+ observedSchedule: { interval: "manual" },
41
+ });
42
+ for (const row of [
43
+ transfer("tr_creator", 600),
44
+ transfer("tr_affiliate", 400, "affiliate"),
45
+ ])
46
+ await t.mutation(
47
+ makeFunctionReference<"mutation">("connect/mutations:upsertTransfer"),
48
+ row,
49
+ );
50
+ const rows = await t.run(async (ctx) => ctx.db.query("transfers").take(10));
51
+ const args = {
52
+ ...scope,
53
+ operationKey: "release-1",
54
+ expectedRevision: 0,
55
+ currency: "usd",
56
+ providerAvailable: 1000,
57
+ independentLiabilities: 0,
58
+ observations: rows.map((row) => ({
59
+ stripeTransferId: row.stripeTransferId,
60
+ matureNet: row.amount,
61
+ pendingCredits: 0,
62
+ currency: row.currency,
63
+ ledgerFingerprint: transferFingerprint(row),
64
+ observedAt: Date.now(),
65
+ transactionIds: [`txn_${row.stripeTransferId}`],
66
+ })),
67
+ };
68
+ return { t, args };
69
+ }
70
+ it("blocks combined payouts on affiliate debt in the payout currency", async () => {
71
+ const { t, args } = await setup();
72
+ await t.run((ctx) =>
73
+ changeBalance(ctx, scope.accountId, "usd", { outstandingDebt: 100 }),
74
+ );
75
+ await expect(t.mutation(m("claim"), args)).rejects.toThrow(/recovery/);
76
+ expect(
77
+ await t.run((ctx) => ctx.db.query("payoutReleaseClaims").collect()),
78
+ ).toEqual([]);
79
+ expect(
80
+ await t.run((ctx) => ctx.db.query("payoutSourceAllocations").collect()),
81
+ ).toEqual([]);
82
+ });
83
+
84
+ it("keeps independent currency debts out of a verified payout", async () => {
85
+ const { t, args } = await setup();
86
+ await t.run((ctx) =>
87
+ changeBalance(ctx, scope.accountId, "eur", { outstandingDebt: 100 }),
88
+ );
89
+ expect(await t.mutation(m("claim"), args)).toMatchObject({
90
+ status: "reserved",
91
+ amount: 1000,
92
+ });
93
+ });
94
+
95
+ it("shares one reservation between direct and combined payout paths", async () => {
96
+ const { t, args } = await setup();
97
+ await t.run((ctx) => changeBalance(ctx, scope.accountId, "usd", {}));
98
+ const direct = () =>
99
+ t.mutation(
100
+ makeFunctionReference<"mutation">(
101
+ "affiliatePayouts/mutations:reservePayout",
102
+ ),
103
+ {
104
+ affiliateAccountId: scope.accountId,
105
+ currency: "usd",
106
+ amount: 1000,
107
+ minimumAmount: 1,
108
+ operationKey: "direct",
109
+ now: Date.now(),
110
+ },
111
+ );
112
+ const outcomes = await Promise.allSettled([
113
+ t.mutation(m("claim"), args),
114
+ direct(),
115
+ ]);
116
+ expect(
117
+ outcomes.filter((result) => result.status === "fulfilled"),
118
+ ).toHaveLength(1);
119
+ expect(
120
+ outcomes.filter((result) => result.status === "rejected"),
121
+ ).toHaveLength(1);
122
+ });
123
+
124
+ it("rechecks new debt immediately before the provider attempt and permits safe cancellation", async () => {
125
+ const { t, args } = await setup();
126
+ await t.mutation(m("claim"), args);
127
+ await t.run((ctx) =>
128
+ changeBalance(ctx, scope.accountId, "usd", { outstandingDebt: 100 }),
129
+ );
130
+ const identity = { ...scope, operationKey: args.operationKey };
131
+ await expect(t.mutation(m("beginAttempt"), identity)).rejects.toThrow(
132
+ /recovery/,
133
+ );
134
+ await t.mutation(m("cancelUnattempted"), identity);
135
+ expect(
136
+ await t.run((ctx) => ctx.db.query("affiliateRecoveryBalances").first()),
137
+ ).toMatchObject({
138
+ outstandingDebt: 100,
139
+ pendingPayoutAmount: 0,
140
+ });
141
+ });
142
+
143
+ it("holds unknown payout attempts until a verified receipt, without erasing later debt", async () => {
144
+ const { t, args } = await setup();
145
+ await t.mutation(m("claim"), args);
146
+ const identity = { ...scope, operationKey: args.operationKey };
147
+ await t.mutation(m("beginAttempt"), identity);
148
+ await t.run((ctx) =>
149
+ changeBalance(ctx, scope.accountId, "usd", { outstandingDebt: 100 }),
150
+ );
151
+ const before = await t.run((ctx) =>
152
+ ctx.db.query("affiliateRecoveryBalances").first(),
153
+ );
154
+ expect(before?.activePayoutKey).toBe(
155
+ `bs:recipient-payout:${args.operationKey}`,
156
+ );
157
+ await expect(t.mutation(m("cancelUnattempted"), identity)).rejects.toThrow(
158
+ /attempt/,
159
+ );
160
+ await t.mutation(m("recordOutcome"), {
161
+ ...identity,
162
+ stripePayoutId: "po_verified",
163
+ amount: 1000,
164
+ currency: "usd",
165
+ providerStatus: "pending",
166
+ });
167
+ const after = await t.run((ctx) =>
168
+ ctx.db.query("affiliateRecoveryBalances").first(),
169
+ );
170
+ expect(after?.activePayoutKey).toBeUndefined();
171
+ expect(after?.outstandingDebt).toBe(100);
172
+ });
@@ -0,0 +1,148 @@
1
+ // @vitest-environment edge-runtime
2
+ import { convexTest } from "convex-test";
3
+ import { makeFunctionReference } from "convex/server";
4
+ import { expect, it } from "vitest";
5
+ import schema from "./schema.js";
6
+ const modules = import.meta.glob("./**/*.*s");
7
+ const reset = makeFunctionReference<"mutation">(
8
+ "core/mutations:clearAllTables",
9
+ );
10
+ const scope = { accountId: "acct_one", ownerKey: "owner" };
11
+ it.each(["custom", "changing"])(
12
+ "retains restoration records for %s payout policy",
13
+ async (kind) => {
14
+ const t = convexTest(schema, modules);
15
+ await t.run((ctx) =>
16
+ ctx.db.insert("payoutPolicies", {
17
+ ...scope,
18
+ revision: 0,
19
+ mode: kind === "custom" ? "custom" : "stripe_managed",
20
+ status: kind === "changing" ? "changing" : "ready",
21
+ operationKey: "control",
22
+ country: "US",
23
+ thresholds: [],
24
+ previousSchedule: { interval: "weekly", weeklyDays: ["monday"] },
25
+ holdDeadline: Date.now() + 86400000,
26
+ }),
27
+ );
28
+ await expect(t.mutation(reset, {})).rejects.toThrow(/payout.*schedule/i);
29
+ expect(
30
+ await t.run((ctx) => ctx.db.query("payoutPolicies").collect()),
31
+ ).toHaveLength(1);
32
+ },
33
+ );
34
+ it.each(["reserved", "submitted"])(
35
+ "retains an unresolved %s payout claim",
36
+ async (status) => {
37
+ const t = convexTest(schema, modules);
38
+ await t.run((ctx) =>
39
+ ctx.db.insert("payoutReleaseClaims", {
40
+ ...scope,
41
+ operationKey: "money",
42
+ expectedRevision: 0,
43
+ currency: "usd",
44
+ amount: 1000,
45
+ status: status as "reserved" | "submitted",
46
+ allocations: [{ stripeTransferId: "tr_one", amount: 1000 }],
47
+ observations: [],
48
+ attemptedAt: Date.now(),
49
+ }),
50
+ );
51
+ await expect(t.mutation(reset, {})).rejects.toThrow(/payout.*claim/i);
52
+ expect(
53
+ await t.run((ctx) => ctx.db.query("payoutReleaseClaims").collect()),
54
+ ).toHaveLength(1);
55
+ },
56
+ );
57
+ it("retains known in-flight provider payouts", async () => {
58
+ const t = convexTest(schema, modules);
59
+ await t.mutation(
60
+ makeFunctionReference<"mutation">("connect/mutations:upsertPayout"),
61
+ {
62
+ stripePayoutId: "po_one",
63
+ accountId: scope.accountId,
64
+ currency: "usd",
65
+ amount: 1000,
66
+ status: "pending",
67
+ },
68
+ );
69
+ await expect(t.mutation(reset, {})).rejects.toThrow(/in.flight.*payout/i);
70
+ expect(await t.run((ctx) => ctx.db.query("payouts").collect())).toHaveLength(
71
+ 1,
72
+ );
73
+ });
74
+ it("cannot bypass a bound collection through wholesale reset", async () => {
75
+ const t = convexTest(schema, modules);
76
+ const h = await t.mutation(
77
+ makeFunctionReference<"mutation">("payoutSnapshots/mutations:begin"),
78
+ { ...scope, operationKey: "collection", expectedRevision: -1 },
79
+ );
80
+ await t.run((ctx) =>
81
+ ctx.db.patch("payoutSnapshots", h._id, { readOnly: false }),
82
+ );
83
+ await expect(t.mutation(reset, {})).rejects.toThrow(/bound.*collection/i);
84
+ expect(
85
+ await t.run((ctx) => ctx.db.query("payoutSnapshots").collect()),
86
+ ).toHaveLength(1);
87
+ });
88
+ it.each(["pending", "unknown"] as const)(
89
+ "retains %s direct affiliate payout attempts",
90
+ async (state) => {
91
+ const t = convexTest(schema, modules);
92
+ await t.run((ctx) =>
93
+ ctx.db.insert("affiliatePayoutReleases", {
94
+ affiliateAccountId: scope.accountId,
95
+ currency: "usd",
96
+ operationKey: "direct-affiliate",
97
+ amount: 1000,
98
+ minimumAmount: 1,
99
+ createdAt: Date.now(),
100
+ state,
101
+ }),
102
+ );
103
+ await expect(t.mutation(reset, {})).rejects.toThrow(
104
+ /affiliate.*operation/i,
105
+ );
106
+ expect(
107
+ await t.run((ctx) => ctx.db.query("affiliatePayoutReleases").collect()),
108
+ ).toHaveLength(1);
109
+ },
110
+ );
111
+ it.each(["pending", "unknown"] as const)(
112
+ "retains %s affiliate recovery attempts",
113
+ async (state) => {
114
+ const t = convexTest(schema, modules);
115
+ await t.run(async (ctx) => {
116
+ const obligationId = await ctx.db.insert("affiliateObligations", {
117
+ sourceChargeId: "ch_one",
118
+ affiliateAccountId: scope.accountId,
119
+ currency: "usd",
120
+ chargeAmount: 1000,
121
+ originalCommission: 100,
122
+ refundedPrincipal: 1000,
123
+ disputedPrincipal: 0,
124
+ lostPrincipal: 0,
125
+ finalizedAmount: 100,
126
+ provisionalAmount: 0,
127
+ recoveredAmount: 0,
128
+ needsReconciliation: false,
129
+ });
130
+ await ctx.db.insert("affiliateRecoveryOperations", {
131
+ obligationId,
132
+ kind: "recovery",
133
+ amount: 100,
134
+ state,
135
+ attempted: true,
136
+ createdAt: Date.now(),
137
+ });
138
+ });
139
+ await expect(t.mutation(reset, {})).rejects.toThrow(
140
+ /affiliate.*operation/i,
141
+ );
142
+ expect(
143
+ await t.run((ctx) =>
144
+ ctx.db.query("affiliateRecoveryOperations").collect(),
145
+ ),
146
+ ).toHaveLength(1);
147
+ },
148
+ );
@@ -0,0 +1,125 @@
1
+ // @vitest-environment edge-runtime
2
+ import { convexTest } from "convex-test";
3
+ import { makeFunctionReference } from "convex/server";
4
+ import { expect, it } from "vitest";
5
+ import schema from "./schema.js";
6
+ const modules = import.meta.glob("./**/*.*s");
7
+ const m = (name: string) =>
8
+ makeFunctionReference<"mutation">(`connect/mutations:${name}`);
9
+ const transfer = (id = "tr_one", extra = {}) => ({
10
+ stripeTransferId: id,
11
+ destinationAccountId: "acct_one",
12
+ amount: 1000,
13
+ currency: "usd",
14
+ role: "affiliate",
15
+ status: "paid",
16
+ sourceChargeId: "ch_one",
17
+ ...extra,
18
+ });
19
+ const test = () => convexTest(schema, modules);
20
+ const revision = (t: ReturnType<typeof test>, accountId = "acct_one") =>
21
+ t.run((ctx) =>
22
+ ctx.db
23
+ .query("payoutFinancialRevisions")
24
+ .withIndex("by_account", (q) => q.eq("accountId", accountId))
25
+ .unique(),
26
+ );
27
+ it("records new positive funding without invalidating older risk-fenced snapshots", async () => {
28
+ const t = test();
29
+ await t.mutation(m("upsertTransfer"), transfer());
30
+ expect(await revision(t)).toMatchObject({ revision: 1, riskRevision: 0 });
31
+ await t.mutation(m("upsertTransfer"), transfer("tr_two"));
32
+ expect(await revision(t)).toMatchObject({ revision: 2, riskRevision: 0 });
33
+ });
34
+ it("does not invalidate snapshots for replay or metadata-only changes", async () => {
35
+ const t = test();
36
+ await t.mutation(m("upsertTransfer"), transfer());
37
+ await t.mutation(
38
+ m("upsertTransfer"),
39
+ transfer("tr_one", { metadata: { note: "cosmetic" } }),
40
+ );
41
+ expect(await revision(t)).toMatchObject({ revision: 1, riskRevision: 0 });
42
+ });
43
+ it("invalidates risk when a refund/reversal reduces source funding", async () => {
44
+ const t = test();
45
+ await t.mutation(m("upsertTransfer"), transfer());
46
+ await t.mutation(m("recordTransferReversal"), {
47
+ stripeTransferId: "tr_one",
48
+ reversedAmount: 100,
49
+ });
50
+ expect(await revision(t)).toMatchObject({ revision: 2, riskRevision: 1 });
51
+ await t.mutation(m("recordTransferReversal"), {
52
+ stripeTransferId: "tr_one",
53
+ reversedAmount: 100,
54
+ });
55
+ expect(await revision(t)).toMatchObject({ revision: 2, riskRevision: 1 });
56
+ });
57
+ it("reserved reversals invalidate risk before Stripe I/O", async () => {
58
+ const t = test();
59
+ await t.mutation(m("upsertTransfer"), transfer());
60
+ await t.mutation(m("claimReversalSlices"), {
61
+ operationId: "refund-one",
62
+ sourceChargeId: "ch_one",
63
+ mode: { kind: "fraction", chargeAmount: 1000, amountRefunded: 500 },
64
+ });
65
+ expect(await revision(t)).toMatchObject({ revision: 2, riskRevision: 1 });
66
+ });
67
+ it("a moved source invalidates both account scopes", async () => {
68
+ const t = test();
69
+ await t.mutation(m("upsertTransfer"), transfer());
70
+ await t.mutation(
71
+ m("upsertTransfer"),
72
+ transfer("tr_one", { destinationAccountId: "acct_other" }),
73
+ );
74
+ expect(await revision(t)).toMatchObject({ revision: 2, riskRevision: 1 });
75
+ expect(await revision(t, "acct_other")).toMatchObject({
76
+ revision: 1,
77
+ riskRevision: 1,
78
+ });
79
+ });
80
+ it("concurrent independent source inserts cannot lose revision updates", async () => {
81
+ const t = test();
82
+ await Promise.all([
83
+ t.mutation(m("upsertTransfer"), transfer("tr_one")),
84
+ t.mutation(m("upsertTransfer"), transfer("tr_two")),
85
+ ]);
86
+ expect(await revision(t)).toMatchObject({ revision: 2, riskRevision: 0 });
87
+ });
88
+ it("provider payout outcomes invalidate account cash risk", async () => {
89
+ const t = test();
90
+ await t.mutation(m("upsertPayout"), {
91
+ stripePayoutId: "po_one",
92
+ accountId: "acct_one",
93
+ amount: 1000,
94
+ currency: "usd",
95
+ status: "pending",
96
+ arrivalDate: new Date().toISOString(),
97
+ });
98
+ expect(await revision(t)).toMatchObject({ revision: 1, riskRevision: 1 });
99
+ });
100
+ it("records an ordered account risk journal for incremental repair", async () => {
101
+ const t = test();
102
+ await t.mutation(m("upsertTransfer"), transfer());
103
+ await t.mutation(m("recordTransferReversal"), {
104
+ stripeTransferId: "tr_one",
105
+ reversedAmount: 100,
106
+ });
107
+ const events = await t.run((ctx) =>
108
+ ctx.db.query("payoutRiskEvents").collect(),
109
+ );
110
+ expect(events).toMatchObject([
111
+ { accountId: "acct_one", riskRevision: 1, kind: "transfer", key: "tr_one" },
112
+ ]);
113
+ });
114
+ it("positive writes leave the isolated risk fence unchanged", async () => {
115
+ const t = test();
116
+ await t.mutation(m("upsertTransfer"), transfer());
117
+ const first = await t.run((ctx) =>
118
+ ctx.db.query("payoutRiskRevisions").collect(),
119
+ );
120
+ expect(first).toMatchObject([{ accountId: "acct_one", riskRevision: 0 }]);
121
+ await t.mutation(m("upsertTransfer"), transfer("tr_two"));
122
+ expect(
123
+ await t.run((ctx) => ctx.db.query("payoutRiskRevisions").collect()),
124
+ ).toEqual(first);
125
+ });