@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,662 @@
1
+ // Stripe's state machines and the state candidates it rules not state (docs/contributing/architecture.md, "What an
2
+ // author writes": states), each move cited; the manifest takes each resource's whole.
3
+ import type { StateField, Transition } from '@volter/world-core';
4
+
5
+ const OPEN = ['requires_payment_method', 'requires_confirmation', 'requires_action', 'requires_capture', 'processing'];
6
+
7
+ /** A move no API call makes: Stripe's own (`vendor`), the clock's (`time`), or the person on a
8
+ * Stripe-hosted page (`external`: Checkout, the billing portal, a hosted invoice or 3DS page). */
9
+ const by = (actor: 'vendor' | 'time' | 'external', from: string[], to: string, source: string): Transition => ({ actor, from, to, source });
10
+ /** A bank account's `status` as a payout or payment destination. Stripe validates its routing number,
11
+ * verifies it (micro-deposits, or instantly) and marks it errored when a payout or debit to it fails
12
+ * (the page each machine cites); no call the twin serves does any of that (the customer-source verify is
13
+ * a gap), so no move of it is the twin's. */
14
+ const bankAccountStatus = (_doc: string): StateField => ({ initial: 'new', transitions: [] });
15
+
16
+ /** A flag an update sets either way. */
17
+ const flag = (operation: string, source: string): Transition[] => ['true', 'false'].map((to) => ({ operation, from: '*' as const, to, source }));
18
+
19
+ /** A PaymentIntent's `status`: which operation may move it from where, and what Stripe answers otherwise. */
20
+ const paymentIntentStatus: StateField = {
21
+ // "After you create the PaymentIntent, its status is `requires_payment_method` until you attach a payment method"
22
+ // (docs.stripe.com/payments/paymentintents/lifecycle)
23
+ initial: 'requires_payment_method',
24
+ transitions: [
25
+ // created with its payment method, it "enters the `requires_confirmation` status and is ready to confirm" (the same page)
26
+ { operation: 'PostPaymentIntents', from: ['requires_payment_method'], to: 'requires_confirmation', source: 'https://docs.stripe.com/payments/paymentintents/lifecycle' },
27
+ // a bank debit confirmed (created with `confirm`, or confirmed) is submitted and processes: "The PaymentIntent you
28
+ // create initially has a status of `processing`"
29
+ ...['PostPaymentIntents',].map((operation) => ({
30
+ operation, from: ['requires_payment_method', 'requires_confirmation', 'requires_action'], to: 'processing',
31
+ source: 'https://docs.stripe.com/payments/ach-direct-debit/accept-a-payment?payment-ui=direct-api',
32
+ })),
33
+ // and succeeds: "After the payment has succeeded, the PaymentIntent status is updated from `processing`
34
+ // to `succeeded`" (../engine/payment-intents.ts settleBankDebits)
35
+ by('vendor', ['processing'], 'succeeded', 'https://docs.stripe.com/payments/ach-direct-debit/accept-a-payment?payment-ui=direct-api'),
36
+ // creating one with `confirm` confirms it at once, landing where a confirm lands
37
+ ...['requires_payment_method', 'requires_action', 'requires_capture', 'succeeded'].map((to) => ({
38
+ operation: 'PostPaymentIntents',
39
+ from: ['requires_payment_method', 'requires_confirmation'],
40
+ to,
41
+ source: 'spec:PostPaymentIntents "Set to `true` to attempt to [confirm this PaymentIntent](https://docs.stripe.com/api/payment_intents/confirm) immediately."',
42
+ })),
43
+ {
44
+ operation: 'PostPaymentIntentsIntentCancel', from: OPEN, to: 'canceled',
45
+ refusal: { status: 400, code: 'payment_intent_unexpected_state', message: 'You cannot cancel this PaymentIntent because it has a status of {from}. Only a PaymentIntent with one of the following statuses may be canceled: requires_payment_method, requires_capture, requires_confirmation, requires_action, processing.' },
46
+ source: 'https://docs.stripe.com/api/payment_intents/cancel',
47
+ },
48
+ {
49
+ // paying the invoice an intent collects for settles the intent
50
+ operation: 'PostInvoicesInvoicePay',
51
+ from: OPEN,
52
+ to: 'succeeded',
53
+ source: 'https://docs.stripe.com/api/invoices/pay',
54
+ },
55
+ // the customer pays, in the billing portal, the invoice an intent collects for after its charge was declined
56
+ by('external', ['requires_payment_method'], 'succeeded', 'https://docs.stripe.com/customer-management'),
57
+ // Stripe also fails a bank debit back to needing a payment method, completes 3-D Secure on the bank's page and
58
+ // cancels a hold left uncaptured; the twin's bank debits succeed unless their test account stays processing, it has no 3-D Secure page, and it keeps
59
+ // holds until they are canceled. Capture, increment_authorization, verify_microdeposits, apply_customer_balance and
60
+ // the Terminal reader's present_payment_method are the gap (no demand, life step or refresh sends them:
61
+ // ../manifest.ts unmodeled), so no move of theirs is declared.
62
+ ],
63
+ };
64
+
65
+ /** A charge's `captured`: an authorization (capture_method=manual) is captured once, by the Charges API's capture or
66
+ * its PaymentIntent's; both are the gap here (no demand, life step or refresh sends them: ../manifest.ts unmodeled), so
67
+ * a held charge stays uncaptured until its intent is canceled, and no move is declared. */
68
+ const chargeCaptured: StateField = {
69
+ initial: true,
70
+ transitions: [],
71
+ };
72
+
73
+ /** A charge's `refunded`: true once refunds take its whole amount. A capture or a cancel never makes it so: "`refunded` will no longer be `true` for payment cancellation
74
+ * flows", and a partial capture makes no Refund (docs.stripe.com/changelog/basil/2025-03-31/remove-refund-from-partial-
75
+ * capture-and-payment-cancellation-flow). */
76
+ const chargeRefunded: StateField = {
77
+ initial: false,
78
+ transitions: [
79
+ { operation: 'PostRefunds', from: ['false'], to: 'true', source: 'https://docs.stripe.com/api/charges/object#charge_object-refunded' },
80
+ // (a charge's own refunds path, a credit note's refund and a refund's cancel are the gap here: ../manifest.ts unmodeled)
81
+ // (an authorization left uncaptured is canceled after seven days, "Uncaptured PaymentIntents are cancelled a set
82
+ // number of days (7 by default) after their creation", docs.stripe.com/api/payment_intents/capture; the twin keeps it)
83
+ ],
84
+ };
85
+
86
+ /** A charge's `status`: the twin settles a charge when it is made (a declined one is never
87
+ * stored); an asynchronous one settles later, on the network's word. */
88
+ const chargeStatus: StateField = {
89
+ initial: 'succeeded',
90
+ transitions: [
91
+ // (an asynchronous charge is pending at Stripe until it settles or fails; the twin's settle when made)
92
+ ],
93
+ };
94
+
95
+ /** A charge's `paid`: true once it succeeded or was authorized; a pending one becomes paid when it settles. */
96
+ const chargePaid: StateField = {
97
+ initial: true,
98
+ // (a charge is paid when it settles; the twin's settle when made)
99
+ transitions: [],
100
+ };
101
+
102
+ /** A refund's `status`: held pending for want of balance, then made; the rest is the network's. (Canceling one that
103
+ * waits on the customer is the gap here: ../manifest.ts unmodeled.) */
104
+ const refundStatus: StateField = {
105
+ initial: 'succeeded',
106
+ transitions: [
107
+ { operation: 'PostRefunds', from: ['succeeded'], to: 'pending', source: 'https://docs.stripe.com/refunds' },
108
+ by('vendor', ['pending'], 'succeeded', 'https://docs.stripe.com/refunds'),
109
+ // a bank-transfer payment's refund waits in requires_action for the customer's bank details, and is made so
110
+ // (semantics/refunds.ts); (Stripe also fails some refunds; the twin's do not fail)
111
+ ],
112
+ };
113
+
114
+ /** A SetupIntent's `status`: confirm settles it, or leaves a bank account awaiting micro-deposits. (Its cancel and its
115
+ * micro-deposit verification are the gap here: ../manifest.ts unmodeled.) */
116
+ const setupIntentStatus: StateField = {
117
+ // "After you create the SetupIntent, it has a status of `requires_payment_method` until you attach a payment method"
118
+ // (docs.stripe.com/payments/paymentintents/lifecycle)
119
+ initial: 'requires_payment_method',
120
+ transitions: [
121
+ // (Stripe completes 3-D Secure on the bank's page and settles an asynchronous method from processing; the
122
+ // twin has no such page and settles every method at once)
123
+ ],
124
+ };
125
+
126
+ const invoiceRefusal = (message: string) => ({ status: 400, code: 'invoice_not_editable', message });
127
+
128
+ /** An invoice's `status`: a draft is finalized (or sent, which finalizes it) into open, an open one
129
+ * is paid, written off or voided. Sending leaves any other status where it is. */
130
+ const invoiceStatus: StateField = {
131
+ initial: 'draft',
132
+ transitions: [
133
+ { operation: 'PostInvoicesInvoicePay', from: ['draft'], to: 'open', source: 'https://docs.stripe.com/invoicing/integration' },
134
+ {
135
+ // paying a draft finalizes it on the way: "To finalize a draft invoice, use the Dashboard, send it to the customer, or
136
+ // pay it" (docs.stripe.com/invoicing/integration)
137
+ operation: 'PostInvoicesInvoicePay',
138
+ from: ['draft', 'open', 'uncollectible'],
139
+ to: 'paid',
140
+ refusal: invoiceRefusal('This invoice cannot be paid because it has status {from}.'),
141
+ refusals: { paid: { status: 400, code: 'invoice_payment_intent_requires_action', message: 'This invoice has already been paid.' } },
142
+ source: 'https://docs.stripe.com/api/invoices/pay',
143
+ },
144
+ // (marking one uncollectible is the gap here: ../manifest.ts unmodeled)
145
+ // a guard: only a draft is deleted; a finalized invoice is voided instead
146
+ // in any other state it is refused (a refusal with no `to` refuses where it stands)
147
+ {
148
+ // only a finalized invoice is voided; a draft is deleted
149
+ operation: 'PostInvoicesInvoiceVoid',
150
+ from: ['open', 'uncollectible'],
151
+ to: 'void',
152
+ refusal: invoiceRefusal('This invoice cannot be voided because it has status {from}.'),
153
+ source: 'https://docs.stripe.com/api/invoices/void',
154
+ },
155
+ // confirming the PaymentIntent an invoice collects through pays the invoice
156
+ // as does its bank debit succeeding once submitted (../engine/payment-intents.ts settleBankDebits)
157
+ by('vendor', ['draft', 'open', 'uncollectible'], 'paid', 'https://docs.stripe.com/billing/subscriptions/build-subscriptions'),
158
+ // (a bank transfer reconciled from the customer's cash balance pays one at Stripe; funding a cash balance is the gap
159
+ // here: ../manifest.ts unmodeled)
160
+ // a subscription's first invoice is paid on the Checkout page that started it
161
+ by('external', ['draft'], 'paid', 'https://docs.stripe.com/payments/checkout/how-checkout-works'),
162
+ // a subscription's renewal, drafted at its period's end, is finalized about an hour later and charged: paid, or
163
+ // open when the charge is declined (../engine/renewals.ts)
164
+ by('time', ['draft'], 'paid', 'https://docs.stripe.com/invoicing/integration/workflow-transitions#finalized'),
165
+ by('time', ['draft'], 'open', 'https://docs.stripe.com/billing/subscriptions/overview#payment-status'),
166
+ // an update that ends a subscription's trial invoices its new period and attempts payment at once: paid, or open
167
+ // when the charge is declined or not attempted (semantics/subscriptions.ts applyTrialEnd)
168
+ { operation: 'PostSubscriptionsSubscriptionExposedId', from: ['draft'], to: 'paid', source: 'https://docs.stripe.com/billing/subscriptions/upgrade-downgrade#immediate-payment' },
169
+ // a trialing subscription's first invoice, for nothing, is paid as it is made ("An immediate invoice is still
170
+ // created, but the amount is 0", docs.stripe.com/billing/subscriptions/trials/free-trials)
171
+ { operation: 'PostSubscriptionsSubscriptionExposedId', from: ['draft'], to: 'open', source: 'https://docs.stripe.com/billing/subscriptions/upgrade-downgrade#immediate-payment' },
172
+ // the customer pays an open invoice in the billing portal
173
+ by('external', ['open'], 'paid', 'https://docs.stripe.com/customer-management'),
174
+ // (Stripe also finalizes any other auto-advancing draft after an hour, retries an open invoice on its schedule
175
+ // and, retries exhausted, may write it off, and takes payment on the hosted invoice page; the twin's other
176
+ // invoices move only by the calls above)
177
+ ],
178
+ };
179
+
180
+ /** A subscription's `status` as the twin's own operations move it; canceling ends any subscription. */
181
+ const subscriptionStatus: StateField = {
182
+ initial: 'active',
183
+ transitions: [
184
+ { operation: 'DeleteSubscriptionsSubscriptionExposedId', from: '*', to: 'canceled', source: 'https://docs.stripe.com/api/subscriptions/cancel' },
185
+ // (a test clock's advance moves no subscription itself: when the clock reaches its target, a trial that ended there
186
+ // ends by time's move below, on the next request; ../engine/test-clocks.ts finishClockAdvances)
187
+ // (canceling a subscription schedule, which cancels its subscription, is the gap here: ../manifest.ts unmodeled)
188
+ // confirming the first invoice's PaymentIntent, or paying the invoice itself, pays it and activates the subscription
189
+ // or when its bank debit succeeds once submitted (../engine/payment-intents.ts settleBankDebits)
190
+ by('vendor', ['incomplete'], 'active', 'https://docs.stripe.com/billing/subscriptions/build-subscriptions'),
191
+ // paying the invoice a subscription waits on (its first, or a renewal that failed) makes it active
192
+ { operation: 'PostInvoicesInvoicePay', from: ['incomplete', 'past_due'], to: 'active', source: 'https://docs.stripe.com/billing/subscriptions/overview#payment-status' },
193
+ // an update's `trial_end`: `now` ends a trial at once and charges the new period, active when paid and past_due when
194
+ // not; a future timestamp starts a trial on a subscription out of one (semantics/subscriptions.ts applyTrialEnd)
195
+ { operation: 'PostSubscriptionsSubscriptionExposedId', from: ['trialing'], to: 'active', source: 'https://docs.stripe.com/api/subscriptions/update#update_subscription-trial_end' },
196
+ { operation: 'PostSubscriptionsSubscriptionExposedId', from: ['trialing'], to: 'past_due', source: 'https://docs.stripe.com/billing/subscriptions/upgrade-downgrade#immediate-payment' },
197
+ {
198
+ operation: 'PostSubscriptionsSubscriptionExposedId', from: ['active', 'past_due'], to: 'trialing',
199
+ // (Where the documentation stops and the twin decides: the wording of the refusal for a subscription neither
200
+ // active nor past_due; a canceled one answers what Stripe answers any update of a canceled subscription.)
201
+ refusal: { status: 400, message: 'A trial can only be added to an active or past_due subscription; this one is {from}.' },
202
+ refusals: { canceled: { status: 400, message: 'A canceled subscription can only update its cancellation_details and metadata.' } },
203
+ source: 'https://docs.stripe.com/billing/subscriptions/trials/free-trials#adding-a-new-trial-to-a-subscription-previously-in-a-trial',
204
+ },
205
+ // a trial ends on its own clock (Stripe pauses one that ends with no payment method to bill; the twin's
206
+ // trials end active), and a renewal whose charge is declined leaves the subscription past_due
207
+ // (../engine/renewals.ts)
208
+ by('time', ['trialing'], 'active', 'https://docs.stripe.com/billing/subscriptions/trials'),
209
+ by('time', ['active'], 'past_due', 'https://docs.stripe.com/billing/subscriptions/overview#payment-status'),
210
+ // one set to cancel at its period's end is canceled when the period ends
211
+ by('time', ['active', 'trialing', 'past_due'], 'canceled', 'https://docs.stripe.com/billing/subscriptions/cancel#cancel-at-end-of-cycle'),
212
+ // the customer pays the invoice it waits on in the billing portal
213
+ by('external', ['past_due'], 'active', 'https://docs.stripe.com/customer-management'),
214
+ // (Stripe also expires an incomplete subscription after 23 hours, and retries a failed renewal on its schedule,
215
+ // the settings ending the retries unpaid or canceled; the twin makes no retry)
216
+ // the customer cancels in the billing portal
217
+ by('external', ['active', 'trialing', 'past_due', 'unpaid', 'paused'], 'canceled', 'spec:/components/schemas/portal_subscription_cancel "Whether to cancel subscriptions immediately or at the end of the billing period."'),
218
+ ],
219
+ };
220
+
221
+ const notOpen = (verb: string) => ({ status: 400, code: 'checkout_session_not_open', message: `You may only ${verb} a Checkout Session that is currently in the \`open\` state.` });
222
+
223
+ /** A Checkout Session's `status`: an open session expires (asked to, or 24 hours on), or completes
224
+ * when the customer pays on the hosted page. Completion is the external actor's move, the one the
225
+ * hosted Checkout page (src/screens/checkout.tsx) performs. */
226
+ const checkoutStatus: StateField = {
227
+ initial: 'open',
228
+ transitions: [
229
+ { actor: 'external', from: ['open'], to: 'complete', refusal: notOpen('complete'), source: 'https://docs.stripe.com/api/checkout/sessions/object#checkout_session_object-status' },
230
+ // (Stripe expires an open session at expires_at; the twin keeps it open until asked)
231
+ ],
232
+ };
233
+
234
+ /** A Checkout Session's `payment_status`: the customer completing a payment or subscription session
235
+ * pays it; a delayed payment method settles later. */
236
+ const checkoutPaymentStatus: StateField = {
237
+ initial: 'unpaid',
238
+ transitions: [
239
+ { actor: 'external', from: '*', to: 'paid', source: 'https://docs.stripe.com/api/checkout/sessions/object#checkout_session_object-payment_status' },
240
+ // (a delayed method settles a session later at Stripe; the twin's settle on the page)
241
+ ],
242
+ };
243
+
244
+ /** A dispute's `status`: a disputed test card's charge opens one (needs_response, or warning_needs_response for an
245
+ * inquiry). Submitting evidence and closing (conceding) are the gap here (../manifest.ts unmodeled), so nothing puts a
246
+ * dispute under review for the bank to decide; the bank escalates an inquiry and loses one left unanswered at
247
+ * Stripe, and the twin decides none. */
248
+ const disputeStatus: StateField = {
249
+ initial: 'warning_needs_response',
250
+ transitions: [],
251
+ };
252
+
253
+ /** A payout's `status`: cancel ends it; reversing cancels it and pays a reversal, never twice. */
254
+ const payoutStatus: StateField = {
255
+ initial: 'pending',
256
+ transitions: [
257
+ // (canceling a pending payout and reversing a paid one are the gap here: ../manifest.ts unmodeled)
258
+ // it arrives in the bank on its arrival date
259
+ by('time', ['pending'], 'paid', 'https://docs.stripe.com/payouts#payout-statuses'),
260
+ // (a bank may fail a payout at Stripe; the twin's arrive)
261
+ ],
262
+ };
263
+
264
+ /** A credit note's `status`: issued, then voided once at Stripe. Issuing and voiding one are the gap here
265
+ * (../manifest.ts unmodeled): a vendor-backed World reads credit notes back from its root (GetCreditNotes). */
266
+ const creditNoteStatus: StateField = {
267
+ initial: 'issued',
268
+ transitions: [],
269
+ };
270
+
271
+ /** A subscription schedule's `status`: releasing ends it, and an ended one refuses it. (Canceling one is the gap here:
272
+ * ../manifest.ts unmodeled.) */
273
+ const scheduleStatus: StateField = {
274
+ initial: 'active',
275
+ transitions: [
276
+ // "A schedule can only be released if its status is not_started or active" (the release page)
277
+ // its phases run on the clock: it starts at its start date and ends with its last phase
278
+ // (a schedule whose end_behavior is cancel completes at its end at Stripe; the twin's release)
279
+ // (Stripe starts a schedule at its start date and ends it with its last phase; the twin's start at once
280
+ // and end when canceled or released)
281
+ ],
282
+ };
283
+
284
+ /** A quote's `status`: at Stripe a draft is finalized into open, an open one accepted, and either canceled. Quotes are
285
+ * the gap here (../manifest.ts unmodeled): a vendor-backed World reads them back from its root (GetQuotes), so no
286
+ * move is the twin's. */
287
+ const quoteStatus: StateField = {
288
+ initial: 'draft',
289
+ transitions: [],
290
+ };
291
+
292
+ const setBy = (operation: string, values: string[], source: string): Transition[] => values.map((to) => ({ operation, from: '*' as const, to, source }));
293
+
294
+ /** An Issuing authorization's `status`: approve and decline close a pending one, once; a capture
295
+ * closes it, or leaves it pending when told not to close. */
296
+ const issuingAuthorizationStatus: StateField = {
297
+ initial: 'pending',
298
+ transitions: [
299
+ // approving keeps it pending (approved) until the merchant captures; declining closes it
300
+ { operation: 'PostIssuingAuthorizationsAuthorizationApprove', from: ['pending'], source: 'https://docs.stripe.com/issuing/purchases/authorizations' },
301
+ // in any other state it is refused (a refusal with no `to` refuses where it stands)
302
+ { operation: 'PostIssuingAuthorizationsAuthorizationApprove', from: '*', refusal: { status: 400, code: 'authorization_already_finalized', message: 'This authorization has already been finalized (status {from}).' }, source: 'https://docs.stripe.com/issuing/purchases/authorizations' },
303
+ { operation: 'PostIssuingAuthorizationsAuthorizationDecline', from: ['pending'], to: 'closed', refusal: { status: 400, code: 'authorization_already_finalized', message: 'This authorization has already been finalized (status {from}).' }, source: 'https://docs.stripe.com/api/issuing/authorizations/decline' },
304
+ { operation: 'PostTestHelpersIssuingAuthorizationsAuthorizationCapture', from: ['pending'], to: 'closed', source: 'https://docs.stripe.com/api/issuing/authorizations/test_mode_capture' },
305
+ { operation: 'PostTestHelpersIssuingAuthorizationsAuthorizationCapture', from: ['pending'], source: 'https://docs.stripe.com/api/issuing/authorizations/test_mode_capture' },
306
+ // a real-time request no one answered is decided when its window ends: "If Stripe doesn't receive your approve or
307
+ // decline response within 2 seconds, the Authorization is automatically approved or declined based on your timeout
308
+ // settings" (semantics/issuing.ts lapseRealtimeRequests)
309
+ by('time', ['pending'], 'closed', 'https://docs.stripe.com/issuing/controls/real-time-authorizations'),
310
+ // (Stripe also closes, reverses and expires one as the merchant and the clock act; in test mode the
311
+ // capture helper above closes it, and the twin serves no other)
312
+ ],
313
+ };
314
+
315
+ /** A Treasury flow's `status`: at Stripe a processing flow cancels, the network posts or fails it, and a posted one may
316
+ * come back returned. Treasury's flows are the gap here (../manifest.ts unmodeled): a vendor-backed World reads them
317
+ * back from its root, so no move is the twin's. */
318
+ const flow: StateField = { initial: 'processing', transitions: [] };
319
+
320
+ export const states = {
321
+ 'billing.meter': {
322
+ notState: ['event_time_window'],
323
+ // (deactivating and reactivating a meter are the gap here: ../manifest.ts unmodeled)
324
+ state: { status: { initial: 'active', transitions: [] } },
325
+ },
326
+ 'billing.credit_grant': {
327
+ notState: ['category'],
328
+ },
329
+ 'billing.alert': {
330
+ // (activating, deactivating and archiving an alert are the gap here: ../manifest.ts unmodeled)
331
+ state: { status: { initial: 'active', transitions: [] } },
332
+ },
333
+ payment_intent: {
334
+ state: { status: paymentIntentStatus },
335
+ notState: ['cancellation_reason', 'capture_method', 'confirmation_method', 'setup_future_usage'],
336
+ },
337
+ customer: {
338
+ notState: ['tax_exempt'],
339
+ },
340
+ tax_id: {
341
+ notState: ['type'],
342
+ },
343
+ customer_balance_transaction: {
344
+ notState: ['type'],
345
+ },
346
+ customer_cash_balance_transaction: {
347
+ notState: ['type'],
348
+ },
349
+ payment_source: {
350
+ state: { status: bankAccountStatus('https://docs.stripe.com/api/customer_bank_accounts/object#customer_bank_account_object-status') },
351
+ notState: ['allow_redisplay', 'business_type', 'regulated_status', 'type'],
352
+ },
353
+ source: {
354
+ state: {
355
+ status: {
356
+ initial: 'chargeable',
357
+ transitions: [
358
+ // (Stripe makes a redirect source chargeable when the customer authorizes it on the bank's page;
359
+ // the twin has no such page, so a non-card source stays pending)
360
+ // Stripe also fails a source the customer abandons, consumes a single-use one once charged and
361
+ // cancels one left unused; the twin's sources stay chargeable
362
+ ],
363
+ },
364
+ },
365
+ notState: ['allow_redisplay', 'type'],
366
+ },
367
+ charge: {
368
+ state: { status: chargeStatus, captured: chargeCaptured, paid: chargePaid, refunded: chargeRefunded },
369
+ },
370
+ refund: {
371
+ state: { status: refundStatus },
372
+ notState: ['pending_reason', 'reason'],
373
+ },
374
+ setup_intent: {
375
+ state: { status: setupIntentStatus },
376
+ notState: ['cancellation_reason'],
377
+ },
378
+ payment_method: {
379
+ notState: ['allow_redisplay', 'type'],
380
+ },
381
+ subscription: {
382
+ state: { status: subscriptionStatus },
383
+ notState: ['collection_method'],
384
+ },
385
+ invoice: {
386
+ state: { status: invoiceStatus },
387
+ notState: ['billing_reason', 'collection_method', 'customer_tax_exempt'],
388
+ },
389
+ 'checkout.session': {
390
+ state: { status: checkoutStatus, payment_status: checkoutPaymentStatus },
391
+ notState: ['billing_address_collection', 'customer_creation', 'locale', 'mode', 'origin_context', 'payment_method_collection', 'redirect_on_completion', 'submit_type', 'ui_mode'],
392
+ },
393
+ mandate: {
394
+ // Stripe activates a pending mandate, spends a single-use one with its payment and deactivates one revoked; the twin
395
+ // makes no mandate (micro-deposit verification, which accepts one, is the gap here: ../manifest.ts unmodeled), so no
396
+ // move is the twin's
397
+ state: { status: { initial: 'active', transitions: [] } },
398
+ notState: ['type'],
399
+ },
400
+ dispute: {
401
+ state: { status: disputeStatus },
402
+ notState: ['is_charge_refundable'],
403
+ },
404
+ payout: {
405
+ state: { status: payoutStatus },
406
+ notState: ['reconciliation_status', 'type'],
407
+ },
408
+ balance_transaction: {
409
+ state: { status: { initial: 'available', vendorInitial: 'pending', transitions: [by('time', ['pending'], 'available', 'https://docs.stripe.com/api/balance_transactions/object#balance_transaction_object-status')] } },
410
+ notState: ['balance_type', 'type'],
411
+ },
412
+ coupon: {
413
+ notState: ['duration'],
414
+ state: { valid: { initial: true, transitions: [by('time', ['true'], 'false', 'spec:/components/schemas/coupon/properties/redeem_by "Date after which the coupon can no longer be redeemed."')] } },
415
+ },
416
+ promotion_code: {
417
+ state: {
418
+ active: {
419
+ initial: true,
420
+ transitions: [
421
+ ...flag('PostPromotionCodesPromotionCode', 'https://docs.stripe.com/api/promotion_codes/update'),
422
+ ],
423
+ },
424
+ },
425
+ },
426
+ credit_note: {
427
+ state: { status: creditNoteStatus },
428
+ notState: ['reason', 'type'],
429
+ },
430
+ subscription_schedule: {
431
+ state: { status: scheduleStatus },
432
+ notState: ['end_behavior'],
433
+ },
434
+ 'entitlements.feature': {
435
+ // (updating a feature, which "permanently" deactivates it, is the gap here: ../manifest.ts unmodeled)
436
+ state: { active: { initial: true, transitions: [] } },
437
+ },
438
+ 'test_helpers.test_clock': {
439
+ state: {
440
+ status: {
441
+ initial: 'ready',
442
+ transitions: [
443
+ // "advancing: The clock has started to advance but hasn't reached the specified time"; "ready: The clock has
444
+ // completed advancing to the specified time" (docs.stripe.com/billing/testing/test-clocks/api-advanced-usage)
445
+ by('vendor', ['advancing'], 'ready', 'https://docs.stripe.com/billing/testing/test-clocks/api-advanced-usage'),
446
+ // (Stripe may also end an advance in internal_failure; the twin's advances complete)
447
+ ],
448
+ },
449
+ },
450
+ },
451
+ webhook_endpoint: {
452
+ // (disabling and enabling an endpoint by its update is the gap here: ../manifest.ts unmodeled)
453
+ state: { status: { initial: 'enabled', transitions: [] } },
454
+ },
455
+ account: {
456
+ notState: ['business_type', 'type'],
457
+ },
458
+ person: {
459
+ notState: ['political_exposure'],
460
+ },
461
+ capability: {
462
+ state: {
463
+ status: {
464
+ initial: 'unrequested',
465
+ transitions: [
466
+ // (requesting or unrequesting a capability by its update is the gap here: ../manifest.ts unmodeled)
467
+ // Stripe reviews the account's requirements
468
+ ],
469
+ },
470
+ },
471
+ },
472
+ external_account: {
473
+ state: { status: bankAccountStatus('https://docs.stripe.com/api/external_account_bank_accounts/object#account_bank_account_object-status') },
474
+ notState: ['allow_redisplay', 'regulated_status'],
475
+ },
476
+ application_fee: {
477
+ state: { refunded: { initial: false, transitions: [
478
+ { operation: 'PostRefunds', from: ['false'], to: 'true', source: 'https://docs.stripe.com/connect/destination-charges#issue-refunds' },
479
+ ] } },
480
+ },
481
+ file: {
482
+ notState: ['purpose'],
483
+ },
484
+ 'identity.verification_session': {
485
+ // the person verifies on Stripe's hosted page, and Stripe decides (docs.stripe.com/identity/how-sessions-work);
486
+ // sessions are the gap here (../manifest.ts unmodeled) and a vendor-backed World reads them back from its root,
487
+ // so no move is the twin's
488
+ state: { status: { initial: 'requires_input', transitions: [] } },
489
+ notState: ['type'],
490
+ },
491
+ 'identity.verification_report': {
492
+ notState: ['type'],
493
+ },
494
+ 'billing_portal.session': {
495
+ notState: ['locale'],
496
+ },
497
+ 'billing_portal.configuration': {
498
+ state: { active: { initial: true, transitions: [] } },
499
+ notState: ['is_default'],
500
+ },
501
+ tax_rate: {
502
+ // (archiving a rate by its update is the gap here: ../manifest.ts unmodeled)
503
+ state: { active: { initial: true, transitions: [] } },
504
+ notState: ['jurisdiction_level', 'rate_type', 'state', 'tax_type'],
505
+ },
506
+ 'tax.settings': {
507
+ notState: ['status'],
508
+ },
509
+ 'tax.registration': {
510
+ state: {
511
+ // Stripe schedules a registration with a future active_from and expires one at expires_at; the twin's
512
+ // are active from the start and never expire
513
+ status: { initial: 'active', transitions: [] },
514
+ },
515
+ },
516
+ 'tax.transaction': {
517
+ notState: ['type'],
518
+ },
519
+ payment_link: {
520
+ // (switching a link off by its update is the gap here: ../manifest.ts unmodeled)
521
+ state: { active: { initial: true, transitions: [] } },
522
+ notState: ['billing_address_collection', 'customer_creation', 'payment_method_collection', 'submit_type'],
523
+ },
524
+ quote: {
525
+ state: { status: quoteStatus },
526
+ notState: ['collection_method'],
527
+ },
528
+ review: {
529
+ // an elevated-risk card's charge opens one (shared.ts openReview); approving it is the gap here (../manifest.ts
530
+ // unmodeled), and Stripe closes one when the payment is refunded or disputed, which the twin does not
531
+ state: { open: { initial: true, transitions: [] } },
532
+ notState: ['closed_reason', 'opened_reason'],
533
+ },
534
+ 'radar.value_list': {
535
+ notState: ['item_type'],
536
+ },
537
+ 'issuing.cardholder': {
538
+ // (a cardholder's status set by its update is the gap here: ../manifest.ts unmodeled)
539
+ state: { status: { initial: 'active', transitions: [] } },
540
+ notState: ['type'],
541
+ },
542
+ 'issuing.card': {
543
+ // a card is made inactive unless its create names a status: "Defaults to inactive" (docs.stripe.com/api/issuing/cards/create)
544
+ state: { status: { initial: 'inactive', transitions: setBy('PostIssuingCardsCard', ['active', 'inactive', 'canceled'], 'https://docs.stripe.com/api/issuing/cards/update') } },
545
+ notState: ['cancellation_reason', 'replacement_reason', 'type'],
546
+ },
547
+ 'issuing.authorization': {
548
+ state: { status: issuingAuthorizationStatus },
549
+ notState: ['authorization_method', 'card_presence'],
550
+ },
551
+ 'issuing.transaction': {
552
+ notState: ['type', 'wallet'],
553
+ },
554
+ 'issuing.dispute': {
555
+ // (submitting one to the network is the gap here, ../manifest.ts unmodeled, and Stripe decides a submitted dispute
556
+ // won or lost and expires one never submitted: a vendor-backed World reads them back from its root)
557
+ state: { status: { initial: 'unsubmitted', transitions: [] } },
558
+ notState: ['loss_reason'],
559
+ },
560
+ 'issuing.personalization_design': {
561
+ // a new design waits on Stripe's review (docs.stripe.com/issuing/cards/physical/personalization-design); designs and
562
+ // the test helpers that decide them are the gap here (../manifest.ts unmodeled), read back from a vendor-backed root
563
+ state: { status: { initial: 'review', transitions: [] } },
564
+ },
565
+ 'terminal.reader': {
566
+ notState: ['device_type'],
567
+ // (a real reader goes offline and back; the twin's simulated readers stay online)
568
+ state: { status: { initial: 'online', transitions: [] } },
569
+ },
570
+ 'terminal.configuration': {
571
+ notState: ['is_account_default'],
572
+ },
573
+ topup: {
574
+ state: {
575
+ status: {
576
+ // a top-up starts pending (the create page's example answers "status": "pending") and its funds arrive days
577
+ // later: "USA (USD) ACH Debit Transfer 5 days" (docs.stripe.com/connect/top-ups; semantics/terminal.ts)
578
+ initial: 'pending',
579
+ transitions: [
580
+ // (canceling a pending top-up is the gap here: ../manifest.ts unmodeled)
581
+ // to the Issuing balance alike: "Your top-ups can take up to 5 business days to become available"
582
+ // (docs.stripe.com/issuing/funding/balance)
583
+ by('vendor', ['pending'], 'succeeded', 'https://docs.stripe.com/connect/top-ups'),
584
+ // (Stripe also fails a top-up or reverses a settled one; the twin's top-ups do neither)
585
+ ],
586
+ },
587
+ },
588
+ notState: ['initiated_by'],
589
+ },
590
+ 'treasury.financial_account': {
591
+ state: { status: { initial: 'open', transitions: [] } },
592
+ notState: ['is_default'],
593
+ },
594
+ 'treasury.outbound_payment': {
595
+ state: { status: flow },
596
+ },
597
+ 'treasury.outbound_transfer': {
598
+ state: { status: flow },
599
+ },
600
+ 'treasury.inbound_transfer': {
601
+ state: { status: flow },
602
+ },
603
+ 'treasury.received_credit': {
604
+ state: { status: { initial: 'succeeded', transitions: [] } },
605
+ notState: ['failure_code', 'network'],
606
+ },
607
+ 'treasury.received_debit': {
608
+ state: { status: { initial: 'succeeded', transitions: [] } },
609
+ notState: ['failure_code', 'network'],
610
+ },
611
+ 'treasury.transaction': {
612
+ notState: ['flow_type'],
613
+ // a transaction posts as its flow settles and is voided when its flow is canceled, both Stripe's (the flows are the
614
+ // gap here: ../manifest.ts unmodeled)
615
+ state: { status: { initial: 'open', transitions: [] } },
616
+ },
617
+ 'treasury.transaction_entry': {
618
+ notState: ['flow_type', 'type'],
619
+ },
620
+ 'climate.order': {
621
+ state: {
622
+ status: {
623
+ // an order is created confirmed: the create page's example answers "status": "confirmed" with confirmed_at set
624
+ // (docs.stripe.com/api/climate/order/create)
625
+ initial: 'confirmed',
626
+ // (Stripe funds, confirms and delivers an order over months, and cancels one asked to; orders are the gap here,
627
+ // ../manifest.ts unmodeled, read back from a vendor-backed root)
628
+ transitions: [],
629
+ },
630
+ },
631
+ notState: ['cancellation_reason'],
632
+ },
633
+ 'financial_connections.account': {
634
+ state: {
635
+ status: {
636
+ initial: 'active',
637
+ // (disconnecting one is the gap here, ../manifest.ts unmodeled; Stripe marks an account inactive when the bank
638
+ // link breaks, and active again)
639
+ transitions: [],
640
+ },
641
+ },
642
+ notState: ['category', 'subcategory'],
643
+ },
644
+ 'financial_connections.transaction': {
645
+ // (a bank's pending transaction posts or is voided at Stripe; the twin's arrive posted)
646
+ state: { status: { initial: 'posted', transitions: [] } },
647
+ },
648
+ 'reporting.report_run': {
649
+ // "When first created, the object appears with status="pending""; "When the run completes, Stripe updates the
650
+ // object, and it has a status of succeeded" (docs.stripe.com/reports/api). Report runs are the gap here
651
+ // (../manifest.ts unmodeled), read back from a vendor-backed root, so Stripe's move is not the twin's.
652
+ state: { status: { initial: 'pending', transitions: [] } },
653
+ },
654
+ product: {
655
+ state: { active: { initial: true, transitions: [] } },
656
+ },
657
+ price: {
658
+ notState: ['billing_scheme', 'tax_behavior', 'tiers_mode', 'type'],
659
+ // (deleting a plan, which leaves its price inactive, is the gap here: ../manifest.ts unmodeled)
660
+ state: { active: { initial: true, transitions: [] } },
661
+ },
662
+ } satisfies Record<string, { state?: Record<string, StateField>; notState?: string[] }>;