@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
@@ -1,90 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- // STRIPE FINANCIAL CONNECTIONS — a hosted flow (docs/contributing/architecture.md, "Screens"): an application
3
- // creates a Financial Connections Session for an account holder and the permissions it wants, and hands its
4
- // client_secret to Stripe.js, whose authentication flow lets the holder pick their bank and the accounts to share;
5
- // the linked accounts are then on the session and readable through the Accounts API, with balances and
6
- // transactions when the permissions asked for them (docs.stripe.com/financial-connections/fundamentals,
7
- // docs.stripe.com/financial-connections/other-data-powered-products). In test mode the bank is Stripe's test
8
- // institution (docs.stripe.com/financial-connections/testing). Linking is the holder's move, not an API call.
9
- // Authored from @volter/world-ui's consent piece under Stripe's skin; nothing of Stripe's page is copied.
10
- //
11
- // The flow is opened with the session's client_secret, never its id: the session's own documentation says "The
12
- // session's client_secret can be used to launch the flow using Stripe.js", and stripe.collectFinancialConnectionsAccounts
13
- // takes `clientSecret`, "The client_secret of the Financial Connections Session"
14
- // (docs.stripe.com/js/financial_connections/collect_financial_connections_accounts).
15
- // Where the documentation stops and the twin decides: the page is served at
16
- // js.stripe.com/v3/financial-connections/{client_secret}, the twin's address for the "on-page modal UI" Stripe.js
17
- // loads (the twin's stripe.js navigates there, ../stripe-js.ts); an id or an unknown secret finds no flow;
18
- // the test institution holds a checking account (•••• 6789) and a savings account (•••• 4321); a linked account's
19
- // balance and its three transactions are the twin's test data.
20
- import { semanticsContext } from '@volter/world-core';
21
- import { Consent, CONSENT_CSS, flowPage } from '@volter/world-ui';
22
- import surface from '../generated/surface.gen.json' with { type: 'json' };
23
- import { manifest } from "../manifest.js";
24
- import { created } from "../semantics/shared.js";
25
- import { formOf, seeOther, STRIPE_CONSENT_SKIN } from "./consent-skin.js";
26
- const FCS = 'financial_connections.session';
27
- const FCA = 'financial_connections.account';
28
- const FCT = 'financial_connections.transaction';
29
- const OPERATION = surface.operations.find((o) => o.id === 'GetFinancialConnectionsSessionsSession');
30
- const css = [CONSENT_CSS, STRIPE_CONSENT_SKIN];
31
- const TEST_ACCOUNTS = [
32
- { last4: '6789', subcategory: 'checking', display_name: 'Checking', balance: 125_000 },
33
- { last4: '4321', subcategory: 'savings', display_name: 'Savings', balance: 980_000 },
34
- ];
35
- const message = (status, text) => flowPage({ title: 'Link your account', status, css, body: _jsx("main", { className: "consent", children: _jsx("h1", { className: "consent-heading", children: text }) }) });
36
- const permissionsOf = (session) => (Array.isArray(session.permissions) ? session.permissions.map(String) : []);
37
- function page(secret, session) {
38
- const says = { balances: 'Account balances', ownership: 'Account ownership details', payment_method: 'Account and routing numbers', transactions: 'Transactions' };
39
- return flowPage({
40
- title: 'Link your account',
41
- css,
42
- body: (_jsx(Consent, { heading: "Link your account", app: { name: 'Test Institution' }, request: `Test mode · ${TEST_ACCOUNTS.map((a) => `${a.display_name} •••• ${a.last4}`).join(', ')}`, permissions: permissionsOf(session).map((p) => ({ title: says[p] ?? p, detail: 'Shared with the business through Stripe' })), action: `/v3/financial-connections/${secret}`, fields: {}, deny: { name: 'answer', value: 'cancel', label: 'Cancel' }, allow: { name: 'answer', value: 'link', label: 'Link accounts' }, note: "Stripe will share the data above with the business." })),
43
- });
44
- }
45
- /** The holder links the test institution's accounts to the session. */
46
- async function link(ctx, id, session) {
47
- const permissions = permissionsOf(session);
48
- const now = Number(ctx.now());
49
- for (const a of TEST_ACCOUNTS) {
50
- const account = await created(ctx, FCA, { session: id }, {
51
- livemode: false, status: 'active', account_holder: session.account_holder ?? null, institution_name: 'StripeBank', display_name: a.display_name,
52
- last4: a.last4, category: 'cash', subcategory: a.subcategory, supported_payment_method_types: ['us_bank_account', 'link'], permissions,
53
- balance: permissions.includes('balances') ? { as_of: now, type: 'cash', cash: { available: { usd: a.balance } }, current: { usd: a.balance } } : null,
54
- balance_refresh: permissions.includes('balances') ? { status: 'succeeded', last_attempted_at: now, next_refresh_available_at: null } : null,
55
- transaction_refresh: permissions.includes('transactions') ? { id: `fctxnref_${a.last4}`, status: 'succeeded', last_attempted_at: now, next_refresh_available_at: null } : null,
56
- ownership: null, ownership_refresh: null, subscriptions: [],
57
- });
58
- if (!permissions.includes('transactions'))
59
- continue;
60
- for (const [i, t] of [{ amount: -4_250, description: 'COFFEE ROASTERS' }, { amount: -12_000, description: 'CITY UTILITIES' }, { amount: 250_000, description: 'PAYROLL DEPOSIT' }].entries()) {
61
- await created(ctx, FCT, { account: account.id }, {
62
- livemode: false, amount: t.amount, currency: 'usd', description: t.description, status: 'posted',
63
- status_transitions: { posted_at: now - (3 - i) * 86_400, void_at: null }, transacted_at: now - (3 - i) * 86_400, transaction_refresh: `fctxnref_${a.last4}`, updated: now,
64
- });
65
- }
66
- }
67
- }
68
- /** The authentication flow Stripe.js opens, or undefined for any other request. */
69
- export function stripeFinancialConnectionsFlow(scope) {
70
- return async (request) => {
71
- const m = /^\/v3\/financial-connections\/([A-Za-z0-9_]+)\/?$/.exec(new URL(request.url).pathname);
72
- if (!m || (request.method !== 'GET' && request.method !== 'POST'))
73
- return undefined;
74
- const secret = m[1];
75
- const form = request.method === 'POST' ? await formOf(request.clone()) : {};
76
- const ctx = await semanticsContext(manifest, request, OPERATION, scope);
77
- const session = ctx.rows(FCS).find((s) => s.client_secret === secret);
78
- if (!session)
79
- return message(404, 'This link has expired.');
80
- const id = String(session.id);
81
- if (ctx.rows(FCA).some((a) => a.session === id))
82
- return message(200, 'Your accounts are linked.');
83
- if (request.method === 'GET')
84
- return page(secret, session);
85
- if (form.answer === 'link')
86
- await link(ctx, id, session);
87
- const back = typeof session.return_url === 'string' && session.return_url ? session.return_url : undefined;
88
- return back ? seeOther(back) : message(200, form.answer === 'link' ? 'Your accounts are linked.' : 'No accounts were linked.');
89
- };
90
- }
@@ -1,5 +0,0 @@
1
- /** verify.stripe.com's pages, or undefined for any other request. */
2
- export declare function stripeIdentityFlow(scope: {
3
- root?: string;
4
- clock?: () => string;
5
- }): (request: Request) => Promise<Response | undefined>;
@@ -1,86 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- // STRIPE IDENTITY — a hosted flow (docs/contributing/architecture.md, "Screens"): an application creates a
3
- // VerificationSession and sends the person to its `url` at verify.stripe.com/start/{session}; they submit their
4
- // ID there, the session is processing and then verified, with a VerificationReport of what was checked, or it
5
- // asks for input again with the reason in last_error; the person returns to return_url
6
- // (docs.stripe.com/identity/how-sessions-work, docs.stripe.com/identity/verification-sessions). In test mode the
7
- // page offers the outcome instead of a camera (the twin's decision: docs.stripe.com/identity/testing, once cited
8
- // for it, no longer answers). Submitting is the person's move
9
- // (the session machine's external actor) and the check Stripe's (its vendor moves). Authored from
10
- // @volter/world-ui's consent piece under Stripe's skin; nothing of Stripe's page is copied.
11
- //
12
- // Where the documentation stops and the twin decides: test mode's person is Jenny Rosen with a driving licence,
13
- // the name Stripe's test reports carry; a failed check is document_unverified_other.
14
- import { semanticsContext } from '@volter/world-core';
15
- import { Consent, CONSENT_CSS, flowPage } from '@volter/world-ui';
16
- import surface from '../generated/surface.gen.json' with { type: 'json' };
17
- import { manifest } from "../manifest.js";
18
- import { created } from "../semantics/shared.js";
19
- import { formOf, seeOther, STRIPE_CONSENT_SKIN } from "./consent-skin.js";
20
- const VS = 'identity.verification_session';
21
- const OPERATION = surface.operations.find((o) => o.id === 'GetIdentityVerificationSessionsSession');
22
- const css = [CONSENT_CSS, STRIPE_CONSENT_SKIN];
23
- const message = (status, text) => flowPage({ title: 'Stripe Identity', status, css, body: _jsx("main", { className: "consent", children: _jsx("h1", { className: "consent-heading", children: text }) }) });
24
- function page(id, session) {
25
- const kind = session.type === 'id_number' ? 'ID number' : 'Government-issued photo ID';
26
- return flowPage({
27
- title: 'Verify your identity',
28
- css,
29
- body: (_jsx(Consent, { heading: "Verify your identity", app: { name: 'Stripe Identity' }, request: "Test mode: choose how the verification ends", permissions: [
30
- { title: kind, detail: 'Test data: Jenny Rosen, driving licence' },
31
- ...(session.options?.document?.require_matching_selfie === true ? [{ title: 'Selfie', detail: 'Matched to the ID photo' }] : []),
32
- ], action: `/start/${id}`, fields: {}, deny: { name: 'outcome', value: 'unverified', label: 'Fail verification' }, allow: { name: 'outcome', value: 'verified', label: 'Verify' }, note: "Stripe uses this data only to verify your identity." })),
33
- });
34
- }
35
- /** The person submits; Stripe checks and writes the report, and the session is verified or asks again. */
36
- async function submit(ctx, id, session, verified) {
37
- if (ctx.legal(VS, 'status', OPERATION.id, String(session.status), 'processing', id, 'external'))
38
- return;
39
- // Stripe's check decides the processing session at once: the second move of the one write below
40
- ctx.legal(VS, 'status', OPERATION.id, 'processing', verified ? 'verified' : 'requires_input', id, 'vendor');
41
- const type = session.type === 'id_number' ? 'id_number' : 'document';
42
- const error = verified ? null : { code: 'document_unverified_other', reason: 'The document could not be verified.' };
43
- // a document check holds its images: files "Array of File ids containing images for this document" (the served
44
- // spec's document report). Where the documentation stops and the twin decides: the licence's front and back, two
45
- // identity_document files, as the published report's two
46
- const images = [];
47
- if (type === 'document')
48
- for (const side of ['front', 'back']) {
49
- const f = await created(ctx, 'file', { purpose: 'identity_document' }, { filename: `driving_license_${side}.jpg`, size: 0, type: 'jpg', title: null, expires_at: null, url: null, links: { object: 'list', data: [], has_more: false, url: '' } });
50
- images.push(String(f.id));
51
- }
52
- // the report records the options the session was checked with (the session's own, as its object answers them)
53
- const sessionOptions = session.options ?? {};
54
- const report = await created(ctx, 'identity.verification_report', { verification_session: id, type }, {
55
- livemode: false, client_reference_id: session.client_reference_id ?? null,
56
- document: type === 'document' ? { status: verified ? 'verified' : 'unverified', type: 'driving_license', first_name: 'Jenny', last_name: 'Rosen', address: null, dob: null, error, files: images } : null,
57
- id_number: type === 'id_number' ? { status: verified ? 'verified' : 'unverified', id_number_type: 'us_ssn', first_name: 'Jenny', last_name: 'Rosen', dob: null, error } : null,
58
- selfie: null, email: null, phone: null,
59
- options: type === 'document' ? { document: sessionOptions.document ?? {} } : { id_number: sessionOptions.id_number ?? {} },
60
- });
61
- // the url "can only be used once" (the served spec): spent by the submission, as the verification sessions page's
62
- // examples answer a verified and a requires_input session with url null
63
- await ctx.write(VS, id, verified
64
- ? { status: 'verified', last_verification_report: report.id, last_error: null, url: null, client_secret: null, verified_outputs: { first_name: 'Jenny', last_name: 'Rosen' } }
65
- : { status: 'requires_input', last_verification_report: report.id, last_error: error, url: null }, verified ? 'verification_session.verified' : 'verification_session.requires_input');
66
- }
67
- /** verify.stripe.com's pages, or undefined for any other request. */
68
- export function stripeIdentityFlow(scope) {
69
- return async (request) => {
70
- const m = /^\/start\/(vs_[A-Za-z0-9_]+)\/?$/.exec(new URL(request.url).pathname);
71
- if (!m || (request.method !== 'GET' && request.method !== 'POST'))
72
- return undefined;
73
- const id = m[1];
74
- const form = request.method === 'POST' ? await formOf(request.clone()) : {};
75
- const ctx = await semanticsContext(manifest, request, OPERATION, scope);
76
- const session = ctx.get(VS, id);
77
- if (!session)
78
- return message(404, 'This verification link is invalid.');
79
- if (session.status !== 'requires_input')
80
- return message(200, session.status === 'verified' ? 'You are verified.' : 'This verification has ended.');
81
- if (request.method === 'GET')
82
- return page(id, session);
83
- await submit(ctx, id, session, form.outcome === 'verified');
84
- return typeof session.return_url === 'string' && session.return_url ? seeOther(session.return_url) : message(200, form.outcome === 'verified' ? 'You are verified.' : 'We could not verify your identity.');
85
- };
86
- }
@@ -1,13 +0,0 @@
1
- import { type Row } from '../semantics/shared.js';
2
- type Form = Record<string, string>;
3
- type Kind = 'company' | 'individual';
4
- /** The set an account onboards against: the two US sets the twin models, or none. */
5
- export declare function kindOf(account: Row): Kind | undefined;
6
- /** What an account of this kind still owes, given the form's answers (none: all of it). */
7
- export declare function currentlyDue(kind: Kind, v?: Form): string[];
8
- /** connect.stripe.com's onboarding pages, or undefined for any other request. */
9
- export declare function stripeOnboardingFlow(scope: {
10
- root?: string;
11
- clock?: () => string;
12
- }): (request: Request) => Promise<Response | undefined>;
13
- export {};
@@ -1,5 +0,0 @@
1
- /** billing.stripe.com's portal pages, or undefined for any other request. */
2
- export declare function stripePortalFlow(scope: {
3
- root?: string;
4
- clock?: () => string;
5
- }): (request: Request) => Promise<Response | undefined>;
@@ -1,5 +0,0 @@
1
- export declare const PUBLIC_DETAILS_PATH = "/settings/public";
2
- export declare function stripePublicDetailsFlow(scope: {
3
- root?: string;
4
- clock?: () => string;
5
- }): (request: Request) => Promise<Response | undefined>;
@@ -1,90 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- // THE DASHBOARD'S PUBLIC DETAILS — a workspace page (docs/contributing/architecture.md, "Screens") of the Dashboard
3
- // (manifest screen `dashboard`), at dashboard.stripe.com/settings/public: Settings → Business → Public details, where
4
- // the operator sets what their customers see ("Public Details → Business Settings",
5
- // support.stripe.com/questions/update-account-name-shown-in-the-dashboard). Its business name is the account's
6
- // `business_profile.name`, "The customer-facing business name" (docs.stripe.com/api/accounts/object), and it is the
7
- // name Checkout shows: "You can change a Checkout page's name by modifying the Business name field"
8
- // (docs.stripe.com/payments/checkout/customization/appearance). Stripe's API has no call that changes the platform's
9
- // own account (POST /v1/accounts/{account} updates a connected one), so this page is the only way to the act, and
10
- // saving it writes the platform account's stored record (semantics/connect.ts `platform`), which GET /v1/account,
11
- // Checkout and the customer portal then read. The Dashboard's account name (`settings.dashboard.display_name`,
12
- // Settings → Account) is a separate, internal setting, "for internal use only" (the same support article), and this
13
- // page does not touch it. Authored from plain markup under Stripe's type; nothing of Stripe's page is copied.
14
- //
15
- // Where the documentation stops and the twin decides: the page holds the business name only (the real page's
16
- // support details, website and statement descriptor are not modelled here); the name is required and at most 5000
17
- // characters (the spec's bound on business_profile.name), which the browser holds the field to and the page checks
18
- // again for a client that is not a browser; no sign-in guards the page, as none guards the Dashboard mirror. The page
19
- // is matched by its path on whatever host reaches the twin (the World routes only dashboard.stripe.com's
20
- // /settings/public here; the local mirror serves it on its own origin), and the form posts to the page's own address
21
- // and the save redirects to its own path, so it also works under the hosted mirror's path prefix. Saving is an update of an account that exists (the first save included, though
22
- // the twin stores the platform's record only then), so every save is sent as account.updated.
23
- import { semanticsContext } from '@volter/world-core';
24
- import { flowPage } from '@volter/world-ui';
25
- import surface from '../generated/surface.gen.json' with { type: 'json' };
26
- import { manifest } from "../manifest.js";
27
- import { platformAccountDefault } from "../semantics/connect.js";
28
- import { created } from "../semantics/shared.js";
29
- import { publicBusinessName } from "../stripe-shared.js";
30
- import { PLATFORM_ACCOUNT_ID } from "../stripe-twin.js";
31
- import { formOf } from "./consent-skin.js";
32
- export const PUBLIC_DETAILS_PATH = '/settings/public';
33
- const MAX_NAME = 5000;
34
- const OPERATION = surface.operations.find((o) => o.id === 'PostAccountsAccount');
35
- const CSS = `
36
- * { box-sizing: border-box; }
37
- body { margin: 0; background: #f6f8fa; color: #1a1f36; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Ubuntu, sans-serif; font-size: 14px; }
38
- .pd { max-width: 640px; margin: 48px auto; padding: 0 16px; }
39
- .pd h1 { font-size: 28px; margin: 16px 0 4px; }
40
- .pd-lead { color: #697386; margin: 0 0 24px; }
41
- .pd-card { background: #ffffff; border: 1px solid #e3e8ee; border-radius: 8px; padding: 24px; }
42
- .pd-card label { display: block; font-weight: 600; margin-bottom: 6px; }
43
- .pd-card small { display: block; color: #697386; margin-bottom: 8px; }
44
- .pd-card input { width: 100%; padding: 8px 10px; border: 1px solid #c1c9d2; border-radius: 6px; font: inherit; }
45
- .pd-actions { margin-top: 20px; display: flex; justify-content: flex-end; }
46
- .pd-actions button { background: #635bff; color: #ffffff; border: 0; border-radius: 6px; padding: 8px 16px; font: inherit; font-weight: 600; cursor: pointer; }
47
- .pd-notice { padding: 10px 12px; border-radius: 6px; margin-bottom: 16px; }
48
- .pd-error { background: #fff0f3; color: #df1b41; }
49
- .pd-saved { background: #e7f8ef; color: #0e6245; }
50
- `;
51
- function page(account, opts = {}) {
52
- const named = account?.business_profile?.name;
53
- const value = opts.value ?? (typeof named === 'string' ? named : '');
54
- return flowPage({
55
- title: 'Public details – Stripe',
56
- css: [CSS],
57
- ...(opts.error ? { status: 400 } : {}),
58
- body: (_jsxs("main", { className: "pd", children: [_jsx("h1", { children: "Public details" }), _jsxs("p", { className: "pd-lead", children: ["What your customers see on Checkout, the customer portal, receipts and invoices. Currently shown: ", _jsx("strong", { "data-testid": "public-business-name", children: publicBusinessName(account) })] }), opts.error ? _jsx("p", { className: "pd-notice pd-error", role: "alert", children: opts.error }) : null, opts.saved ? _jsx("p", { className: "pd-notice pd-saved", role: "status", children: "Your public details were saved." }) : null, _jsxs("form", { className: "pd-card", method: "post", children: [_jsx("label", { htmlFor: "business_name", children: "Business name" }), _jsx("small", { children: "The name customers see when they pay you." }), _jsx("input", { id: "business_name", name: "business_name", autoComplete: "organization", defaultValue: value, required: true, maxLength: MAX_NAME }), _jsx("div", { className: "pd-actions", children: _jsx("button", { type: "submit", children: "Save" }) })] })] })),
59
- });
60
- }
61
- /** Save the business name on the platform's own account: the stored record, made from Stripe's default the first
62
- * time anything is saved, and otherwise changed in place (its other public details kept). */
63
- async function save(ctx, name) {
64
- const held = ctx.get('account', PLATFORM_ACCOUNT_ID);
65
- const profile = { business_profile: { ...((held ?? platformAccountDefault()).business_profile ?? {}), name } };
66
- await (held ? ctx.write('account', PLATFORM_ACCOUNT_ID, profile, 'account.update') : created(ctx, 'account', { ...platformAccountDefault(), ...profile }, {}, { operation: 'account.update' }));
67
- }
68
- /** What the page says of a name no browser sends (the field is required and bounded), for a client that sends it. */
69
- function nameRefused(name) {
70
- return !name ? 'Enter your business name.' : name.length > MAX_NAME ? `Your business name must be at most ${MAX_NAME} characters.` : undefined;
71
- }
72
- export function stripePublicDetailsFlow(scope) {
73
- return async (request) => {
74
- const url = new URL(request.url);
75
- if (url.pathname.replace(/\/+$/, '') !== PUBLIC_DETAILS_PATH || (request.method !== 'GET' && request.method !== 'POST'))
76
- return undefined;
77
- // the form is read before the context, which reads the request's body itself
78
- const form = request.method === 'POST' ? await formOf(request.clone()) : {};
79
- const ctx = await semanticsContext(manifest, request, OPERATION, scope);
80
- if (request.method === 'GET')
81
- return page(ctx.get('account', PLATFORM_ACCOUNT_ID), { saved: url.searchParams.has('saved') });
82
- const name = (form.business_name ?? '').trim();
83
- const refused = nameRefused(name);
84
- if (refused)
85
- return page(ctx.get('account', PLATFORM_ACCOUNT_ID), { value: form.business_name ?? '', error: refused });
86
- await save(ctx, name);
87
- // a query-only reference: the page's own path, wherever it is mounted and with or without its trailing slash
88
- return new Response(null, { status: 303, headers: { location: '?saved=1' } });
89
- };
90
- }
@@ -1,22 +0,0 @@
1
- import type { SemanticsContext } from '@volter/world-core';
2
- type Outcome = 'dispute' | 'dispute_not_received' | 'inquiry' | 'review' | 'available';
3
- /** The test cards whose success Stripe follows with its own act, by number and by their documented test names. */
4
- export declare const AFTER_SUCCESS_CARDS: Record<string, {
5
- brand: string;
6
- number: string;
7
- outcome: Outcome;
8
- }>;
9
- /** What Stripe does after a card succeeds: from a raw number, a test name (pm_card_* or tok_*), or a stored
10
- * PaymentMethod that recorded it when it was made. */
11
- export declare function afterSuccessOf(ctx: SemanticsContext, ref: unknown): Outcome | undefined;
12
- /** Stripe's acts on a charge that just succeeded: a dispute or a review its card brings, and the platform's fee. */
13
- export declare function afterCharge(ctx: SemanticsContext, chargeId: string, charge: {
14
- amount: number;
15
- currency: string;
16
- payment_intent?: string | undefined;
17
- application_fee_amount?: unknown;
18
- destination?: unknown;
19
- }, ref: unknown): Promise<void>;
20
- /** The mandate a verified bank account carries for a payment (single use) or a setup (multi use). */
21
- export declare function mintMandate(ctx: SemanticsContext, paymentMethod: unknown, use: 'single_use' | 'multi_use', amount?: number, currency?: string): Promise<string>;
22
- export {};
@@ -1,99 +0,0 @@
1
- import { disputeEvidence } from "../stripe-twin.js";
2
- import { actingAccount, settleApplicationFee, settleDispute, settleTransfer } from "./ledger.js";
3
- import { BYPASS_PENDING_CARDS } from "./test-cards.js";
4
- import { created } from "./shared.js";
5
- const DAY = 86_400;
6
- /** The test cards whose success Stripe follows with its own act, by number and by their documented test names. */
7
- export const AFTER_SUCCESS_CARDS = {
8
- pm_card_createDispute: { brand: 'visa', number: '4000000000000259', outcome: 'dispute' },
9
- pm_card_createDisputeProductNotReceived: { brand: 'visa', number: '4000000000002685', outcome: 'dispute_not_received' },
10
- pm_card_createDisputeInquiry: { brand: 'visa', number: '4000000000001976', outcome: 'inquiry' },
11
- pm_card_riskLevelElevated: { brand: 'visa', number: '4000000000009235', outcome: 'review' },
12
- // its funds go straight to the available balance (ledger.ts reads it; no act follows here)
13
- ...Object.fromEntries(Object.entries(BYPASS_PENDING_CARDS).map(([name, c]) => [name, { ...c, outcome: 'available' }])),
14
- };
15
- const BY_NUMBER = Object.fromEntries(Object.values(AFTER_SUCCESS_CARDS).map((c) => [c.number, c.outcome]));
16
- /** What Stripe does after a card succeeds: from a raw number, a test name (pm_card_* or tok_*), or a stored
17
- * PaymentMethod that recorded it when it was made. */
18
- export function afterSuccessOf(ctx, ref) {
19
- // a card given as a token (card[token], payment_method_data[card][token]) is the card the token names
20
- if (ref && typeof ref === 'object' && typeof ref.token === 'string')
21
- return afterSuccessOf(ctx, ref.token);
22
- if (ref && typeof ref === 'object')
23
- return BY_NUMBER[String(ref.number ?? '').replace(/\D/g, '')];
24
- if (typeof ref !== 'string' || !ref)
25
- return undefined;
26
- const stored = ctx.row('payment_method', ref);
27
- if (stored)
28
- return stored._afterSuccess ?? undefined;
29
- return AFTER_SUCCESS_CARDS[ref.replace(/^tok_/, 'pm_card_')]?.outcome ?? BY_NUMBER[ref.replace(/\D/g, '')];
30
- }
31
- /** Stripe's acts on a charge that just succeeded: a dispute or a review its card brings, and the platform's fee. */
32
- export async function afterCharge(ctx, chargeId, charge, ref) {
33
- const outcome = afterSuccessOf(ctx, ref);
34
- const pi = charge.payment_intent ? { payment_intent: charge.payment_intent } : { payment_intent: null };
35
- const now = Number(ctx.now());
36
- if (outcome === 'dispute' || outcome === 'dispute_not_received' || outcome === 'inquiry') {
37
- const dispute = await created(ctx, 'dispute', { charge: chargeId, ...pi, amount: charge.amount, currency: charge.currency }, {
38
- reason: outcome === 'dispute_not_received' ? 'product_not_received' : 'fraudulent', status: outcome === 'inquiry' ? 'warning_needs_response' : 'needs_response', is_charge_refundable: false,
39
- evidence: disputeEvidence(), evidence_details: { due_by: now + 7 * DAY, has_evidence: false, past_due: false, submission_count: 0, enhanced_eligibility: {} },
40
- balance_transactions: [], livemode: false, metadata: {}, enhanced_eligibility_types: [],
41
- });
42
- // an inquiry moves no money; a dispute takes the amount and its fee until it is decided
43
- if (outcome !== 'inquiry') {
44
- const bt = await settleDispute(ctx, String(dispute.id), charge.amount, charge.currency);
45
- await ctx.write('dispute', String(dispute.id), { balance_transactions: [ctx.get('balance_transaction', bt) ?? bt] }, 'dispute.funds_withdrawn');
46
- }
47
- await ctx.write('charge', chargeId, { disputed: true }, 'charge.dispute.created');
48
- }
49
- if (outcome === 'review')
50
- await openReview(ctx, chargeId, pi);
51
- const feeAmount = Math.trunc(Number(charge.application_fee_amount) || 0);
52
- const destination = typeof charge.destination === 'string' && charge.destination ? charge.destination : undefined;
53
- const direct = actingAccount(ctx);
54
- const account = destination ?? direct;
55
- // a destination charge transfers what it collected, less the platform's fee, available when the charge's funds are
56
- if (destination) {
57
- const amount = charge.amount - feeAmount;
58
- const chargeBt = ctx.get('charge', chargeId)?.balance_transaction;
59
- const availableOn = Number(ctx.get('balance_transaction', String(chargeBt))?.available_on ?? ctx.now());
60
- const tr = await created(ctx, 'transfer', { amount, currency: charge.currency, destination }, {
61
- amount_reversed: 0, balance_transaction: null, livemode: false, metadata: {}, reversed: false, source_type: 'card', source_transaction: chargeId,
62
- reversals: { object: 'list', data: [], has_more: false, total_count: 0, url: '' },
63
- });
64
- const bt = await settleTransfer(ctx, String(tr.id), amount, charge.currency, destination, availableOn);
65
- await ctx.write('transfer', String(tr.id), { balance_transaction: bt, destination_payment: `py_${String(tr.id).replace(/^tr_/, '')}`, reversals: { object: 'list', data: [], has_more: false, total_count: 0, url: `/v1/transfers/${String(tr.id)}/reversals` } }, 'transfer.created');
66
- await ctx.write('charge', chargeId, { transfer: tr.id }, 'charge.updated');
67
- }
68
- if (feeAmount > 0 && account) {
69
- const fee = await created(ctx, 'application_fee', { account, amount: feeAmount, charge: chargeId, currency: charge.currency }, {
70
- amount_refunded: 0, application: 'ca_twin', balance_transaction: null, originating_transaction: null, refunded: false, livemode: false,
71
- });
72
- // a direct charge's fee moves from the connected account to the platform (a destination charge kept it back)
73
- const bt = !destination && direct ? await settleApplicationFee(ctx, String(fee.id), feeAmount, charge.currency, direct) : null;
74
- await ctx.write('application_fee', String(fee.id), { balance_transaction: bt, refunds: { object: 'list', data: [], has_more: false, total_count: 0, url: `/v1/application_fees/${String(fee.id)}/refunds` } }, 'application_fee.created');
75
- await ctx.write('charge', chargeId, { application_fee: fee.id, application_fee_amount: feeAmount }, 'charge.updated');
76
- }
77
- }
78
- /** Radar places an elevated-risk card's charge in review (docs.stripe.com/radar/reviews). */
79
- async function openReview(ctx, chargeId, pi) {
80
- const review = await created(ctx, 'review', { charge: chargeId, ...pi }, {
81
- open: true, opened_reason: 'rule', reason: 'rule', closed_reason: null, billing_zip: null, ip_address: null, ip_address_location: null, session: null, livemode: false,
82
- });
83
- const existing = ctx.get('charge', chargeId)?.outcome ?? {};
84
- await ctx.write('charge', chargeId, {
85
- review: review.id,
86
- outcome: { ...existing, type: 'manual_review', risk_level: 'elevated', risk_score: 67, seller_message: 'Stripe evaluated this payment as having elevated risk, and placed it in review.' },
87
- }, 'review.opened');
88
- }
89
- /** The mandate a verified bank account carries for a payment (single use) or a setup (multi use). */
90
- export async function mintMandate(ctx, paymentMethod, use, amount, currency) {
91
- const now = Number(ctx.now());
92
- const mandate = await created(ctx, 'mandate', { payment_method: typeof paymentMethod === 'string' ? paymentMethod : null }, {
93
- status: 'active', type: use, livemode: false,
94
- customer_acceptance: { type: 'online', accepted_at: now, online: { ip_address: '127.0.0.1', user_agent: 'twin' } },
95
- payment_method_details: { type: 'us_bank_account', us_bank_account: { collection_method: 'paper' } },
96
- ...(use === 'single_use' ? { single_use: { amount: amount ?? 0, currency: currency ?? 'usd' } } : { multi_use: {} }),
97
- }, { timeField: '_created' });
98
- return String(mandate.id);
99
- }
@@ -1,2 +0,0 @@
1
- import type { Semantics } from '@volter/world-core';
2
- export declare const appsSecrets: Record<string, Semantics>;
@@ -1,2 +0,0 @@
1
- import type { Semantics } from '@volter/world-core';
2
- export declare const billing: Record<string, Semantics>;