@fantastic.dev/better-stripe 0.7.0 → 0.8.1

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 (359) hide show
  1. package/CHANGELOG.md +29 -18
  2. package/README.md +123 -91
  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/disputes.d.ts +1 -1
  8. package/dist/client/connect/disputes.d.ts.map +1 -1
  9. package/dist/client/connect/disputes.js +12 -6
  10. package/dist/client/connect/disputes.js.map +1 -1
  11. package/dist/client/connect/paymentMethods.d.ts.map +1 -1
  12. package/dist/client/connect/paymentMethods.js.map +1 -1
  13. package/dist/client/connect/refundActor.d.ts.map +1 -1
  14. package/dist/client/connect/refundActor.js.map +1 -1
  15. package/dist/client/connect/refunds.d.ts.map +1 -1
  16. package/dist/client/connect/refunds.js.map +1 -1
  17. package/dist/client/connect/transfers.d.ts.map +1 -1
  18. package/dist/client/connect/transfers.js +15 -4
  19. package/dist/client/connect/transfers.js.map +1 -1
  20. package/dist/client/core/accountDefaults.d.ts +6 -0
  21. package/dist/client/core/accountDefaults.d.ts.map +1 -0
  22. package/dist/client/core/accountDefaults.js +15 -0
  23. package/dist/client/core/accountDefaults.js.map +1 -0
  24. package/dist/client/core/accounts.d.ts +1 -5
  25. package/dist/client/core/accounts.d.ts.map +1 -1
  26. package/dist/client/core/accounts.js +2 -14
  27. package/dist/client/core/accounts.js.map +1 -1
  28. package/dist/client/core/fees.d.ts.map +1 -1
  29. package/dist/client/core/fees.js +7 -2
  30. package/dist/client/core/fees.js.map +1 -1
  31. package/dist/client/index.d.ts +1 -1
  32. package/dist/client/index.d.ts.map +1 -1
  33. package/dist/client/products/prices.d.ts.map +1 -1
  34. package/dist/client/products/prices.js.map +1 -1
  35. package/dist/client/products/products.d.ts.map +1 -1
  36. package/dist/client/products/products.js +3 -1
  37. package/dist/client/products/products.js.map +1 -1
  38. package/dist/client/utils/owner.d.ts.map +1 -1
  39. package/dist/client/utils/owner.js +3 -1
  40. package/dist/client/utils/owner.js.map +1 -1
  41. package/dist/client/utils/stripeDashboardUrl.d.ts.map +1 -1
  42. package/dist/client/utils/stripeDashboardUrl.js.map +1 -1
  43. package/dist/client/webhooks/helpers.d.ts +10 -0
  44. package/dist/client/webhooks/helpers.d.ts.map +1 -1
  45. package/dist/client/webhooks/helpers.js +18 -0
  46. package/dist/client/webhooks/helpers.js.map +1 -1
  47. package/dist/client/webhooks/processors.d.ts.map +1 -1
  48. package/dist/client/webhooks/processors.js +1 -19
  49. package/dist/client/webhooks/processors.js.map +1 -1
  50. package/dist/component/connect/mutations.d.ts.map +1 -1
  51. package/dist/component/connect/mutations.js +4 -33
  52. package/dist/component/connect/mutations.js.map +1 -1
  53. package/dist/component/connect/schema.d.ts.map +1 -1
  54. package/dist/component/connect/schema.js.map +1 -1
  55. package/dist/component/lib/paymentSeller.d.ts +3 -0
  56. package/dist/component/lib/paymentSeller.d.ts.map +1 -0
  57. package/dist/component/lib/paymentSeller.js +10 -0
  58. package/dist/component/lib/paymentSeller.js.map +1 -0
  59. package/dist/component/lib/reversals.d.ts +10 -0
  60. package/dist/component/lib/reversals.d.ts.map +1 -1
  61. package/dist/component/lib/reversals.js +17 -0
  62. package/dist/component/lib/reversals.js.map +1 -1
  63. package/dist/react/components/ConnectProvider.d.ts +1 -1
  64. package/dist/react/components/ConnectProvider.d.ts.map +1 -1
  65. package/dist/react/components/ConnectProvider.js +18 -4
  66. package/dist/react/components/ConnectProvider.js.map +1 -1
  67. package/dist/react/components/ConnectStatusBadge.d.ts.map +1 -1
  68. package/dist/react/components/ConnectStatusBadge.js.map +1 -1
  69. package/dist/react/components/DisputeDetail.d.ts +4 -1
  70. package/dist/react/components/DisputeDetail.d.ts.map +1 -1
  71. package/dist/react/components/DisputeDetail.js +12 -6
  72. package/dist/react/components/DisputeDetail.js.map +1 -1
  73. package/dist/react/components/DisputesList.d.ts.map +1 -1
  74. package/dist/react/components/DisputesList.js +2 -1
  75. package/dist/react/components/DisputesList.js.map +1 -1
  76. package/dist/react/components/EmbeddedDisputes.d.ts +1 -1
  77. package/dist/react/components/EmbeddedDisputes.d.ts.map +1 -1
  78. package/dist/react/components/EmbeddedDisputes.js +1 -1
  79. package/dist/react/components/EmbeddedDisputes.js.map +1 -1
  80. package/dist/react/components/SplitBreakdown.d.ts.map +1 -1
  81. package/dist/react/components/SplitBreakdown.js +12 -2
  82. package/dist/react/components/SplitBreakdown.js.map +1 -1
  83. package/dist/react/hooks/useCheckoutSession.d.ts.map +1 -1
  84. package/dist/react/hooks/useCheckoutSession.js.map +1 -1
  85. package/dist/react/hooks/useConfirmPayment.d.ts.map +1 -1
  86. package/dist/react/hooks/useConfirmPayment.js.map +1 -1
  87. package/dist/react/index.d.ts +2 -1
  88. package/dist/react/index.d.ts.map +1 -1
  89. package/dist/react/index.js +3 -1
  90. package/dist/react/index.js.map +1 -1
  91. package/dist/react/workflows/Account.d.ts +67 -0
  92. package/dist/react/workflows/Account.d.ts.map +1 -0
  93. package/dist/react/workflows/Account.js +74 -0
  94. package/dist/react/workflows/Account.js.map +1 -0
  95. package/dist/react/workflows/Billing.d.ts +60 -0
  96. package/dist/react/workflows/Billing.d.ts.map +1 -0
  97. package/dist/react/workflows/Billing.js +84 -0
  98. package/dist/react/workflows/Billing.js.map +1 -0
  99. package/dist/react/workflows/BillingPlans.d.ts +45 -0
  100. package/dist/react/workflows/BillingPlans.d.ts.map +1 -0
  101. package/dist/react/workflows/BillingPlans.js +51 -0
  102. package/dist/react/workflows/BillingPlans.js.map +1 -0
  103. package/dist/react/workflows/Checkout.d.ts +46 -0
  104. package/dist/react/workflows/Checkout.d.ts.map +1 -0
  105. package/dist/react/workflows/Checkout.js +61 -0
  106. package/dist/react/workflows/Checkout.js.map +1 -0
  107. package/dist/react/workflows/CheckoutChooser.d.ts +20 -0
  108. package/dist/react/workflows/CheckoutChooser.d.ts.map +1 -0
  109. package/dist/react/workflows/CheckoutChooser.js +24 -0
  110. package/dist/react/workflows/CheckoutChooser.js.map +1 -0
  111. package/dist/react/workflows/CheckoutForms.d.ts +26 -0
  112. package/dist/react/workflows/CheckoutForms.d.ts.map +1 -0
  113. package/dist/react/workflows/CheckoutForms.js +126 -0
  114. package/dist/react/workflows/CheckoutForms.js.map +1 -0
  115. package/dist/react/workflows/ClipboardButton.d.ts +17 -0
  116. package/dist/react/workflows/ClipboardButton.d.ts.map +1 -0
  117. package/dist/react/workflows/ClipboardButton.js +35 -0
  118. package/dist/react/workflows/ClipboardButton.js.map +1 -0
  119. package/dist/react/workflows/Collection.d.ts +30 -0
  120. package/dist/react/workflows/Collection.d.ts.map +1 -0
  121. package/dist/react/workflows/Collection.js +25 -0
  122. package/dist/react/workflows/Collection.js.map +1 -0
  123. package/dist/react/workflows/Collections.d.ts +56 -0
  124. package/dist/react/workflows/Collections.d.ts.map +1 -0
  125. package/dist/react/workflows/Collections.js +111 -0
  126. package/dist/react/workflows/Collections.js.map +1 -0
  127. package/dist/react/workflows/Connect.d.ts +19 -0
  128. package/dist/react/workflows/Connect.d.ts.map +1 -0
  129. package/dist/react/workflows/Connect.js +43 -0
  130. package/dist/react/workflows/Connect.js.map +1 -0
  131. package/dist/react/workflows/Costs.d.ts +48 -0
  132. package/dist/react/workflows/Costs.d.ts.map +1 -0
  133. package/dist/react/workflows/Costs.js +66 -0
  134. package/dist/react/workflows/Costs.js.map +1 -0
  135. package/dist/react/workflows/Disputes.d.ts +36 -0
  136. package/dist/react/workflows/Disputes.d.ts.map +1 -0
  137. package/dist/react/workflows/Disputes.js +74 -0
  138. package/dist/react/workflows/Disputes.js.map +1 -0
  139. package/dist/react/workflows/Earnings.d.ts +42 -0
  140. package/dist/react/workflows/Earnings.d.ts.map +1 -0
  141. package/dist/react/workflows/Earnings.js +38 -0
  142. package/dist/react/workflows/Earnings.js.map +1 -0
  143. package/dist/react/workflows/Financials.d.ts +43 -0
  144. package/dist/react/workflows/Financials.d.ts.map +1 -0
  145. package/dist/react/workflows/Financials.js +57 -0
  146. package/dist/react/workflows/Financials.js.map +1 -0
  147. package/dist/react/workflows/IntegrationSwitch.d.ts +23 -0
  148. package/dist/react/workflows/IntegrationSwitch.d.ts.map +1 -0
  149. package/dist/react/workflows/IntegrationSwitch.js +31 -0
  150. package/dist/react/workflows/IntegrationSwitch.js.map +1 -0
  151. package/dist/react/workflows/Onboarding.d.ts +56 -0
  152. package/dist/react/workflows/Onboarding.d.ts.map +1 -0
  153. package/dist/react/workflows/Onboarding.js +86 -0
  154. package/dist/react/workflows/Onboarding.js.map +1 -0
  155. package/dist/react/workflows/Overview.d.ts +51 -0
  156. package/dist/react/workflows/Overview.d.ts.map +1 -0
  157. package/dist/react/workflows/Overview.js +63 -0
  158. package/dist/react/workflows/Overview.js.map +1 -0
  159. package/dist/react/workflows/PaymentMethods.d.ts +35 -0
  160. package/dist/react/workflows/PaymentMethods.d.ts.map +1 -0
  161. package/dist/react/workflows/PaymentMethods.js +63 -0
  162. package/dist/react/workflows/PaymentMethods.js.map +1 -0
  163. package/dist/react/workflows/PaymentReceipt.d.ts +20 -0
  164. package/dist/react/workflows/PaymentReceipt.d.ts.map +1 -0
  165. package/dist/react/workflows/PaymentReceipt.js +24 -0
  166. package/dist/react/workflows/PaymentReceipt.js.map +1 -0
  167. package/dist/react/workflows/Payouts.d.ts +48 -0
  168. package/dist/react/workflows/Payouts.d.ts.map +1 -0
  169. package/dist/react/workflows/Payouts.js +88 -0
  170. package/dist/react/workflows/Payouts.js.map +1 -0
  171. package/dist/react/workflows/Products.d.ts +92 -0
  172. package/dist/react/workflows/Products.d.ts.map +1 -0
  173. package/dist/react/workflows/Products.js +179 -0
  174. package/dist/react/workflows/Products.js.map +1 -0
  175. package/dist/react/workflows/ReferralLinks.d.ts +26 -0
  176. package/dist/react/workflows/ReferralLinks.d.ts.map +1 -0
  177. package/dist/react/workflows/ReferralLinks.js +30 -0
  178. package/dist/react/workflows/ReferralLinks.js.map +1 -0
  179. package/dist/react/workflows/Refunds.d.ts +72 -0
  180. package/dist/react/workflows/Refunds.d.ts.map +1 -0
  181. package/dist/react/workflows/Refunds.js +95 -0
  182. package/dist/react/workflows/Refunds.js.map +1 -0
  183. package/dist/react/workflows/Setup.d.ts +50 -0
  184. package/dist/react/workflows/Setup.d.ts.map +1 -0
  185. package/dist/react/workflows/Setup.js +59 -0
  186. package/dist/react/workflows/Setup.js.map +1 -0
  187. package/dist/react/workflows/Storefront.d.ts +53 -0
  188. package/dist/react/workflows/Storefront.d.ts.map +1 -0
  189. package/dist/react/workflows/Storefront.js +44 -0
  190. package/dist/react/workflows/Storefront.js.map +1 -0
  191. package/dist/react/workflows/SubscriptionOverview.d.ts +13 -0
  192. package/dist/react/workflows/SubscriptionOverview.d.ts.map +1 -0
  193. package/dist/react/workflows/SubscriptionOverview.js +26 -0
  194. package/dist/react/workflows/SubscriptionOverview.js.map +1 -0
  195. package/dist/react/workflows/Subscriptions.d.ts +92 -0
  196. package/dist/react/workflows/Subscriptions.d.ts.map +1 -0
  197. package/dist/react/workflows/Subscriptions.js +149 -0
  198. package/dist/react/workflows/Subscriptions.js.map +1 -0
  199. package/dist/react/workflows/Tasks.d.ts +40 -0
  200. package/dist/react/workflows/Tasks.d.ts.map +1 -0
  201. package/dist/react/workflows/Tasks.js +113 -0
  202. package/dist/react/workflows/Tasks.js.map +1 -0
  203. package/dist/react/workflows/checkout-options.d.ts +37 -0
  204. package/dist/react/workflows/checkout-options.d.ts.map +1 -0
  205. package/dist/react/workflows/checkout-options.js +43 -0
  206. package/dist/react/workflows/checkout-options.js.map +1 -0
  207. package/dist/react/workflows/current-subscription.d.ts +11 -0
  208. package/dist/react/workflows/current-subscription.d.ts.map +1 -0
  209. package/dist/react/workflows/current-subscription.js +14 -0
  210. package/dist/react/workflows/current-subscription.js.map +1 -0
  211. package/dist/react/workflows/filters.d.ts +17 -0
  212. package/dist/react/workflows/filters.d.ts.map +1 -0
  213. package/dist/react/workflows/filters.js +23 -0
  214. package/dist/react/workflows/filters.js.map +1 -0
  215. package/dist/react/workflows/index.d.ts +70 -0
  216. package/dist/react/workflows/index.d.ts.map +1 -0
  217. package/dist/react/workflows/index.js +38 -0
  218. package/dist/react/workflows/index.js.map +1 -0
  219. package/dist/react/workflows/useWorkflowAction.d.ts +11 -0
  220. package/dist/react/workflows/useWorkflowAction.d.ts.map +1 -0
  221. package/dist/react/workflows/useWorkflowAction.js +68 -0
  222. package/dist/react/workflows/useWorkflowAction.js.map +1 -0
  223. package/dist/react/workflows/useWorkflowResource.d.ts +9 -0
  224. package/dist/react/workflows/useWorkflowResource.d.ts.map +1 -0
  225. package/dist/react/workflows/useWorkflowResource.js +67 -0
  226. package/dist/react/workflows/useWorkflowResource.js.map +1 -0
  227. package/docs/react-workflows-audit.md +88 -0
  228. package/docs/react-workflows.md +234 -0
  229. package/package.json +19 -3
  230. package/src/client/billing/checkout-ui-modes.test.ts +49 -0
  231. package/src/client/billing/checkout.ts +8 -3
  232. package/src/client/billing/invoices.test.ts +12 -6
  233. package/src/client/connect/disputes.test.ts +15 -0
  234. package/src/client/connect/disputes.ts +13 -7
  235. package/src/client/connect/paymentMethods.test.ts +3 -1
  236. package/src/client/connect/paymentMethods.ts +4 -1
  237. package/src/client/connect/refundActor.ts +1 -2
  238. package/src/client/connect/refunds.test.ts +35 -10
  239. package/src/client/connect/refunds.ts +4 -1
  240. package/src/client/connect/transfers.test.ts +66 -12
  241. package/src/client/connect/transfers.ts +32 -8
  242. package/src/client/core/accountDefaults.ts +15 -0
  243. package/src/client/core/accounts.ts +14 -17
  244. package/src/client/core/config.test.ts +2 -1
  245. package/src/client/core/descriptors.test.ts +6 -4
  246. package/src/client/core/fees.test.ts +20 -28
  247. package/src/client/core/fees.ts +9 -2
  248. package/src/client/index.test.ts +22 -22
  249. package/src/client/index.ts +1 -1
  250. package/src/client/products/prices.test.ts +8 -2
  251. package/src/client/products/prices.ts +4 -1
  252. package/src/client/products/products.test.ts +61 -20
  253. package/src/client/products/products.ts +3 -1
  254. package/src/client/utils/data.test.ts +3 -1
  255. package/src/client/utils/owner.test.ts +4 -1
  256. package/src/client/utils/owner.ts +5 -1
  257. package/src/client/utils/stripeDashboardUrl.ts +1 -4
  258. package/src/client/webhooks/handler.test.ts +16 -19
  259. package/src/client/webhooks/helpers.test.ts +26 -13
  260. package/src/client/webhooks/helpers.ts +23 -0
  261. package/src/client/webhooks/hooks.test.ts +1 -2
  262. package/src/client/webhooks/processors.test.ts +18 -34
  263. package/src/client/webhooks/processors.ts +1 -23
  264. package/src/client/webhooks.test.ts +1 -2
  265. package/src/component/_generated/api.ts +2 -0
  266. package/src/component/connect/mutations.ts +5 -46
  267. package/src/component/connect/schema.ts +4 -3
  268. package/src/component/connect.test.ts +1 -5
  269. package/src/component/lib/paymentSeller.ts +15 -0
  270. package/src/component/lib/reversals.ts +30 -2
  271. package/src/component/subscription-scoping.test.ts +5 -1
  272. package/src/component/triggers.test.ts +7 -4
  273. package/src/react/components/BuyerBillingView.render.test.tsx +7 -2
  274. package/src/react/components/ConnectProvider.live.test.tsx +61 -0
  275. package/src/react/components/ConnectProvider.tsx +18 -4
  276. package/src/react/components/ConnectStatusBadge.tsx +1 -4
  277. package/src/react/components/DisputeDetail.render.test.tsx +5 -1
  278. package/src/react/components/DisputeDetail.tsx +14 -5
  279. package/src/react/components/DisputesList.render.test.tsx +21 -0
  280. package/src/react/components/DisputesList.tsx +2 -1
  281. package/src/react/components/EarningsSummary.render.test.tsx +2 -6
  282. package/src/react/components/EmbeddedDisputes.render.test.tsx +7 -5
  283. package/src/react/components/EmbeddedDisputes.tsx +4 -1
  284. package/src/react/components/EvidenceForm.render.test.tsx +3 -10
  285. package/src/react/components/SplitBreakdown.render.test.tsx +28 -5
  286. package/src/react/components/SplitBreakdown.tsx +12 -2
  287. package/src/react/hooks/useCheckoutSession.ts +1 -2
  288. package/src/react/hooks/useConfirmPayment.ts +1 -2
  289. package/src/react/hooks/useEarnings.test.ts +43 -8
  290. package/src/react/hooks/useStripeMode.test.ts +5 -8
  291. package/src/react/index.ts +7 -1
  292. package/src/react/workflows/Account.test.tsx +31 -0
  293. package/src/react/workflows/Account.tsx +183 -0
  294. package/src/react/workflows/Billing.test.tsx +45 -0
  295. package/src/react/workflows/Billing.tsx +213 -0
  296. package/src/react/workflows/BillingPlans.test.tsx +31 -0
  297. package/src/react/workflows/BillingPlans.tsx +130 -0
  298. package/src/react/workflows/Checkout.test.tsx +118 -0
  299. package/src/react/workflows/Checkout.tsx +135 -0
  300. package/src/react/workflows/CheckoutChooser.test.tsx +44 -0
  301. package/src/react/workflows/CheckoutChooser.tsx +77 -0
  302. package/src/react/workflows/CheckoutForm.test.tsx +66 -0
  303. package/src/react/workflows/CheckoutForms.test.tsx +123 -0
  304. package/src/react/workflows/CheckoutForms.tsx +247 -0
  305. package/src/react/workflows/ClipboardButton.test.tsx +34 -0
  306. package/src/react/workflows/ClipboardButton.tsx +67 -0
  307. package/src/react/workflows/Collection.tsx +76 -0
  308. package/src/react/workflows/Collections.test.tsx +86 -0
  309. package/src/react/workflows/Collections.tsx +213 -0
  310. package/src/react/workflows/Connect.test.tsx +50 -0
  311. package/src/react/workflows/Connect.tsx +107 -0
  312. package/src/react/workflows/Costs.test.tsx +41 -0
  313. package/src/react/workflows/Costs.tsx +133 -0
  314. package/src/react/workflows/Disputes.test.tsx +64 -0
  315. package/src/react/workflows/Disputes.tsx +173 -0
  316. package/src/react/workflows/Earnings.test.ts +19 -0
  317. package/src/react/workflows/Earnings.tsx +84 -0
  318. package/src/react/workflows/Financials.test.tsx +35 -0
  319. package/src/react/workflows/Financials.tsx +117 -0
  320. package/src/react/workflows/IntegrationSwitch.test.tsx +36 -0
  321. package/src/react/workflows/IntegrationSwitch.tsx +63 -0
  322. package/src/react/workflows/Onboarding.test.tsx +75 -0
  323. package/src/react/workflows/Onboarding.tsx +171 -0
  324. package/src/react/workflows/Overview.test.tsx +57 -0
  325. package/src/react/workflows/Overview.tsx +123 -0
  326. package/src/react/workflows/PaymentMethods.test.tsx +60 -0
  327. package/src/react/workflows/PaymentMethods.tsx +117 -0
  328. package/src/react/workflows/PaymentReceipt.test.tsx +24 -0
  329. package/src/react/workflows/PaymentReceipt.tsx +46 -0
  330. package/src/react/workflows/Payouts.test.tsx +112 -0
  331. package/src/react/workflows/Payouts.tsx +215 -0
  332. package/src/react/workflows/Products.test.tsx +90 -0
  333. package/src/react/workflows/Products.tsx +377 -0
  334. package/src/react/workflows/ReferralLinks.test.tsx +39 -0
  335. package/src/react/workflows/ReferralLinks.tsx +75 -0
  336. package/src/react/workflows/Refunds.test.tsx +75 -0
  337. package/src/react/workflows/Refunds.tsx +223 -0
  338. package/src/react/workflows/Setup.test.tsx +25 -0
  339. package/src/react/workflows/Setup.tsx +166 -0
  340. package/src/react/workflows/Storefront.test.tsx +82 -0
  341. package/src/react/workflows/Storefront.tsx +138 -0
  342. package/src/react/workflows/SubscriptionOverview.test.tsx +27 -0
  343. package/src/react/workflows/SubscriptionOverview.tsx +48 -0
  344. package/src/react/workflows/Subscriptions.test.tsx +61 -0
  345. package/src/react/workflows/Subscriptions.tsx +282 -0
  346. package/src/react/workflows/Tasks.test.tsx +23 -0
  347. package/src/react/workflows/Tasks.tsx +199 -0
  348. package/src/react/workflows/checkout-options.ts +42 -0
  349. package/src/react/workflows/current-subscription.test.ts +29 -0
  350. package/src/react/workflows/current-subscription.ts +25 -0
  351. package/src/react/workflows/filters.test.ts +12 -0
  352. package/src/react/workflows/filters.ts +22 -0
  353. package/src/react/workflows/index.ts +238 -0
  354. package/src/react/workflows/native-interactions.test.tsx +73 -0
  355. package/src/react/workflows/public-workflows.test.tsx +216 -0
  356. package/src/react/workflows/useWorkflowAction.test.tsx +54 -0
  357. package/src/react/workflows/useWorkflowAction.ts +75 -0
  358. package/src/react/workflows/useWorkflowResource.test.tsx +41 -0
  359. package/src/react/workflows/useWorkflowResource.ts +78 -0
@@ -64,10 +64,14 @@ export function computeReversalSlices(
64
64
  );
65
65
  break;
66
66
  case "fraction":
67
- to = Math.min(leg.amount, Math.max(from, Math.round(leg.amount * fraction)));
67
+ to = Math.min(
68
+ leg.amount,
69
+ Math.max(from, Math.round(leg.amount * fraction)),
70
+ );
68
71
  break;
69
72
  case "amount": {
70
- const prorata = total > 0 ? Math.round((mode.amount * leg.amount) / total) : 0;
73
+ const prorata =
74
+ total > 0 ? Math.round((mode.amount * leg.amount) / total) : 0;
71
75
  const take = Math.max(0, Math.min(prorata, budget, leg.amount - from));
72
76
  budget -= take;
73
77
  to = from + take;
@@ -111,3 +115,27 @@ export function computeReversalSlices(
111
115
 
112
116
  return slices;
113
117
  }
118
+
119
+ /**
120
+ * Derive reversal status + transfer status from a (transfer amount, cumulative
121
+ * reversed amount) pair. Shared by upsert and reversal so the three reversal
122
+ * fields can never drift.
123
+ */
124
+ export function deriveReversalState(
125
+ amount: number,
126
+ reversedAmount: number,
127
+ baseStatus: "pending" | "paid" | "failed" | "reversed",
128
+ ) {
129
+ const reversalStatus =
130
+ reversedAmount <= 0
131
+ ? undefined
132
+ : reversedAmount >= amount
133
+ ? ("fully_reversed" as const)
134
+ : ("partially_reversed" as const);
135
+ return {
136
+ reversedAmount: reversedAmount > 0 ? reversedAmount : undefined,
137
+ reversalStatus,
138
+ status:
139
+ reversalStatus === "fully_reversed" ? ("reversed" as const) : baseStatus,
140
+ };
141
+ }
@@ -64,7 +64,11 @@ describe("per-store subscription scoping (BTS-19)", () => {
64
64
 
65
65
  const active = await t.query(
66
66
  api.billing.queries.listSubscriptionsByUserAndStore,
67
- { userId: "buyer_1", destinationAccountId: "acct_store_a", status: "active" },
67
+ {
68
+ userId: "buyer_1",
69
+ destinationAccountId: "acct_store_a",
70
+ status: "active",
71
+ },
68
72
  );
69
73
  expect(active.map((s) => s.stripeSubscriptionId)).toEqual(["sub_active"]);
70
74
  });
@@ -236,10 +236,13 @@ describe("webhook event ledger", () => {
236
236
  it("fresh processing dedupes", async () => {
237
237
  const t = convexTest(schema, modules);
238
238
 
239
- const first = await t.mutation(api.webhooks.mutations.insertWebhookEvent, {
240
- stripeEventId: "evt_stale_001",
241
- eventType: "invoice.paid",
242
- });
239
+ const first = await t.mutation(
240
+ api.webhooks.mutations.insertWebhookEvent,
241
+ {
242
+ stripeEventId: "evt_stale_001",
243
+ eventType: "invoice.paid",
244
+ },
245
+ );
243
246
  expect(first).toBe("inserted");
244
247
 
245
248
  // Immediate second insert — row is fresh processing, must dedupe.
@@ -69,7 +69,10 @@ describe("BuyerBillingView", () => {
69
69
 
70
70
  it("renders the empty label with no subscriptions and no saved card", () => {
71
71
  const html = renderToStaticMarkup(
72
- createElement(BuyerBillingView, { subscriptions: [], paymentMethod: null }),
72
+ createElement(BuyerBillingView, {
73
+ subscriptions: [],
74
+ paymentMethod: null,
75
+ }),
73
76
  );
74
77
  expect(html).toContain("No billing yet");
75
78
  });
@@ -122,7 +125,9 @@ describe("BuyerBillingView", () => {
122
125
  createElement(BuyerBillingView, {
123
126
  subscriptions: [activeSub],
124
127
  paymentMethod,
125
- updateCardSlot: createElement("div", { "data-testid": "embedded-card" }),
128
+ updateCardSlot: createElement("div", {
129
+ "data-testid": "embedded-card",
130
+ }),
126
131
  }),
127
132
  );
128
133
  expect(html).toContain('data-testid="embedded-card"');
@@ -0,0 +1,61 @@
1
+ // @vitest-environment jsdom
2
+ import { cleanup, render } from "@testing-library/react";
3
+ import { afterEach, expect, it, vi } from "vitest";
4
+ import type { ReactNode } from "react";
5
+ const stripe = vi.hoisted(() => ({ initialize: vi.fn(), update: vi.fn() }));
6
+ vi.mock("@stripe/connect-js/pure.js", () => ({
7
+ loadConnectAndInitialize: stripe.initialize,
8
+ }));
9
+ vi.mock("@stripe/connect-js", () => ({
10
+ loadConnectAndInitialize: stripe.initialize,
11
+ }));
12
+ vi.mock("@stripe/react-connect-js", () => ({
13
+ ConnectComponentsProvider: ({ children }: { children: ReactNode }) =>
14
+ children,
15
+ }));
16
+ import { ConnectProvider } from "./ConnectProvider.js";
17
+ afterEach(() => {
18
+ cleanup();
19
+ vi.clearAllMocks();
20
+ });
21
+ it("updates appearance and locale while retaining the active Connect session", async () => {
22
+ stripe.initialize.mockReturnValue({ update: stripe.update });
23
+ const first = vi.fn(async () => "first_session");
24
+ const next = vi.fn(async () => "refreshed_session");
25
+ const { rerender } = render(
26
+ <ConnectProvider
27
+ publishableKey="pk_test_one"
28
+ fetchClientSecret={first}
29
+ locale="en"
30
+ />,
31
+ );
32
+ const fetch = stripe.initialize.mock.calls[0][0].fetchClientSecret;
33
+ expect(await fetch()).toBe("first_session");
34
+ rerender(
35
+ <ConnectProvider
36
+ publishableKey="pk_test_one"
37
+ fetchClientSecret={next}
38
+ locale="fr"
39
+ appearance={{ variables: { colorPrimary: "#123456" } }}
40
+ />,
41
+ );
42
+ expect(stripe.initialize).toHaveBeenCalledTimes(1);
43
+ expect(stripe.update).toHaveBeenLastCalledWith({
44
+ locale: "fr",
45
+ appearance: { variables: { colorPrimary: "#123456" } },
46
+ });
47
+ expect(await fetch()).toBe("refreshed_session");
48
+ expect(next).toHaveBeenCalledTimes(1);
49
+ });
50
+ it("creates a separate Connect instance when the publishable key changes", () => {
51
+ stripe.initialize.mockReturnValue({ update: stripe.update });
52
+ const fetch = async () => "session";
53
+ const { rerender } = render(
54
+ <ConnectProvider publishableKey="pk_test_one" fetchClientSecret={fetch} />,
55
+ );
56
+ rerender(
57
+ <ConnectProvider publishableKey="pk_test_two" fetchClientSecret={fetch} />,
58
+ );
59
+ expect(stripe.initialize).toHaveBeenCalledTimes(2);
60
+ expect(stripe.initialize.mock.calls[1][0].publishableKey).toBe("pk_test_two");
61
+ });
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
 
3
- import { type ReactNode, useState } from "react";
3
+ import { type ReactNode, useEffect, useRef, useState } from "react";
4
4
 
5
5
  import type { IStripeConnectInitParams } from "@stripe/connect-js";
6
- import { loadConnectAndInitialize } from "@stripe/connect-js";
6
+ import { loadConnectAndInitialize } from "@stripe/connect-js/pure.js";
7
7
  import { ConnectComponentsProvider } from "@stripe/react-connect-js";
8
8
 
9
9
  export type ConnectProviderProps = {
@@ -32,24 +32,38 @@ export type ConnectProviderProps = {
32
32
  * ConnectJS renders client-only iframes; on the server this component renders
33
33
  * its tree but the embedded surfaces only materialize in the browser.
34
34
  */
35
- export function ConnectProvider({
35
+ export function ConnectProvider(props: ConnectProviderProps) {
36
+ return <ConnectInstanceProvider key={props.publishableKey} {...props} />;
37
+ }
38
+ function ConnectInstanceProvider({
36
39
  publishableKey,
37
40
  fetchClientSecret,
38
41
  appearance,
39
42
  locale,
40
43
  children,
41
44
  }: ConnectProviderProps) {
45
+ const fetcher = useRef(fetchClientSecret);
46
+ useEffect(() => {
47
+ fetcher.current = fetchClientSecret;
48
+ }, [fetchClientSecret]);
42
49
  // Lazy useState initializer: exactly one Connect instance per mount, stable
43
50
  // across re-renders (loadConnectAndInitialize returns synchronously).
44
51
  const [connectInstance] = useState(() =>
45
52
  loadConnectAndInitialize({
46
53
  publishableKey,
47
- fetchClientSecret,
54
+ fetchClientSecret: () => fetcher.current(),
48
55
  ...(appearance !== undefined ? { appearance } : {}),
49
56
  ...(locale !== undefined ? { locale } : {}),
50
57
  }),
51
58
  );
52
59
 
60
+ useEffect(() => {
61
+ if (appearance !== undefined || locale !== undefined)
62
+ connectInstance.update({
63
+ ...(appearance !== undefined ? { appearance } : {}),
64
+ ...(locale !== undefined ? { locale } : {}),
65
+ });
66
+ }, [connectInstance, appearance, locale]);
53
67
  return (
54
68
  <ConnectComponentsProvider connectInstance={connectInstance}>
55
69
  {children}
@@ -3,10 +3,7 @@
3
3
  import type { ReactNode } from "react";
4
4
 
5
5
  export type ConnectStatus =
6
- | "pending"
7
- | "in_progress"
8
- | "complete"
9
- | "restricted";
6
+ "pending" | "in_progress" | "complete" | "restricted";
10
7
 
11
8
  export type ConnectStatusDetails = {
12
9
  detailsSubmitted: boolean;
@@ -74,7 +74,11 @@ describe("DisputeDetail", () => {
74
74
  createElement(DisputeDetail, {
75
75
  dispute: {
76
76
  ...dispute,
77
- countdown: { dueBy: dispute.evidenceDueBy, daysRemaining: -2, isOverdue: true },
77
+ countdown: {
78
+ dueBy: dispute.evidenceDueBy,
79
+ daysRemaining: -2,
80
+ isOverdue: true,
81
+ },
78
82
  },
79
83
  }),
80
84
  );
@@ -5,6 +5,11 @@ import type { ReactNode } from "react";
5
5
  import type { DisputeWithCountdown } from "../hooks/useDisputeWithCountdown.js";
6
6
  import { formatPrice } from "../lib/price-helpers.js";
7
7
 
8
+ /** Stripe only accepts responses while the dispute requires one. */
9
+ export function canRespondToDispute(status: string | undefined) {
10
+ return status === "needs_response" || status === "warning_needs_response";
11
+ }
12
+
8
13
  export type DisputeDetailRenderProps = {
9
14
  dispute: DisputeWithCountdown;
10
15
  /** Formatted dispute amount, e.g. "$120.50". */
@@ -26,6 +31,7 @@ export type DisputeDetailProps = {
26
31
  dueLabel?: string;
27
32
  overdueLabel?: string;
28
33
  noDeadlineLabel?: string;
34
+ responseClosedLabel?: string;
29
35
  /** Field captions in the default rendering. */
30
36
  labels?: {
31
37
  amount?: string;
@@ -53,6 +59,7 @@ export function DisputeDetail({
53
59
  dueLabel = "Evidence due in {days} days",
54
60
  overdueLabel = "Evidence overdue",
55
61
  noDeadlineLabel = "No evidence deadline",
62
+ responseClosedLabel = "Evidence submission closed",
56
63
  labels,
57
64
  locale,
58
65
  className,
@@ -70,11 +77,13 @@ export function DisputeDetail({
70
77
  }
71
78
 
72
79
  const { countdown } = dispute;
73
- const countdownMessage = countdown.isOverdue
74
- ? overdueLabel
75
- : countdown.daysRemaining !== undefined
76
- ? dueLabel.replace("{days}", String(countdown.daysRemaining))
77
- : noDeadlineLabel;
80
+ const countdownMessage = !canRespondToDispute(dispute.status)
81
+ ? responseClosedLabel
82
+ : countdown.isOverdue
83
+ ? overdueLabel
84
+ : countdown.daysRemaining !== undefined
85
+ ? dueLabel.replace("{days}", String(countdown.daysRemaining))
86
+ : noDeadlineLabel;
78
87
 
79
88
  const renderProps: DisputeDetailRenderProps = {
80
89
  dispute,
@@ -242,3 +242,24 @@ describe("DisputesList", () => {
242
242
  expect(html).not.toContain("No disputes");
243
243
  });
244
244
  });
245
+ it.each(["won", "lost", "under_review"] as const)(
246
+ "hides stale evidence deadlines for %s disputes",
247
+ (status) => {
248
+ const html = renderToStaticMarkup(
249
+ createElement(DisputesList, {
250
+ disputes: [
251
+ makeDispute({
252
+ status,
253
+ countdown: {
254
+ dueBy: "2030-01-01T00:00:00Z",
255
+ daysRemaining: 9,
256
+ isOverdue: false,
257
+ },
258
+ }),
259
+ ],
260
+ }),
261
+ );
262
+ expect(html).toContain(status);
263
+ expect(html).not.toContain("Evidence due in");
264
+ },
265
+ );
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import type { ReactNode } from "react";
4
+ import { canRespondToDispute } from "./DisputeDetail.js";
4
5
 
5
6
  import type { StripeComponentDispute } from "../types.js";
6
7
  import type { DisputeEvidenceCountdown } from "../hooks/useDisputeWithCountdown.js";
@@ -78,7 +79,7 @@ export function DisputesList({
78
79
 
79
80
  const badgeTextFor = (row: DisputesListRow): string | undefined => {
80
81
  const countdown = row.countdown;
81
- if (!countdown?.dueBy) return undefined;
82
+ if (!canRespondToDispute(row.status) || !countdown?.dueBy) return undefined;
82
83
  if (countdown.isOverdue) return overdueLabel;
83
84
  return dueLabel.replace("{days}", String(countdown.daysRemaining));
84
85
  };
@@ -73,9 +73,7 @@ describe("EarningsSummary", () => {
73
73
  });
74
74
 
75
75
  it("renders gross, reversals, net, and paid-out amounts", () => {
76
- const html = renderToStaticMarkup(
77
- createElement(EarningsSummary, earnings),
78
- );
76
+ const html = renderToStaticMarkup(createElement(EarningsSummary, earnings));
79
77
  expect(html).toContain("Gross");
80
78
  expect(html).toContain("$105.00");
81
79
  // Honest label per the BTS-36 review — NOT "Fees".
@@ -89,9 +87,7 @@ describe("EarningsSummary", () => {
89
87
  });
90
88
 
91
89
  it("announces the latest payout with amount and status", () => {
92
- const html = renderToStaticMarkup(
93
- createElement(EarningsSummary, earnings),
94
- );
90
+ const html = renderToStaticMarkup(createElement(EarningsSummary, earnings));
95
91
  // po_latest (newest _creationTime) wins over po_old.
96
92
  expect(html).toContain("Latest payout of $40.00 — in_transit");
97
93
  });
@@ -21,12 +21,15 @@ const loadConnectAndInitialize = vi.fn(
21
21
  }),
22
22
  );
23
23
 
24
- vi.mock("@stripe/connect-js", () => ({
24
+ vi.mock("@stripe/connect-js/pure.js", () => ({
25
25
  loadConnectAndInitialize: (initParams: unknown) =>
26
26
  loadConnectAndInitialize(initParams as Record<string, unknown>),
27
27
  }));
28
28
 
29
- vi.mock("@stripe/react-connect-js", () => ({
29
+ vi.mock("@stripe/react-connect-js", async () => ({
30
+ ...(await vi.importActual<typeof import("@stripe/react-connect-js")>(
31
+ "@stripe/react-connect-js",
32
+ )),
30
33
  ConnectComponentsProvider: ({
31
34
  connectInstance,
32
35
  children,
@@ -73,9 +76,8 @@ describe("ConnectProvider", () => {
73
76
  expect(loadConnectAndInitialize).toHaveBeenCalledTimes(1);
74
77
  const initParams = loadConnectAndInitialize.mock.calls[0][0];
75
78
  expect(initParams.publishableKey).toBe("pk_test_123");
76
- // The EXACT fetcher reference is handed over — the Connect runtime calls
77
- // it to obtain the createDisputeSession clientSecret; render must not.
78
- expect(initParams.fetchClientSecret).toBe(fetchClientSecret);
79
+ // The Connect runtime receives a lazy fetcher. Rendering does not request a session.
80
+ expect(initParams.fetchClientSecret).toEqual(expect.any(Function));
79
81
  expect(fetchClientSecret).not.toHaveBeenCalled();
80
82
  // Provider rendered with an instance, children inside.
81
83
  expect(html).toContain('data-testid="connect-provider"');
@@ -25,7 +25,10 @@ export type EmbeddedDisputesProps = {
25
25
  * Must be rendered inside a {@link ConnectProvider} whose `fetchClientSecret`
26
26
  * returns that session's `clientSecret`.
27
27
  */
28
- export function EmbeddedDisputes({ payment, className }: EmbeddedDisputesProps) {
28
+ export function EmbeddedDisputes({
29
+ payment,
30
+ className,
31
+ }: EmbeddedDisputesProps) {
29
32
  return (
30
33
  <div className={className}>
31
34
  {payment ? (
@@ -19,10 +19,7 @@ import { renderToStaticMarkup } from "react-dom/server";
19
19
  import { describe, expect, it, vi } from "vitest";
20
20
 
21
21
  import { EvidenceForm as BarrelExport } from "../index.js";
22
- import {
23
- EvidenceForm,
24
- type EvidenceFormRenderProps,
25
- } from "./EvidenceForm.js";
22
+ import { EvidenceForm, type EvidenceFormRenderProps } from "./EvidenceForm.js";
26
23
 
27
24
  const allFields = {
28
25
  productDescription: "Ceramics Masterclass, lifetime access",
@@ -33,10 +30,7 @@ const allFields = {
33
30
 
34
31
  /** Render via the children prop and hand back the captured render props. */
35
32
  function capture(
36
- props: Omit<
37
- Parameters<typeof EvidenceForm>[0],
38
- "children"
39
- >,
33
+ props: Omit<Parameters<typeof EvidenceForm>[0], "children">,
40
34
  ): EvidenceFormRenderProps {
41
35
  let received: EvidenceFormRenderProps | undefined;
42
36
  renderToStaticMarkup(
@@ -85,8 +79,7 @@ describe("EvidenceForm", () => {
85
79
  expect(args.evidence).toEqual({
86
80
  product_description: allFields.productDescription,
87
81
  access_activity_log: allFields.accessActivity,
88
- uncategorized_text: allFields.additionalInfo,
89
- customer_communication: allFields.customerCommunication,
82
+ uncategorized_text: `${allFields.additionalInfo}\n\nCustomer communication:\n${allFields.customerCommunication}`,
90
83
  });
91
84
  // Stripe's dispute-update `submit` DEFAULTS TO TRUE when omitted, so a
92
85
  // draft must send an explicit false — omission would submit to the bank.
@@ -34,8 +34,18 @@ const leg = (over: Record<string, unknown>) => ({
34
34
 
35
35
  const totals = {
36
36
  legs: [
37
- leg({ stripeTransferId: "tr_store", role: "store", amount: 8000, net: 8000 }),
38
- leg({ stripeTransferId: "tr_aff", role: "affiliate", amount: 1000, net: 1000 }),
37
+ leg({
38
+ stripeTransferId: "tr_store",
39
+ role: "store",
40
+ amount: 8000,
41
+ net: 8000,
42
+ }),
43
+ leg({
44
+ stripeTransferId: "tr_aff",
45
+ role: "affiliate",
46
+ amount: 1000,
47
+ net: 1000,
48
+ }),
39
49
  ],
40
50
  store: 8000,
41
51
  affiliate: 1000,
@@ -79,7 +89,10 @@ describe("SplitBreakdown", () => {
79
89
  createElement(SplitBreakdown, {
80
90
  breakdown: {
81
91
  ...totals,
82
- legs: [...totals.legs, leg({ stripeTransferId: "tr_misc", amount: 500, net: 500 })],
92
+ legs: [
93
+ ...totals.legs,
94
+ leg({ stripeTransferId: "tr_misc", amount: 500, net: 500 }),
95
+ ],
83
96
  other: 500,
84
97
  recipientsTotal: 9500,
85
98
  platform: 500,
@@ -136,8 +149,18 @@ describe("SplitBreakdown", () => {
136
149
  expect(received!.breakdown).toBe(totals);
137
150
  expect(received!.lines).toEqual([
138
151
  { key: "store", label: "Store", amount: 8000, amountLabel: "$80.00" },
139
- { key: "affiliate", label: "Affiliate", amount: 1000, amountLabel: "$10.00" },
140
- { key: "platform", label: "Platform", amount: 1000, amountLabel: "$10.00" },
152
+ {
153
+ key: "affiliate",
154
+ label: "Affiliate",
155
+ amount: 1000,
156
+ amountLabel: "$10.00",
157
+ },
158
+ {
159
+ key: "platform",
160
+ label: "Platform",
161
+ amount: 1000,
162
+ amountLabel: "$10.00",
163
+ },
141
164
  ]);
142
165
  expect(html).toBe("<p>3</p>");
143
166
  });
@@ -75,7 +75,11 @@ export function SplitBreakdown({
75
75
  const money = (amount: number) => formatPrice(amount, currency, locale);
76
76
 
77
77
  const lines: SplitBreakdownLine[] = [
78
- { key: "store" as const, label: labels?.store ?? "Store", amount: breakdown.store },
78
+ {
79
+ key: "store" as const,
80
+ label: labels?.store ?? "Store",
81
+ amount: breakdown.store,
82
+ },
79
83
  {
80
84
  key: "affiliate" as const,
81
85
  label: labels?.affiliate ?? "Affiliate",
@@ -83,7 +87,13 @@ export function SplitBreakdown({
83
87
  },
84
88
  // The catch-all bucket only earns a line when it carries money.
85
89
  ...(breakdown.other > 0
86
- ? [{ key: "other" as const, label: labels?.other ?? "Other", amount: breakdown.other }]
90
+ ? [
91
+ {
92
+ key: "other" as const,
93
+ label: labels?.other ?? "Other",
94
+ amount: breakdown.other,
95
+ },
96
+ ]
87
97
  : []),
88
98
  {
89
99
  key: "platform" as const,
@@ -14,8 +14,7 @@ function extractErrorMessage(error: unknown, fallback: string): string {
14
14
  * Result of a checkout confirmation attempt.
15
15
  */
16
16
  export type CheckoutConfirmResult =
17
- | { type: "success" }
18
- | { type: "error"; message: string };
17
+ { type: "success" } | { type: "error"; message: string };
19
18
 
20
19
  /**
21
20
  * Checkout session state and actions.
@@ -8,8 +8,7 @@ import { useElements, useStripe } from "@stripe/react-stripe-js";
8
8
  * Normalized result from a Stripe confirmation operation.
9
9
  */
10
10
  export type StripeConfirmResult =
11
- | { success: true }
12
- | { success: false; error: string };
11
+ { success: true } | { success: false; error: string };
13
12
 
14
13
  /**
15
14
  * Hook for confirming a PaymentIntent (immediate charge) or SetupIntent (future charge / trial).
@@ -48,8 +48,20 @@ const earningsResult = {
48
48
  };
49
49
 
50
50
  const previewPayouts = [
51
- { stripePayoutId: "po_1", accountId: "acct_store", amount: 4000, currency: "usd", status: "paid" },
52
- { stripePayoutId: "po_2", accountId: "acct_store", amount: 1500, currency: "usd", status: "pending" },
51
+ {
52
+ stripePayoutId: "po_1",
53
+ accountId: "acct_store",
54
+ amount: 4000,
55
+ currency: "usd",
56
+ status: "paid",
57
+ },
58
+ {
59
+ stripePayoutId: "po_2",
60
+ accountId: "acct_store",
61
+ amount: 1500,
62
+ currency: "usd",
63
+ status: "pending",
64
+ },
53
65
  ];
54
66
 
55
67
  const payoutsResult = {
@@ -70,7 +82,11 @@ describe("createUseEarnings", () => {
70
82
  [payoutsRef, payoutsResult],
71
83
  ]),
72
84
  );
73
- const useEarnings = createUseEarnings(mockUseQuery, earningsRef, payoutsRef);
85
+ const useEarnings = createUseEarnings(
86
+ mockUseQuery,
87
+ earningsRef,
88
+ payoutsRef,
89
+ );
74
90
 
75
91
  const result = useEarnings("acct_store");
76
92
 
@@ -92,7 +108,11 @@ describe("createUseEarnings", () => {
92
108
  [payoutsRef, payoutsResult],
93
109
  ]),
94
110
  );
95
- const useEarnings = createUseEarnings(mockUseQuery, earningsRef, payoutsRef);
111
+ const useEarnings = createUseEarnings(
112
+ mockUseQuery,
113
+ earningsRef,
114
+ payoutsRef,
115
+ );
96
116
 
97
117
  const result = useEarnings("acct_store");
98
118
 
@@ -111,7 +131,11 @@ describe("createUseEarnings", () => {
111
131
  [payoutsRef, undefined],
112
132
  ]),
113
133
  );
114
- const useEarnings = createUseEarnings(mockUseQuery, earningsRef, payoutsRef);
134
+ const useEarnings = createUseEarnings(
135
+ mockUseQuery,
136
+ earningsRef,
137
+ payoutsRef,
138
+ );
115
139
 
116
140
  const result = useEarnings("acct_store");
117
141
 
@@ -125,7 +149,11 @@ describe("createUseEarnings", () => {
125
149
 
126
150
  it("skips both queries when the account id is undefined", () => {
127
151
  const mockUseQuery = useQueryFor(new Map());
128
- const useEarnings = createUseEarnings(mockUseQuery, earningsRef, payoutsRef);
152
+ const useEarnings = createUseEarnings(
153
+ mockUseQuery,
154
+ earningsRef,
155
+ payoutsRef,
156
+ );
129
157
 
130
158
  const result = useEarnings(undefined);
131
159
 
@@ -143,11 +171,18 @@ describe("createUseEarnings", () => {
143
171
  it("treats empty ledgers as loaded with zero totals", () => {
144
172
  const mockUseQuery = useQueryFor(
145
173
  new Map<unknown, unknown>([
146
- [earningsRef, { gross: 0, reversed: 0, transferCount: 0, transfers: [] }],
174
+ [
175
+ earningsRef,
176
+ { gross: 0, reversed: 0, transferCount: 0, transfers: [] },
177
+ ],
147
178
  [payoutsRef, { paidOut: 0, payoutCount: 0, payouts: [] }],
148
179
  ]),
149
180
  );
150
- const useEarnings = createUseEarnings(mockUseQuery, earningsRef, payoutsRef);
181
+ const useEarnings = createUseEarnings(
182
+ mockUseQuery,
183
+ earningsRef,
184
+ payoutsRef,
185
+ );
151
186
 
152
187
  const result = useEarnings("acct_new");
153
188
 
@@ -28,16 +28,13 @@ describe("useStripeMode", () => {
28
28
  expect(useQueryMock).toHaveBeenCalledWith(mockQueryRef, {});
29
29
  });
30
30
 
31
- it.each(["test", "live"] as const)(
32
- "returns the resolved %s mode",
33
- (mode) => {
34
- useQueryMock.mockReturnValue(mode);
31
+ it.each(["test", "live"] as const)("returns the resolved %s mode", (mode) => {
32
+ useQueryMock.mockReturnValue(mode);
35
33
 
36
- const result = useStripeMode(mockQueryRef);
34
+ const result = useStripeMode(mockQueryRef);
37
35
 
38
- expect(result).toBe(mode);
39
- },
40
- );
36
+ expect(result).toBe(mode);
37
+ });
41
38
 
42
39
  it("returns undefined while the query is still loading", () => {
43
40
  useQueryMock.mockReturnValue(undefined);