@volter/twin-stripe 2.0.37 → 3.0.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 (442) hide show
  1. package/README.md +82 -207
  2. package/dist/generated/pack-facts.json +94 -0
  3. package/dist/spec/SOURCE.md +14 -0
  4. package/dist/spec/fixtures3.json.gz +0 -0
  5. package/dist/spec/openapi.json.gz +0 -0
  6. package/dist/spec/patches.json +34 -0
  7. package/dist/spec/sources.json +378 -0
  8. package/dist/src/cli.js +12 -30
  9. package/dist/src/engine/after-payment.d.ts +9 -0
  10. package/dist/src/engine/after-payment.js +28 -0
  11. package/dist/src/engine/apps-secrets.d.ts +1 -0
  12. package/dist/src/engine/apps-secrets.js +3 -0
  13. package/dist/src/engine/balance.d.ts +5 -0
  14. package/dist/src/engine/balance.js +15 -0
  15. package/dist/src/engine/billing.d.ts +5 -0
  16. package/dist/src/engine/billing.js +6 -0
  17. package/dist/src/engine/charges.d.ts +6 -0
  18. package/dist/src/engine/charges.js +13 -0
  19. package/dist/src/engine/checkout.d.ts +24 -0
  20. package/dist/src/engine/checkout.js +30 -0
  21. package/dist/src/engine/common.d.ts +19 -0
  22. package/dist/src/engine/common.js +32 -0
  23. package/dist/src/{screens → engine}/connect-settings.d.ts +1 -7
  24. package/dist/src/engine/connect-settings.js +26 -0
  25. package/dist/src/engine/connect.d.ts +66 -0
  26. package/dist/src/engine/connect.js +189 -0
  27. package/dist/src/engine/coupons.d.ts +0 -0
  28. package/dist/src/engine/coupons.js +5 -0
  29. package/dist/src/engine/credit-notes.d.ts +1 -0
  30. package/dist/src/engine/credit-notes.js +5 -0
  31. package/dist/src/engine/customers.d.ts +12 -0
  32. package/dist/src/engine/customers.js +30 -0
  33. package/dist/src/engine/display.d.ts +14 -0
  34. package/dist/src/engine/display.js +16 -0
  35. package/dist/src/engine/disputes.d.ts +0 -0
  36. package/dist/src/engine/disputes.js +9 -0
  37. package/dist/src/engine/entitlements.d.ts +1 -0
  38. package/dist/src/engine/entitlements.js +4 -0
  39. package/dist/src/engine/ephemeral-keys.d.ts +0 -0
  40. package/dist/src/engine/ephemeral-keys.js +4 -0
  41. package/dist/src/engine/files.d.ts +18 -0
  42. package/dist/src/engine/files.js +33 -0
  43. package/dist/src/engine/front.d.ts +5 -0
  44. package/dist/src/engine/front.js +25 -0
  45. package/dist/src/engine/invoices.d.ts +24 -0
  46. package/dist/src/engine/invoices.js +57 -0
  47. package/dist/src/engine/issuing.d.ts +35 -0
  48. package/dist/src/engine/issuing.js +45 -0
  49. package/dist/src/engine/ledger.d.ts +9 -0
  50. package/dist/src/engine/ledger.js +9 -0
  51. package/dist/src/engine/oauth.d.ts +4 -0
  52. package/dist/src/engine/oauth.js +25 -0
  53. package/dist/src/engine/onboarding.d.ts +13 -0
  54. package/dist/src/engine/onboarding.js +42 -0
  55. package/dist/src/{stripe-params.d.ts → engine/params.d.ts} +20 -3
  56. package/dist/src/{stripe-params.js → engine/params.js} +7 -60
  57. package/dist/src/engine/payment-intents.d.ts +10 -0
  58. package/dist/src/engine/payment-intents.js +27 -0
  59. package/dist/src/engine/payment-links.d.ts +1 -0
  60. package/dist/src/engine/payment-links.js +5 -0
  61. package/dist/src/engine/payment-methods.d.ts +16 -0
  62. package/dist/src/engine/payment-methods.js +22 -0
  63. package/dist/src/engine/plans.d.ts +6 -0
  64. package/dist/src/engine/plans.js +26 -0
  65. package/dist/src/engine/platform.d.ts +39 -0
  66. package/dist/src/engine/platform.js +34 -0
  67. package/dist/src/engine/products.d.ts +0 -0
  68. package/dist/src/engine/products.js +4 -0
  69. package/dist/src/engine/radar.d.ts +2 -0
  70. package/dist/src/engine/radar.js +5 -0
  71. package/dist/src/engine/refunds.d.ts +1 -0
  72. package/dist/src/engine/refunds.js +28 -0
  73. package/dist/src/engine/renewals.d.ts +36 -0
  74. package/dist/src/engine/renewals.js +65 -0
  75. package/dist/src/engine/setup-intents.d.ts +1 -0
  76. package/dist/src/engine/setup-intents.js +4 -0
  77. package/dist/src/{stripe-twin.d.ts → engine/stripe.d.ts} +11 -39
  78. package/dist/src/{stripe-twin.js → engine/stripe.js} +25 -310
  79. package/dist/src/engine/subscription-schedules.d.ts +3 -0
  80. package/dist/src/engine/subscription-schedules.js +1 -0
  81. package/dist/src/engine/subscriptions.d.ts +12 -0
  82. package/dist/src/engine/subscriptions.js +31 -0
  83. package/dist/src/engine/tax.d.ts +7 -0
  84. package/dist/src/engine/tax.js +28 -0
  85. package/dist/src/engine/terminal.d.ts +4 -0
  86. package/dist/src/engine/terminal.js +20 -0
  87. package/dist/src/engine/test-clocks.d.ts +5 -0
  88. package/dist/src/engine/test-clocks.js +9 -0
  89. package/dist/src/engine/tokens.d.ts +7 -0
  90. package/dist/src/engine/tokens.js +20 -0
  91. package/dist/src/engine/transfers.d.ts +2 -0
  92. package/dist/src/engine/transfers.js +1 -0
  93. package/dist/src/engine/treasury.d.ts +23 -0
  94. package/dist/src/engine/treasury.js +45 -0
  95. package/dist/src/{stripe-version.js → engine/version.js} +4 -3
  96. package/dist/src/engine/webhook-endpoints.d.ts +1 -0
  97. package/dist/src/engine/webhook-endpoints.js +12 -0
  98. package/dist/src/engine/webhooks.d.ts +31 -0
  99. package/dist/src/engine/webhooks.js +68 -0
  100. package/dist/src/fetch.d.ts +2 -0
  101. package/dist/src/fetch.js +26 -0
  102. package/dist/src/generated/surface.gen.json +1 -1
  103. package/dist/src/generated/ui.gen.json +1 -1
  104. package/dist/src/index.d.ts +5 -14
  105. package/dist/src/index.js +8 -75
  106. package/dist/src/manifest.js +232 -758
  107. package/dist/src/screens/billing-portal.d.ts +3 -0
  108. package/dist/src/screens/{portal.js → billing-portal.js} +28 -54
  109. package/dist/src/screens/checkout.d.ts +2 -31
  110. package/dist/src/screens/checkout.js +32 -121
  111. package/dist/src/screens/connect-oauth.d.ts +3 -27
  112. package/dist/src/screens/connect-oauth.js +51 -132
  113. package/dist/src/screens/connect-onboarding.d.ts +3 -0
  114. package/dist/src/screens/{onboarding.js → connect-onboarding.js} +36 -102
  115. package/dist/src/screens/dashboard.d.ts +3 -0
  116. package/dist/src/screens/dashboard.js +117 -0
  117. package/dist/src/screens/shared.d.ts +27 -0
  118. package/dist/src/screens/shared.js +87 -0
  119. package/dist/src/screens/stripe-js.d.ts +3 -0
  120. package/dist/src/screens/stripe-js.js +135 -0
  121. package/dist/src/semantics/account_links.d.ts +2 -0
  122. package/dist/src/semantics/account_links.js +22 -0
  123. package/dist/src/semantics/accounts.d.ts +4 -0
  124. package/dist/src/semantics/accounts.js +38 -0
  125. package/dist/src/semantics/apps.d.ts +4 -0
  126. package/dist/src/semantics/{apps-secrets.js → apps.js} +14 -26
  127. package/dist/src/semantics/around.d.ts +2 -0
  128. package/dist/src/semantics/around.js +16 -0
  129. package/dist/src/semantics/balance.d.ts +2 -11
  130. package/dist/src/semantics/balance.js +3 -194
  131. package/dist/src/semantics/balance_transactions.d.ts +2 -0
  132. package/dist/src/semantics/balance_transactions.js +15 -0
  133. package/dist/src/semantics/billing_portal.d.ts +5 -0
  134. package/dist/src/semantics/billing_portal.js +42 -0
  135. package/dist/src/semantics/charges.d.ts +3 -28
  136. package/dist/src/semantics/charges.js +5 -202
  137. package/dist/src/semantics/checkout.d.ts +3 -20
  138. package/dist/src/semantics/checkout.js +8 -261
  139. package/dist/src/semantics/clock.d.ts +2 -0
  140. package/dist/src/semantics/clock.js +21 -0
  141. package/dist/src/semantics/coupons.d.ts +2 -6
  142. package/dist/src/semantics/coupons.js +2 -60
  143. package/dist/src/semantics/customers.d.ts +6 -6
  144. package/dist/src/semantics/customers.js +27 -387
  145. package/dist/src/semantics/disputes.d.ts +2 -2
  146. package/dist/src/semantics/disputes.js +3 -49
  147. package/dist/src/semantics/doors.d.ts +23 -0
  148. package/dist/src/semantics/doors.js +73 -0
  149. package/dist/src/semantics/entitlements.d.ts +2 -2
  150. package/dist/src/semantics/entitlements.js +5 -50
  151. package/dist/src/semantics/events.d.ts +12 -0
  152. package/dist/src/semantics/events.js +36 -0
  153. package/dist/src/semantics/index.d.ts +2 -0
  154. package/dist/src/semantics/index.js +107 -0
  155. package/dist/src/semantics/invoice_payments.d.ts +2 -0
  156. package/dist/src/semantics/invoice_payments.js +12 -0
  157. package/dist/src/semantics/invoiceitems.d.ts +3 -0
  158. package/dist/src/semantics/invoiceitems.js +59 -0
  159. package/dist/src/semantics/invoices.d.ts +16 -18
  160. package/dist/src/semantics/invoices.js +118 -444
  161. package/dist/src/semantics/payment_intents.d.ts +4 -0
  162. package/dist/src/semantics/payment_intents.js +79 -0
  163. package/dist/src/semantics/payment_methods.d.ts +5 -0
  164. package/dist/src/semantics/payment_methods.js +39 -0
  165. package/dist/src/semantics/payouts.d.ts +2 -0
  166. package/dist/src/semantics/payouts.js +21 -0
  167. package/dist/src/semantics/prices.d.ts +4 -0
  168. package/dist/src/semantics/prices.js +37 -0
  169. package/dist/src/semantics/products.d.ts +6 -2
  170. package/dist/src/semantics/products.js +15 -130
  171. package/dist/src/semantics/promotion_codes.d.ts +3 -0
  172. package/dist/src/semantics/promotion_codes.js +35 -0
  173. package/dist/src/semantics/radar.d.ts +2 -2
  174. package/dist/src/semantics/radar.js +5 -74
  175. package/dist/src/semantics/refunds.d.ts +3 -9
  176. package/dist/src/semantics/refunds.js +6 -192
  177. package/dist/src/semantics/setup_intents.d.ts +3 -0
  178. package/dist/src/semantics/{setup-intents.js → setup_intents.js} +10 -53
  179. package/dist/src/semantics/shared.d.ts +822 -47
  180. package/dist/src/semantics/shared.js +3044 -78
  181. package/dist/src/semantics/states.d.ts +531 -0
  182. package/dist/src/semantics/states.js +852 -0
  183. package/dist/src/semantics/subscription_items.d.ts +5 -0
  184. package/dist/src/semantics/subscription_items.js +55 -0
  185. package/dist/src/semantics/subscription_schedules.d.ts +4 -0
  186. package/dist/src/semantics/subscription_schedules.js +60 -0
  187. package/dist/src/semantics/subscriptions.d.ts +7 -11
  188. package/dist/src/semantics/subscriptions.js +44 -415
  189. package/dist/src/semantics/test_helpers.d.ts +6 -0
  190. package/dist/src/semantics/{test-clocks.js → test_helpers.js} +14 -40
  191. package/dist/src/semantics/transfers.d.ts +2 -2
  192. package/dist/src/semantics/transfers.js +6 -101
  193. package/dist/src/server.d.ts +7 -0
  194. package/dist/src/server.js +7 -0
  195. package/generated/pack-facts.json +94 -0
  196. package/package.json +10 -20
  197. package/spec/SOURCE.md +14 -0
  198. package/spec/fixtures3.json.gz +0 -0
  199. package/spec/openapi.json.gz +0 -0
  200. package/spec/patches.json +34 -0
  201. package/spec/sources.json +378 -0
  202. package/src/cli.ts +12 -26
  203. package/src/engine/after-payment.ts +31 -0
  204. package/src/engine/apps-secrets.ts +4 -0
  205. package/src/engine/balance.ts +33 -0
  206. package/src/engine/billing.ts +16 -0
  207. package/src/engine/charges.ts +19 -0
  208. package/src/engine/checkout.ts +40 -0
  209. package/src/engine/common.ts +47 -0
  210. package/src/engine/connect-settings.ts +23 -0
  211. package/src/engine/connect.ts +184 -0
  212. package/src/engine/coupons.ts +5 -0
  213. package/src/engine/credit-notes.ts +6 -0
  214. package/src/engine/customers.ts +35 -0
  215. package/src/engine/display.ts +19 -0
  216. package/src/engine/disputes.ts +9 -0
  217. package/src/engine/entitlements.ts +5 -0
  218. package/src/engine/ephemeral-keys.ts +3 -0
  219. package/src/engine/files.ts +41 -0
  220. package/src/engine/front.ts +31 -0
  221. package/src/engine/invoices.ts +71 -0
  222. package/src/engine/issuing.ts +61 -0
  223. package/src/engine/ledger.ts +50 -0
  224. package/src/engine/oauth.ts +19 -0
  225. package/src/engine/onboarding.ts +54 -0
  226. package/src/{stripe-params.ts → engine/params.ts} +8 -56
  227. package/src/engine/payment-intents.ts +33 -0
  228. package/src/engine/payment-links.ts +6 -0
  229. package/src/engine/payment-methods.ts +25 -0
  230. package/src/engine/plans.ts +42 -0
  231. package/src/engine/platform.ts +47 -0
  232. package/src/engine/products.ts +3 -0
  233. package/src/engine/radar.ts +6 -0
  234. package/src/engine/refunds.ts +29 -0
  235. package/src/engine/renewals.ts +73 -0
  236. package/src/engine/setup-intents.ts +5 -0
  237. package/src/{stripe-twin.ts → engine/stripe.ts} +28 -323
  238. package/src/engine/subscription-schedules.ts +10 -0
  239. package/src/engine/subscriptions.ts +40 -0
  240. package/src/engine/tax.ts +39 -0
  241. package/src/engine/terminal.ts +23 -0
  242. package/src/engine/test-clocks.ts +11 -0
  243. package/src/engine/tokens.ts +22 -0
  244. package/src/engine/transfers.ts +23 -0
  245. package/src/engine/treasury.ts +47 -0
  246. package/src/{stripe-version.ts → engine/version.ts} +4 -3
  247. package/src/engine/webhook-endpoints.ts +14 -0
  248. package/src/engine/webhooks.ts +72 -0
  249. package/src/fetch.ts +27 -0
  250. package/src/generated/surface.gen.json +1 -1
  251. package/src/generated/ui.gen.json +1 -1
  252. package/src/index.ts +8 -116
  253. package/src/manifest.ts +234 -786
  254. package/src/screens/{portal.tsx → billing-portal.tsx} +32 -37
  255. package/src/screens/checkout.tsx +33 -95
  256. package/src/screens/connect-oauth.tsx +64 -88
  257. package/src/screens/{onboarding.tsx → connect-onboarding.tsx} +38 -82
  258. package/src/screens/dashboard.tsx +198 -0
  259. package/src/screens/shared.tsx +84 -0
  260. package/src/screens/stripe-js.ts +170 -0
  261. package/src/semantics/account_links.ts +21 -0
  262. package/src/semantics/accounts.ts +43 -0
  263. package/src/semantics/{apps-secrets.ts → apps.ts} +17 -32
  264. package/src/semantics/around.ts +20 -0
  265. package/src/semantics/balance.ts +6 -207
  266. package/src/semantics/balance_transactions.ts +20 -0
  267. package/src/semantics/billing_portal.ts +51 -0
  268. package/src/semantics/charges.ts +12 -211
  269. package/src/semantics/checkout.ts +13 -268
  270. package/src/semantics/clock.ts +26 -0
  271. package/src/semantics/coupons.ts +5 -67
  272. package/src/semantics/customers.ts +29 -392
  273. package/src/semantics/disputes.ts +9 -59
  274. package/src/semantics/doors.ts +80 -0
  275. package/src/semantics/entitlements.ts +9 -56
  276. package/src/semantics/events.ts +44 -0
  277. package/src/semantics/index.ts +111 -0
  278. package/src/semantics/invoice_payments.ts +18 -0
  279. package/src/semantics/invoiceitems.ts +59 -0
  280. package/src/semantics/invoices.ts +109 -443
  281. package/src/semantics/payment_intents.ts +83 -0
  282. package/src/semantics/payment_methods.ts +43 -0
  283. package/src/semantics/payouts.ts +23 -0
  284. package/src/semantics/prices.ts +42 -0
  285. package/src/semantics/products.ts +18 -142
  286. package/src/semantics/promotion_codes.ts +39 -0
  287. package/src/semantics/radar.ts +8 -77
  288. package/src/semantics/refunds.ts +9 -212
  289. package/src/semantics/setup_intents.ts +45 -0
  290. package/src/semantics/shared.ts +3092 -106
  291. package/src/semantics/states.ts +883 -0
  292. package/src/semantics/subscription_items.ts +54 -0
  293. package/src/semantics/subscription_schedules.ts +66 -0
  294. package/src/semantics/subscriptions.ts +49 -432
  295. package/src/semantics/{test-clocks.ts → test_helpers.ts} +23 -47
  296. package/src/semantics/transfers.ts +11 -131
  297. package/src/server.ts +8 -0
  298. package/client/dashboard-api.ts +0 -286
  299. package/client/stripe-mirror.css +0 -277
  300. package/client/stripe-mirror.tsx +0 -1559
  301. package/dist/client/dashboard-api.d.ts +0 -107
  302. package/dist/client/dashboard-api.js +0 -238
  303. package/dist/client/dashboard-api.ts +0 -286
  304. package/dist/client/stripe-mirror.bundle.js +0 -236
  305. package/dist/client/stripe-mirror.css +0 -277
  306. package/dist/client/stripe-mirror.d.ts +0 -134
  307. package/dist/client/stripe-mirror.js +0 -859
  308. package/dist/client/stripe-mirror.tsx +0 -1559
  309. package/dist/src/screens/connect-settings.js +0 -103
  310. package/dist/src/screens/consent-skin.d.ts +0 -4
  311. package/dist/src/screens/consent-skin.js +0 -18
  312. package/dist/src/screens/financial-connections.d.ts +0 -5
  313. package/dist/src/screens/financial-connections.js +0 -90
  314. package/dist/src/screens/identity.d.ts +0 -5
  315. package/dist/src/screens/identity.js +0 -86
  316. package/dist/src/screens/onboarding.d.ts +0 -13
  317. package/dist/src/screens/portal.d.ts +0 -5
  318. package/dist/src/screens/public-details.d.ts +0 -5
  319. package/dist/src/screens/public-details.js +0 -90
  320. package/dist/src/semantics/after-payment.d.ts +0 -22
  321. package/dist/src/semantics/after-payment.js +0 -99
  322. package/dist/src/semantics/apps-secrets.d.ts +0 -2
  323. package/dist/src/semantics/billing.d.ts +0 -2
  324. package/dist/src/semantics/billing.js +0 -220
  325. package/dist/src/semantics/connect.d.ts +0 -5
  326. package/dist/src/semantics/connect.js +0 -493
  327. package/dist/src/semantics/credit-notes.d.ts +0 -2
  328. package/dist/src/semantics/credit-notes.js +0 -172
  329. package/dist/src/semantics/ephemeral-keys.d.ts +0 -2
  330. package/dist/src/semantics/ephemeral-keys.js +0 -34
  331. package/dist/src/semantics/files.d.ts +0 -2
  332. package/dist/src/semantics/files.js +0 -125
  333. package/dist/src/semantics/issuing.d.ts +0 -13
  334. package/dist/src/semantics/issuing.js +0 -575
  335. package/dist/src/semantics/ledger.d.ts +0 -59
  336. package/dist/src/semantics/ledger.js +0 -200
  337. package/dist/src/semantics/payment-intents.d.ts +0 -18
  338. package/dist/src/semantics/payment-intents.js +0 -452
  339. package/dist/src/semantics/payment-links.d.ts +0 -2
  340. package/dist/src/semantics/payment-links.js +0 -133
  341. package/dist/src/semantics/payment-methods.d.ts +0 -20
  342. package/dist/src/semantics/payment-methods.js +0 -140
  343. package/dist/src/semantics/plans.d.ts +0 -5
  344. package/dist/src/semantics/plans.js +0 -121
  345. package/dist/src/semantics/platform.d.ts +0 -9
  346. package/dist/src/semantics/platform.js +0 -206
  347. package/dist/src/semantics/renewals.d.ts +0 -47
  348. package/dist/src/semantics/renewals.js +0 -281
  349. package/dist/src/semantics/setup-intents.d.ts +0 -2
  350. package/dist/src/semantics/subscription-schedules.d.ts +0 -2
  351. package/dist/src/semantics/subscription-schedules.js +0 -119
  352. package/dist/src/semantics/tax.d.ts +0 -2
  353. package/dist/src/semantics/tax.js +0 -197
  354. package/dist/src/semantics/terminal.d.ts +0 -5
  355. package/dist/src/semantics/terminal.js +0 -182
  356. package/dist/src/semantics/test-clocks.d.ts +0 -6
  357. package/dist/src/semantics/tokens.d.ts +0 -4
  358. package/dist/src/semantics/tokens.js +0 -44
  359. package/dist/src/semantics/treasury.d.ts +0 -2
  360. package/dist/src/semantics/treasury.js +0 -377
  361. package/dist/src/semantics/webhook-endpoints.d.ts +0 -3
  362. package/dist/src/semantics/webhook-endpoints.js +0 -85
  363. package/dist/src/stripe-budget.d.ts +0 -55
  364. package/dist/src/stripe-budget.js +0 -155
  365. package/dist/src/stripe-capabilities.d.ts +0 -3
  366. package/dist/src/stripe-capabilities.js +0 -5836
  367. package/dist/src/stripe-conformance.d.ts +0 -43
  368. package/dist/src/stripe-conformance.js +0 -105
  369. package/dist/src/stripe-connector.d.ts +0 -161
  370. package/dist/src/stripe-connector.js +0 -414
  371. package/dist/src/stripe-emit.d.ts +0 -2
  372. package/dist/src/stripe-emit.js +0 -145
  373. package/dist/src/stripe-events.d.ts +0 -93
  374. package/dist/src/stripe-events.js +0 -392
  375. package/dist/src/stripe-js.d.ts +0 -4
  376. package/dist/src/stripe-js.js +0 -70
  377. package/dist/src/stripe-mirror-ui.d.ts +0 -15
  378. package/dist/src/stripe-mirror-ui.js +0 -87
  379. package/dist/src/stripe-perform-harness.d.ts +0 -9
  380. package/dist/src/stripe-perform-harness.js +0 -26
  381. package/dist/src/stripe-server.d.ts +0 -33
  382. package/dist/src/stripe-server.js +0 -429
  383. package/dist/src/stripe-shared.d.ts +0 -109
  384. package/dist/src/stripe-shared.js +0 -276
  385. package/dist/src/stripe-ui-conformance.d.ts +0 -5
  386. package/dist/src/stripe-ui-conformance.js +0 -79
  387. package/dist/src/stripe-ui-structure.d.ts +0 -3
  388. package/dist/src/stripe-ui-structure.js +0 -168
  389. package/dist/test-fixtures/stripe-known-deviations.json +0 -110
  390. package/dist/test-fixtures/stripe-openapi-operations.SOURCE.md +0 -14
  391. package/dist/test-fixtures/stripe-openapi-operations.json +0 -4717
  392. package/dist/test-fixtures/stripe-schemas.SOURCE.md +0 -35
  393. package/dist/test-fixtures/stripe-schemas.json +0 -3813
  394. package/src/screens/connect-settings.tsx +0 -121
  395. package/src/screens/consent-skin.ts +0 -20
  396. package/src/screens/financial-connections.tsx +0 -101
  397. package/src/screens/identity.tsx +0 -96
  398. package/src/screens/public-details.tsx +0 -105
  399. package/src/semantics/after-payment.ts +0 -118
  400. package/src/semantics/billing.ts +0 -216
  401. package/src/semantics/connect.ts +0 -487
  402. package/src/semantics/credit-notes.ts +0 -168
  403. package/src/semantics/ephemeral-keys.ts +0 -34
  404. package/src/semantics/files.ts +0 -143
  405. package/src/semantics/issuing.ts +0 -590
  406. package/src/semantics/ledger.ts +0 -253
  407. package/src/semantics/payment-intents.ts +0 -463
  408. package/src/semantics/payment-links.ts +0 -148
  409. package/src/semantics/payment-methods.ts +0 -145
  410. package/src/semantics/plans.ts +0 -131
  411. package/src/semantics/platform.ts +0 -220
  412. package/src/semantics/renewals.ts +0 -279
  413. package/src/semantics/setup-intents.ts +0 -87
  414. package/src/semantics/subscription-schedules.ts +0 -129
  415. package/src/semantics/tax.ts +0 -220
  416. package/src/semantics/terminal.ts +0 -195
  417. package/src/semantics/tokens.ts +0 -52
  418. package/src/semantics/treasury.ts +0 -383
  419. package/src/semantics/webhook-endpoints.ts +0 -87
  420. package/src/stripe-budget.ts +0 -181
  421. package/src/stripe-capabilities.ts +0 -5651
  422. package/src/stripe-conformance.ts +0 -124
  423. package/src/stripe-connector.ts +0 -462
  424. package/src/stripe-emit.ts +0 -157
  425. package/src/stripe-events.ts +0 -434
  426. package/src/stripe-js.ts +0 -70
  427. package/src/stripe-mirror-ui.ts +0 -90
  428. package/src/stripe-perform-harness.ts +0 -29
  429. package/src/stripe-server.ts +0 -393
  430. package/src/stripe-shared.ts +0 -297
  431. package/src/stripe-ui-conformance.ts +0 -88
  432. package/src/stripe-ui-structure.ts +0 -182
  433. package/test-fixtures/stripe-known-deviations.json +0 -110
  434. package/test-fixtures/stripe-openapi-operations.json +0 -4717
  435. package/test-fixtures/stripe-schemas.json +0 -3813
  436. /package/dist/src/{screens → engine}/industries.d.ts +0 -0
  437. /package/dist/src/{screens → engine}/industries.js +0 -0
  438. /package/dist/src/{semantics → engine}/test-cards.d.ts +0 -0
  439. /package/dist/src/{semantics → engine}/test-cards.js +0 -0
  440. /package/dist/src/{stripe-version.d.ts → engine/version.d.ts} +0 -0
  441. /package/src/{screens → engine}/industries.ts +0 -0
  442. /package/src/{semantics → engine}/test-cards.ts +0 -0
@@ -1,37 +1,12 @@
1
- // Transfer and application-fee semantics: money the platform moves to a connected account and
2
- // claws back (reversals), and the platform's fee on a connected charge and its refunds. A
3
- // reversal or fee refund never exceeds what is left, and lands on its parent's totals and list.
4
- // A transfer goes only to an account whose transfers capability is active, comes out of the
5
- // platform's available balance, and lands in the destination's (docs.stripe.com/connect/separate-
6
- // charges-and-transfers); a reversal moves it back.
7
- // A transfer tied to a charge (`source_transaction`, "Transfer availability" in the same guide) "returns success
8
- // regardless of your available balance if the related charge hasn't settled yet", but "the funds don't become
9
- // available in the destination account until the funds from the associated charge are available"; a charge whose funds
10
- // are already available by the World's clock is no exception, and the transfer is held to the available balance as any
11
- // other. "The amount of the transfer must not exceed the amount of the source charge", several transfers may share one
12
- // charge while "the sum of the transfers doesn't exceed the source charge", and the charge's balance currency must
13
- // match. "If the source charge has a `transfer_group` value, Stripe assigns the same value to the transfer's
14
- // `transfer_group`. If it doesn't, then Stripe generates a string in the format `group_` plus the associated
15
- // PaymentIntent ID ... It assigns that string as the `transfer_group` for both the charge and the transfer."
16
- // Where the documentation stops and the twin decides: the sum from one charge counts each transfer less what was
17
- // reversed of it; a transfer_group the request names is kept only when the charge has none and no PaymentIntent to
18
- // name one after; an uncaptured charge (an authorization, docs silent) is refused as a source_transaction until it is
19
- // captured; the refusals' wording is the twin's.
20
- // Transfer list, retrieve and update and application-fee list and retrieve are the derived core's.
21
- import type { Semantics, SemanticsContext } from '@volter/world-core';
22
- import { validateMoney } from '../stripe-twin.ts';
23
- import { refusePayout, settleTransfer, settleTransferReversal } from './ledger.ts';
24
- import { at, created, fail, list, newest, send, type Row } from './shared.ts';
25
-
26
- const transferMissing = (ctx: SemanticsContext, id: string): Response => fail(ctx, `No such transfer: '${id}'`, 404, 'resource_missing');
27
- const emptyList = (url: string): Row => ({ object: 'list', data: [], has_more: false, total_count: 0, url });
28
-
29
- /** A transfer to an account whose transfers capability is not active. */
30
- function transfersInactive(ctx: SemanticsContext): Response {
31
- return ctx.refuse({ status: 400, code: 'insufficient_capabilities_for_transfer', param: 'destination', message: 'Your destination account needs to have at least one of the following capabilities enabled: transfers, crypto_transfers, legacy_payments' });
32
- }
33
-
34
- const create: Semantics = async (ctx) => {
1
+ // Stripe's transfers operations (docs/contributing/architecture.md, "What an author writes"): each handler over the
2
+ // handler contract's context, computing with the engine (../engine/).
3
+ import type { HandlerContext } from '@volter/world-core';
4
+ import type { Row } from '../engine/common.ts';
5
+ import { nowUnix, validateMoney } from '../engine/stripe.ts';
6
+ import { emptyList } from '../engine/transfers.ts';
7
+ import { at, created, fail, giveBack, list, newest, refusePayout, send, settledSourceRefused, settleTransfer, settleTransferReversal, transferMissing, transfersInactive } from './shared.ts';
8
+
9
+ export async function PostTransfers(ctx: HandlerContext): Promise<Response> {
35
10
  const bad = validateMoney(ctx.params);
36
11
  if (bad) return send(ctx, bad);
37
12
  const destination = typeof ctx.params.destination === 'string' ? ctx.params.destination : '';
@@ -55,9 +30,9 @@ const create: Semantics = async (ctx) => {
55
30
  if (already + amount > Number(charge.amount ?? 0)) return fail(ctx, `The transfers from source_transaction ${sourceId} would exceed its amount (${String(charge.amount)}).`, 400, 'invalid_request_error');
56
31
  const bt = typeof charge.balance_transaction === 'string' ? ctx.get('balance_transaction', charge.balance_transaction) : undefined;
57
32
  // a charge that has settled waives nothing: the transfer comes out of what is available
58
- const settledRefusal = bt && Number(bt.available_on) <= Number(ctx.now()) ? settledSourceRefused(ctx, amount, currency) : undefined;
33
+ const settledRefusal = bt && Number(bt.available_on) <= Number(nowUnix(ctx.occurredAt)) ? settledSourceRefused(ctx, amount, currency) : undefined;
59
34
  if (settledRefusal) return settledRefusal;
60
- availableOn = Math.max(Number(ctx.now()), Number(bt?.available_on) || 0);
35
+ availableOn = Math.max(Number(nowUnix(ctx.occurredAt)), Number(bt?.available_on) || 0);
61
36
  group = typeof charge.transfer_group === 'string' ? charge.transfer_group : typeof charge.payment_intent === 'string' ? `group_${charge.payment_intent}` : undefined;
62
37
  // the generated group is the charge's too
63
38
  if (group && charge.transfer_group !== group) await ctx.write('charge', sourceId, { transfer_group: group }, 'charge.transfer_group_assigned');
@@ -75,100 +50,5 @@ const create: Semantics = async (ctx) => {
75
50
  destination_payment: `py_${id.replace(/^tr_/, '')}`,
76
51
  }),
77
52
  );
78
- };
79
-
80
- /** A transfer from a charge whose funds have settled: "With a source_transaction, the transfer request returns success
81
- * regardless of your available balance if the related charge hasn't settled yet" (docs.stripe.com/connect/separate-
82
- * charges-and-transfers), so a settled one comes out of the available balance. */
83
- function settledSourceRefused(ctx: SemanticsContext, amount: number, currency: string): Response | undefined {
84
- return refusePayout(ctx, amount, currency, undefined);
85
- }
86
-
87
- /** An application fee refunded to its whole through its own refunds endpoint: the fee machine's move, or its refusal. */
88
- function feeFullyRefunded(ctx: SemanticsContext, resource: string, flag: string, id: string): Response | undefined {
89
- const refused = ctx.legal(resource, flag, ctx.call.operation.id, 'false', 'true', id);
90
- return refused ? ctx.refuse(refused) : undefined;
91
53
  }
92
54
 
93
- /** Take `amount` (the remainder by default) back out of a parent's total, as a child row appended to its list. */
94
- async function giveBack(ctx: SemanticsContext, o: {
95
- parent: Row; parentResource: string; child: string; childFields: (amount: number) => Row; childDefaults: Row;
96
- doneField: string; flag: string; listUrl: string; op: string; tooLarge: (remaining: number) => string;
97
- /** what the money movement itself writes, once the child exists */
98
- settle?: (child: Row, amount: number) => Promise<void>;
99
- }): Promise<Response> {
100
- const id = String(o.parent.id);
101
- const total = Number(o.parent.amount ?? 0);
102
- const already = Number(o.parent[o.doneField] ?? 0);
103
- const remaining = total - already;
104
- const amount = ctx.params.amount !== undefined ? Math.trunc(Number(ctx.params.amount) || 0) : remaining;
105
- if (amount <= 0 || amount > remaining) return fail(ctx, o.tooLarge(remaining), 400, 'amount_too_large');
106
- const done = already + amount;
107
- // a fee refunded in full is `refunded`: the application fee machine's move (a transfer's `reversed` is no state)
108
- const feeRefusal = o.parentResource === 'application_fee' && done >= total && o.parent[o.flag] !== true ? feeFullyRefunded(ctx, o.parentResource, o.flag, id) : undefined;
109
- if (feeRefusal) return feeRefusal;
110
- // the `metadata` a reversal or a fee refund is created with is its own ("Set of key-value pairs that you can attach to
111
- // an object", docs.stripe.com/api/transfer_reversals/create, docs.stripe.com/api/fee_refunds/create)
112
- const metadata = ctx.params.metadata && typeof ctx.params.metadata === 'object' ? { metadata: ctx.params.metadata } : {};
113
- const child = await created(ctx, o.child, { ...o.childFields(amount), ...metadata }, o.childDefaults);
114
- if (o.settle) await o.settle(child, amount);
115
- const existing = (o.parent[o.flag === 'reversed' ? 'reversals' : 'refunds'] as Row) ?? { object: 'list', data: [], has_more: false, total_count: 0 };
116
- const data = [...((existing.data as unknown[]) ?? []), child];
117
- await ctx.write(o.parentResource, id, {
118
- [o.doneField]: done, [o.flag]: done >= total,
119
- [o.flag === 'reversed' ? 'reversals' : 'refunds']: { ...existing, data, total_count: data.length, url: o.listUrl },
120
- }, o.op);
121
- return ctx.reply(child);
122
- }
123
-
124
- const reverse: Semantics = async (ctx) => {
125
- const id = at(ctx, 'id');
126
- const tr = ctx.get('transfer', id);
127
- if (!tr) return transferMissing(ctx, id);
128
- return giveBack(ctx, {
129
- parent: tr, parentResource: 'transfer', child: 'transfer_reversal',
130
- childFields: (amount) => ({ amount, currency: tr.currency ?? 'usd', transfer: id }),
131
- childDefaults: { balance_transaction: null, destination_payment_refund: null, source_refund: null, metadata: {} },
132
- doneField: 'amount_reversed', flag: 'reversed', listUrl: `/v1/transfers/${id}/reversals`, op: 'transfer.reversed',
133
- tooLarge: (remaining) => `Transfer ${id} can only be reversed up to ${remaining}.`,
134
- settle: async (child, amount) => {
135
- const bt = await settleTransferReversal(ctx, String(child.id), amount, String(tr.currency ?? 'usd'), String(tr.destination));
136
- await ctx.write('transfer_reversal', String(child.id), { balance_transaction: bt }, 'transfer_reversal.updated');
137
- },
138
- });
139
- };
140
-
141
- const reversals: Semantics = async (ctx) => {
142
- const id = at(ctx, 'id');
143
- if (!ctx.get('transfer', id)) return transferMissing(ctx, id);
144
- return list(ctx, 'transfer_reversal', newest(ctx, 'transfer_reversal').filter((r) => r.transfer === id));
145
- };
146
-
147
- const feeMissing = (ctx: SemanticsContext, id: string): Response => fail(ctx, `No such application fee: '${id}'`, 404, 'resource_missing');
148
-
149
- const refundFee: Semantics = async (ctx) => {
150
- const id = at(ctx, 'id');
151
- const fee = ctx.get('application_fee', id);
152
- if (!fee) return feeMissing(ctx, id);
153
- return giveBack(ctx, {
154
- parent: fee, parentResource: 'application_fee', child: 'fee_refund',
155
- childFields: (amount) => ({ amount, currency: fee.currency ?? 'usd', fee: id }),
156
- childDefaults: { balance_transaction: null, metadata: {} },
157
- doneField: 'amount_refunded', flag: 'refunded', listUrl: `/v1/application_fees/${id}/refunds`, op: 'application_fee.refunded',
158
- tooLarge: (remaining) => `Application fee ${id} can only be refunded up to ${remaining}.`,
159
- });
160
- };
161
-
162
- const feeRefunds: Semantics = async (ctx) => {
163
- const id = at(ctx, 'id');
164
- if (!ctx.get('application_fee', id)) return feeMissing(ctx, id);
165
- return list(ctx, 'fee_refund', newest(ctx, 'fee_refund').filter((r) => r.fee === id));
166
- };
167
-
168
- export const transfers: Record<string, Semantics> = {
169
- PostTransfers: create,
170
- PostTransfersIdReversals: reverse,
171
- GetTransfersIdReversals: reversals,
172
- PostApplicationFeesIdRefunds: refundFee,
173
- GetApplicationFeesIdRefunds: feeRefunds,
174
- };
package/src/server.ts ADDED
@@ -0,0 +1,8 @@
1
+ // FETCH-FIRST (runtime contract R12b): a fixed file, the kernel's serve seam around the pack's fetch (./fetch.ts).
2
+ import { serveHttp, type PackFetchOptions } from '@volter/world-core';
3
+ import { createStripeFetch } from './fetch.ts';
4
+
5
+ export async function createStripeTwinServer(options: PackFetchOptions & { port?: number } = {}): Promise<{ port: number; stop: () => void }> {
6
+ const server = await serveHttp({ port: options.port ?? 0, idleTimeout: 60, fetch: createStripeFetch(options) });
7
+ return { port: server.port ?? options.port ?? 0, stop: () => server.stop(true) };
8
+ }
@@ -1,286 +0,0 @@
1
- // The Stripe Dashboard's reads and writes, through Stripe's own API on this origin (docs/contributing/
2
- // architecture.md, "Screens": a workspace reads and writes only through the pack's operations). The calls
3
- // the Dashboard makes for the pages it shows: the balance, payments (PaymentIntents and the Charges they
4
- // made), refunds, customers and their saved payment methods, subscriptions, invoices, products and prices,
5
- // and events for a detail page's timeline. The writes a person makes here: refund a payment
6
- // (POST /v1/refunds), cancel a subscription (DELETE /v1/subscriptions/{id}, or schedule it with
7
- // cancel_at_period_end), create a customer or a product. Bodies are form-encoded as Stripe's API takes them;
8
- // an `error` envelope, never the HTTP status alone, is what refuses.
9
-
10
- type Json = any;
11
- export type StripeObject = Record<string, any>;
12
-
13
- export function wireBaseFrom(hasBaseElement: boolean, baseURI: string): string {
14
- return hasBaseElement ? new URL('.', baseURI).pathname.replace(/\/$/, '') : '';
15
- }
16
- // Served at the origin root the base is ''; served under a path prefix (an embedder's earlier <base>) every
17
- // call resolves inside that prefix.
18
- export const API_BASE = typeof document === 'undefined' ? '' : wireBaseFrom(document.querySelector('base[href]') !== null, document.baseURI);
19
-
20
- export class StripeApiError extends Error {
21
- constructor(message: string, readonly code?: string) { super(message); }
22
- }
23
-
24
- async function call(method: string, path: string, body?: Record<string, string | number | boolean | undefined>): Promise<Json> {
25
- const init: RequestInit = { method, headers: { accept: 'application/json' } };
26
- if (body) {
27
- const form = Object.entries(body).filter(([, v]) => v !== undefined && v !== '').map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`).join('&');
28
- init.body = form;
29
- (init.headers as Record<string, string>)['content-type'] = 'application/x-www-form-urlencoded';
30
- }
31
- const res = await fetch(`${API_BASE}${path}`, init);
32
- const json = await res.json().catch(() => ({ error: { message: `${res.status} ${res.statusText}` } }));
33
- if (json && json.error) throw new StripeApiError(String(json.error.message ?? 'Request failed'), json.error.code);
34
- return json;
35
- }
36
-
37
- export const retrieve = (path: string): Promise<StripeObject> => call('GET', path);
38
- /** A list endpoint's `data`, newest first as Stripe returns it (one page of up to 100). */
39
- export async function list(path: string): Promise<StripeObject[]> {
40
- const sep = path.includes('?') ? '&' : '?';
41
- const body = await call('GET', `${path}${sep}limit=100`);
42
- return Array.isArray(body?.data) ? body.data : [];
43
- }
44
- const optional = <T>(p: Promise<T>, fallback: T): Promise<T> => p.catch(() => fallback);
45
-
46
- // ── what a payment row is ────────────────────────────────────────────────────
47
- /** One row of the Payments list: a PaymentIntent (or a Charge made without one) with what the Dashboard
48
- * shows beside it — its charge, refunds, card and customer. */
49
- export type Payment = {
50
- id: string;
51
- amount: number;
52
- currency: string;
53
- status: PaymentStatus;
54
- description?: string;
55
- created: number;
56
- customer?: StripeObject;
57
- charge?: StripeObject;
58
- intent?: StripeObject;
59
- paymentMethod?: StripeObject;
60
- amountRefunded: number;
61
- refundedAt?: number;
62
- declineReason?: string;
63
- declineMessage?: string;
64
- };
65
- export type PaymentStatus = 'succeeded' | 'refunded' | 'partially_refunded' | 'failed' | 'incomplete' | 'uncaptured' | 'canceled' | 'disputed' | 'processing';
66
-
67
- export function paymentStatusOf(intent: StripeObject | undefined, charge: StripeObject | undefined): PaymentStatus {
68
- if (charge?.disputed) return 'disputed';
69
- if (charge?.refunded) return 'refunded';
70
- if (charge && Number(charge.amount_refunded) > 0) return 'partially_refunded';
71
- if (charge?.status === 'failed') return 'failed';
72
- if (intent) {
73
- if (intent.status === 'succeeded') return 'succeeded';
74
- if (intent.status === 'canceled') return 'canceled';
75
- if (intent.status === 'requires_capture') return 'uncaptured';
76
- if (intent.status === 'processing') return 'processing';
77
- if (intent.last_payment_error) return 'failed';
78
- return 'incomplete';
79
- }
80
- return charge?.status === 'succeeded' ? 'succeeded' : charge?.status === 'pending' ? 'processing' : 'failed';
81
- }
82
-
83
- const DECLINE_REASONS: Record<string, string> = {
84
- generic_decline: 'Generic decline', insufficient_funds: 'Insufficient funds', lost_card: 'Lost card', stolen_card: 'Stolen card',
85
- expired_card: 'Expired card', incorrect_cvc: 'Incorrect CVC', processing_error: 'Processing error', card_declined: 'Card declined',
86
- };
87
- export const declineReasonText = (code: string | undefined): string | undefined => (code ? DECLINE_REASONS[code] ?? code.replace(/_/g, ' ') : undefined);
88
-
89
- type Directory = { customers: Map<string, StripeObject>; paymentMethods: Map<string, StripeObject> };
90
-
91
- async function paymentMethodsById(ids: Iterable<string>): Promise<Map<string, StripeObject>> {
92
- const unique = [...new Set([...ids].filter((id) => typeof id === 'string' && id.startsWith('pm_')))];
93
- const found = await Promise.all(unique.map((id) => optional(retrieve(`/v1/payment_methods/${id}`), undefined as StripeObject | undefined)));
94
- return new Map(found.filter((pm): pm is StripeObject => Boolean(pm?.id)).map((pm) => [pm.id, pm]));
95
- }
96
-
97
- function paymentOf(intent: StripeObject | undefined, charge: StripeObject | undefined, refunds: StripeObject[], dir: Directory): Payment {
98
- const base = intent ?? charge!;
99
- const customerId = typeof base.customer === 'string' ? base.customer : base.customer?.id;
100
- const pmId = typeof base.payment_method === 'string' ? base.payment_method : charge?.payment_method;
101
- const error = intent?.last_payment_error;
102
- const refundsOf = refunds.filter((r) => (intent && r.payment_intent === intent.id) || (charge && r.charge === charge.id));
103
- return {
104
- id: String(base.id),
105
- amount: Number(base.amount) || 0,
106
- currency: String(base.currency ?? 'usd'),
107
- status: paymentStatusOf(intent, charge),
108
- description: base.description ?? charge?.description ?? undefined,
109
- created: Number(base.created) || 0,
110
- customer: customerId ? dir.customers.get(customerId) ?? { id: customerId } : undefined,
111
- charge, intent,
112
- paymentMethod: pmId ? dir.paymentMethods.get(pmId) : undefined,
113
- amountRefunded: Number(charge?.amount_refunded) || refundsOf.reduce((n, r) => n + (r.status === 'failed' ? 0 : Number(r.amount) || 0), 0),
114
- refundedAt: refundsOf.length ? Math.max(...refundsOf.map((r) => Number(r.created) || 0)) : undefined,
115
- declineReason: declineReasonText(error?.decline_code ?? error?.code ?? charge?.failure_code),
116
- declineMessage: error?.message ?? charge?.failure_message ?? undefined,
117
- };
118
- }
119
-
120
- /** The Payments list: every PaymentIntent, and every Charge made without one. */
121
- export async function loadPayments(): Promise<Payment[]> {
122
- const [intents, charges, refunds, customers] = await Promise.all([
123
- list('/v1/payment_intents'), list('/v1/charges'), optional(list('/v1/refunds'), []), list('/v1/customers'),
124
- ]);
125
- const chargeById = new Map(charges.map((c) => [c.id, c]));
126
- const pmIds = [...intents.map((i) => i.payment_method), ...charges.map((c) => c.payment_method)];
127
- const dir: Directory = { customers: new Map(customers.map((c) => [c.id, c])), paymentMethods: await paymentMethodsById(pmIds) };
128
- const rows = intents.map((pi) => {
129
- const charge = (typeof pi.latest_charge === 'string' ? chargeById.get(pi.latest_charge) : pi.latest_charge) ?? charges.find((c) => c.payment_intent === pi.id);
130
- return paymentOf(pi, charge, refunds, dir);
131
- });
132
- for (const ch of charges) if (!ch.payment_intent) rows.push(paymentOf(undefined, ch, refunds, dir));
133
- return rows.sort((a, b) => b.created - a.created);
134
- }
135
-
136
- export type PaymentDetail = Payment & { refunds: StripeObject[]; events: StripeObject[]; invoice?: StripeObject };
137
-
138
- /** One payment's page: the intent (or charge), its charge, refunds, card, customer and the events about it. */
139
- export async function loadPayment(id: string): Promise<PaymentDetail> {
140
- let intent: StripeObject | undefined;
141
- let charge: StripeObject | undefined;
142
- if (id.startsWith('ch_') || id.startsWith('py_')) {
143
- charge = await retrieve(`/v1/charges/${id}`);
144
- if (typeof charge.payment_intent === 'string') intent = await optional(retrieve(`/v1/payment_intents/${charge.payment_intent}`), undefined);
145
- } else {
146
- intent = await retrieve(`/v1/payment_intents/${id}`);
147
- const chargeId = typeof intent.latest_charge === 'string' ? intent.latest_charge : intent.latest_charge?.id;
148
- if (chargeId) charge = await optional(retrieve(`/v1/charges/${chargeId}`), undefined);
149
- }
150
- const base = intent ?? charge!;
151
- const customerId = typeof base.customer === 'string' ? base.customer : undefined;
152
- const pmId = typeof base.payment_method === 'string' ? base.payment_method : charge?.payment_method;
153
- const refundPath = intent ? `/v1/refunds?payment_intent=${intent.id}` : `/v1/refunds?charge=${charge!.id}`;
154
- const [customer, pms, refunds, events, invoice] = await Promise.all([
155
- customerId ? optional(retrieve(`/v1/customers/${customerId}`), { id: customerId }) : Promise.resolve(undefined),
156
- paymentMethodsById(pmId ? [pmId] : []),
157
- optional(list(refundPath), []),
158
- optional(list('/v1/events'), []),
159
- typeof base.invoice === 'string' ? optional(retrieve(`/v1/invoices/${base.invoice}`), undefined) : Promise.resolve(undefined),
160
- ]);
161
- const dir: Directory = { customers: new Map(customer ? [[customer.id, customer]] : []), paymentMethods: pms };
162
- const related = new Set<string>([base.id, charge?.id, intent?.id, ...refunds.map((r) => r.id)].filter(Boolean) as string[]);
163
- return {
164
- ...paymentOf(intent, charge, refunds, dir),
165
- refunds,
166
- events: events.filter((e) => related.has(e?.data?.object?.id)).sort((a, b) => b.created - a.created),
167
- invoice,
168
- };
169
- }
170
-
171
- // ── customers ────────────────────────────────────────────────────────────────
172
- export type CustomerRow = StripeObject & { defaultCard?: StripeObject; totalSpend: number; payments: number; refunds: number; currency: string };
173
-
174
- export async function loadCustomers(): Promise<CustomerRow[]> {
175
- const [customers, charges, intents] = await Promise.all([list('/v1/customers'), list('/v1/charges'), list('/v1/payment_intents')]);
176
- const pmIds = customers.map((c) => c.invoice_settings?.default_payment_method).filter((x) => typeof x === 'string');
177
- const pms = await paymentMethodsById(pmIds);
178
- return customers.map((c) => {
179
- const mine = charges.filter((ch) => ch.customer === c.id && ch.status === 'succeeded');
180
- const pmId = c.invoice_settings?.default_payment_method;
181
- return {
182
- ...c,
183
- defaultCard: typeof pmId === 'string' ? pms.get(pmId) : undefined,
184
- totalSpend: mine.reduce((n, ch) => n + (Number(ch.amount_captured ?? ch.amount) || 0) - (Number(ch.amount_refunded) || 0), 0),
185
- payments: intents.filter((i) => i.customer === c.id && i.status === 'succeeded').length || mine.length,
186
- refunds: mine.reduce((n, ch) => n + (Number(ch.amount_refunded) || 0), 0),
187
- currency: String(mine[0]?.currency ?? c.currency ?? 'usd'),
188
- };
189
- });
190
- }
191
-
192
- export type CustomerDetail = {
193
- customer: StripeObject;
194
- paymentMethods: StripeObject[];
195
- subscriptions: StripeObject[];
196
- invoices: StripeObject[];
197
- payments: Payment[];
198
- products: Map<string, StripeObject>;
199
- events: StripeObject[];
200
- };
201
-
202
- export async function loadCustomer(id: string): Promise<CustomerDetail> {
203
- const customer = await retrieve(`/v1/customers/${id}`);
204
- const [paymentMethods, subscriptions, invoices, payments, products, events] = await Promise.all([
205
- optional(list(`/v1/customers/${id}/payment_methods`), []),
206
- optional(list(`/v1/subscriptions?customer=${id}&status=all`), []),
207
- optional(list(`/v1/invoices?customer=${id}`), []),
208
- loadPayments().then((all) => all.filter((p) => p.customer?.id === id)),
209
- optional(list('/v1/products'), []),
210
- optional(list('/v1/events'), []),
211
- ]);
212
- const mine = new Set([id, ...subscriptions.map((s) => s.id), ...invoices.map((i) => i.id), ...payments.map((p) => p.id)]);
213
- return {
214
- customer, paymentMethods, subscriptions, invoices, payments,
215
- products: new Map(products.map((p) => [p.id, p])),
216
- events: events.filter((e) => mine.has(e?.data?.object?.id)).sort((a, b) => b.created - a.created),
217
- };
218
- }
219
-
220
- // ── billing ──────────────────────────────────────────────────────────────────
221
- export type Billing = { subscriptions: StripeObject[]; customers: Map<string, StripeObject>; products: Map<string, StripeObject> };
222
-
223
- export async function loadSubscriptions(): Promise<Billing> {
224
- const [subscriptions, customers, products] = await Promise.all([list('/v1/subscriptions?status=all'), list('/v1/customers'), list('/v1/products')]);
225
- return { subscriptions, customers: new Map(customers.map((c) => [c.id, c])), products: new Map(products.map((p) => [p.id, p])) };
226
- }
227
-
228
- export type SubscriptionDetail = { subscription: StripeObject; customer?: StripeObject; invoices: StripeObject[]; products: Map<string, StripeObject>; events: StripeObject[]; paymentMethod?: StripeObject };
229
-
230
- export async function loadSubscription(id: string): Promise<SubscriptionDetail> {
231
- const subscription = await retrieve(`/v1/subscriptions/${id}`);
232
- const customerId = typeof subscription.customer === 'string' ? subscription.customer : subscription.customer?.id;
233
- const [customer, invoices, products, events] = await Promise.all([
234
- customerId ? optional(retrieve(`/v1/customers/${customerId}`), undefined) : Promise.resolve(undefined),
235
- optional(list(`/v1/invoices?subscription=${id}`), []),
236
- optional(list('/v1/products'), []),
237
- optional(list('/v1/events'), []),
238
- ]);
239
- const pmId = subscription.default_payment_method ?? customer?.invoice_settings?.default_payment_method;
240
- const pms = await paymentMethodsById(typeof pmId === 'string' ? [pmId] : []);
241
- return {
242
- subscription, customer, invoices, products: new Map(products.map((p) => [p.id, p])),
243
- events: events.filter((e) => e?.data?.object?.id === id).sort((a, b) => b.created - a.created),
244
- paymentMethod: typeof pmId === 'string' ? pms.get(pmId) : undefined,
245
- };
246
- }
247
-
248
- export async function loadInvoices(): Promise<{ invoices: StripeObject[]; customers: Map<string, StripeObject> }> {
249
- const [invoices, customers] = await Promise.all([list('/v1/invoices'), list('/v1/customers')]);
250
- return { invoices, customers: new Map(customers.map((c) => [c.id, c])) };
251
- }
252
-
253
- export async function loadProducts(): Promise<{ products: StripeObject[]; prices: StripeObject[] }> {
254
- const [products, prices] = await Promise.all([list('/v1/products'), list('/v1/prices')]);
255
- return { products, prices };
256
- }
257
-
258
- export type HomeData = { balance: StripeObject; payments: Payment[]; customers: StripeObject[]; subscriptions: StripeObject[]; invoices: StripeObject[] };
259
- export async function loadHome(): Promise<HomeData> {
260
- const [balance, payments, customers, subscriptions, invoices] = await Promise.all([
261
- retrieve('/v1/balance'), loadPayments(), list('/v1/customers'), optional(list('/v1/subscriptions?status=all'), []), optional(list('/v1/invoices'), []),
262
- ]);
263
- return { balance, payments, customers, subscriptions, invoices };
264
- }
265
-
266
- export async function loadBalances(): Promise<{ balance: StripeObject; transactions: StripeObject[]; payouts: StripeObject[] }> {
267
- const [balance, transactions, payouts] = await Promise.all([retrieve('/v1/balance'), optional(list('/v1/balance_transactions'), []), optional(list('/v1/payouts'), [])]);
268
- return { balance, transactions, payouts };
269
- }
270
-
271
- export async function loadDevelopers(): Promise<{ events: StripeObject[]; webhooks: StripeObject[]; account?: StripeObject }> {
272
- const [events, webhooks, account] = await Promise.all([optional(list('/v1/events'), []), optional(list('/v1/webhook_endpoints'), []), optional(retrieve('/v1/account'), undefined)]);
273
- return { events, webhooks, account };
274
- }
275
-
276
- // ── writes ───────────────────────────────────────────────────────────────────
277
- /** Refund a payment in full (no amount) or in part. */
278
- export function createRefund(payment: { intent?: StripeObject; charge?: StripeObject }, amount: number | undefined, reason: string | undefined): Promise<StripeObject> {
279
- const target = payment.intent ? { payment_intent: String(payment.intent.id) } : { charge: String(payment.charge?.id) };
280
- return call('POST', '/v1/refunds', { ...target, amount, reason });
281
- }
282
- /** Cancel now (DELETE) or at the end of the current period (cancel_at_period_end). */
283
- export function cancelSubscription(id: string, when: 'now' | 'period_end'): Promise<StripeObject> {
284
- return when === 'now' ? call('DELETE', `/v1/subscriptions/${id}`) : call('POST', `/v1/subscriptions/${id}`, { cancel_at_period_end: true });
285
- }
286
- export const createObject = (collection: string, fields: Record<string, string>): Promise<StripeObject> => call('POST', `/v1/${collection}`, fields);