@fantastic.dev/better-stripe 0.7.0 → 0.8.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 (343) hide show
  1. package/CHANGELOG.md +23 -18
  2. package/README.md +122 -90
  3. package/dist/client/billing/checkout.d.ts +1 -1
  4. package/dist/client/billing/checkout.d.ts.map +1 -1
  5. package/dist/client/billing/checkout.js +7 -2
  6. package/dist/client/billing/checkout.js.map +1 -1
  7. package/dist/client/connect/paymentMethods.d.ts.map +1 -1
  8. package/dist/client/connect/paymentMethods.js.map +1 -1
  9. package/dist/client/connect/refundActor.d.ts.map +1 -1
  10. package/dist/client/connect/refundActor.js.map +1 -1
  11. package/dist/client/connect/refunds.d.ts.map +1 -1
  12. package/dist/client/connect/refunds.js.map +1 -1
  13. package/dist/client/connect/transfers.d.ts.map +1 -1
  14. package/dist/client/connect/transfers.js +15 -4
  15. package/dist/client/connect/transfers.js.map +1 -1
  16. package/dist/client/core/accountDefaults.d.ts +6 -0
  17. package/dist/client/core/accountDefaults.d.ts.map +1 -0
  18. package/dist/client/core/accountDefaults.js +15 -0
  19. package/dist/client/core/accountDefaults.js.map +1 -0
  20. package/dist/client/core/accounts.d.ts +1 -5
  21. package/dist/client/core/accounts.d.ts.map +1 -1
  22. package/dist/client/core/accounts.js +2 -14
  23. package/dist/client/core/accounts.js.map +1 -1
  24. package/dist/client/core/fees.d.ts.map +1 -1
  25. package/dist/client/core/fees.js +7 -2
  26. package/dist/client/core/fees.js.map +1 -1
  27. package/dist/client/index.d.ts +1 -1
  28. package/dist/client/index.d.ts.map +1 -1
  29. package/dist/client/products/prices.d.ts.map +1 -1
  30. package/dist/client/products/prices.js.map +1 -1
  31. package/dist/client/products/products.d.ts.map +1 -1
  32. package/dist/client/products/products.js +3 -1
  33. package/dist/client/products/products.js.map +1 -1
  34. package/dist/client/utils/owner.d.ts.map +1 -1
  35. package/dist/client/utils/owner.js +3 -1
  36. package/dist/client/utils/owner.js.map +1 -1
  37. package/dist/client/utils/stripeDashboardUrl.d.ts.map +1 -1
  38. package/dist/client/utils/stripeDashboardUrl.js.map +1 -1
  39. package/dist/client/webhooks/helpers.d.ts +10 -0
  40. package/dist/client/webhooks/helpers.d.ts.map +1 -1
  41. package/dist/client/webhooks/helpers.js +18 -0
  42. package/dist/client/webhooks/helpers.js.map +1 -1
  43. package/dist/client/webhooks/processors.d.ts.map +1 -1
  44. package/dist/client/webhooks/processors.js +1 -19
  45. package/dist/client/webhooks/processors.js.map +1 -1
  46. package/dist/component/connect/mutations.d.ts.map +1 -1
  47. package/dist/component/connect/mutations.js +4 -33
  48. package/dist/component/connect/mutations.js.map +1 -1
  49. package/dist/component/connect/schema.d.ts.map +1 -1
  50. package/dist/component/connect/schema.js.map +1 -1
  51. package/dist/component/lib/paymentSeller.d.ts +3 -0
  52. package/dist/component/lib/paymentSeller.d.ts.map +1 -0
  53. package/dist/component/lib/paymentSeller.js +10 -0
  54. package/dist/component/lib/paymentSeller.js.map +1 -0
  55. package/dist/component/lib/reversals.d.ts +10 -0
  56. package/dist/component/lib/reversals.d.ts.map +1 -1
  57. package/dist/component/lib/reversals.js +17 -0
  58. package/dist/component/lib/reversals.js.map +1 -1
  59. package/dist/react/components/ConnectProvider.d.ts +1 -1
  60. package/dist/react/components/ConnectProvider.d.ts.map +1 -1
  61. package/dist/react/components/ConnectProvider.js +18 -4
  62. package/dist/react/components/ConnectProvider.js.map +1 -1
  63. package/dist/react/components/ConnectStatusBadge.d.ts.map +1 -1
  64. package/dist/react/components/ConnectStatusBadge.js.map +1 -1
  65. package/dist/react/components/EmbeddedDisputes.d.ts +1 -1
  66. package/dist/react/components/EmbeddedDisputes.d.ts.map +1 -1
  67. package/dist/react/components/EmbeddedDisputes.js +1 -1
  68. package/dist/react/components/EmbeddedDisputes.js.map +1 -1
  69. package/dist/react/components/SplitBreakdown.d.ts.map +1 -1
  70. package/dist/react/components/SplitBreakdown.js +12 -2
  71. package/dist/react/components/SplitBreakdown.js.map +1 -1
  72. package/dist/react/hooks/useCheckoutSession.d.ts.map +1 -1
  73. package/dist/react/hooks/useCheckoutSession.js.map +1 -1
  74. package/dist/react/hooks/useConfirmPayment.d.ts.map +1 -1
  75. package/dist/react/hooks/useConfirmPayment.js.map +1 -1
  76. package/dist/react/index.d.ts +1 -0
  77. package/dist/react/index.d.ts.map +1 -1
  78. package/dist/react/index.js +2 -0
  79. package/dist/react/index.js.map +1 -1
  80. package/dist/react/workflows/Account.d.ts +67 -0
  81. package/dist/react/workflows/Account.d.ts.map +1 -0
  82. package/dist/react/workflows/Account.js +74 -0
  83. package/dist/react/workflows/Account.js.map +1 -0
  84. package/dist/react/workflows/Billing.d.ts +60 -0
  85. package/dist/react/workflows/Billing.d.ts.map +1 -0
  86. package/dist/react/workflows/Billing.js +84 -0
  87. package/dist/react/workflows/Billing.js.map +1 -0
  88. package/dist/react/workflows/BillingPlans.d.ts +45 -0
  89. package/dist/react/workflows/BillingPlans.d.ts.map +1 -0
  90. package/dist/react/workflows/BillingPlans.js +51 -0
  91. package/dist/react/workflows/BillingPlans.js.map +1 -0
  92. package/dist/react/workflows/Checkout.d.ts +46 -0
  93. package/dist/react/workflows/Checkout.d.ts.map +1 -0
  94. package/dist/react/workflows/Checkout.js +61 -0
  95. package/dist/react/workflows/Checkout.js.map +1 -0
  96. package/dist/react/workflows/CheckoutChooser.d.ts +20 -0
  97. package/dist/react/workflows/CheckoutChooser.d.ts.map +1 -0
  98. package/dist/react/workflows/CheckoutChooser.js +24 -0
  99. package/dist/react/workflows/CheckoutChooser.js.map +1 -0
  100. package/dist/react/workflows/CheckoutForms.d.ts +26 -0
  101. package/dist/react/workflows/CheckoutForms.d.ts.map +1 -0
  102. package/dist/react/workflows/CheckoutForms.js +126 -0
  103. package/dist/react/workflows/CheckoutForms.js.map +1 -0
  104. package/dist/react/workflows/ClipboardButton.d.ts +17 -0
  105. package/dist/react/workflows/ClipboardButton.d.ts.map +1 -0
  106. package/dist/react/workflows/ClipboardButton.js +35 -0
  107. package/dist/react/workflows/ClipboardButton.js.map +1 -0
  108. package/dist/react/workflows/Collection.d.ts +30 -0
  109. package/dist/react/workflows/Collection.d.ts.map +1 -0
  110. package/dist/react/workflows/Collection.js +25 -0
  111. package/dist/react/workflows/Collection.js.map +1 -0
  112. package/dist/react/workflows/Collections.d.ts +56 -0
  113. package/dist/react/workflows/Collections.d.ts.map +1 -0
  114. package/dist/react/workflows/Collections.js +111 -0
  115. package/dist/react/workflows/Collections.js.map +1 -0
  116. package/dist/react/workflows/Connect.d.ts +19 -0
  117. package/dist/react/workflows/Connect.d.ts.map +1 -0
  118. package/dist/react/workflows/Connect.js +43 -0
  119. package/dist/react/workflows/Connect.js.map +1 -0
  120. package/dist/react/workflows/Costs.d.ts +48 -0
  121. package/dist/react/workflows/Costs.d.ts.map +1 -0
  122. package/dist/react/workflows/Costs.js +66 -0
  123. package/dist/react/workflows/Costs.js.map +1 -0
  124. package/dist/react/workflows/Disputes.d.ts +36 -0
  125. package/dist/react/workflows/Disputes.d.ts.map +1 -0
  126. package/dist/react/workflows/Disputes.js +74 -0
  127. package/dist/react/workflows/Disputes.js.map +1 -0
  128. package/dist/react/workflows/Earnings.d.ts +42 -0
  129. package/dist/react/workflows/Earnings.d.ts.map +1 -0
  130. package/dist/react/workflows/Earnings.js +38 -0
  131. package/dist/react/workflows/Earnings.js.map +1 -0
  132. package/dist/react/workflows/Financials.d.ts +43 -0
  133. package/dist/react/workflows/Financials.d.ts.map +1 -0
  134. package/dist/react/workflows/Financials.js +57 -0
  135. package/dist/react/workflows/Financials.js.map +1 -0
  136. package/dist/react/workflows/IntegrationSwitch.d.ts +23 -0
  137. package/dist/react/workflows/IntegrationSwitch.d.ts.map +1 -0
  138. package/dist/react/workflows/IntegrationSwitch.js +31 -0
  139. package/dist/react/workflows/IntegrationSwitch.js.map +1 -0
  140. package/dist/react/workflows/Onboarding.d.ts +56 -0
  141. package/dist/react/workflows/Onboarding.d.ts.map +1 -0
  142. package/dist/react/workflows/Onboarding.js +86 -0
  143. package/dist/react/workflows/Onboarding.js.map +1 -0
  144. package/dist/react/workflows/Overview.d.ts +51 -0
  145. package/dist/react/workflows/Overview.d.ts.map +1 -0
  146. package/dist/react/workflows/Overview.js +63 -0
  147. package/dist/react/workflows/Overview.js.map +1 -0
  148. package/dist/react/workflows/PaymentMethods.d.ts +35 -0
  149. package/dist/react/workflows/PaymentMethods.d.ts.map +1 -0
  150. package/dist/react/workflows/PaymentMethods.js +63 -0
  151. package/dist/react/workflows/PaymentMethods.js.map +1 -0
  152. package/dist/react/workflows/PaymentReceipt.d.ts +20 -0
  153. package/dist/react/workflows/PaymentReceipt.d.ts.map +1 -0
  154. package/dist/react/workflows/PaymentReceipt.js +24 -0
  155. package/dist/react/workflows/PaymentReceipt.js.map +1 -0
  156. package/dist/react/workflows/Payouts.d.ts +47 -0
  157. package/dist/react/workflows/Payouts.d.ts.map +1 -0
  158. package/dist/react/workflows/Payouts.js +87 -0
  159. package/dist/react/workflows/Payouts.js.map +1 -0
  160. package/dist/react/workflows/Products.d.ts +92 -0
  161. package/dist/react/workflows/Products.d.ts.map +1 -0
  162. package/dist/react/workflows/Products.js +179 -0
  163. package/dist/react/workflows/Products.js.map +1 -0
  164. package/dist/react/workflows/ReferralLinks.d.ts +26 -0
  165. package/dist/react/workflows/ReferralLinks.d.ts.map +1 -0
  166. package/dist/react/workflows/ReferralLinks.js +30 -0
  167. package/dist/react/workflows/ReferralLinks.js.map +1 -0
  168. package/dist/react/workflows/Refunds.d.ts +72 -0
  169. package/dist/react/workflows/Refunds.d.ts.map +1 -0
  170. package/dist/react/workflows/Refunds.js +95 -0
  171. package/dist/react/workflows/Refunds.js.map +1 -0
  172. package/dist/react/workflows/Setup.d.ts +50 -0
  173. package/dist/react/workflows/Setup.d.ts.map +1 -0
  174. package/dist/react/workflows/Setup.js +59 -0
  175. package/dist/react/workflows/Setup.js.map +1 -0
  176. package/dist/react/workflows/Storefront.d.ts +53 -0
  177. package/dist/react/workflows/Storefront.d.ts.map +1 -0
  178. package/dist/react/workflows/Storefront.js +44 -0
  179. package/dist/react/workflows/Storefront.js.map +1 -0
  180. package/dist/react/workflows/SubscriptionOverview.d.ts +13 -0
  181. package/dist/react/workflows/SubscriptionOverview.d.ts.map +1 -0
  182. package/dist/react/workflows/SubscriptionOverview.js +26 -0
  183. package/dist/react/workflows/SubscriptionOverview.js.map +1 -0
  184. package/dist/react/workflows/Subscriptions.d.ts +92 -0
  185. package/dist/react/workflows/Subscriptions.d.ts.map +1 -0
  186. package/dist/react/workflows/Subscriptions.js +149 -0
  187. package/dist/react/workflows/Subscriptions.js.map +1 -0
  188. package/dist/react/workflows/Tasks.d.ts +40 -0
  189. package/dist/react/workflows/Tasks.d.ts.map +1 -0
  190. package/dist/react/workflows/Tasks.js +113 -0
  191. package/dist/react/workflows/Tasks.js.map +1 -0
  192. package/dist/react/workflows/checkout-options.d.ts +37 -0
  193. package/dist/react/workflows/checkout-options.d.ts.map +1 -0
  194. package/dist/react/workflows/checkout-options.js +43 -0
  195. package/dist/react/workflows/checkout-options.js.map +1 -0
  196. package/dist/react/workflows/current-subscription.d.ts +11 -0
  197. package/dist/react/workflows/current-subscription.d.ts.map +1 -0
  198. package/dist/react/workflows/current-subscription.js +14 -0
  199. package/dist/react/workflows/current-subscription.js.map +1 -0
  200. package/dist/react/workflows/filters.d.ts +17 -0
  201. package/dist/react/workflows/filters.d.ts.map +1 -0
  202. package/dist/react/workflows/filters.js +23 -0
  203. package/dist/react/workflows/filters.js.map +1 -0
  204. package/dist/react/workflows/index.d.ts +70 -0
  205. package/dist/react/workflows/index.d.ts.map +1 -0
  206. package/dist/react/workflows/index.js +38 -0
  207. package/dist/react/workflows/index.js.map +1 -0
  208. package/dist/react/workflows/useWorkflowAction.d.ts +11 -0
  209. package/dist/react/workflows/useWorkflowAction.d.ts.map +1 -0
  210. package/dist/react/workflows/useWorkflowAction.js +68 -0
  211. package/dist/react/workflows/useWorkflowAction.js.map +1 -0
  212. package/dist/react/workflows/useWorkflowResource.d.ts +9 -0
  213. package/dist/react/workflows/useWorkflowResource.d.ts.map +1 -0
  214. package/dist/react/workflows/useWorkflowResource.js +67 -0
  215. package/dist/react/workflows/useWorkflowResource.js.map +1 -0
  216. package/docs/react-workflows-audit.md +66 -0
  217. package/docs/react-workflows.md +231 -0
  218. package/package.json +19 -3
  219. package/src/client/billing/checkout-ui-modes.test.ts +49 -0
  220. package/src/client/billing/checkout.ts +8 -3
  221. package/src/client/billing/invoices.test.ts +12 -6
  222. package/src/client/connect/paymentMethods.test.ts +3 -1
  223. package/src/client/connect/paymentMethods.ts +4 -1
  224. package/src/client/connect/refundActor.ts +1 -2
  225. package/src/client/connect/refunds.test.ts +35 -10
  226. package/src/client/connect/refunds.ts +4 -1
  227. package/src/client/connect/transfers.test.ts +66 -12
  228. package/src/client/connect/transfers.ts +32 -8
  229. package/src/client/core/accountDefaults.ts +15 -0
  230. package/src/client/core/accounts.ts +14 -17
  231. package/src/client/core/config.test.ts +2 -1
  232. package/src/client/core/descriptors.test.ts +6 -4
  233. package/src/client/core/fees.test.ts +20 -28
  234. package/src/client/core/fees.ts +9 -2
  235. package/src/client/index.test.ts +22 -22
  236. package/src/client/index.ts +1 -1
  237. package/src/client/products/prices.test.ts +8 -2
  238. package/src/client/products/prices.ts +4 -1
  239. package/src/client/products/products.test.ts +61 -20
  240. package/src/client/products/products.ts +3 -1
  241. package/src/client/utils/data.test.ts +3 -1
  242. package/src/client/utils/owner.test.ts +4 -1
  243. package/src/client/utils/owner.ts +5 -1
  244. package/src/client/utils/stripeDashboardUrl.ts +1 -4
  245. package/src/client/webhooks/handler.test.ts +16 -19
  246. package/src/client/webhooks/helpers.test.ts +26 -13
  247. package/src/client/webhooks/helpers.ts +23 -0
  248. package/src/client/webhooks/hooks.test.ts +1 -2
  249. package/src/client/webhooks/processors.test.ts +18 -34
  250. package/src/client/webhooks/processors.ts +1 -23
  251. package/src/client/webhooks.test.ts +1 -2
  252. package/src/component/_generated/api.ts +2 -0
  253. package/src/component/connect/mutations.ts +5 -46
  254. package/src/component/connect/schema.ts +4 -3
  255. package/src/component/connect.test.ts +1 -5
  256. package/src/component/lib/paymentSeller.ts +15 -0
  257. package/src/component/lib/reversals.ts +30 -2
  258. package/src/component/subscription-scoping.test.ts +5 -1
  259. package/src/component/triggers.test.ts +7 -4
  260. package/src/react/components/BuyerBillingView.render.test.tsx +7 -2
  261. package/src/react/components/ConnectProvider.live.test.tsx +61 -0
  262. package/src/react/components/ConnectProvider.tsx +18 -4
  263. package/src/react/components/ConnectStatusBadge.tsx +1 -4
  264. package/src/react/components/DisputeDetail.render.test.tsx +5 -1
  265. package/src/react/components/EarningsSummary.render.test.tsx +2 -6
  266. package/src/react/components/EmbeddedDisputes.render.test.tsx +7 -5
  267. package/src/react/components/EmbeddedDisputes.tsx +4 -1
  268. package/src/react/components/EvidenceForm.render.test.tsx +2 -8
  269. package/src/react/components/SplitBreakdown.render.test.tsx +28 -5
  270. package/src/react/components/SplitBreakdown.tsx +12 -2
  271. package/src/react/hooks/useCheckoutSession.ts +1 -2
  272. package/src/react/hooks/useConfirmPayment.ts +1 -2
  273. package/src/react/hooks/useEarnings.test.ts +43 -8
  274. package/src/react/hooks/useStripeMode.test.ts +5 -8
  275. package/src/react/index.ts +3 -0
  276. package/src/react/workflows/Account.test.tsx +31 -0
  277. package/src/react/workflows/Account.tsx +183 -0
  278. package/src/react/workflows/Billing.test.tsx +45 -0
  279. package/src/react/workflows/Billing.tsx +213 -0
  280. package/src/react/workflows/BillingPlans.test.tsx +31 -0
  281. package/src/react/workflows/BillingPlans.tsx +130 -0
  282. package/src/react/workflows/Checkout.test.tsx +118 -0
  283. package/src/react/workflows/Checkout.tsx +135 -0
  284. package/src/react/workflows/CheckoutChooser.test.tsx +44 -0
  285. package/src/react/workflows/CheckoutChooser.tsx +77 -0
  286. package/src/react/workflows/CheckoutForm.test.tsx +66 -0
  287. package/src/react/workflows/CheckoutForms.test.tsx +123 -0
  288. package/src/react/workflows/CheckoutForms.tsx +247 -0
  289. package/src/react/workflows/ClipboardButton.test.tsx +34 -0
  290. package/src/react/workflows/ClipboardButton.tsx +67 -0
  291. package/src/react/workflows/Collection.tsx +76 -0
  292. package/src/react/workflows/Collections.test.tsx +86 -0
  293. package/src/react/workflows/Collections.tsx +213 -0
  294. package/src/react/workflows/Connect.test.tsx +50 -0
  295. package/src/react/workflows/Connect.tsx +107 -0
  296. package/src/react/workflows/Costs.test.tsx +41 -0
  297. package/src/react/workflows/Costs.tsx +133 -0
  298. package/src/react/workflows/Disputes.test.tsx +25 -0
  299. package/src/react/workflows/Disputes.tsx +164 -0
  300. package/src/react/workflows/Earnings.test.ts +19 -0
  301. package/src/react/workflows/Earnings.tsx +84 -0
  302. package/src/react/workflows/Financials.test.tsx +35 -0
  303. package/src/react/workflows/Financials.tsx +117 -0
  304. package/src/react/workflows/IntegrationSwitch.test.tsx +36 -0
  305. package/src/react/workflows/IntegrationSwitch.tsx +63 -0
  306. package/src/react/workflows/Onboarding.test.tsx +75 -0
  307. package/src/react/workflows/Onboarding.tsx +171 -0
  308. package/src/react/workflows/Overview.test.tsx +57 -0
  309. package/src/react/workflows/Overview.tsx +123 -0
  310. package/src/react/workflows/PaymentMethods.test.tsx +60 -0
  311. package/src/react/workflows/PaymentMethods.tsx +117 -0
  312. package/src/react/workflows/PaymentReceipt.test.tsx +24 -0
  313. package/src/react/workflows/PaymentReceipt.tsx +46 -0
  314. package/src/react/workflows/Payouts.test.tsx +82 -0
  315. package/src/react/workflows/Payouts.tsx +212 -0
  316. package/src/react/workflows/Products.test.tsx +90 -0
  317. package/src/react/workflows/Products.tsx +377 -0
  318. package/src/react/workflows/ReferralLinks.test.tsx +39 -0
  319. package/src/react/workflows/ReferralLinks.tsx +75 -0
  320. package/src/react/workflows/Refunds.test.tsx +75 -0
  321. package/src/react/workflows/Refunds.tsx +223 -0
  322. package/src/react/workflows/Setup.test.tsx +25 -0
  323. package/src/react/workflows/Setup.tsx +166 -0
  324. package/src/react/workflows/Storefront.test.tsx +82 -0
  325. package/src/react/workflows/Storefront.tsx +138 -0
  326. package/src/react/workflows/SubscriptionOverview.test.tsx +27 -0
  327. package/src/react/workflows/SubscriptionOverview.tsx +48 -0
  328. package/src/react/workflows/Subscriptions.test.tsx +61 -0
  329. package/src/react/workflows/Subscriptions.tsx +282 -0
  330. package/src/react/workflows/Tasks.test.tsx +23 -0
  331. package/src/react/workflows/Tasks.tsx +199 -0
  332. package/src/react/workflows/checkout-options.ts +42 -0
  333. package/src/react/workflows/current-subscription.test.ts +29 -0
  334. package/src/react/workflows/current-subscription.ts +25 -0
  335. package/src/react/workflows/filters.test.ts +12 -0
  336. package/src/react/workflows/filters.ts +22 -0
  337. package/src/react/workflows/index.ts +238 -0
  338. package/src/react/workflows/native-interactions.test.tsx +73 -0
  339. package/src/react/workflows/public-workflows.test.tsx +216 -0
  340. package/src/react/workflows/useWorkflowAction.test.tsx +54 -0
  341. package/src/react/workflows/useWorkflowAction.ts +75 -0
  342. package/src/react/workflows/useWorkflowResource.test.tsx +41 -0
  343. package/src/react/workflows/useWorkflowResource.ts +78 -0
@@ -114,7 +114,7 @@ export async function createCheckoutSession(
114
114
  orgId?: string;
115
115
  stripePriceId: string;
116
116
  mode: "payment" | "subscription" | "setup";
117
- uiMode?: "embedded" | "redirect";
117
+ uiMode?: "embedded" | "redirect" | "custom" | "form";
118
118
  quantity?: number;
119
119
  returnUrl: string;
120
120
  trialDays?: number;
@@ -295,8 +295,13 @@ export async function createCheckoutSession(
295
295
  sessionParams.payment_intent_data = paymentIntentData;
296
296
  }
297
297
 
298
- if (uiMode === "embedded") {
299
- sessionParams.ui_mode = "embedded_page";
298
+ if (uiMode === "embedded" || uiMode === "custom" || uiMode === "form") {
299
+ sessionParams.ui_mode =
300
+ uiMode === "custom"
301
+ ? "elements"
302
+ : uiMode === "form"
303
+ ? "form"
304
+ : "embedded_page";
300
305
  sessionParams.return_url = opts.returnUrl;
301
306
  } else {
302
307
  sessionParams.success_url = `${opts.returnUrl}?session_id={CHECKOUT_SESSION_ID}`;
@@ -75,7 +75,9 @@ describe("listInvoices", () => {
75
75
 
76
76
  expect(result).toEqual([]);
77
77
  const [ref, args] = ctx.runQuery.mock.calls[0];
78
- expect(ref[TO_REF]).toBe(refPath(component, "billing/queries/listInvoices"));
78
+ expect(ref[TO_REF]).toBe(
79
+ refPath(component, "billing/queries/listInvoices"),
80
+ );
79
81
  expect(args).toEqual({});
80
82
  });
81
83
 
@@ -125,7 +127,9 @@ describe("listInvoicesByUser", () => {
125
127
 
126
128
  expect(result).toBe(rows);
127
129
  const [ref, args] = ctx.runQuery.mock.calls[0];
128
- expect(ref[TO_REF]).toBe(refPath(component, "billing/queries/listInvoices"));
130
+ expect(ref[TO_REF]).toBe(
131
+ refPath(component, "billing/queries/listInvoices"),
132
+ );
129
133
  expect(args).toEqual({ userId: "u_9" });
130
134
  });
131
135
  });
@@ -177,9 +181,9 @@ describe("upsertInvoice", () => {
177
181
  it("throws when ctx has no runMutation (runMutationOrThrow guard)", async () => {
178
182
  const ctx = { runQuery: vi.fn() } as unknown as RunCtx;
179
183
 
180
- await expect(
181
- upsertInvoice(makeComponent(), ctx, baseOpts),
182
- ).rejects.toThrow(/requires a Convex ctx with runMutation/);
184
+ await expect(upsertInvoice(makeComponent(), ctx, baseOpts)).rejects.toThrow(
185
+ /requires a Convex ctx with runMutation/,
186
+ );
183
187
  });
184
188
  });
185
189
 
@@ -189,7 +193,9 @@ describe("getInvoice", () => {
189
193
  const row = { stripeInvoiceId: "in_4", status: "paid" };
190
194
  const ctx = makeCtx(row);
191
195
 
192
- const result = await getInvoice(component, ctx, { stripeInvoiceId: "in_4" });
196
+ const result = await getInvoice(component, ctx, {
197
+ stripeInvoiceId: "in_4",
198
+ });
193
199
 
194
200
  expect(result).toBe(row);
195
201
  const [ref, args] = ctx.runQuery.mock.calls[0];
@@ -60,7 +60,9 @@ describe("payment methods are keyed to the customer_account (BTS-19 reuse)", ()
60
60
 
61
61
  it("detaches a payment method by id", async () => {
62
62
  const stripe = makeStripe();
63
- await detachPaymentMethod(asStripe(stripe), ctx, { paymentMethodId: "pm_1" });
63
+ await detachPaymentMethod(asStripe(stripe), ctx, {
64
+ paymentMethodId: "pm_1",
65
+ });
64
66
  expect(stripe.paymentMethods.detach).toHaveBeenCalledWith("pm_1");
65
67
  });
66
68
  });
@@ -51,5 +51,8 @@ export async function setDefaultPaymentMethod(
51
51
  _ctx: RunCtx,
52
52
  _opts: { stripeAccountId: string; paymentMethodId: string },
53
53
  ) {
54
- throwStripeError("PAYMENT_METHOD_FAILED", "[better-stripe] setDefaultPaymentMethod is not yet implemented for V2 Accounts. Use createBillingPortalSession() to let users manage payment methods.");
54
+ throwStripeError(
55
+ "PAYMENT_METHOD_FAILED",
56
+ "[better-stripe] setDefaultPaymentMethod is not yet implemented for V2 Accounts. Use createBillingPortalSession() to let users manage payment methods.",
57
+ );
55
58
  }
@@ -19,8 +19,7 @@ import type { SplitRecipientRole } from "../../component/lib/fees.js";
19
19
 
20
20
  /** Who is initiating a refund. `accountId` is the seller's `acct_…` id. */
21
21
  export type RefundActor =
22
- | { type: "admin" }
23
- | { type: "seller"; accountId: string };
22
+ { type: "admin" } | { type: "seller"; accountId: string };
24
23
 
25
24
  /**
26
25
  * The subset of a payment's routing needed to authorize a seller refund, read
@@ -53,7 +53,9 @@ function makeStripe(charge: Record<string, unknown>) {
53
53
  .mockResolvedValue({ id: "ch_1", payment_intent: "pi_1", ...charge }),
54
54
  },
55
55
  paymentIntents: {
56
- retrieve: vi.fn().mockResolvedValue({ id: "pi_1", latest_charge: "ch_1" }),
56
+ retrieve: vi
57
+ .fn()
58
+ .mockResolvedValue({ id: "pi_1", latest_charge: "ch_1" }),
57
59
  },
58
60
  };
59
61
  }
@@ -62,12 +64,20 @@ const asStripe = (s: ReturnType<typeof makeStripe>) => s as unknown as Stripe;
62
64
 
63
65
  describe("createRefund — fee & transfer flags (BTS-34)", () => {
64
66
  it("defaults both flags on for a destination charge with an application fee", async () => {
65
- const stripe = makeStripe({ transfer: "tr_auto", application_fee: "fee_1" });
66
-
67
- const result = await createRefund(asStripe(stripe), makeComponent(), noCtx, {
68
- stripeChargeId: "ch_1",
67
+ const stripe = makeStripe({
68
+ transfer: "tr_auto",
69
+ application_fee: "fee_1",
69
70
  });
70
71
 
72
+ const result = await createRefund(
73
+ asStripe(stripe),
74
+ makeComponent(),
75
+ noCtx,
76
+ {
77
+ stripeChargeId: "ch_1",
78
+ },
79
+ );
80
+
71
81
  expect(result).toEqual({ stripeRefundId: "re_new" });
72
82
  expect(stripe.refunds.create).toHaveBeenCalledWith(
73
83
  {
@@ -80,7 +90,10 @@ describe("createRefund — fee & transfer flags (BTS-34)", () => {
80
90
  });
81
91
 
82
92
  it("keeps the flags on a partial refund (Stripe pro-rates both natively)", async () => {
83
- const stripe = makeStripe({ transfer: "tr_auto", application_fee: "fee_1" });
93
+ const stripe = makeStripe({
94
+ transfer: "tr_auto",
95
+ application_fee: "fee_1",
96
+ });
84
97
 
85
98
  await createRefund(asStripe(stripe), makeComponent(), noCtx, {
86
99
  stripeChargeId: "ch_1",
@@ -124,7 +137,10 @@ describe("createRefund — fee & transfer flags (BTS-34)", () => {
124
137
  });
125
138
 
126
139
  it("honours an explicit false even when the charge is capable", async () => {
127
- const stripe = makeStripe({ transfer: "tr_auto", application_fee: "fee_1" });
140
+ const stripe = makeStripe({
141
+ transfer: "tr_auto",
142
+ application_fee: "fee_1",
143
+ });
128
144
 
129
145
  await createRefund(asStripe(stripe), makeComponent(), noCtx, {
130
146
  stripeChargeId: "ch_1",
@@ -217,7 +233,10 @@ describe("createRefund — fee & transfer flags (BTS-34)", () => {
217
233
 
218
234
  describe("createRefund — actor scoping (BTS-35)", () => {
219
235
  it("lets a platform admin refund any sale without a ledger lookup", async () => {
220
- const stripe = makeStripe({ transfer: "tr_auto", application_fee: "fee_1" });
236
+ const stripe = makeStripe({
237
+ transfer: "tr_auto",
238
+ application_fee: "fee_1",
239
+ });
221
240
  const ctx = makeCtx();
222
241
 
223
242
  await createRefund(asStripe(stripe), makeComponent(), ctx, {
@@ -250,7 +269,10 @@ describe("createRefund — actor scoping (BTS-35)", () => {
250
269
  });
251
270
 
252
271
  it("rejects a seller refunding another seller's destination charge", async () => {
253
- const stripe = makeStripe({ transfer: "tr_auto", application_fee: "fee_1" });
272
+ const stripe = makeStripe({
273
+ transfer: "tr_auto",
274
+ application_fee: "fee_1",
275
+ });
254
276
  const ctx = makeCtx({
255
277
  stripePaymentIntentId: "pi_1",
256
278
  destinationAccountId: "acct_other",
@@ -307,7 +329,10 @@ describe("createRefund — actor scoping (BTS-35)", () => {
307
329
  });
308
330
 
309
331
  it("rejects a seller when no matching payment exists in the ledger (fail closed)", async () => {
310
- const stripe = makeStripe({ transfer: "tr_auto", application_fee: "fee_1" });
332
+ const stripe = makeStripe({
333
+ transfer: "tr_auto",
334
+ application_fee: "fee_1",
335
+ });
311
336
  const ctx = makeCtx(null);
312
337
 
313
338
  await expect(
@@ -3,7 +3,10 @@ import type Stripe from "stripe";
3
3
  import type { RefundStatus } from "../../component/connect/validators.js";
4
4
  import { throwStripeError } from "../errors.js";
5
5
  import type { Component, RunCtx } from "../helpers.js";
6
- import type { StripeComponentPayment, StripeComponentRefund } from "../types.js";
6
+ import type {
7
+ StripeComponentPayment,
8
+ StripeComponentRefund,
9
+ } from "../types.js";
7
10
  import { componentRef } from "../webhooks/helpers.js";
8
11
  import { type RefundActor, isRefundAuthorized } from "./refundActor.js";
9
12
 
@@ -14,7 +14,9 @@ function makeComponent(): Component {
14
14
  const ref = (path: string) => ({ [TO_REF]: `betterStripe/${path}` });
15
15
  return {
16
16
  connect: {
17
- queries: { listTransfersByCharge: ref("connect/queries/listTransfersByCharge") },
17
+ queries: {
18
+ listTransfersByCharge: ref("connect/queries/listTransfersByCharge"),
19
+ },
18
20
  mutations: {
19
21
  recordTransferReversal: ref("connect/mutations/recordTransferReversal"),
20
22
  upsertTransfer: ref("connect/mutations/upsertTransfer"),
@@ -56,7 +58,10 @@ function makeCtx(transfers: unknown[]) {
56
58
  legs.map((t) => ({
57
59
  stripeTransferId: t.stripeTransferId,
58
60
  amount: t.amount,
59
- frontier: Math.max(t.reversedAmount ?? 0, t.reversalClaimedAmount ?? 0),
61
+ frontier: Math.max(
62
+ t.reversedAmount ?? 0,
63
+ t.reversalClaimedAmount ?? 0,
64
+ ),
60
65
  })),
61
66
  args.mode as Parameters<typeof computeReversalSlices>[1],
62
67
  );
@@ -117,7 +122,9 @@ describe("reverseTransfers (BTS-25)", () => {
117
122
  undefined,
118
123
  );
119
124
  // ledger updated with cumulative reversed amounts
120
- const reversedAmounts = ctx.runMutation.mock.calls.map((c) => c[1].reversedAmount);
125
+ const reversedAmounts = ctx.runMutation.mock.calls.map(
126
+ (c) => c[1].reversedAmount,
127
+ );
121
128
  expect(reversedAmounts).toEqual([8000, 1000]);
122
129
  });
123
130
 
@@ -391,7 +398,12 @@ describe("createSplitTransfers idempotency (BTS-24)", () => {
391
398
  const stripe = makeStripe();
392
399
  // The store transfer already exists from a prior (partial) run.
393
400
  const ctx = makeCtx([
394
- { stripeTransferId: "tr_store", destinationAccountId: "acct_store", role: "store", amount: 8000 },
401
+ {
402
+ stripeTransferId: "tr_store",
403
+ destinationAccountId: "acct_store",
404
+ role: "store",
405
+ amount: 8000,
406
+ },
395
407
  ]);
396
408
 
397
409
  await createSplitTransfers(asStripe(stripe), makeComponent(), ctx, {
@@ -414,8 +426,18 @@ describe("createSplitTransfers idempotency (BTS-24)", () => {
414
426
  it("creates nothing when all recipients are already in the ledger (full replay)", async () => {
415
427
  const stripe = makeStripe();
416
428
  const ctx = makeCtx([
417
- { stripeTransferId: "tr_store", destinationAccountId: "acct_store", role: "store", amount: 8000 },
418
- { stripeTransferId: "tr_aff", destinationAccountId: "acct_aff", role: "affiliate", amount: 1000 },
429
+ {
430
+ stripeTransferId: "tr_store",
431
+ destinationAccountId: "acct_store",
432
+ role: "store",
433
+ amount: 8000,
434
+ },
435
+ {
436
+ stripeTransferId: "tr_aff",
437
+ destinationAccountId: "acct_aff",
438
+ role: "affiliate",
439
+ amount: 1000,
440
+ },
419
441
  ]);
420
442
 
421
443
  await createSplitTransfers(asStripe(stripe), makeComponent(), ctx, {
@@ -436,8 +458,22 @@ describe("reinstateTransfers (BTS-29)", () => {
436
458
  it("re-creates transfers for the reversed amounts (dispute won)", async () => {
437
459
  const stripe = makeStripe();
438
460
  const ctx = makeCtx([
439
- { stripeTransferId: "tr_store", destinationAccountId: "acct_store", role: "store", amount: 8000, currency: "usd", reversedAmount: 8000 },
440
- { stripeTransferId: "tr_aff", destinationAccountId: "acct_aff", role: "affiliate", amount: 1000, currency: "usd", reversedAmount: 1000 },
461
+ {
462
+ stripeTransferId: "tr_store",
463
+ destinationAccountId: "acct_store",
464
+ role: "store",
465
+ amount: 8000,
466
+ currency: "usd",
467
+ reversedAmount: 8000,
468
+ },
469
+ {
470
+ stripeTransferId: "tr_aff",
471
+ destinationAccountId: "acct_aff",
472
+ role: "affiliate",
473
+ amount: 1000,
474
+ currency: "usd",
475
+ reversedAmount: 1000,
476
+ },
441
477
  ]);
442
478
 
443
479
  await reinstateTransfers(asStripe(stripe), makeComponent(), ctx, {
@@ -448,7 +484,11 @@ describe("reinstateTransfers (BTS-29)", () => {
448
484
 
449
485
  expect(stripe.transfers.create).toHaveBeenCalledTimes(2);
450
486
  expect(stripe.transfers.create).toHaveBeenCalledWith(
451
- expect.objectContaining({ amount: 8000, currency: "usd", destination: "acct_store" }),
487
+ expect.objectContaining({
488
+ amount: 8000,
489
+ currency: "usd",
490
+ destination: "acct_store",
491
+ }),
452
492
  { idempotencyKey: "bs_reinstate_dp_1_acct_store_store" },
453
493
  );
454
494
  expect(stripe.transfers.create).toHaveBeenCalledWith(
@@ -457,14 +497,22 @@ describe("reinstateTransfers (BTS-29)", () => {
457
497
  );
458
498
  // Ledger rows are tagged reinstatement so they stay out of the charge's
459
499
  // split-leg view and can't be re-reversed.
460
- expect(ctx.runMutation.mock.calls[0][1]).toMatchObject({ reinstatement: true });
500
+ expect(ctx.runMutation.mock.calls[0][1]).toMatchObject({
501
+ reinstatement: true,
502
+ });
461
503
  });
462
504
 
463
505
  it("uses a legacy row's fallback currency from the dispute, not USD", async () => {
464
506
  const stripe = makeStripe();
465
507
  const ctx = makeCtx([
466
508
  // Legacy row with no stored currency.
467
- { stripeTransferId: "tr_x", destinationAccountId: "acct_x", role: "store", amount: 5000, reversedAmount: 5000 },
509
+ {
510
+ stripeTransferId: "tr_x",
511
+ destinationAccountId: "acct_x",
512
+ role: "store",
513
+ amount: 5000,
514
+ reversedAmount: 5000,
515
+ },
468
516
  ]);
469
517
  await reinstateTransfers(asStripe(stripe), makeComponent(), ctx, {
470
518
  sourceChargeId: "ch_1",
@@ -480,7 +528,13 @@ describe("reinstateTransfers (BTS-29)", () => {
480
528
  it("skips transfers that were never reversed", async () => {
481
529
  const stripe = makeStripe();
482
530
  const ctx = makeCtx([
483
- { stripeTransferId: "tr_store", destinationAccountId: "acct_store", role: "store", amount: 8000, currency: "usd" },
531
+ {
532
+ stripeTransferId: "tr_store",
533
+ destinationAccountId: "acct_store",
534
+ role: "store",
535
+ amount: 8000,
536
+ currency: "usd",
537
+ },
484
538
  ]);
485
539
  await reinstateTransfers(asStripe(stripe), makeComponent(), ctx, {
486
540
  sourceChargeId: "ch_1",
@@ -78,7 +78,10 @@ async function executeClaimedSlices(
78
78
  await runMutationOrThrow(
79
79
  ctx,
80
80
  componentRef(component, "connect/mutations/recordTransferReversal"),
81
- { stripeTransferId: slice.stripeTransferId, reversedAmount: slice.to },
81
+ {
82
+ stripeTransferId: slice.stripeTransferId,
83
+ reversedAmount: slice.to,
84
+ },
82
85
  );
83
86
  continue;
84
87
  }
@@ -242,7 +245,10 @@ export async function reclaimReversalClaim(
242
245
  ctx,
243
246
  componentRef(component, "connect/mutations/releaseReversalClaim"),
244
247
  { operationId: op.operationId, verified },
245
- )) as { released: boolean; rewound: { stripeTransferId: string; to: number }[] };
248
+ )) as {
249
+ released: boolean;
250
+ rewound: { stripeTransferId: string; to: number }[];
251
+ };
246
252
  return { mode: "release", ...res };
247
253
  }
248
254
 
@@ -312,7 +318,13 @@ export async function reverseTransfers(
312
318
  : { kind: "full" as const },
313
319
  },
314
320
  )) as ReversalClaim;
315
- return executeClaimedSlices(stripe, component, ctx, opts.operationId, claim);
321
+ return executeClaimedSlices(
322
+ stripe,
323
+ component,
324
+ ctx,
325
+ opts.operationId,
326
+ claim,
327
+ );
316
328
  }
317
329
 
318
330
  // Legacy one-shot path (no operationId): size against the claim frontier so
@@ -330,7 +342,10 @@ export async function reverseTransfers(
330
342
  const reversals: { stripeTransferId: string; amount: number }[] = [];
331
343
 
332
344
  for (const t of transfers) {
333
- const already = Math.max(t.reversedAmount ?? 0, t.reversalClaimedAmount ?? 0);
345
+ const already = Math.max(
346
+ t.reversedAmount ?? 0,
347
+ t.reversalClaimedAmount ?? 0,
348
+ );
334
349
  const remaining = t.amount - already;
335
350
  if (remaining <= 0) continue; // already fully reversed — idempotent
336
351
 
@@ -338,7 +353,8 @@ export async function reverseTransfers(
338
353
  if (opts.percent !== undefined) {
339
354
  reversalAmt = Math.round((t.amount * opts.percent) / 100);
340
355
  } else if (amountBudget !== undefined) {
341
- const prorata = total > 0 ? Math.round((opts.amount! * t.amount) / total) : 0;
356
+ const prorata =
357
+ total > 0 ? Math.round((opts.amount! * t.amount) / total) : 0;
342
358
  reversalAmt = Math.min(prorata, amountBudget);
343
359
  } else {
344
360
  reversalAmt = remaining; // full reversal
@@ -355,9 +371,15 @@ export async function reverseTransfers(
355
371
  await runMutationOrThrow(
356
372
  ctx,
357
373
  componentRef(component, "connect/mutations/recordTransferReversal"),
358
- { stripeTransferId: t.stripeTransferId, reversedAmount: already + reversalAmt },
374
+ {
375
+ stripeTransferId: t.stripeTransferId,
376
+ reversedAmount: already + reversalAmt,
377
+ },
359
378
  );
360
- reversals.push({ stripeTransferId: t.stripeTransferId, amount: reversalAmt });
379
+ reversals.push({
380
+ stripeTransferId: t.stripeTransferId,
381
+ amount: reversalAmt,
382
+ });
361
383
  }
362
384
 
363
385
  return { reversals };
@@ -461,7 +483,9 @@ export async function createSplitTransfers(
461
483
  metadata: { bsRole: t.role, bsSourceCharge: opts.sourceChargeId },
462
484
  },
463
485
  // Deterministic key so a webhook retry can't double-transfer (BTS-24).
464
- { idempotencyKey: `bs_split_${opts.sourceChargeId}_${t.destinationAccountId}_${t.role}` },
486
+ {
487
+ idempotencyKey: `bs_split_${opts.sourceChargeId}_${t.destinationAccountId}_${t.role}`,
488
+ },
465
489
  );
466
490
  await runMutationOrThrow(
467
491
  ctx,
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Default V2 account configuration: merchant with card_payments.
3
+ */
4
+ export const DEFAULT_ACCOUNT_CONFIGURATION: Record<string, unknown> = {
5
+ merchant: {
6
+ capabilities: { card_payments: { requested: true } },
7
+ },
8
+ };
9
+
10
+ export const DEFAULT_ACCOUNT_DEFAULTS: Record<string, unknown> = {
11
+ responsibilities: {
12
+ losses_collector: "application",
13
+ fees_collector: "application",
14
+ },
15
+ };
@@ -14,6 +14,15 @@ import { componentRef } from "../webhooks/helpers.js";
14
14
  import { validateStatementDescriptorSuffix } from "./descriptors.js";
15
15
  import { deriveAccountStatus } from "./accountStatus.js";
16
16
 
17
+ import {
18
+ DEFAULT_ACCOUNT_CONFIGURATION,
19
+ DEFAULT_ACCOUNT_DEFAULTS,
20
+ } from "./accountDefaults.js";
21
+ export {
22
+ DEFAULT_ACCOUNT_CONFIGURATION,
23
+ DEFAULT_ACCOUNT_DEFAULTS,
24
+ } from "./accountDefaults.js";
25
+
17
26
  // =============================================================================
18
27
  // Account CRUD
19
28
  // =============================================================================
@@ -76,22 +85,6 @@ export async function createAccount(
76
85
  };
77
86
  }
78
87
 
79
- /**
80
- * Default V2 account configuration: merchant with card_payments.
81
- */
82
- export const DEFAULT_ACCOUNT_CONFIGURATION: Record<string, unknown> = {
83
- merchant: {
84
- capabilities: { card_payments: { requested: true } },
85
- },
86
- };
87
-
88
- export const DEFAULT_ACCOUNT_DEFAULTS: Record<string, unknown> = {
89
- responsibilities: {
90
- losses_collector: "application",
91
- fees_collector: "application",
92
- },
93
- };
94
-
95
88
  export async function createAccountWithOnboarding(
96
89
  stripe: Stripe,
97
90
  component: Component,
@@ -145,7 +138,11 @@ export async function createAccountWithOnboarding(
145
138
  } catch {
146
139
  // Best effort cleanup
147
140
  }
148
- throwStripeError("ACCOUNT_CREATE_FAILED", "Failed to apply account configuration after create; account was rolled back", configError);
141
+ throwStripeError(
142
+ "ACCOUNT_CREATE_FAILED",
143
+ "Failed to apply account configuration after create; account was rolled back",
144
+ configError,
145
+ );
149
146
  }
150
147
 
151
148
  // Re-fetch account to get actual applied_configurations from Stripe
@@ -37,7 +37,8 @@ describe("getPublishableKey", () => {
37
37
  const result = await getPublishableKey(component, ctx);
38
38
 
39
39
  expect(result).toBe("pk_test_123");
40
- const [ref, args] = (ctx.runQuery as ReturnType<typeof vi.fn>).mock.calls[0];
40
+ const [ref, args] = (ctx.runQuery as ReturnType<typeof vi.fn>).mock
41
+ .calls[0];
41
42
  expect(ref[TO_REF]).toBe("betterStripe/core/queries/getPublishableKey");
42
43
  expect(args).toEqual({});
43
44
  });
@@ -38,15 +38,17 @@ describe("validateStatementDescriptorSuffix", () => {
38
38
  it.each(["<", ">", "\\", "'", '"', "*"])(
39
39
  "rejects the disallowed character %s",
40
40
  (char) => {
41
- expect(() => validateStatementDescriptorSuffix(`STORE${char}NAME`)).toThrow(
42
- /character/i,
43
- );
41
+ expect(() =>
42
+ validateStatementDescriptorSuffix(`STORE${char}NAME`),
43
+ ).toThrow(/character/i);
44
44
  },
45
45
  );
46
46
 
47
47
  it("rejects a value with no letter (digits/punctuation only)", () => {
48
48
  expect(() => validateStatementDescriptorSuffix("12345")).toThrow(/letter/i);
49
- expect(() => validateStatementDescriptorSuffix("--- 9")).toThrow(/letter/i);
49
+ expect(() => validateStatementDescriptorSuffix("--- 9")).toThrow(
50
+ /letter/i,
51
+ );
50
52
  });
51
53
 
52
54
  it("rejects non-ASCII (non-Latin) characters", () => {
@@ -14,7 +14,9 @@ describe("validatePlatformFee (BTS-13)", () => {
14
14
  });
15
15
 
16
16
  it("accepts percent + fixed", () => {
17
- expect(() => validatePlatformFee({ percent: 2.9, fixed: 30 })).not.toThrow();
17
+ expect(() =>
18
+ validatePlatformFee({ percent: 2.9, fixed: 30 }),
19
+ ).not.toThrow();
18
20
  });
19
21
 
20
22
  it("accepts ascending tiers with a null final upper bound", () => {
@@ -219,14 +221,10 @@ describe("computeSplit (BTS-23)", () => {
219
221
  const aff = "acct_aff";
220
222
 
221
223
  it("splits with fixed recipient amounts; platform retains the rest", () => {
222
- const r = computeSplit(
223
- 10000,
224
- { percent: 10 },
225
- [
226
- { destinationAccountId: store, role: "store", amount: 8000 },
227
- { destinationAccountId: aff, role: "affiliate", amount: 1000 },
228
- ],
229
- );
224
+ const r = computeSplit(10000, { percent: 10 }, [
225
+ { destinationAccountId: store, role: "store", amount: 8000 },
226
+ { destinationAccountId: aff, role: "affiliate", amount: 1000 },
227
+ ]);
230
228
  expect(r.transfers).toEqual([
231
229
  { destinationAccountId: store, role: "store", amount: 8000 },
232
230
  { destinationAccountId: aff, role: "affiliate", amount: 1000 },
@@ -239,14 +237,10 @@ describe("computeSplit (BTS-23)", () => {
239
237
  });
240
238
 
241
239
  it("supports percent-of-gross recipients", () => {
242
- const r = computeSplit(
243
- 10000,
244
- { percent: 10 },
245
- [
246
- { destinationAccountId: store, role: "store", percent: 80 },
247
- { destinationAccountId: aff, role: "affiliate", percent: 5 },
248
- ],
249
- );
240
+ const r = computeSplit(10000, { percent: 10 }, [
241
+ { destinationAccountId: store, role: "store", percent: 80 },
242
+ { destinationAccountId: aff, role: "affiliate", percent: 5 },
243
+ ]);
250
244
  expect(r.transfers.map((t) => t.amount)).toEqual([8000, 500]);
251
245
  expect(r.platformRetained).toBe(1500); // 10000 - 8500
252
246
  });
@@ -269,15 +263,11 @@ describe("computeSplit (BTS-23)", () => {
269
263
 
270
264
  it("assigns the rounding remainder deterministically to the platform", () => {
271
265
  // 33% + 33% + 33% of 100 → 33 + 33 + 33 = 99; platform keeps the 1 remainder.
272
- const r = computeSplit(
273
- 100,
274
- undefined,
275
- [
276
- { destinationAccountId: store, role: "store", percent: 33 },
277
- { destinationAccountId: aff, role: "affiliate", percent: 33 },
278
- { destinationAccountId: "acct_c", role: "other", percent: 33 },
279
- ],
280
- );
266
+ const r = computeSplit(100, undefined, [
267
+ { destinationAccountId: store, role: "store", percent: 33 },
268
+ { destinationAccountId: aff, role: "affiliate", percent: 33 },
269
+ { destinationAccountId: "acct_c", role: "other", percent: 33 },
270
+ ]);
281
271
  const sum = r.transfers.reduce((s, t) => s + t.amount, 0);
282
272
  expect(sum).toBe(99);
283
273
  expect(r.platformRetained).toBe(1);
@@ -300,7 +290,7 @@ describe("computeSplit (BTS-23)", () => {
300
290
  expect(r.platformFee).toBe(0);
301
291
  expect(r.platformRetained).toBe(0);
302
292
  });
303
- })
293
+ });
304
294
 
305
295
  describe("validateSplit (BTS-21)", () => {
306
296
  const r = (over = {}) => ({
@@ -354,7 +344,9 @@ describe("validateSplit (BTS-21)", () => {
354
344
  });
355
345
 
356
346
  it("rejects an empty destinationAccountId", () => {
357
- expect(() => validateSplit([r({ destinationAccountId: "", amount: 100 })])).toThrow();
347
+ expect(() =>
348
+ validateSplit([r({ destinationAccountId: "", amount: 100 })]),
349
+ ).toThrow();
358
350
  });
359
351
 
360
352
  it("rejects duplicate destination+role legs (idempotency-key collision)", () => {
@@ -201,7 +201,11 @@ export function computeSplit(
201
201
  `Invalid split amount for ${r.destinationAccountId}: ${amt}`,
202
202
  );
203
203
  }
204
- return { destinationAccountId: r.destinationAccountId, role: r.role, amount: amt };
204
+ return {
205
+ destinationAccountId: r.destinationAccountId,
206
+ role: r.role,
207
+ amount: amt,
208
+ };
205
209
  });
206
210
 
207
211
  const sumTransfers = transfers.reduce((s, t) => s + t.amount, 0);
@@ -247,7 +251,10 @@ export function validateSplit(recipients: SplitRecipient[]): void {
247
251
  `split recipient ${r.destinationAccountId} must set exactly one of amount or percent`,
248
252
  );
249
253
  }
250
- if (hasAmount && (!Number.isInteger(r.amount) || (r.amount as number) < 0)) {
254
+ if (
255
+ hasAmount &&
256
+ (!Number.isInteger(r.amount) || (r.amount as number) < 0)
257
+ ) {
251
258
  throw new Error(
252
259
  `split recipient ${r.destinationAccountId} amount must be a non-negative integer (minor units)`,
253
260
  );