@volter/twin-stripe 2.0.38 → 3.0.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 (402) hide show
  1. package/README.md +112 -207
  2. package/dist/generated/pack-facts.json +94 -0
  3. package/dist/journeys/coverage.json +596 -0
  4. package/dist/journeys/customer-life.json +6108 -0
  5. package/dist/journeys/customer-life.outline.md +371 -0
  6. package/dist/journeys/decisions.json +677 -0
  7. package/dist/journeys/demand.json +706 -0
  8. package/dist/journeys/score.json +853 -0
  9. package/dist/journeys/unreachable.json +102 -0
  10. package/dist/journeys/vendor-examples.json +8010 -0
  11. package/dist/spec/SOURCE.md +18 -0
  12. package/dist/spec/doc-examples.json +445 -0
  13. package/dist/spec/fixtures3.json.gz +0 -0
  14. package/dist/spec/openapi.json.gz +0 -0
  15. package/dist/spec/patches.json +34 -0
  16. package/dist/spec/sources.json +306 -0
  17. package/dist/src/cli.d.ts +0 -1
  18. package/dist/src/cli.js +11 -31
  19. package/dist/src/engine/after-payment.d.ts +8 -0
  20. package/dist/src/engine/after-payment.js +27 -0
  21. package/dist/src/engine/apps-secrets.d.ts +1 -0
  22. package/dist/src/engine/apps-secrets.js +3 -0
  23. package/dist/src/engine/balance.d.ts +5 -0
  24. package/dist/src/engine/balance.js +15 -0
  25. package/dist/src/engine/checkout.d.ts +24 -0
  26. package/dist/src/engine/checkout.js +30 -0
  27. package/dist/src/engine/common.d.ts +19 -0
  28. package/dist/src/engine/common.js +34 -0
  29. package/dist/src/engine/connect.d.ts +45 -0
  30. package/dist/src/engine/connect.js +108 -0
  31. package/dist/src/engine/customers.d.ts +4 -0
  32. package/dist/src/engine/customers.js +8 -0
  33. package/dist/src/engine/display.d.ts +11 -0
  34. package/dist/src/engine/display.js +13 -0
  35. package/dist/src/engine/files.d.ts +11 -0
  36. package/dist/src/engine/files.js +23 -0
  37. package/dist/src/engine/invoices.d.ts +21 -0
  38. package/dist/src/engine/invoices.js +84 -0
  39. package/dist/src/engine/issuing.d.ts +33 -0
  40. package/dist/src/engine/issuing.js +54 -0
  41. package/dist/src/engine/ledger.d.ts +8 -0
  42. package/dist/src/engine/ledger.js +8 -0
  43. package/dist/src/engine/oauth.d.ts +4 -0
  44. package/dist/src/engine/oauth.js +24 -0
  45. package/dist/src/engine/onboarding.d.ts +13 -0
  46. package/dist/src/engine/onboarding.js +42 -0
  47. package/dist/src/{stripe-params.d.ts → engine/params.d.ts} +20 -3
  48. package/dist/src/{stripe-params.js → engine/params.js} +7 -60
  49. package/dist/src/engine/payment-intents.d.ts +10 -0
  50. package/dist/src/engine/payment-intents.js +27 -0
  51. package/dist/src/engine/payment-methods.d.ts +16 -0
  52. package/dist/src/engine/payment-methods.js +22 -0
  53. package/dist/src/engine/radar.d.ts +2 -0
  54. package/dist/src/engine/radar.js +5 -0
  55. package/dist/src/engine/refunds.d.ts +1 -0
  56. package/dist/src/engine/refunds.js +3 -0
  57. package/dist/src/engine/renewals.d.ts +36 -0
  58. package/dist/src/engine/renewals.js +65 -0
  59. package/dist/src/{stripe-twin.d.ts → engine/stripe.d.ts} +12 -45
  60. package/dist/src/{stripe-twin.js → engine/stripe.js} +53 -387
  61. package/dist/src/engine/subscriptions.d.ts +11 -0
  62. package/dist/src/engine/subscriptions.js +30 -0
  63. package/dist/src/engine/transfers.d.ts +2 -0
  64. package/dist/src/engine/transfers.js +1 -0
  65. package/dist/src/{stripe-version.d.ts → engine/version.d.ts} +0 -2
  66. package/dist/src/{stripe-version.js → engine/version.js} +21 -9
  67. package/dist/src/engine/webhook-endpoints.d.ts +1 -0
  68. package/dist/src/engine/webhook-endpoints.js +12 -0
  69. package/dist/src/engine/webhooks.d.ts +31 -0
  70. package/dist/src/engine/webhooks.js +68 -0
  71. package/dist/src/fetch.d.ts +2 -0
  72. package/dist/src/fetch.js +26 -0
  73. package/dist/src/generated/surface.gen.json +1 -1
  74. package/dist/src/generated/ui.gen.json +1 -1
  75. package/dist/src/index.d.ts +5 -14
  76. package/dist/src/index.js +10 -75
  77. package/dist/src/manifest.js +478 -876
  78. package/dist/src/screens/billing-portal.d.ts +3 -0
  79. package/dist/src/screens/{portal.js → billing-portal.js} +32 -58
  80. package/dist/src/screens/checkout-js.d.ts +2 -0
  81. package/dist/src/screens/checkout-js.js +84 -0
  82. package/dist/src/screens/checkout.d.ts +2 -31
  83. package/dist/src/screens/checkout.js +32 -121
  84. package/dist/src/screens/connect-onboarding.d.ts +3 -0
  85. package/dist/src/screens/{onboarding.js → connect-onboarding.js} +38 -104
  86. package/dist/src/screens/dashboard.d.ts +3 -0
  87. package/dist/src/screens/dashboard.js +116 -0
  88. package/dist/src/screens/shared.d.ts +27 -0
  89. package/dist/src/screens/shared.js +87 -0
  90. package/dist/src/screens/stripe-js.d.ts +3 -0
  91. package/dist/src/screens/stripe-js.js +95 -0
  92. package/dist/src/semantics/account.d.ts +2 -0
  93. package/dist/src/semantics/account.js +8 -0
  94. package/dist/src/semantics/account_links.d.ts +2 -0
  95. package/dist/src/semantics/account_links.js +22 -0
  96. package/dist/src/semantics/accounts.d.ts +4 -0
  97. package/dist/src/semantics/accounts.js +40 -0
  98. package/dist/src/semantics/apps.d.ts +4 -0
  99. package/dist/src/semantics/{apps-secrets.js → apps.js} +14 -26
  100. package/dist/src/semantics/around.d.ts +2 -0
  101. package/dist/src/semantics/around.js +13 -0
  102. package/dist/src/semantics/balance.d.ts +2 -11
  103. package/dist/src/semantics/balance.js +3 -194
  104. package/dist/src/semantics/balance_transactions.d.ts +2 -0
  105. package/dist/src/semantics/balance_transactions.js +15 -0
  106. package/dist/src/semantics/billing_portal.d.ts +4 -0
  107. package/dist/src/semantics/billing_portal.js +36 -0
  108. package/dist/src/semantics/charges.d.ts +3 -28
  109. package/dist/src/semantics/charges.js +5 -202
  110. package/dist/src/semantics/checkout.d.ts +3 -20
  111. package/dist/src/semantics/checkout.js +21 -271
  112. package/dist/src/semantics/clock.d.ts +2 -0
  113. package/dist/src/semantics/clock.js +15 -0
  114. package/dist/src/semantics/coupons.d.ts +2 -6
  115. package/dist/src/semantics/coupons.js +2 -60
  116. package/dist/src/semantics/customers.d.ts +5 -6
  117. package/dist/src/semantics/customers.js +47 -413
  118. package/dist/src/semantics/doors.d.ts +23 -0
  119. package/dist/src/semantics/doors.js +73 -0
  120. package/dist/src/semantics/entitlements.d.ts +0 -2
  121. package/dist/src/semantics/entitlements.js +4 -95
  122. package/dist/src/semantics/events.d.ts +11 -0
  123. package/dist/src/semantics/events.js +31 -0
  124. package/dist/src/semantics/index.d.ts +2 -0
  125. package/dist/src/semantics/index.js +85 -0
  126. package/dist/src/semantics/invoice_payments.d.ts +2 -0
  127. package/dist/src/semantics/invoice_payments.js +12 -0
  128. package/dist/src/semantics/invoices.d.ts +11 -18
  129. package/dist/src/semantics/invoices.js +121 -440
  130. package/dist/src/semantics/issuing.d.ts +6 -13
  131. package/dist/src/semantics/issuing.js +58 -556
  132. package/dist/src/semantics/payment_intents.d.ts +3 -0
  133. package/dist/src/semantics/payment_intents.js +71 -0
  134. package/dist/src/semantics/payment_methods.d.ts +3 -0
  135. package/dist/src/semantics/payment_methods.js +15 -0
  136. package/dist/src/semantics/payouts.d.ts +3 -0
  137. package/dist/src/semantics/payouts.js +28 -0
  138. package/dist/src/semantics/prices.d.ts +4 -0
  139. package/dist/src/semantics/prices.js +37 -0
  140. package/dist/src/semantics/products.d.ts +4 -2
  141. package/dist/src/semantics/products.js +12 -138
  142. package/dist/src/semantics/promotion_codes.d.ts +3 -0
  143. package/dist/src/semantics/promotion_codes.js +35 -0
  144. package/dist/src/semantics/radar.d.ts +2 -2
  145. package/dist/src/semantics/radar.js +5 -74
  146. package/dist/src/semantics/refunds.d.ts +2 -9
  147. package/dist/src/semantics/refunds.js +3 -193
  148. package/dist/src/semantics/shared.d.ts +558 -55
  149. package/dist/src/semantics/shared.js +2070 -114
  150. package/dist/src/semantics/states.d.ts +462 -0
  151. package/dist/src/semantics/states.js +634 -0
  152. package/dist/src/semantics/subscriptions.d.ts +6 -11
  153. package/dist/src/semantics/subscriptions.js +37 -530
  154. package/dist/src/semantics/test_helpers.d.ts +3 -0
  155. package/dist/src/semantics/test_helpers.js +125 -0
  156. package/dist/src/semantics/transfers.d.ts +2 -2
  157. package/dist/src/semantics/transfers.js +6 -101
  158. package/dist/src/semantics/webhook_endpoints.d.ts +2 -0
  159. package/dist/src/semantics/webhook_endpoints.js +26 -0
  160. package/dist/src/server.d.ts +7 -0
  161. package/dist/src/server.js +7 -0
  162. package/generated/pack-facts.json +94 -0
  163. package/journeys/coverage.json +596 -0
  164. package/journeys/customer-life.json +6108 -0
  165. package/journeys/customer-life.outline.md +371 -0
  166. package/journeys/decisions.json +677 -0
  167. package/journeys/demand.json +706 -0
  168. package/journeys/score.json +853 -0
  169. package/journeys/unreachable.json +102 -0
  170. package/journeys/vendor-examples.json +8010 -0
  171. package/package.json +11 -20
  172. package/spec/SOURCE.md +18 -0
  173. package/spec/doc-examples.json +445 -0
  174. package/spec/fixtures3.json.gz +0 -0
  175. package/spec/openapi.json.gz +0 -0
  176. package/spec/patches.json +34 -0
  177. package/spec/sources.json +306 -0
  178. package/src/cli.ts +11 -28
  179. package/src/engine/after-payment.ts +29 -0
  180. package/src/engine/apps-secrets.ts +4 -0
  181. package/src/engine/balance.ts +32 -0
  182. package/src/engine/checkout.ts +39 -0
  183. package/src/engine/common.ts +49 -0
  184. package/src/engine/connect.ts +106 -0
  185. package/src/engine/customers.ts +10 -0
  186. package/src/engine/display.ts +18 -0
  187. package/src/engine/files.ts +28 -0
  188. package/src/engine/invoices.ts +102 -0
  189. package/src/engine/issuing.ts +66 -0
  190. package/src/engine/ledger.ts +48 -0
  191. package/src/engine/oauth.ts +18 -0
  192. package/src/engine/onboarding.ts +53 -0
  193. package/src/{stripe-params.ts → engine/params.ts} +7 -56
  194. package/src/engine/payment-intents.ts +32 -0
  195. package/src/engine/payment-methods.ts +24 -0
  196. package/src/engine/radar.ts +6 -0
  197. package/src/engine/refunds.ts +3 -0
  198. package/src/engine/renewals.ts +72 -0
  199. package/src/{stripe-twin.ts → engine/stripe.ts} +57 -400
  200. package/src/engine/subscriptions.ts +37 -0
  201. package/src/engine/transfers.ts +22 -0
  202. package/src/{stripe-version.ts → engine/version.ts} +19 -10
  203. package/src/engine/webhook-endpoints.ts +14 -0
  204. package/src/engine/webhooks.ts +70 -0
  205. package/src/fetch.ts +27 -0
  206. package/src/generated/surface.gen.json +1 -1
  207. package/src/generated/ui.gen.json +1 -1
  208. package/src/index.ts +10 -116
  209. package/src/manifest.ts +480 -904
  210. package/src/screens/{portal.tsx → billing-portal.tsx} +35 -42
  211. package/src/screens/checkout-js.ts +80 -0
  212. package/src/screens/checkout.tsx +32 -96
  213. package/src/screens/{onboarding.tsx → connect-onboarding.tsx} +39 -85
  214. package/src/screens/dashboard.tsx +178 -0
  215. package/src/screens/shared.tsx +84 -0
  216. package/src/screens/stripe-js.ts +102 -0
  217. package/src/semantics/account.ts +10 -0
  218. package/src/semantics/account_links.ts +20 -0
  219. package/src/semantics/accounts.ts +44 -0
  220. package/src/semantics/{apps-secrets.ts → apps.ts} +17 -33
  221. package/src/semantics/around.ts +17 -0
  222. package/src/semantics/balance.ts +6 -208
  223. package/src/semantics/balance_transactions.ts +18 -0
  224. package/src/semantics/billing_portal.ts +45 -0
  225. package/src/semantics/charges.ts +8 -212
  226. package/src/semantics/checkout.ts +25 -276
  227. package/src/semantics/clock.ts +19 -0
  228. package/src/semantics/coupons.ts +5 -68
  229. package/src/semantics/customers.ts +48 -414
  230. package/src/semantics/doors.ts +79 -0
  231. package/src/semantics/entitlements.ts +3 -94
  232. package/src/semantics/events.ts +37 -0
  233. package/src/semantics/index.ts +89 -0
  234. package/src/semantics/invoice_payments.ts +16 -0
  235. package/src/semantics/invoices.ts +112 -441
  236. package/src/semantics/issuing.ts +57 -573
  237. package/src/semantics/payment_intents.ts +76 -0
  238. package/src/semantics/payment_methods.ts +20 -0
  239. package/src/semantics/payouts.ts +29 -0
  240. package/src/semantics/prices.ts +41 -0
  241. package/src/semantics/products.ts +12 -146
  242. package/src/semantics/promotion_codes.ts +38 -0
  243. package/src/semantics/radar.ts +8 -79
  244. package/src/semantics/refunds.ts +4 -216
  245. package/src/semantics/shared.ts +2089 -135
  246. package/src/semantics/states.ts +662 -0
  247. package/src/semantics/subscriptions.ts +39 -542
  248. package/src/semantics/test_helpers.ts +119 -0
  249. package/src/semantics/transfers.ts +10 -132
  250. package/src/semantics/webhook_endpoints.ts +27 -0
  251. package/src/server.ts +7 -0
  252. package/client/dashboard-api.ts +0 -286
  253. package/client/stripe-mirror.css +0 -277
  254. package/client/stripe-mirror.tsx +0 -1559
  255. package/dist/client/dashboard-api.d.ts +0 -107
  256. package/dist/client/dashboard-api.js +0 -238
  257. package/dist/client/dashboard-api.ts +0 -286
  258. package/dist/client/stripe-mirror.bundle.js +0 -236
  259. package/dist/client/stripe-mirror.css +0 -277
  260. package/dist/client/stripe-mirror.d.ts +0 -134
  261. package/dist/client/stripe-mirror.js +0 -859
  262. package/dist/client/stripe-mirror.tsx +0 -1559
  263. package/dist/src/screens/connect-oauth.d.ts +0 -27
  264. package/dist/src/screens/connect-oauth.js +0 -414
  265. package/dist/src/screens/connect-settings.d.ts +0 -22
  266. package/dist/src/screens/connect-settings.js +0 -103
  267. package/dist/src/screens/consent-skin.d.ts +0 -4
  268. package/dist/src/screens/consent-skin.js +0 -18
  269. package/dist/src/screens/financial-connections.d.ts +0 -5
  270. package/dist/src/screens/financial-connections.js +0 -90
  271. package/dist/src/screens/identity.d.ts +0 -5
  272. package/dist/src/screens/identity.js +0 -86
  273. package/dist/src/screens/onboarding.d.ts +0 -13
  274. package/dist/src/screens/portal.d.ts +0 -5
  275. package/dist/src/screens/public-details.d.ts +0 -5
  276. package/dist/src/screens/public-details.js +0 -90
  277. package/dist/src/semantics/after-payment.d.ts +0 -22
  278. package/dist/src/semantics/after-payment.js +0 -99
  279. package/dist/src/semantics/apps-secrets.d.ts +0 -2
  280. package/dist/src/semantics/billing.d.ts +0 -2
  281. package/dist/src/semantics/billing.js +0 -220
  282. package/dist/src/semantics/connect.d.ts +0 -5
  283. package/dist/src/semantics/connect.js +0 -493
  284. package/dist/src/semantics/credit-notes.d.ts +0 -2
  285. package/dist/src/semantics/credit-notes.js +0 -172
  286. package/dist/src/semantics/disputes.d.ts +0 -2
  287. package/dist/src/semantics/disputes.js +0 -51
  288. package/dist/src/semantics/ephemeral-keys.d.ts +0 -2
  289. package/dist/src/semantics/ephemeral-keys.js +0 -34
  290. package/dist/src/semantics/files.d.ts +0 -2
  291. package/dist/src/semantics/files.js +0 -125
  292. package/dist/src/semantics/ledger.d.ts +0 -59
  293. package/dist/src/semantics/ledger.js +0 -200
  294. package/dist/src/semantics/payment-intents.d.ts +0 -18
  295. package/dist/src/semantics/payment-intents.js +0 -452
  296. package/dist/src/semantics/payment-links.d.ts +0 -2
  297. package/dist/src/semantics/payment-links.js +0 -133
  298. package/dist/src/semantics/payment-methods.d.ts +0 -20
  299. package/dist/src/semantics/payment-methods.js +0 -140
  300. package/dist/src/semantics/plans.d.ts +0 -5
  301. package/dist/src/semantics/plans.js +0 -121
  302. package/dist/src/semantics/platform.d.ts +0 -9
  303. package/dist/src/semantics/platform.js +0 -206
  304. package/dist/src/semantics/renewals.d.ts +0 -47
  305. package/dist/src/semantics/renewals.js +0 -281
  306. package/dist/src/semantics/setup-intents.d.ts +0 -2
  307. package/dist/src/semantics/setup-intents.js +0 -84
  308. package/dist/src/semantics/subscription-schedules.d.ts +0 -2
  309. package/dist/src/semantics/subscription-schedules.js +0 -119
  310. package/dist/src/semantics/tax.d.ts +0 -2
  311. package/dist/src/semantics/tax.js +0 -197
  312. package/dist/src/semantics/terminal.d.ts +0 -5
  313. package/dist/src/semantics/terminal.js +0 -182
  314. package/dist/src/semantics/test-clocks.d.ts +0 -6
  315. package/dist/src/semantics/test-clocks.js +0 -73
  316. package/dist/src/semantics/tokens.d.ts +0 -4
  317. package/dist/src/semantics/tokens.js +0 -44
  318. package/dist/src/semantics/treasury.d.ts +0 -2
  319. package/dist/src/semantics/treasury.js +0 -377
  320. package/dist/src/semantics/webhook-endpoints.d.ts +0 -3
  321. package/dist/src/semantics/webhook-endpoints.js +0 -85
  322. package/dist/src/stripe-budget.d.ts +0 -55
  323. package/dist/src/stripe-budget.js +0 -155
  324. package/dist/src/stripe-capabilities.d.ts +0 -3
  325. package/dist/src/stripe-capabilities.js +0 -5836
  326. package/dist/src/stripe-conformance.d.ts +0 -43
  327. package/dist/src/stripe-conformance.js +0 -105
  328. package/dist/src/stripe-connector.d.ts +0 -161
  329. package/dist/src/stripe-connector.js +0 -414
  330. package/dist/src/stripe-emit.d.ts +0 -2
  331. package/dist/src/stripe-emit.js +0 -145
  332. package/dist/src/stripe-events.d.ts +0 -93
  333. package/dist/src/stripe-events.js +0 -392
  334. package/dist/src/stripe-js.d.ts +0 -4
  335. package/dist/src/stripe-js.js +0 -70
  336. package/dist/src/stripe-mirror-ui.d.ts +0 -15
  337. package/dist/src/stripe-mirror-ui.js +0 -87
  338. package/dist/src/stripe-perform-harness.d.ts +0 -9
  339. package/dist/src/stripe-perform-harness.js +0 -26
  340. package/dist/src/stripe-server.d.ts +0 -33
  341. package/dist/src/stripe-server.js +0 -429
  342. package/dist/src/stripe-shared.d.ts +0 -109
  343. package/dist/src/stripe-shared.js +0 -276
  344. package/dist/src/stripe-ui-conformance.d.ts +0 -5
  345. package/dist/src/stripe-ui-conformance.js +0 -79
  346. package/dist/src/stripe-ui-structure.d.ts +0 -3
  347. package/dist/src/stripe-ui-structure.js +0 -168
  348. package/dist/test-fixtures/stripe-known-deviations.json +0 -110
  349. package/dist/test-fixtures/stripe-openapi-operations.SOURCE.md +0 -14
  350. package/dist/test-fixtures/stripe-openapi-operations.json +0 -4717
  351. package/dist/test-fixtures/stripe-schemas.SOURCE.md +0 -35
  352. package/dist/test-fixtures/stripe-schemas.json +0 -3813
  353. package/src/screens/connect-oauth.tsx +0 -400
  354. package/src/screens/connect-settings.tsx +0 -121
  355. package/src/screens/consent-skin.ts +0 -20
  356. package/src/screens/financial-connections.tsx +0 -101
  357. package/src/screens/identity.tsx +0 -96
  358. package/src/screens/public-details.tsx +0 -105
  359. package/src/semantics/after-payment.ts +0 -118
  360. package/src/semantics/billing.ts +0 -216
  361. package/src/semantics/connect.ts +0 -487
  362. package/src/semantics/credit-notes.ts +0 -168
  363. package/src/semantics/disputes.ts +0 -62
  364. package/src/semantics/ephemeral-keys.ts +0 -34
  365. package/src/semantics/files.ts +0 -143
  366. package/src/semantics/ledger.ts +0 -253
  367. package/src/semantics/payment-intents.ts +0 -463
  368. package/src/semantics/payment-links.ts +0 -148
  369. package/src/semantics/payment-methods.ts +0 -145
  370. package/src/semantics/plans.ts +0 -131
  371. package/src/semantics/platform.ts +0 -220
  372. package/src/semantics/renewals.ts +0 -279
  373. package/src/semantics/setup-intents.ts +0 -87
  374. package/src/semantics/subscription-schedules.ts +0 -129
  375. package/src/semantics/tax.ts +0 -220
  376. package/src/semantics/terminal.ts +0 -195
  377. package/src/semantics/test-clocks.ts +0 -77
  378. package/src/semantics/tokens.ts +0 -52
  379. package/src/semantics/treasury.ts +0 -383
  380. package/src/semantics/webhook-endpoints.ts +0 -87
  381. package/src/stripe-budget.ts +0 -181
  382. package/src/stripe-capabilities.ts +0 -5651
  383. package/src/stripe-conformance.ts +0 -124
  384. package/src/stripe-connector.ts +0 -462
  385. package/src/stripe-emit.ts +0 -157
  386. package/src/stripe-events.ts +0 -434
  387. package/src/stripe-js.ts +0 -70
  388. package/src/stripe-mirror-ui.ts +0 -90
  389. package/src/stripe-perform-harness.ts +0 -29
  390. package/src/stripe-server.ts +0 -393
  391. package/src/stripe-shared.ts +0 -297
  392. package/src/stripe-ui-conformance.ts +0 -88
  393. package/src/stripe-ui-structure.ts +0 -182
  394. package/test-fixtures/stripe-known-deviations.json +0 -110
  395. package/test-fixtures/stripe-openapi-operations.json +0 -4717
  396. package/test-fixtures/stripe-schemas.json +0 -3813
  397. /package/dist/src/{screens → engine}/industries.d.ts +0 -0
  398. /package/dist/src/{screens → engine}/industries.js +0 -0
  399. /package/dist/src/{semantics → engine}/test-cards.d.ts +0 -0
  400. /package/dist/src/{semantics → engine}/test-cards.js +0 -0
  401. /package/src/{screens → engine}/industries.ts +0 -0
  402. /package/src/{semantics → engine}/test-cards.ts +0 -0
@@ -0,0 +1,44 @@
1
+ // Stripe's accounts 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 { externalList } from '../engine/common.ts';
5
+ import { controllerOf, expressRequirements, keptKyc } from '../engine/connect.ts';
6
+ import { ACCOUNT_TYPES, accountCapabilities, accountRequirements, accountSettings, nowUnix } from '../engine/stripe.ts';
7
+ import { accountMissing, accountRow, at, connectReview, created, fail, list, newest } from './shared.ts';
8
+ export async function GetAccountsAccountExternalAccounts(ctx: HandlerContext): Promise<Response> {
9
+ const account = at(ctx, 'account');
10
+ if (!accountRow(ctx, account)) return accountMissing(ctx, account);
11
+ return list(ctx, 'external_account', newest(ctx, 'external_account').filter((e) => e.account === account));
12
+ }
13
+
14
+ // the requested capabilities become Stripe's status map, and settings its canonical shape
15
+ export async function PostAccounts(ctx: HandlerContext): Promise<Response> {
16
+ const params = ctx.params;
17
+ const type = typeof params.type === 'string' ? params.type : 'standard';
18
+ if (!ACCOUNT_TYPES.has(type)) return fail(ctx, 'Invalid account type: must be one of express, standard, or custom.', 400, 'parameter_invalid_string_enum');
19
+ const { capabilities: _caps, settings: _settings, ...accountParams } = keptKyc(params);
20
+ const id = ctx.mint('account');
21
+ const made = await created(ctx, 'account', { ...accountParams, id, type }, {
22
+ business_type: null, charges_enabled: false, payouts_enabled: false, details_submitted: false,
23
+ capabilities: accountCapabilities(params), requirements: type === 'express' ? expressRequirements(params) : accountRequirements(),
24
+ country: typeof params.country === 'string' ? params.country : 'US',
25
+ default_currency: 'usd', email: params.email ?? null, metadata: {}, livemode: false,
26
+ settings: accountSettings(params.settings), business_profile: {},
27
+ controller: controllerOf(type), external_accounts: externalList(id, []),
28
+ future_requirements: { alternatives: [], current_deadline: null, currently_due: [], disabled_reason: null, errors: [], eventually_due: [], past_due: [], pending_verification: [] },
29
+ tos_acceptance: { date: null, ip: null, user_agent: null },
30
+ });
31
+ await connectReview(ctx, String(made.id));
32
+ return ctx.reply(ctx.expand('account', ctx.get('account', String(made.id))!));
33
+ }
34
+
35
+ // a single-use Express dashboard link, not stored
36
+ export async function PostAccountsAccountLoginLinks(ctx: HandlerContext): Promise<Response> {
37
+ const id = at(ctx, 'account');
38
+ if (!ctx.get('account', id)) return accountMissing(ctx, id);
39
+ return ctx.reply({ object: 'login_link', created: nowUnix(ctx.occurredAt), url: `https://connect.twin.local/express/${id}` });
40
+ }
41
+
42
+
43
+ // source: spec:PostAccountsAccount "left unchanged."
44
+ // source: https://docs.stripe.com/connect/account-capabilities "If a connected account has both card_payments and transfers"
@@ -1,18 +1,18 @@
1
- // Apps secret-store semantics: a secret is named within a scope (the account, or one user); setting
2
- // the same name in the same scope overwrites it. The scope is kept as a bookkeeping key.
3
- import type { Semantics, SemanticsContext } from '@volter/world-core';
4
- import { created, fail, list, newest, type Row, kept } from './shared.ts';
5
-
6
- const SECRET = 'apps.secret';
7
-
8
- function scopeKeyOf(ctx: SemanticsContext): string {
9
- const scope = ctx.params.scope && typeof ctx.params.scope === 'object' ? (ctx.params.scope as Row) : undefined;
10
- const scopeType = scope && typeof scope.type === 'string' ? scope.type : 'account';
11
- return scopeType === 'user' ? `user:${String(scope!.user)}` : 'account';
1
+ // Stripe's apps 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 { SECRET } from '../engine/apps-secrets.ts';
5
+ import type { Row } from '../engine/common.ts';
6
+ import { nowUnix } from '../engine/stripe.ts';
7
+ import { created, fail, named, scopeKeyOf } from './shared.ts';
8
+ export async function GetAppsSecretsFind(ctx: HandlerContext): Promise<Response> {
9
+ const name = typeof ctx.params.name === 'string' ? ctx.params.name : '';
10
+ if (!name) return fail(ctx, 'Missing required param: name.', 400, 'parameter_missing');
11
+ const s = named(ctx, name);
12
+ return s ? ctx.reply(s) : fail(ctx, `No such secret: '${name}'`, 404, 'resource_missing');
12
13
  }
13
- const named = (ctx: SemanticsContext, name: string): Row | undefined => ctx.rows(SECRET).find((s) => s.name === name && kept(ctx, SECRET, s, '_scope_key') === scopeKeyOf(ctx));
14
14
 
15
- const set: Semantics = async (ctx) => {
15
+ export async function PostAppsSecrets(ctx: HandlerContext): Promise<Response> {
16
16
  const params = ctx.params;
17
17
  const name = typeof params.name === 'string' ? params.name : '';
18
18
  if (!name) return fail(ctx, 'Missing required param: name.', 400, 'parameter_missing');
@@ -23,7 +23,7 @@ const set: Semantics = async (ctx) => {
23
23
  if (params.payload === undefined) return fail(ctx, 'Missing required param: payload.', 400, 'parameter_missing');
24
24
  const expiresAt = params.expires_at !== undefined ? Math.trunc(Number(params.expires_at)) : null;
25
25
  const existing = named(ctx, name);
26
- if (existing) return ctx.reply(await ctx.write(SECRET, String(existing.id), { payload: params.payload, expires_at: expiresAt, _updated: ctx.now() }, 'apps_secret.update'));
26
+ if (existing) return ctx.reply(await ctx.write(SECRET, String(existing.id), { payload: params.payload, expires_at: expiresAt, _updated: nowUnix(ctx.occurredAt) }, 'apps_secret.update'));
27
27
  return ctx.reply(
28
28
  await created(ctx, SECRET, { name }, {
29
29
  livemode: false, deleted: false, expires_at: expiresAt, payload: params.payload,
@@ -31,28 +31,12 @@ const set: Semantics = async (ctx) => {
31
31
  _scope_key: scopeKeyOf(ctx),
32
32
  }),
33
33
  );
34
- };
35
-
36
- const find: Semantics = async (ctx) => {
37
- const name = typeof ctx.params.name === 'string' ? ctx.params.name : '';
38
- if (!name) return fail(ctx, 'Missing required param: name.', 400, 'parameter_missing');
39
- const s = named(ctx, name);
40
- return s ? ctx.reply(s) : fail(ctx, `No such secret: '${name}'`, 404, 'resource_missing');
41
- };
34
+ }
42
35
 
43
- const remove: Semantics = async (ctx) => {
36
+ export async function PostAppsSecretsDelete(ctx: HandlerContext): Promise<Response> {
44
37
  const name = typeof ctx.params.name === 'string' ? ctx.params.name : '';
45
38
  if (!name) return fail(ctx, 'Missing required param: name.', 400, 'parameter_missing');
46
39
  const s = named(ctx, name);
47
40
  if (!s) return fail(ctx, `No such secret: '${name}'`, 404, 'resource_missing');
48
41
  return ctx.reply(await ctx.write(SECRET, String(s.id), { deleted: true }, 'apps_secret.delete'));
49
- };
50
-
51
- const listSecrets: Semantics = async (ctx) => list(ctx, SECRET, newest(ctx, SECRET).filter((s) => kept(ctx, SECRET, s, '_scope_key') === scopeKeyOf(ctx)));
52
-
53
- export const appsSecrets: Record<string, Semantics> = {
54
- PostAppsSecrets: set,
55
- GetAppsSecretsFind: find,
56
- PostAppsSecretsDelete: remove,
57
- GetAppsSecrets: listSecrets,
58
- };
42
+ }
@@ -0,0 +1,17 @@
1
+ // What Stripe does around every API request (docs/contributing/architecture.md, "What an author writes": around): a
2
+ // request's key is one Stripe issued (the platform's, or a connected account's OAuth key); an OAuth key acts as its
3
+ // connected account; a publishable key is held to the client-side calls, a revoked account is
4
+ // refused and the parameters are checked against the operation's; a metadata hash merges; and every answer is rendered
5
+ // in the caller's API version (../engine/front.ts).
6
+ import type { HandlerContext } from '@volter/world-core';
7
+ import { platformKeyRefused, publishableKeyRefused, refuseParameters, rendered, withMetadata } from './shared.ts';
8
+ export async function around(ctx: HandlerContext, next: (request?: Request) => Promise<Response>): Promise<Response> {
9
+ const arrived = ctx.call.request;
10
+ const unkeyed = platformKeyRefused(ctx, arrived);
11
+ if (unkeyed) return unkeyed;
12
+ if (ctx.call.operation.id !== 'unmatched') {
13
+ const refused = publishableKeyRefused(ctx) ?? refuseParameters(ctx);
14
+ if (refused) return refused;
15
+ }
16
+ return rendered(arrived, await next(withMetadata(ctx, arrived.clone())));
17
+ }
@@ -1,209 +1,7 @@
1
- // Balance and payout semantics. The balance is computed from the balance-transaction ledger (./ledger.ts), never
2
- // stored: funds past their available_on are available, the rest pending, and Issuing funds their own section. The
3
- // balance, the payouts and the ledger are the acting account's: the platform's, or a connected account's under the
4
- // Stripe-Account header. A payout comes out of what that account has available and goes to its bank account, which a
5
- // connected account must have (docs.stripe.com/connect/payouts-connected-accounts). A pending payout can be canceled,
6
- // which returns its money; a connected account's paid payout can be reversed, which debits its bank account back
7
- // into its balance (docs.stripe.com/api/payouts/reverse). The machine in ../manifest.ts says how a payout's status
8
- // moves.
9
- //
10
- // Stripe also pays each account out on its own schedule (settings.payouts.schedule: daily by default, weekly or monthly
11
- // on an anchor, or manual): an automatic payout takes what has become available since the last one, and the ledger
12
- // lists the entries it paid (docs.stripe.com/payouts#payout-schedule, docs.stripe.com/connect/manage-payout-schedule).
13
- // A connected account is paid out once it can be (payouts_enabled, with a bank account).
14
- //
15
- // Where the documentation stops and the twin decides: a payout arrives two days after it is made (Stripe's standard
16
- // US schedule counts business days) and reads paid from then on; an automatic payout is made at midnight UTC on the
17
- // first scheduled day on or after its funds become available, only when what it would pay is positive.
18
- import type { Semantics, SemanticsContext } from '@volter/world-core';
19
- import { validateMoney } from '../stripe-twin.ts';
20
- import { accountSettings, PLATFORM_ACCOUNT_ID } from '../stripe-twin.ts';
21
- import { actingAccount, balanceOf, refusePayout, settleAutomaticPayout, settlePayout, unpaidEntries } from './ledger.ts';
22
- import { at, at_, created, fail, inRange, list, newest, send, where, type Row, kept } from './shared.ts';
23
-
24
- const account = actingAccount;
25
- const DAY = 86_400;
26
- const payoutMissing = (ctx: SemanticsContext, id: string): Response => fail(ctx, `No such payout: '${id}'`, 404, 'resource_missing');
27
-
28
- /** The acting account's Balance object (docs.stripe.com/api/balance/balance_object). */
29
- export function balanceBody(ctx: SemanticsContext): Row {
30
- const { available, pending, issuing } = balanceOf(ctx);
31
- const toArr = (m: Map<string, number>) => {
32
- const out = [...m.entries()].map(([currency, amount]) => ({ amount, currency, source_types: { card: amount } }));
33
- return out.length ? out : [{ amount: 0, currency: 'usd', source_types: { card: 0 } }];
34
- };
35
- // a platform's balance holds its connected accounts' reserve, "Funds held due to negative balances on connected accounts
36
- // where account.controller.requirement_collection is `application`" (docs.stripe.com/api/balance/balance_object, whose
37
- // example answers `[{"amount": 0, "currency": "usd"}]`); the twin models no such reserve, so it is zero in each currency
38
- const reserved = account(ctx) ? {} : { connect_reserved: toArr(available).map((b) => ({ amount: 0, currency: b.currency })) };
39
- return {
40
- object: 'balance', available: toArr(available), pending: toArr(pending), ...reserved, livemode: false,
41
- ...(issuing.size ? { issuing: { available: [...issuing.entries()].map(([currency, amount]) => ({ amount, currency, source_types: { card: amount } })) } } : {}),
42
- };
1
+ // Stripe's balance 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 { balanceBody } from './shared.ts';
5
+ export async function GetBalance(ctx: HandlerContext): Promise<Response> {
6
+ return ctx.reply(balanceBody(ctx));
43
7
  }
44
-
45
- const balance: Semantics = async (ctx) => ctx.reply(balanceBody(ctx));
46
-
47
- /** Time's arrivals, written: each of the acting account's payouts whose arrival date has come moves pending → paid
48
- * (the clock's move, as asOf reads it), written as `payout.paid`, the event Stripe sends for it. Answers their ids. */
49
- export async function payDuePayouts(ctx: SemanticsContext): Promise<string[]> {
50
- const acct = account(ctx);
51
- const now = Number(ctx.now());
52
- const paid: string[] = [];
53
- for (const p of newest(ctx, 'payout')) {
54
- if ((acct ? kept(ctx, 'payout', p, '_account') !== acct : !!kept(ctx, 'payout', p, '_account')) || p.status !== 'pending' || Number(p.arrival_date) > now) continue;
55
- if (ctx.legal('payout', 'status', ctx.call.operation.id, 'pending', 'paid', String(p.id), 'time')) continue;
56
- await ctx.write('payout', String(p.id), { status: 'paid' }, 'payout.paid');
57
- paid.push(String(p.id));
58
- }
59
- return paid;
60
- }
61
-
62
- /** Where a connected account's payout goes: "ID of the bank account or card the payout is sent to" (served spec,
63
- * payout.destination), its default external account for the currency, "When multiple accounts are available for a given
64
- * currency, Stripe uses the one set as `default_for_currency`" (docs.stripe.com/connect/payouts-bank-accounts), the
65
- * newest such. Where the documentation stops and the twin decides: the platform's own bank account is not modelled, so
66
- * its payouts name none. */
67
- function payoutBank(ctx: SemanticsContext, account: string, currency: string): string | null {
68
- const banks = newest(ctx, 'external_account').filter((e) => e.account === account && String(e.currency ?? currency) === currency);
69
- return String((banks.find((e) => e.default_for_currency === true) ?? banks[0])?.id ?? '') || null;
70
- }
71
-
72
- const payoutDefaults = (ctx: SemanticsContext): Row => ({
73
- method: 'standard', type: 'bank_account', source_type: 'card', automatic: false,
74
- reconciliation_status: 'not_applicable', arrival_date: Number(ctx.now()) + 2 * DAY, livemode: false, metadata: {},
75
- });
76
-
77
- /** A payout as the clock reads it: paid once its arrival date has come, the clock's move, asked of the
78
- * machine as a write asks it. */
79
- function asOf(ctx: SemanticsContext, p: Row): Row {
80
- if (p.status !== 'pending' || Number(p.arrival_date) > Number(ctx.now())) return p;
81
- ctx.legal('payout', 'status', ctx.call.operation.id, 'pending', 'paid', String(p.id), 'time');
82
- return { ...p, status: 'paid' };
83
- }
84
-
85
- /** A connected account's payout in a currency none of its bank accounts takes. */
86
- function noExternalAccount(ctx: SemanticsContext, currency: string): Response {
87
- return fail(ctx, `Sorry, you don't have any external accounts in that currency (${currency}).`, 400);
88
- }
89
-
90
- const createPayout: Semantics = async (ctx) => {
91
- const bad = validateMoney(ctx.params);
92
- if (bad) return send(ctx, bad);
93
- const acct = account(ctx);
94
- if (acct && !ctx.get('account', acct)) return fail(ctx, `No such account: '${acct}'`, 400, 'account_invalid');
95
- const amount = Math.trunc(Number(ctx.params.amount) || 0);
96
- const currency = String(ctx.params.currency ?? 'usd');
97
- // a connected account is paid out to its own bank account
98
- if (acct && !ctx.rows('external_account').some((e) => e.account === acct && (e.currency ?? currency) === currency)) return noExternalAccount(ctx, currency);
99
- const refused = refusePayout(ctx, amount, currency);
100
- if (refused) return refused;
101
- const id = ctx.mint('payout');
102
- const bt = await settlePayout(ctx, id, -amount, currency);
103
- return ctx.reply(await created(ctx, 'payout', { ...ctx.params, id }, { status: 'pending', ...payoutDefaults(ctx), balance_transaction: bt, destination: acct ? payoutBank(ctx, acct, currency) : null, ...(acct ? { _account: acct } : {}) }));
104
- };
105
-
106
- const listPayouts: Semantics = async (ctx) => {
107
- const acct = account(ctx);
108
- const scoped = newest(ctx, 'payout').filter((p) => (acct ? kept(ctx, 'payout', p, '_account') === acct : !kept(ctx, 'payout', p, '_account'))).map((p) => asOf(ctx, p));
109
- return list(ctx, 'payout', where(ctx, scoped, { status: (p, v) => p.status === v, created: (p, v) => inRange(p.created, v), arrival_date: (p, v) => inRange(p.arrival_date, v) }));
110
- };
111
-
112
- const DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
113
- /** The first scheduled payout time on or after `from`: midnight UTC of a day the schedule pays out on. */
114
- function payoutDay(from: number, schedule: Row): number {
115
- const first = Math.ceil(from / DAY) * DAY;
116
- const pays = (day: number): boolean => {
117
- const d = new Date(day * 1000);
118
- if (schedule.interval === 'weekly') return DAYS[d.getUTCDay()] === String(schedule.weekly_anchor ?? 'monday');
119
- if (schedule.interval === 'monthly') return d.getUTCDate() === Math.min(Number(schedule.monthly_anchor ?? 1), new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + 1, 0)).getUTCDate());
120
- return true;
121
- };
122
- return Array.from({ length: 62 }, (_, i) => first + i * DAY).find(pays) ?? first;
123
- }
124
-
125
- /** Time's payouts, caught up to the World's clock: each account on an automatic schedule is paid out, on each of its
126
- * scheduled days that has come, what became available by then. */
127
- export async function advancePayouts(ctx: SemanticsContext): Promise<void> {
128
- const now = Number(ctx.now());
129
- const platform = ctx.get('account', PLATFORM_ACCOUNT_ID);
130
- const accounts: Array<{ id: string | undefined; settings: unknown }> = [{ id: undefined, settings: platform?.settings }];
131
- for (const a of ctx.rows('account')) {
132
- if (a.id === PLATFORM_ACCOUNT_ID || a.payouts_enabled !== true) continue;
133
- if (!ctx.rows('external_account').some((e) => e.account === a.id)) continue;
134
- accounts.push({ id: String(a.id), settings: a.settings });
135
- }
136
- for (const acct of accounts) {
137
- const schedule = ((accountSettings(acct.settings, (acct.settings as Row | undefined) ?? undefined).payouts as Row).schedule ?? {}) as Row;
138
- if (schedule.interval === 'manual') continue;
139
- const unpaid = unpaidEntries(ctx, acct.id);
140
- const days = [...new Set(unpaid.map((t) => payoutDay(Number(t.available_on) || 0, schedule)))].filter((d) => d <= now).sort((x, y) => x - y);
141
- const paid = new Set<unknown>();
142
- for (const day of days) {
143
- const due = unpaid.filter((t) => !paid.has(t.id) && (Number(t.available_on) || 0) <= day);
144
- const byCurrency = new Map<string, Row[]>();
145
- for (const t of due) byCurrency.set(String(t.currency ?? 'usd'), [...(byCurrency.get(String(t.currency ?? 'usd')) ?? []), t]);
146
- for (const [currency, entries] of byCurrency) {
147
- const amount = entries.reduce((n, t) => n + (Number(t.net) || 0), 0);
148
- // nothing to pay yet: what came due is carried to the next payout
149
- if (amount <= 0) continue;
150
- // made on its day, as Stripe makes it, whenever the request that catches it up comes
151
- const c = await at_(ctx)(day);
152
- const id = c.mint('payout');
153
- const bt = await settleAutomaticPayout(c, id, amount, currency, acct.id, day, entries);
154
- await created(c, 'payout', { id, amount, currency }, {
155
- status: 'pending', ...payoutDefaults(c), arrival_date: day + 2 * DAY, automatic: true, balance_transaction: bt, destination: acct.id ? payoutBank(c, String(acct.id), currency) : null,
156
- description: 'STRIPE PAYOUT', ...(acct.id ? { _account: acct.id } : {}),
157
- });
158
- for (const t of entries) paid.add(t.id);
159
- }
160
- }
161
- }
162
- }
163
-
164
- const retrievePayout: Semantics = async (ctx) => {
165
- const p = ctx.get('payout', at(ctx, 'payout'));
166
- return p ? ctx.reply(asOf(ctx, p)) : payoutMissing(ctx, at(ctx, 'payout'));
167
- };
168
-
169
- const cancelPayout: Semantics = async (ctx) => {
170
- const id = at(ctx, 'payout');
171
- const po = ctx.get('payout', id);
172
- if (!po) return payoutMissing(ctx, id);
173
- const refused = ctx.legal('payout', 'status', 'PostPayoutsPayoutCancel', asOf(ctx, po).status, undefined, id);
174
- if (refused) return ctx.refuse(refused);
175
- // the money comes back to the balance it left
176
- const owner = kept(ctx, 'payout', po, '_account');
177
- await settlePayout(ctx, id, Number(po.amount) || 0, String(po.currency ?? 'usd'), typeof owner === 'string' ? owner : null);
178
- return ctx.reply(await ctx.write('payout', id, { status: 'canceled' }, 'payout.cancel'));
179
- };
180
-
181
- // a reversal is itself a payout in the other direction, back into the connected account's balance, as the reverse page's
182
- // example answers it: a negative amount, pending until it arrives, carrying the request's metadata
183
- // (docs.stripe.com/api/payouts/reverse); the original stays paid and names it
184
- const reversePayout: Semantics = async (ctx) => {
185
- const id = at(ctx, 'payout');
186
- const po = ctx.get('payout', id);
187
- if (!po) return payoutMissing(ctx, id);
188
- const owner = kept(ctx, 'payout', po, '_account');
189
- if (typeof owner !== 'string') return fail(ctx, "Payout reversals are only supported for payouts to connected accounts' bank accounts.", 400);
190
- const status = String(asOf(ctx, po).status);
191
- if (po.reversed_by || status !== 'paid') return ctx.refuse({ status: 400, code: 'payout_reversal_not_allowed', message: po.reversed_by ? 'This payout has already been reversed.' : `This payout cannot be reversed because it has a status of ${status}. A pending payout can be canceled instead.` });
192
- const reversalId = ctx.mint('payout');
193
- const bt = await settlePayout(ctx, reversalId, Number(po.amount) || 0, String(po.currency ?? 'usd'), owner);
194
- const metadata = ctx.params.metadata && typeof ctx.params.metadata === 'object' ? { metadata: ctx.params.metadata } : {};
195
- const reversal = await created(ctx, 'payout', { id: reversalId, amount: -(Number(po.amount) || 0), currency: po.currency, ...metadata }, {
196
- status: 'pending', ...payoutDefaults(ctx), balance_transaction: bt, original_payout: id, destination: po.destination ?? null, _account: owner,
197
- });
198
- await ctx.write('payout', id, { reversed_by: reversal.id }, 'payout.reversed');
199
- return ctx.reply(reversal);
200
- };
201
-
202
- export const balances: Record<string, Semantics> = {
203
- GetBalance: balance,
204
- PostPayouts: createPayout,
205
- GetPayouts: listPayouts,
206
- GetPayoutsPayout: retrievePayout,
207
- PostPayoutsPayoutCancel: cancelPayout,
208
- PostPayoutsPayoutReverse: reversePayout,
209
- };
@@ -0,0 +1,18 @@
1
+ // Stripe's balance_transactions 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 { inRange } from '../engine/common.ts';
5
+ import { BT } from '../engine/ledger.ts';
6
+ import { commonAsOf, kept, list, mine, newest, where } from './shared.ts';
7
+ export async function GetBalanceTransactions(ctx: HandlerContext): Promise<Response> {
8
+ const own = mine(ctx);
9
+ return list(ctx, BT, where(ctx, newest(ctx, BT).filter((t) => own.has(t.id)).map((t) => commonAsOf(ctx, t)), {
10
+ type: (t, v) => t.type === v,
11
+ currency: (t, v) => t.currency === v,
12
+ source: (t, v) => t.source === v,
13
+ // an automatic payout lists the entries it paid out, its own debit among them
14
+ payout: (t, v) => t.source === v || kept(ctx, BT, t, '_payout') === v,
15
+ // a range of creation times (docs.stripe.com/api/balance_transactions/list#balance_transaction_list-created)
16
+ created: (t, v) => inRange(t.created, v),
17
+ }));
18
+ }
@@ -0,0 +1,45 @@
1
+ // Stripe's billing_portal 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 { filled, PBC, PORTAL_FEATURES } from '../engine/files.ts';
5
+ import { asBool, nowUnix } from '../engine/stripe.ts';
6
+ import { actingAccount, created, fail, list, newest, where } from './shared.ts';
7
+ export async function GetBillingPortalConfigurations(ctx: HandlerContext): Promise<Response> {
8
+ return list(ctx, PBC, where(ctx, newest(ctx, PBC), {
9
+ active: (c, v) => asBool(c.active) === asBool(v),
10
+ is_default: (c, v) => asBool(c.is_default) === asBool(v),
11
+ }));
12
+ }
13
+
14
+ export async function PostBillingPortalConfigurations(ctx: HandlerContext): Promise<Response> {
15
+ return ctx.reply(
16
+ await created(ctx, PBC, { ...ctx.params, business_profile: filled({ headline: null, privacy_policy_url: null, terms_of_service_url: null }, ctx.params.business_profile), features: filled(PORTAL_FEATURES, ctx.params.features) }, {
17
+ active: true, is_default: false, livemode: false,
18
+ login_page: { enabled: false, url: null },
19
+ metadata: {}, default_return_url: ctx.params.default_return_url ?? null,
20
+ updated: nowUnix(ctx.occurredAt),
21
+ }),
22
+ );
23
+ }
24
+
25
+
26
+ // ── the customer portal ──
27
+
28
+ // the configuration defaults to the account's default one
29
+ export async function PostBillingPortalSessions(ctx: HandlerContext): Promise<Response> {
30
+ const customer = typeof ctx.params.customer === 'string' ? ctx.params.customer : '';
31
+ if (!customer) return fail(ctx, 'Missing required param: customer.', 400, 'parameter_missing');
32
+ if (!ctx.row('customer', customer, { withDeleted: true })) return fail(ctx, `No such customer: '${customer}'`, 404, 'resource_missing');
33
+ const configuration = typeof ctx.params.configuration === 'string' && ctx.params.configuration
34
+ ? ctx.params.configuration
35
+ : (ctx.rowsRaw('billing_portal.configuration', { withDeleted: true }).find((c) => c.is_default)?.id ?? 'bpc_twin_default');
36
+ const id = ctx.mint('billing_portal.session');
37
+ return ctx.reply(
38
+ await created(ctx, 'billing_portal.session', {
39
+ id, customer, configuration, return_url: ctx.params.return_url ?? null, url: `https://billing.stripe.com/p/session/${id}`,
40
+ locale: ctx.params.locale ?? null, on_behalf_of: ctx.params.on_behalf_of ?? null, livemode: false,
41
+ // the account the session was made on (Stripe-Account), whose name the portal shows (screens/billing-portal.tsx)
42
+ ...(actingAccount(ctx) ? { _brand_account: actingAccount(ctx) } : {}),
43
+ }, {}),
44
+ );
45
+ }