@volter/twin-stripe 2.0.38 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (442) hide show
  1. package/README.md +82 -207
  2. package/dist/generated/pack-facts.json +94 -0
  3. package/dist/spec/SOURCE.md +14 -0
  4. package/dist/spec/fixtures3.json.gz +0 -0
  5. package/dist/spec/openapi.json.gz +0 -0
  6. package/dist/spec/patches.json +34 -0
  7. package/dist/spec/sources.json +378 -0
  8. package/dist/src/cli.js +12 -30
  9. package/dist/src/engine/after-payment.d.ts +9 -0
  10. package/dist/src/engine/after-payment.js +28 -0
  11. package/dist/src/engine/apps-secrets.d.ts +1 -0
  12. package/dist/src/engine/apps-secrets.js +3 -0
  13. package/dist/src/engine/balance.d.ts +5 -0
  14. package/dist/src/engine/balance.js +15 -0
  15. package/dist/src/engine/billing.d.ts +5 -0
  16. package/dist/src/engine/billing.js +6 -0
  17. package/dist/src/engine/charges.d.ts +6 -0
  18. package/dist/src/engine/charges.js +13 -0
  19. package/dist/src/engine/checkout.d.ts +24 -0
  20. package/dist/src/engine/checkout.js +30 -0
  21. package/dist/src/engine/common.d.ts +19 -0
  22. package/dist/src/engine/common.js +32 -0
  23. package/dist/src/{screens → engine}/connect-settings.d.ts +1 -7
  24. package/dist/src/engine/connect-settings.js +26 -0
  25. package/dist/src/engine/connect.d.ts +66 -0
  26. package/dist/src/engine/connect.js +189 -0
  27. package/dist/src/engine/coupons.d.ts +0 -0
  28. package/dist/src/engine/coupons.js +5 -0
  29. package/dist/src/engine/credit-notes.d.ts +1 -0
  30. package/dist/src/engine/credit-notes.js +5 -0
  31. package/dist/src/engine/customers.d.ts +12 -0
  32. package/dist/src/engine/customers.js +30 -0
  33. package/dist/src/engine/display.d.ts +14 -0
  34. package/dist/src/engine/display.js +16 -0
  35. package/dist/src/engine/disputes.d.ts +0 -0
  36. package/dist/src/engine/disputes.js +9 -0
  37. package/dist/src/engine/entitlements.d.ts +1 -0
  38. package/dist/src/engine/entitlements.js +4 -0
  39. package/dist/src/engine/ephemeral-keys.d.ts +0 -0
  40. package/dist/src/engine/ephemeral-keys.js +4 -0
  41. package/dist/src/engine/files.d.ts +18 -0
  42. package/dist/src/engine/files.js +33 -0
  43. package/dist/src/engine/front.d.ts +5 -0
  44. package/dist/src/engine/front.js +25 -0
  45. package/dist/src/engine/invoices.d.ts +24 -0
  46. package/dist/src/engine/invoices.js +57 -0
  47. package/dist/src/engine/issuing.d.ts +35 -0
  48. package/dist/src/engine/issuing.js +45 -0
  49. package/dist/src/engine/ledger.d.ts +9 -0
  50. package/dist/src/engine/ledger.js +9 -0
  51. package/dist/src/engine/oauth.d.ts +4 -0
  52. package/dist/src/engine/oauth.js +25 -0
  53. package/dist/src/engine/onboarding.d.ts +13 -0
  54. package/dist/src/engine/onboarding.js +42 -0
  55. package/dist/src/{stripe-params.d.ts → engine/params.d.ts} +20 -3
  56. package/dist/src/{stripe-params.js → engine/params.js} +7 -60
  57. package/dist/src/engine/payment-intents.d.ts +10 -0
  58. package/dist/src/engine/payment-intents.js +27 -0
  59. package/dist/src/engine/payment-links.d.ts +1 -0
  60. package/dist/src/engine/payment-links.js +5 -0
  61. package/dist/src/engine/payment-methods.d.ts +16 -0
  62. package/dist/src/engine/payment-methods.js +22 -0
  63. package/dist/src/engine/plans.d.ts +6 -0
  64. package/dist/src/engine/plans.js +26 -0
  65. package/dist/src/engine/platform.d.ts +39 -0
  66. package/dist/src/engine/platform.js +34 -0
  67. package/dist/src/engine/products.d.ts +0 -0
  68. package/dist/src/engine/products.js +4 -0
  69. package/dist/src/engine/radar.d.ts +2 -0
  70. package/dist/src/engine/radar.js +5 -0
  71. package/dist/src/engine/refunds.d.ts +1 -0
  72. package/dist/src/engine/refunds.js +28 -0
  73. package/dist/src/engine/renewals.d.ts +36 -0
  74. package/dist/src/engine/renewals.js +65 -0
  75. package/dist/src/engine/setup-intents.d.ts +1 -0
  76. package/dist/src/engine/setup-intents.js +4 -0
  77. package/dist/src/{stripe-twin.d.ts → engine/stripe.d.ts} +11 -39
  78. package/dist/src/{stripe-twin.js → engine/stripe.js} +25 -310
  79. package/dist/src/engine/subscription-schedules.d.ts +3 -0
  80. package/dist/src/engine/subscription-schedules.js +1 -0
  81. package/dist/src/engine/subscriptions.d.ts +12 -0
  82. package/dist/src/engine/subscriptions.js +31 -0
  83. package/dist/src/engine/tax.d.ts +7 -0
  84. package/dist/src/engine/tax.js +28 -0
  85. package/dist/src/engine/terminal.d.ts +4 -0
  86. package/dist/src/engine/terminal.js +20 -0
  87. package/dist/src/engine/test-clocks.d.ts +5 -0
  88. package/dist/src/engine/test-clocks.js +9 -0
  89. package/dist/src/engine/tokens.d.ts +7 -0
  90. package/dist/src/engine/tokens.js +20 -0
  91. package/dist/src/engine/transfers.d.ts +2 -0
  92. package/dist/src/engine/transfers.js +1 -0
  93. package/dist/src/engine/treasury.d.ts +23 -0
  94. package/dist/src/engine/treasury.js +45 -0
  95. package/dist/src/{stripe-version.js → engine/version.js} +4 -3
  96. package/dist/src/engine/webhook-endpoints.d.ts +1 -0
  97. package/dist/src/engine/webhook-endpoints.js +12 -0
  98. package/dist/src/engine/webhooks.d.ts +31 -0
  99. package/dist/src/engine/webhooks.js +68 -0
  100. package/dist/src/fetch.d.ts +2 -0
  101. package/dist/src/fetch.js +26 -0
  102. package/dist/src/generated/surface.gen.json +1 -1
  103. package/dist/src/generated/ui.gen.json +1 -1
  104. package/dist/src/index.d.ts +5 -14
  105. package/dist/src/index.js +8 -75
  106. package/dist/src/manifest.js +232 -758
  107. package/dist/src/screens/billing-portal.d.ts +3 -0
  108. package/dist/src/screens/{portal.js → billing-portal.js} +28 -54
  109. package/dist/src/screens/checkout.d.ts +2 -31
  110. package/dist/src/screens/checkout.js +32 -121
  111. package/dist/src/screens/connect-oauth.d.ts +3 -27
  112. package/dist/src/screens/connect-oauth.js +51 -132
  113. package/dist/src/screens/connect-onboarding.d.ts +3 -0
  114. package/dist/src/screens/{onboarding.js → connect-onboarding.js} +36 -102
  115. package/dist/src/screens/dashboard.d.ts +3 -0
  116. package/dist/src/screens/dashboard.js +117 -0
  117. package/dist/src/screens/shared.d.ts +27 -0
  118. package/dist/src/screens/shared.js +87 -0
  119. package/dist/src/screens/stripe-js.d.ts +3 -0
  120. package/dist/src/screens/stripe-js.js +135 -0
  121. package/dist/src/semantics/account_links.d.ts +2 -0
  122. package/dist/src/semantics/account_links.js +22 -0
  123. package/dist/src/semantics/accounts.d.ts +4 -0
  124. package/dist/src/semantics/accounts.js +38 -0
  125. package/dist/src/semantics/apps.d.ts +4 -0
  126. package/dist/src/semantics/{apps-secrets.js → apps.js} +14 -26
  127. package/dist/src/semantics/around.d.ts +2 -0
  128. package/dist/src/semantics/around.js +16 -0
  129. package/dist/src/semantics/balance.d.ts +2 -11
  130. package/dist/src/semantics/balance.js +3 -194
  131. package/dist/src/semantics/balance_transactions.d.ts +2 -0
  132. package/dist/src/semantics/balance_transactions.js +15 -0
  133. package/dist/src/semantics/billing_portal.d.ts +5 -0
  134. package/dist/src/semantics/billing_portal.js +42 -0
  135. package/dist/src/semantics/charges.d.ts +3 -28
  136. package/dist/src/semantics/charges.js +5 -202
  137. package/dist/src/semantics/checkout.d.ts +3 -20
  138. package/dist/src/semantics/checkout.js +8 -261
  139. package/dist/src/semantics/clock.d.ts +2 -0
  140. package/dist/src/semantics/clock.js +21 -0
  141. package/dist/src/semantics/coupons.d.ts +2 -6
  142. package/dist/src/semantics/coupons.js +2 -60
  143. package/dist/src/semantics/customers.d.ts +6 -6
  144. package/dist/src/semantics/customers.js +27 -387
  145. package/dist/src/semantics/disputes.d.ts +2 -2
  146. package/dist/src/semantics/disputes.js +3 -49
  147. package/dist/src/semantics/doors.d.ts +23 -0
  148. package/dist/src/semantics/doors.js +73 -0
  149. package/dist/src/semantics/entitlements.d.ts +2 -2
  150. package/dist/src/semantics/entitlements.js +5 -50
  151. package/dist/src/semantics/events.d.ts +12 -0
  152. package/dist/src/semantics/events.js +36 -0
  153. package/dist/src/semantics/index.d.ts +2 -0
  154. package/dist/src/semantics/index.js +107 -0
  155. package/dist/src/semantics/invoice_payments.d.ts +2 -0
  156. package/dist/src/semantics/invoice_payments.js +12 -0
  157. package/dist/src/semantics/invoiceitems.d.ts +3 -0
  158. package/dist/src/semantics/invoiceitems.js +59 -0
  159. package/dist/src/semantics/invoices.d.ts +16 -18
  160. package/dist/src/semantics/invoices.js +118 -444
  161. package/dist/src/semantics/payment_intents.d.ts +4 -0
  162. package/dist/src/semantics/payment_intents.js +79 -0
  163. package/dist/src/semantics/payment_methods.d.ts +5 -0
  164. package/dist/src/semantics/payment_methods.js +39 -0
  165. package/dist/src/semantics/payouts.d.ts +2 -0
  166. package/dist/src/semantics/payouts.js +21 -0
  167. package/dist/src/semantics/prices.d.ts +4 -0
  168. package/dist/src/semantics/prices.js +37 -0
  169. package/dist/src/semantics/products.d.ts +6 -2
  170. package/dist/src/semantics/products.js +15 -130
  171. package/dist/src/semantics/promotion_codes.d.ts +3 -0
  172. package/dist/src/semantics/promotion_codes.js +35 -0
  173. package/dist/src/semantics/radar.d.ts +2 -2
  174. package/dist/src/semantics/radar.js +5 -74
  175. package/dist/src/semantics/refunds.d.ts +3 -9
  176. package/dist/src/semantics/refunds.js +6 -192
  177. package/dist/src/semantics/setup_intents.d.ts +3 -0
  178. package/dist/src/semantics/{setup-intents.js → setup_intents.js} +10 -53
  179. package/dist/src/semantics/shared.d.ts +822 -47
  180. package/dist/src/semantics/shared.js +3044 -78
  181. package/dist/src/semantics/states.d.ts +531 -0
  182. package/dist/src/semantics/states.js +852 -0
  183. package/dist/src/semantics/subscription_items.d.ts +5 -0
  184. package/dist/src/semantics/subscription_items.js +55 -0
  185. package/dist/src/semantics/subscription_schedules.d.ts +4 -0
  186. package/dist/src/semantics/subscription_schedules.js +60 -0
  187. package/dist/src/semantics/subscriptions.d.ts +7 -11
  188. package/dist/src/semantics/subscriptions.js +44 -415
  189. package/dist/src/semantics/test_helpers.d.ts +6 -0
  190. package/dist/src/semantics/{test-clocks.js → test_helpers.js} +14 -40
  191. package/dist/src/semantics/transfers.d.ts +2 -2
  192. package/dist/src/semantics/transfers.js +6 -101
  193. package/dist/src/server.d.ts +7 -0
  194. package/dist/src/server.js +7 -0
  195. package/generated/pack-facts.json +94 -0
  196. package/package.json +10 -20
  197. package/spec/SOURCE.md +14 -0
  198. package/spec/fixtures3.json.gz +0 -0
  199. package/spec/openapi.json.gz +0 -0
  200. package/spec/patches.json +34 -0
  201. package/spec/sources.json +378 -0
  202. package/src/cli.ts +12 -26
  203. package/src/engine/after-payment.ts +31 -0
  204. package/src/engine/apps-secrets.ts +4 -0
  205. package/src/engine/balance.ts +33 -0
  206. package/src/engine/billing.ts +16 -0
  207. package/src/engine/charges.ts +19 -0
  208. package/src/engine/checkout.ts +40 -0
  209. package/src/engine/common.ts +47 -0
  210. package/src/engine/connect-settings.ts +23 -0
  211. package/src/engine/connect.ts +184 -0
  212. package/src/engine/coupons.ts +5 -0
  213. package/src/engine/credit-notes.ts +6 -0
  214. package/src/engine/customers.ts +35 -0
  215. package/src/engine/display.ts +19 -0
  216. package/src/engine/disputes.ts +9 -0
  217. package/src/engine/entitlements.ts +5 -0
  218. package/src/engine/ephemeral-keys.ts +3 -0
  219. package/src/engine/files.ts +41 -0
  220. package/src/engine/front.ts +31 -0
  221. package/src/engine/invoices.ts +71 -0
  222. package/src/engine/issuing.ts +61 -0
  223. package/src/engine/ledger.ts +50 -0
  224. package/src/engine/oauth.ts +19 -0
  225. package/src/engine/onboarding.ts +54 -0
  226. package/src/{stripe-params.ts → engine/params.ts} +8 -56
  227. package/src/engine/payment-intents.ts +33 -0
  228. package/src/engine/payment-links.ts +6 -0
  229. package/src/engine/payment-methods.ts +25 -0
  230. package/src/engine/plans.ts +42 -0
  231. package/src/engine/platform.ts +47 -0
  232. package/src/engine/products.ts +3 -0
  233. package/src/engine/radar.ts +6 -0
  234. package/src/engine/refunds.ts +29 -0
  235. package/src/engine/renewals.ts +73 -0
  236. package/src/engine/setup-intents.ts +5 -0
  237. package/src/{stripe-twin.ts → engine/stripe.ts} +28 -323
  238. package/src/engine/subscription-schedules.ts +10 -0
  239. package/src/engine/subscriptions.ts +40 -0
  240. package/src/engine/tax.ts +39 -0
  241. package/src/engine/terminal.ts +23 -0
  242. package/src/engine/test-clocks.ts +11 -0
  243. package/src/engine/tokens.ts +22 -0
  244. package/src/engine/transfers.ts +23 -0
  245. package/src/engine/treasury.ts +47 -0
  246. package/src/{stripe-version.ts → engine/version.ts} +4 -3
  247. package/src/engine/webhook-endpoints.ts +14 -0
  248. package/src/engine/webhooks.ts +72 -0
  249. package/src/fetch.ts +27 -0
  250. package/src/generated/surface.gen.json +1 -1
  251. package/src/generated/ui.gen.json +1 -1
  252. package/src/index.ts +8 -116
  253. package/src/manifest.ts +234 -786
  254. package/src/screens/{portal.tsx → billing-portal.tsx} +32 -37
  255. package/src/screens/checkout.tsx +33 -95
  256. package/src/screens/connect-oauth.tsx +64 -88
  257. package/src/screens/{onboarding.tsx → connect-onboarding.tsx} +38 -82
  258. package/src/screens/dashboard.tsx +198 -0
  259. package/src/screens/shared.tsx +84 -0
  260. package/src/screens/stripe-js.ts +170 -0
  261. package/src/semantics/account_links.ts +21 -0
  262. package/src/semantics/accounts.ts +43 -0
  263. package/src/semantics/{apps-secrets.ts → apps.ts} +17 -32
  264. package/src/semantics/around.ts +20 -0
  265. package/src/semantics/balance.ts +6 -207
  266. package/src/semantics/balance_transactions.ts +20 -0
  267. package/src/semantics/billing_portal.ts +51 -0
  268. package/src/semantics/charges.ts +12 -211
  269. package/src/semantics/checkout.ts +13 -268
  270. package/src/semantics/clock.ts +26 -0
  271. package/src/semantics/coupons.ts +5 -67
  272. package/src/semantics/customers.ts +29 -392
  273. package/src/semantics/disputes.ts +9 -59
  274. package/src/semantics/doors.ts +80 -0
  275. package/src/semantics/entitlements.ts +9 -56
  276. package/src/semantics/events.ts +44 -0
  277. package/src/semantics/index.ts +111 -0
  278. package/src/semantics/invoice_payments.ts +18 -0
  279. package/src/semantics/invoiceitems.ts +59 -0
  280. package/src/semantics/invoices.ts +109 -443
  281. package/src/semantics/payment_intents.ts +83 -0
  282. package/src/semantics/payment_methods.ts +43 -0
  283. package/src/semantics/payouts.ts +23 -0
  284. package/src/semantics/prices.ts +42 -0
  285. package/src/semantics/products.ts +18 -142
  286. package/src/semantics/promotion_codes.ts +39 -0
  287. package/src/semantics/radar.ts +8 -77
  288. package/src/semantics/refunds.ts +9 -212
  289. package/src/semantics/setup_intents.ts +45 -0
  290. package/src/semantics/shared.ts +3092 -106
  291. package/src/semantics/states.ts +883 -0
  292. package/src/semantics/subscription_items.ts +54 -0
  293. package/src/semantics/subscription_schedules.ts +66 -0
  294. package/src/semantics/subscriptions.ts +49 -432
  295. package/src/semantics/{test-clocks.ts → test_helpers.ts} +23 -47
  296. package/src/semantics/transfers.ts +11 -131
  297. package/src/server.ts +8 -0
  298. package/client/dashboard-api.ts +0 -286
  299. package/client/stripe-mirror.css +0 -277
  300. package/client/stripe-mirror.tsx +0 -1559
  301. package/dist/client/dashboard-api.d.ts +0 -107
  302. package/dist/client/dashboard-api.js +0 -238
  303. package/dist/client/dashboard-api.ts +0 -286
  304. package/dist/client/stripe-mirror.bundle.js +0 -236
  305. package/dist/client/stripe-mirror.css +0 -277
  306. package/dist/client/stripe-mirror.d.ts +0 -134
  307. package/dist/client/stripe-mirror.js +0 -859
  308. package/dist/client/stripe-mirror.tsx +0 -1559
  309. package/dist/src/screens/connect-settings.js +0 -103
  310. package/dist/src/screens/consent-skin.d.ts +0 -4
  311. package/dist/src/screens/consent-skin.js +0 -18
  312. package/dist/src/screens/financial-connections.d.ts +0 -5
  313. package/dist/src/screens/financial-connections.js +0 -90
  314. package/dist/src/screens/identity.d.ts +0 -5
  315. package/dist/src/screens/identity.js +0 -86
  316. package/dist/src/screens/onboarding.d.ts +0 -13
  317. package/dist/src/screens/portal.d.ts +0 -5
  318. package/dist/src/screens/public-details.d.ts +0 -5
  319. package/dist/src/screens/public-details.js +0 -90
  320. package/dist/src/semantics/after-payment.d.ts +0 -22
  321. package/dist/src/semantics/after-payment.js +0 -99
  322. package/dist/src/semantics/apps-secrets.d.ts +0 -2
  323. package/dist/src/semantics/billing.d.ts +0 -2
  324. package/dist/src/semantics/billing.js +0 -220
  325. package/dist/src/semantics/connect.d.ts +0 -5
  326. package/dist/src/semantics/connect.js +0 -493
  327. package/dist/src/semantics/credit-notes.d.ts +0 -2
  328. package/dist/src/semantics/credit-notes.js +0 -172
  329. package/dist/src/semantics/ephemeral-keys.d.ts +0 -2
  330. package/dist/src/semantics/ephemeral-keys.js +0 -34
  331. package/dist/src/semantics/files.d.ts +0 -2
  332. package/dist/src/semantics/files.js +0 -125
  333. package/dist/src/semantics/issuing.d.ts +0 -13
  334. package/dist/src/semantics/issuing.js +0 -575
  335. package/dist/src/semantics/ledger.d.ts +0 -59
  336. package/dist/src/semantics/ledger.js +0 -200
  337. package/dist/src/semantics/payment-intents.d.ts +0 -18
  338. package/dist/src/semantics/payment-intents.js +0 -452
  339. package/dist/src/semantics/payment-links.d.ts +0 -2
  340. package/dist/src/semantics/payment-links.js +0 -133
  341. package/dist/src/semantics/payment-methods.d.ts +0 -20
  342. package/dist/src/semantics/payment-methods.js +0 -140
  343. package/dist/src/semantics/plans.d.ts +0 -5
  344. package/dist/src/semantics/plans.js +0 -121
  345. package/dist/src/semantics/platform.d.ts +0 -9
  346. package/dist/src/semantics/platform.js +0 -206
  347. package/dist/src/semantics/renewals.d.ts +0 -47
  348. package/dist/src/semantics/renewals.js +0 -281
  349. package/dist/src/semantics/setup-intents.d.ts +0 -2
  350. package/dist/src/semantics/subscription-schedules.d.ts +0 -2
  351. package/dist/src/semantics/subscription-schedules.js +0 -119
  352. package/dist/src/semantics/tax.d.ts +0 -2
  353. package/dist/src/semantics/tax.js +0 -197
  354. package/dist/src/semantics/terminal.d.ts +0 -5
  355. package/dist/src/semantics/terminal.js +0 -182
  356. package/dist/src/semantics/test-clocks.d.ts +0 -6
  357. package/dist/src/semantics/tokens.d.ts +0 -4
  358. package/dist/src/semantics/tokens.js +0 -44
  359. package/dist/src/semantics/treasury.d.ts +0 -2
  360. package/dist/src/semantics/treasury.js +0 -377
  361. package/dist/src/semantics/webhook-endpoints.d.ts +0 -3
  362. package/dist/src/semantics/webhook-endpoints.js +0 -85
  363. package/dist/src/stripe-budget.d.ts +0 -55
  364. package/dist/src/stripe-budget.js +0 -155
  365. package/dist/src/stripe-capabilities.d.ts +0 -3
  366. package/dist/src/stripe-capabilities.js +0 -5836
  367. package/dist/src/stripe-conformance.d.ts +0 -43
  368. package/dist/src/stripe-conformance.js +0 -105
  369. package/dist/src/stripe-connector.d.ts +0 -161
  370. package/dist/src/stripe-connector.js +0 -414
  371. package/dist/src/stripe-emit.d.ts +0 -2
  372. package/dist/src/stripe-emit.js +0 -145
  373. package/dist/src/stripe-events.d.ts +0 -93
  374. package/dist/src/stripe-events.js +0 -392
  375. package/dist/src/stripe-js.d.ts +0 -4
  376. package/dist/src/stripe-js.js +0 -70
  377. package/dist/src/stripe-mirror-ui.d.ts +0 -15
  378. package/dist/src/stripe-mirror-ui.js +0 -87
  379. package/dist/src/stripe-perform-harness.d.ts +0 -9
  380. package/dist/src/stripe-perform-harness.js +0 -26
  381. package/dist/src/stripe-server.d.ts +0 -33
  382. package/dist/src/stripe-server.js +0 -429
  383. package/dist/src/stripe-shared.d.ts +0 -109
  384. package/dist/src/stripe-shared.js +0 -276
  385. package/dist/src/stripe-ui-conformance.d.ts +0 -5
  386. package/dist/src/stripe-ui-conformance.js +0 -79
  387. package/dist/src/stripe-ui-structure.d.ts +0 -3
  388. package/dist/src/stripe-ui-structure.js +0 -168
  389. package/dist/test-fixtures/stripe-known-deviations.json +0 -110
  390. package/dist/test-fixtures/stripe-openapi-operations.SOURCE.md +0 -14
  391. package/dist/test-fixtures/stripe-openapi-operations.json +0 -4717
  392. package/dist/test-fixtures/stripe-schemas.SOURCE.md +0 -35
  393. package/dist/test-fixtures/stripe-schemas.json +0 -3813
  394. package/src/screens/connect-settings.tsx +0 -121
  395. package/src/screens/consent-skin.ts +0 -20
  396. package/src/screens/financial-connections.tsx +0 -101
  397. package/src/screens/identity.tsx +0 -96
  398. package/src/screens/public-details.tsx +0 -105
  399. package/src/semantics/after-payment.ts +0 -118
  400. package/src/semantics/billing.ts +0 -216
  401. package/src/semantics/connect.ts +0 -487
  402. package/src/semantics/credit-notes.ts +0 -168
  403. package/src/semantics/ephemeral-keys.ts +0 -34
  404. package/src/semantics/files.ts +0 -143
  405. package/src/semantics/issuing.ts +0 -590
  406. package/src/semantics/ledger.ts +0 -253
  407. package/src/semantics/payment-intents.ts +0 -463
  408. package/src/semantics/payment-links.ts +0 -148
  409. package/src/semantics/payment-methods.ts +0 -145
  410. package/src/semantics/plans.ts +0 -131
  411. package/src/semantics/platform.ts +0 -220
  412. package/src/semantics/renewals.ts +0 -279
  413. package/src/semantics/setup-intents.ts +0 -87
  414. package/src/semantics/subscription-schedules.ts +0 -129
  415. package/src/semantics/tax.ts +0 -220
  416. package/src/semantics/terminal.ts +0 -195
  417. package/src/semantics/tokens.ts +0 -52
  418. package/src/semantics/treasury.ts +0 -383
  419. package/src/semantics/webhook-endpoints.ts +0 -87
  420. package/src/stripe-budget.ts +0 -181
  421. package/src/stripe-capabilities.ts +0 -5651
  422. package/src/stripe-conformance.ts +0 -124
  423. package/src/stripe-connector.ts +0 -462
  424. package/src/stripe-emit.ts +0 -157
  425. package/src/stripe-events.ts +0 -434
  426. package/src/stripe-js.ts +0 -70
  427. package/src/stripe-mirror-ui.ts +0 -90
  428. package/src/stripe-perform-harness.ts +0 -29
  429. package/src/stripe-server.ts +0 -393
  430. package/src/stripe-shared.ts +0 -297
  431. package/src/stripe-ui-conformance.ts +0 -88
  432. package/src/stripe-ui-structure.ts +0 -182
  433. package/test-fixtures/stripe-known-deviations.json +0 -110
  434. package/test-fixtures/stripe-openapi-operations.json +0 -4717
  435. package/test-fixtures/stripe-schemas.json +0 -3813
  436. /package/dist/src/{screens → engine}/industries.d.ts +0 -0
  437. /package/dist/src/{screens → engine}/industries.js +0 -0
  438. /package/dist/src/{semantics → engine}/test-cards.d.ts +0 -0
  439. /package/dist/src/{semantics → engine}/test-cards.js +0 -0
  440. /package/dist/src/{stripe-version.d.ts → engine/version.d.ts} +0 -0
  441. /package/src/{screens → engine}/industries.ts +0 -0
  442. /package/src/{semantics → engine}/test-cards.ts +0 -0
@@ -0,0 +1,83 @@
1
+ // Stripe's payment_intents operations (docs/contributing/architecture.md, "What an author writes"): each handler over the
2
+ // handler contract's context, computing with the engine (../engine/).
3
+ import type { HandlerContext } from '@volter/world-core';
4
+ import type { Row } from '../engine/common.ts';
5
+ import { PI, TYPES_GIVEN } from '../engine/payment-intents.ts';
6
+ import { asBool, mintClientSecret, nowUnix, validateMoney, verifyMicrodeposits } from '../engine/stripe.ts';
7
+ import { afterCharge, beginBankDebit, cancelAuthorization, captureAuthorization, confirmIntent, confirmOnly, fundFromCashBalance, incrementTooSmall, methodFromData, mintCharge, mintMandate, payInvoiceOf, paymentIntentsLoad, paymentIntentsSend, search } from './shared.ts';
8
+
9
+ export async function PostPaymentIntents(ctx: HandlerContext): Promise<Response> {
10
+ const params = ctx.params;
11
+ const bad = validateMoney(params);
12
+ if (bad) return paymentIntentsSend(ctx, bad);
13
+ // what describes a confirmation needs one: error_on_requires_action, mandate, mandate_data, off_session and return_url
14
+ // are each, in the served spec, a parameter that "can only be used with `confirm=true`" (shared.ts confirmOnly)
15
+ const unconfirmed = confirmOnly(ctx, ['error_on_requires_action', 'mandate', 'mandate_data', 'off_session', 'return_url'], asBool(params.confirm));
16
+ if (unconfirmed) return unconfirmed;
17
+ // automatic_payment_methods: when enabled, Stripe selects eligible methods and answers the
18
+ // normalized { enabled, allow_redirects } object
19
+ const apmIn = params.automatic_payment_methods;
20
+ const apmEnabled = apmIn && typeof apmIn === 'object' ? asBool((apmIn as Record<string, unknown>).enabled) : false;
21
+ const automatic_payment_methods = apmEnabled ? { enabled: true, allow_redirects: ((apmIn as Record<string, unknown>).allow_redirects as string) ?? 'always' } : null;
22
+ // the methods it may be paid with: allowed_payment_method_types in the served version, payment_method_types for a
23
+ // caller pinned to an earlier one (docs.stripe.com/api/payment_intents/create)
24
+ const given = Array.isArray(params.allowed_payment_method_types) ? params.allowed_payment_method_types : params.payment_method_types;
25
+ const payment_method_types = Array.isArray(given) ? given.map(String) : ['card'];
26
+ // `confirm` is an instruction, not a field: `confirm=true` attempts to confirm the intent at once
27
+ // (https://docs.stripe.com/api/payment_intents/create#create_payment_intent-confirm)
28
+ const { automatic_payment_methods: _a, payment_method_types: _p, allowed_payment_method_types: _ap, id: provided, expand: _e, confirm: confirmNow, payment_method_data: data, mandate_data: _mandate, ...rest } = params;
29
+ // a create's payment_method_data makes its method, as a confirm's does (payment-methods.ts methodFromData)
30
+ const made = await methodFromData(ctx, data);
31
+ if (made) rest.payment_method = made;
32
+ // the id is minted first so the client secret can carry it: Stripe.js parses the id back out
33
+ const id = typeof provided === 'string' && provided ? provided : ctx.mint(PI);
34
+ // it waits for a payment method until it has one, then for its confirmation (manifest.ts)
35
+ const hasMethod = typeof rest.payment_method === 'string' && rest.payment_method !== '';
36
+ if (hasMethod) ctx.legal(PI, 'status', 'PostPaymentIntents', 'requires_payment_method', 'requires_confirmation', id);
37
+ const body = await ctx.write(
38
+ PI,
39
+ id,
40
+ {
41
+ object: 'payment_intent',
42
+ created: nowUnix(ctx.occurredAt),
43
+ status: hasMethod ? 'requires_confirmation' : 'requires_payment_method',
44
+ client_secret: mintClientSecret(id, await ctx.secret(`client-secret:${id}`)),
45
+ livemode: false,
46
+ capture_method: 'automatic',
47
+ amount_capturable: 0,
48
+ amount_received: 0,
49
+ next_action: null,
50
+ automatic_payment_methods,
51
+ payment_method_types,
52
+ ...(Array.isArray(params.allowed_payment_method_types) ? { allowed_payment_method_types: payment_method_types } : {}),
53
+ payment_method_options: (params.payment_method_options as object) ?? {},
54
+ ...rest,
55
+ },
56
+ 'payment_intent.create',
57
+ );
58
+ if (Array.isArray(given)) await ctx.record(TYPES_GIVEN, { payment_intent: id }, id);
59
+ if (asBool(confirmNow)) return confirmIntent(ctx, body, {});
60
+ return ctx.reply(ctx.expand(PI, body));
61
+ }
62
+
63
+ export async function PostPaymentIntentsIntentCancel(ctx: HandlerContext): Promise<Response> {
64
+ const loaded = paymentIntentsLoad(ctx, 'PostPaymentIntentsIntentCancel');
65
+ if ('answer' in loaded) return loaded.answer;
66
+ const cancellation_reason = typeof ctx.params.cancellation_reason === 'string' ? ctx.params.cancellation_reason : 'requested_by_customer';
67
+ // "For PaymentIntents with a `status` of `requires_capture`, the remaining `amount_capturable` is automatically
68
+ // refunded" (docs.stripe.com/api/payment_intents/cancel): the authorization is released (charges.ts)
69
+ const held = loaded.pi.status === 'requires_capture' && typeof loaded.pi.latest_charge === 'string' ? ctx.get('charge', loaded.pi.latest_charge) : undefined;
70
+ if (held && held.captured === false && held.refunded !== true) await cancelAuthorization(ctx, held);
71
+ return ctx.reply(ctx.expand(PI, await ctx.write(PI, String(loaded.pi.id), { status: 'canceled', cancellation_reason, amount_capturable: 0 }, 'payment_intent.canceled')));
72
+ }
73
+
74
+ export async function PostPaymentIntentsIntentConfirm(ctx: HandlerContext): Promise<Response> {
75
+ const loaded = paymentIntentsLoad(ctx, 'PostPaymentIntentsIntentConfirm');
76
+ if ('answer' in loaded) return loaded.answer;
77
+ const given = ctx.params;
78
+ const { expand: _e, payment_method_data: data, mandate_data: _mandate, ...params } = given;
79
+ // a confirm's payment_method_data makes the method it pays with; neither it nor mandate_data is a field of the intent
80
+ const made = await methodFromData(ctx, data);
81
+ return confirmIntent(ctx, loaded.pi, made ? { ...params, payment_method: made } : params);
82
+ }
83
+
@@ -0,0 +1,43 @@
1
+ // Stripe's payment_methods operations (docs/contributing/architecture.md, "What an author writes"): each handler over the
2
+ // handler contract's context, computing with the engine (../engine/).
3
+ import type { HandlerContext } from '@volter/world-core';
4
+ import type { Row } from '../engine/common.ts';
5
+ import { noBilling, PM } from '../engine/payment-methods.ts';
6
+ import { declineFor, paymentMethodSubObject } from '../engine/stripe.ts';
7
+ import { afterSuccessOf, at, attachable, attachPaymentMethod, created, fail, pmMissing } from './shared.ts';
8
+
9
+ export async function GetPaymentMethodsPaymentMethod(ctx: HandlerContext): Promise<Response> {
10
+ const m = ctx.get(PM, at(ctx, 'payment_method'));
11
+ return m ? ctx.reply(m) : pmMissing(ctx, at(ctx, 'payment_method'));
12
+ }
13
+
14
+ // the raw card number, cvc and bank account number are never echoed: the modeled sub-object is
15
+ // what the PaymentMethod carries, with the decline outcome its card implies, so a later charge
16
+ // naming it only by id declines the same way
17
+ export async function PostPaymentMethods(ctx: HandlerContext): Promise<Response> {
18
+ const params = ctx.params;
19
+ const pmType = typeof params.type === 'string' ? params.type : 'card';
20
+ const { card: _card, sepa_debit: _sepa, us_bank_account: _ach, type: _t, ...rest } = params;
21
+ const sub = paymentMethodSubObject(pmType, params);
22
+ const declineOutcome = pmType === 'card' ? (declineFor(() => undefined, params) ?? null) : null;
23
+ // and what Stripe does after its card succeeds (a dispute, a review), which a later charge naming it by id brings
24
+ const afterSuccess = pmType === 'card' ? afterSuccessOf(ctx, params.card) : undefined;
25
+ // the billing details the create gives are the method's (docs.stripe.com/api/payment_methods/create#create_payment_method-billing_details)
26
+ const given = rest.billing_details && typeof rest.billing_details === 'object' ? (rest.billing_details as Row) : {};
27
+ return ctx.reply(await created(ctx, PM, { ...rest, type: pmType, customer: null, livemode: false, billing_details: { ...noBilling, ...given }, ...sub, _declineOutcome: declineOutcome, ...(afterSuccess ? { _afterSuccess: afterSuccess } : {}) }, {}));
28
+ }
29
+
30
+ export async function PostPaymentMethodsPaymentMethodAttach(ctx: HandlerContext): Promise<Response> {
31
+ const id = at(ctx, 'payment_method');
32
+ const customer = typeof ctx.params.customer === 'string' ? ctx.params.customer : '';
33
+ if (!customer) return fail(ctx, 'Missing required param: customer.', 400, 'parameter_missing');
34
+ if (!ctx.get('customer', customer)) return fail(ctx, `No such customer: '${customer}'`, 400, 'resource_missing');
35
+ if (!attachable(ctx, id)) return pmMissing(ctx, id);
36
+ return ctx.reply(await attachPaymentMethod(ctx, id, customer));
37
+ }
38
+
39
+ export async function PostPaymentMethodsPaymentMethodDetach(ctx: HandlerContext): Promise<Response> {
40
+ const id = at(ctx, 'payment_method');
41
+ if (!ctx.get(PM, id)) return pmMissing(ctx, id);
42
+ return ctx.reply(await ctx.write(PM, id, { customer: null }, 'payment_method.detach'));
43
+ }
@@ -0,0 +1,23 @@
1
+ // Stripe's payouts operations (docs/contributing/architecture.md, "What an author writes"): each handler over the
2
+ // handler contract's context, computing with the engine (../engine/).
3
+ import type { HandlerContext } from '@volter/world-core';
4
+ import { inRange } from '../engine/common.ts';
5
+ import { validateMoney } from '../engine/stripe.ts';
6
+ import { account, asOf, at, created, fail, kept, list, newest, noExternalAccount, payoutBank, payoutDefaults, payoutMissing, refusePayout, send, settlePayout, where } from './shared.ts';
7
+
8
+ export async function PostPayouts(ctx: HandlerContext): Promise<Response> {
9
+ const bad = validateMoney(ctx.params);
10
+ if (bad) return send(ctx, bad);
11
+ const acct = account(ctx);
12
+ if (acct && !ctx.get('account', acct)) return fail(ctx, `No such account: '${acct}'`, 400, 'account_invalid');
13
+ const amount = Math.trunc(Number(ctx.params.amount) || 0);
14
+ const currency = String(ctx.params.currency ?? 'usd');
15
+ // a connected account is paid out to its own bank account
16
+ if (acct && !ctx.rows('external_account').some((e) => e.account === acct && (e.currency ?? currency) === currency)) return noExternalAccount(ctx, currency);
17
+ const refused = refusePayout(ctx, amount, currency);
18
+ if (refused) return refused;
19
+ const id = ctx.mint('payout');
20
+ const bt = await settlePayout(ctx, id, -amount, currency);
21
+ return ctx.reply(await created(ctx, 'payout', { ...ctx.params, id }, { status: 'pending', ...payoutDefaults(ctx), balance_transaction: bt, destination: acct ? payoutBank(ctx, acct, currency) : null, ...(acct ? { _account: acct } : {}) }));
22
+ }
23
+
@@ -0,0 +1,42 @@
1
+ // Stripe's prices operations (docs/contributing/architecture.md, "What an author writes"): each handler over the
2
+ // handler contract's context, computing with the engine (../engine/).
3
+ import type { HandlerContext } from '@volter/world-core';
4
+ import type { Row } from '../engine/common.ts';
5
+ import { asBool } from '../engine/stripe.ts';
6
+ import { at, created, fail, list, newest, tieredPrice, where } from './shared.ts';
7
+
8
+ // `type` is not stored (it collides with the tree's discriminator), so `recurring` stands for it
9
+ export async function GetPrices(ctx: HandlerContext): Promise<Response> {
10
+ return list(ctx, 'price', where(ctx, newest(ctx, 'price'), {
11
+ active: (p, v) => asBool(p.active) === asBool(v),
12
+ product: (p, v) => p.product === v,
13
+ currency: (p, v) => p.currency === v,
14
+ type: (p, v) => (v === 'recurring' ? !!p.recurring : !p.recurring),
15
+ lookup_keys: (p, v) => (Array.isArray(v) ? v.map(String) : [String(v)]).includes(String(p.lookup_key)),
16
+ }));
17
+ }
18
+
19
+ export async function GetPricesPrice(ctx: HandlerContext): Promise<Response> {
20
+ const p = ctx.get('price', at(ctx, 'price'));
21
+ return p ? ctx.reply(p) : fail(ctx, `No such price: '${at(ctx, 'price')}'`, 404, 'resource_missing');
22
+ }
23
+
24
+ export async function PostPrices(ctx: HandlerContext): Promise<Response> {
25
+ const params = ctx.params;
26
+ // the product must exist
27
+ const product = typeof params.product === 'string' ? params.product : '';
28
+ if (!product || !ctx.get('product', product)) return fail(ctx, `No such product: '${product}'`, 400, 'resource_missing');
29
+ // a tiered price needs tiers_mode and tiers, each tier with up_to and a unit or flat amount; it
30
+ // has no single unit_amount, and its last tier's up_to is null (∞)
31
+ const scheme = typeof params.billing_scheme === 'string' ? params.billing_scheme : 'per_unit';
32
+ if (scheme === 'tiered') return tieredPrice(ctx, params);
33
+ // a price that recurs is billed by subscriptions; any other is paid once. Its recurring block answers what the create
34
+ // left out as Stripe does: `usage_type` "Defaults to `licensed`", and the create example's answer
35
+ // (docs.stripe.com/api/prices/create) carries `"interval_count": 1, "trial_period_days": null`; a meter only a metered
36
+ // price names
37
+ if (params.recurring && typeof params.recurring === 'object') {
38
+ const r = params.recurring as Row;
39
+ params.recurring = { ...r, interval_count: r.interval_count !== undefined ? Math.trunc(Number(r.interval_count)) : 1, usage_type: r.usage_type ?? 'licensed', trial_period_days: r.trial_period_days !== undefined ? Math.trunc(Number(r.trial_period_days)) : null, meter: r.meter ?? null };
40
+ }
41
+ return ctx.reply(await created(ctx, 'price', params, { active: true, livemode: false, billing_scheme: 'per_unit', type: params.recurring ? 'recurring' : 'one_time', metadata: {} }));
42
+ }
@@ -1,154 +1,30 @@
1
- // Product and Price semantics, with the entitlement features granted to a product. Retrieve of a
2
- // product and the product and price updates (archiving and restoring by `active`, the machines in
3
- // ../manifest.ts) are the derived core's.
4
- import type { Semantics, SemanticsContext } from '@volter/world-core';
5
- import { asBool } from '../stripe-twin.ts';
6
- import { at, created, fail, kept, list, newest, where, type Row } from './shared.ts';
1
+ // Stripe's products operations (docs/contributing/architecture.md, "What an author writes"): each handler over the
2
+ // handler contract's context, computing with the engine (../engine/).
3
+ import type { HandlerContext } from '@volter/world-core';
4
+ import { asBool, nowUnix } from '../engine/stripe.ts';
5
+ import { alreadyAttached, at, created, fail, search, featureMissing, kept, list, newest, pricedProductRefused, productFeature, productMissing, where } from './shared.ts';
7
6
 
8
- const productMissing = (ctx: SemanticsContext, id: string): Response => fail(ctx, `No such product: '${id}'`, 404, 'resource_missing');
9
-
10
- const createProduct: Semantics = async (ctx) =>
11
- ctx.reply(await created(ctx, 'product', ctx.params, { active: true, livemode: false, images: [], marketing_features: [], metadata: {}, updated: ctx.now() }));
12
-
13
- const listProducts: Semantics = async (ctx) =>
14
- list(ctx, 'product', where(ctx, newest(ctx, 'product'), {
15
- active: (p, v) => asBool(p.active) === asBool(v),
16
- ids: (p, v) => (Array.isArray(v) ? v.map(String).includes(String(p.id)) : String(p.id) === String(v)),
17
- }));
18
-
19
- // a product with prices cannot be deleted; Stripe says to deactivate it instead
20
- /** A product deleted while it has prices: "Deleting a product is only possible if it has no prices associated with it"
21
- * (docs.stripe.com/api/products/delete). */
22
- function pricedProductRefused(ctx: SemanticsContext): Response {
23
- return fail(ctx, 'You cannot delete the product because it has one or more prices. Deactivate the product instead.', 400, 'resource_already_exists');
24
- }
25
-
26
- const deleteProduct: Semantics = async (ctx) => {
7
+ export async function DeleteProductsId(ctx: HandlerContext): Promise<Response> {
27
8
  const id = at(ctx, 'id');
28
9
  if (!ctx.get('product', id)) return productMissing(ctx, id);
29
10
  if (ctx.rows('price').some((p) => p.product === id)) return pricedProductRefused(ctx);
30
11
  await ctx.write('product', id, { deleted: true }, 'product.delete');
31
12
  return ctx.reply({ id, object: 'product', deleted: true });
32
- };
33
-
34
- // ── features: an entitlements feature granted to a product, at most once ──
35
-
36
- /** A feature attached to a product that already has it. */
37
- function alreadyAttached(ctx: SemanticsContext): Response {
38
- return fail(ctx, 'This feature is already attached to the product.', 400, 'resource_already_exists');
39
- }
40
-
41
- const attachFeature: Semantics = async (ctx) => {
42
- const product = at(ctx, 'product');
43
- if (!ctx.get('product', product)) return productMissing(ctx, product);
44
- const feature = typeof ctx.params.entitlement_feature === 'string' ? ctx.params.entitlement_feature : '';
45
- if (!feature) return fail(ctx, 'Missing required param: entitlement_feature.', 400, 'parameter_missing');
46
- const feat = ctx.get('entitlements_feature', feature);
47
- if (!feat) return fail(ctx, `No such feature: '${feature}'`, 400, 'resource_missing');
48
- if (ctx.rowsRaw('product_feature').some((pf) => pf._product === product && pf._feature === feature)) return alreadyAttached(ctx);
49
- // Stripe answers the feature itself as the product feature's entitlement_feature (docs.stripe.com/api/product-feature/object)
50
- return ctx.reply(
51
- await created(ctx, 'product_feature', { _product: product, _feature: feature }, {
52
- livemode: false,
53
- entitlement_feature: { id: feature, object: 'entitlements.feature', name: feat.name, lookup_key: feat.lookup_key, active: feat.active, metadata: feat.metadata ?? {}, livemode: false },
54
- }),
55
- );
56
- };
57
-
58
- const features: Semantics = async (ctx) => {
59
- const product = at(ctx, 'product');
60
- if (!ctx.get('product', product)) return productMissing(ctx, product);
61
- return list(ctx, 'product_feature', newest(ctx, 'product_feature').filter((pf) => kept(ctx, 'product_feature', pf, '_product') === product));
62
- };
63
-
64
- const productFeature = (ctx: SemanticsContext): Row | undefined => {
65
- const pf = ctx.get('product_feature', at(ctx, 'id'));
66
- // the product a feature is attached to is its address, not a field Stripe answers
67
- return pf && kept(ctx, 'product_feature', pf, '_product') === at(ctx, 'product') ? pf : undefined;
68
- };
69
- const featureMissing = (ctx: SemanticsContext): Response => fail(ctx, `No such product feature: '${at(ctx, 'id')}'`, 404, 'resource_missing');
70
-
71
- const feature: Semantics = async (ctx) => {
72
- const pf = productFeature(ctx);
73
- return pf ? ctx.reply(pf) : featureMissing(ctx);
74
- };
75
-
76
- const detachFeature: Semantics = async (ctx) => {
77
- if (!productFeature(ctx)) return featureMissing(ctx);
78
- const id = at(ctx, 'id');
79
- // when it came off the product: a subscription keeps it until its next period (semantics/entitlements.ts)
80
- await ctx.write('product_feature', id, { deleted: true, _removed_at: Number(ctx.now()) }, 'product_feature.delete');
81
- return ctx.reply({ id, object: 'product_feature', deleted: true });
82
- };
83
-
84
- // ── prices ──
85
-
86
- /** A tiered price: tiers_mode and tiers, each tier with up_to and a unit or flat amount; no single unit_amount, and
87
- * the last tier's up_to null (∞) (docs.stripe.com/products-prices/pricing-models#tiered-pricing). */
88
- async function tieredPrice(ctx: SemanticsContext, params: Row): Promise<Response> {
89
- const mode = typeof params.tiers_mode === 'string' ? params.tiers_mode : '';
90
- if (mode !== 'graduated' && mode !== 'volume') return fail(ctx, 'Missing required param: tiers_mode (graduated or volume).', 400, 'parameter_missing');
91
- const rawTiers = Array.isArray(params.tiers) ? (params.tiers as Row[]) : [];
92
- if (rawTiers.length === 0) return fail(ctx, 'Missing required param: tiers.', 400, 'parameter_missing');
93
- const tiers = rawTiers.map((t) => {
94
- const upToRaw = t.up_to;
95
- return {
96
- up_to: upToRaw === 'inf' || upToRaw === undefined || upToRaw === null ? null : Math.trunc(Number(upToRaw)),
97
- unit_amount: t.unit_amount !== undefined ? Math.trunc(Number(t.unit_amount)) : null,
98
- unit_amount_decimal: t.unit_amount !== undefined ? String(Math.trunc(Number(t.unit_amount))) : null,
99
- flat_amount: t.flat_amount !== undefined ? Math.trunc(Number(t.flat_amount)) : null,
100
- flat_amount_decimal: t.flat_amount !== undefined ? String(Math.trunc(Number(t.flat_amount))) : null,
101
- };
102
- });
103
- if (tiers.some((t) => t.unit_amount === null && t.flat_amount === null)) return fail(ctx, 'Each tier must specify a unit_amount or flat_amount.', 400, 'parameter_invalid_empty');
104
- const { tiers: _t, ...rest } = params;
105
- return ctx.reply(await created(ctx, 'price', { ...rest, billing_scheme: 'tiered', tiers_mode: mode, tiers, unit_amount: null }, { active: true, livemode: false, type: rest.recurring ? 'recurring' : 'one_time', metadata: {} }));
106
13
  }
107
14
 
108
- const createPrice: Semantics = async (ctx) => {
109
- const params = ctx.params;
110
- // the product must exist
111
- const product = typeof params.product === 'string' ? params.product : '';
112
- if (!product || !ctx.get('product', product)) return fail(ctx, `No such product: '${product}'`, 400, 'resource_missing');
113
- // a tiered price needs tiers_mode and tiers, each tier with up_to and a unit or flat amount; it
114
- // has no single unit_amount, and its last tier's up_to is null (∞)
115
- const scheme = typeof params.billing_scheme === 'string' ? params.billing_scheme : 'per_unit';
116
- if (scheme === 'tiered') return tieredPrice(ctx, params);
117
- // a price that recurs is billed by subscriptions; any other is paid once. Its recurring block answers what the create
118
- // left out as Stripe does: `usage_type` "Defaults to `licensed`", and the create example's answer
119
- // (docs.stripe.com/api/prices/create) carries `"interval_count": 1, "trial_period_days": null`; a meter only a metered
120
- // price names
121
- if (params.recurring && typeof params.recurring === 'object') {
122
- const r = params.recurring as Row;
123
- params.recurring = { ...r, interval_count: r.interval_count !== undefined ? Math.trunc(Number(r.interval_count)) : 1, usage_type: r.usage_type ?? 'licensed', trial_period_days: r.trial_period_days !== undefined ? Math.trunc(Number(r.trial_period_days)) : null, meter: r.meter ?? null };
124
- }
125
- return ctx.reply(await created(ctx, 'price', params, { active: true, livemode: false, billing_scheme: 'per_unit', type: params.recurring ? 'recurring' : 'one_time', metadata: {} }));
126
- };
127
-
128
- // `type` is not stored (it collides with the tree's discriminator), so `recurring` stands for it
129
- const listPrices: Semantics = async (ctx) =>
130
- list(ctx, 'price', where(ctx, newest(ctx, 'price'), {
15
+ export async function GetProducts(ctx: HandlerContext): Promise<Response> {
16
+ return list(ctx, 'product', where(ctx, newest(ctx, 'product'), {
131
17
  active: (p, v) => asBool(p.active) === asBool(v),
132
- product: (p, v) => p.product === v,
133
- currency: (p, v) => p.currency === v,
134
- type: (p, v) => (v === 'recurring' ? !!p.recurring : !p.recurring),
135
- lookup_keys: (p, v) => (Array.isArray(v) ? v.map(String) : [String(v)]).includes(String(p.lookup_key)),
18
+ ids: (p, v) => (Array.isArray(v) ? v.map(String).includes(String(p.id)) : String(p.id) === String(v)),
136
19
  }));
20
+ }
137
21
 
138
- const retrievePrice: Semantics = async (ctx) => {
139
- const p = ctx.get('price', at(ctx, 'price'));
140
- return p ? ctx.reply(p) : fail(ctx, `No such price: '${at(ctx, 'price')}'`, 404, 'resource_missing');
141
- };
22
+ export async function PostProducts(ctx: HandlerContext): Promise<Response> {
23
+ return ctx.reply(await created(ctx, 'product', ctx.params, { active: true, livemode: false, images: [], marketing_features: [], metadata: {}, updated: nowUnix(ctx.occurredAt) }));
24
+ }
142
25
 
143
- export const products: Record<string, Semantics> = {
144
- PostProducts: createProduct,
145
- GetProducts: listProducts,
146
- DeleteProductsId: deleteProduct,
147
- PostProductsProductFeatures: attachFeature,
148
- GetProductsProductFeatures: features,
149
- GetProductsProductFeaturesId: feature,
150
- DeleteProductsProductFeaturesId: detachFeature,
151
- PostPrices: createPrice,
152
- GetPrices: listPrices,
153
- GetPricesPrice: retrievePrice,
154
- };
26
+ /** `GET /v1/products/search?query=`: the products Stripe's search language selects (Ponder's catalog probes). */
27
+ // source: spec:GetProductsSearch "Search for products you’ve previously created using Stripe’s"
28
+ export async function GetProductsSearch(ctx: HandlerContext): Promise<Response> {
29
+ return search(ctx, 'product');
30
+ }
@@ -0,0 +1,39 @@
1
+ // Stripe's promotion_codes operations (docs/contributing/architecture.md, "What an author writes"): each handler over the
2
+ // handler contract's context, computing with the engine (../engine/).
3
+ import type { HandlerContext } from '@volter/world-core';
4
+ import { asBool } from '../engine/stripe.ts';
5
+ import { created, fail, list, newest, where } from './shared.ts';
6
+
7
+ export async function GetPromotionCodes(ctx: HandlerContext): Promise<Response> {
8
+ return list(ctx, 'promotion_code', where(ctx, newest(ctx, 'promotion_code'), {
9
+ code: (p, v) => p.code === v,
10
+ active: (p, v) => asBool(p.active) === asBool(v),
11
+ coupon: (p, v) => p.coupon === v,
12
+ customer: (p, v) => p.customer === v,
13
+ }));
14
+ }
15
+
16
+ // a code the caller does not give is derived from the promotion code's id
17
+ export async function PostPromotionCodes(ctx: HandlerContext): Promise<Response> {
18
+ // what it promotes: promotion[type]=coupon and promotion[coupon] (2025-09-30.clover,
19
+ // docs.stripe.com/changelog/clover/2025-09-30/polymorphic-coupon), or the top-level coupon a caller pinned to an
20
+ // earlier version sends; the twin keeps the coupon's id on the code for its rules
21
+ const given = ctx.params;
22
+ const { promotion, coupon: legacy, ...params } = given;
23
+ const promo = promotion && typeof promotion === 'object' ? (promotion as Record<string, unknown>) : undefined;
24
+ if (promo && promo.type !== 'coupon') return fail(ctx, 'Invalid promotion[type]: must be coupon.', 400, 'parameter_invalid_string_enum');
25
+ const coupon = typeof promo?.coupon === 'string' ? promo.coupon : typeof legacy === 'string' ? legacy : '';
26
+ if (!coupon) return fail(ctx, promo ? 'Missing required param: promotion[coupon].' : 'Missing required param: promotion.', 400, 'parameter_missing');
27
+ if (!ctx.get('coupon', coupon)) return fail(ctx, `No such coupon: '${coupon}'`, 400, 'resource_missing');
28
+ const id = ctx.mint('promotion_code');
29
+ const code = typeof params.code === 'string' && params.code ? params.code : `TWIN${id.toUpperCase().replace(/[^A-Z0-9]/g, '')}`;
30
+ return ctx.reply(
31
+ await created(ctx, 'promotion_code', { ...params, coupon, promotion: { type: 'coupon', coupon }, id, code }, {
32
+ active: params.active !== undefined ? asBool(params.active) : true,
33
+ customer: typeof params.customer === 'string' ? params.customer : null,
34
+ expires_at: params.expires_at !== undefined ? Number(params.expires_at) : null,
35
+ max_redemptions: params.max_redemptions !== undefined ? Number(params.max_redemptions) : null,
36
+ times_redeemed: 0, livemode: false, metadata: {}, restrictions: { first_time_transaction: false, minimum_amount: null, minimum_amount_currency: null },
37
+ }),
38
+ );
39
+ }
@@ -1,85 +1,16 @@
1
- // Radar semantics: reviews of payments Radar held (approving closes one, the machine in
2
- // ../manifest.ts) and the value lists custom rules reference, with their items. Review list and
3
- // retrieve, value-list list and retrieve, and value-list-item retrieve are the derived core's.
4
- import type { Semantics, SemanticsContext } from '@volter/world-core';
5
- import { at, created, fail, list, newest } from './shared.ts';
1
+ // Stripe's radar operations (docs/contributing/architecture.md, "What an author writes"): each handler over the
2
+ // handler contract's context, computing with the engine (../engine/).
3
+ import type { HandlerContext } from '@volter/world-core';
4
+ import { VL, VLI } from '../engine/radar.ts';
5
+ import { at, created, fail, list, listMissing, newest, radarSyncItems } from './shared.ts';
6
6
 
7
- const approve: Semantics = async (ctx) => {
8
- const id = at(ctx, 'review');
9
- const r = ctx.get('review', id);
10
- if (!r) return fail(ctx, `No such review: '${id}'`, 404, 'resource_missing');
11
- const refused = ctx.legal('review', 'open', 'PostReviewsReviewApprove', r.open === true, undefined, id);
12
- if (refused) return ctx.refuse(refused);
13
- return ctx.reply(await ctx.write('review', id, { open: false, closed_reason: 'approved', reason: 'approved' }, 'review.closed'));
14
- };
15
-
16
- const VL = 'radar.value_list';
17
- const VLI = 'radar.value_list_item';
18
- const listMissing = (ctx: SemanticsContext, id: string, status = 404): Response => fail(ctx, `No such radar value list: '${id}'`, status, 'resource_missing');
19
-
20
- const createList: Semantics = async (ctx) => {
21
- const params = ctx.params;
22
- if (params.alias === undefined || params.alias === '') return fail(ctx, 'Missing required param: alias.', 400, 'parameter_missing');
23
- if (params.name === undefined || params.name === '') return fail(ctx, 'Missing required param: name.', 400, 'parameter_missing');
24
- const made = await created(ctx, VL, params, {
25
- item_type: typeof params.item_type === 'string' ? params.item_type : 'string', livemode: false, metadata: {},
26
- created_by: 'twin', list_items: { object: 'list', data: [], has_more: false, url: '' },
27
- });
28
- await syncItems(ctx, String(made.id));
29
- return ctx.reply(ctx.get(VL, String(made.id))!);
30
- };
31
-
32
- /** A value list's list_items, "List of items contained within this value list" (the served spec), kept in step with
33
- * its items, at the address the fixture names (/v1/radar/value_list_items?value_list=…). */
34
- async function syncItems(ctx: SemanticsContext, listId: string): Promise<void> {
35
- const data = newest(ctx, VLI).filter((i) => i.value_list === listId);
36
- await ctx.write(VL, listId, { list_items: { object: 'list', data, has_more: false, url: `/v1/radar/value_list_items?value_list=${listId}` } }, 'radar.value_list.items_synced');
37
- }
38
-
39
- const updateList: Semantics = async (ctx) => {
40
- const id = at(ctx, 'value_list');
41
- if (!ctx.row(VL, id, { withDeleted: true })) return listMissing(ctx, id);
42
- return ctx.reply(await ctx.write(VL, id, ctx.params, 'radar.value_list.updated'));
43
- };
44
-
45
- const deleteList: Semantics = async (ctx) => {
46
- const id = at(ctx, 'value_list');
47
- if (!ctx.row(VL, id, { withDeleted: true })) return listMissing(ctx, id);
48
- await ctx.write(VL, id, { deleted: true }, 'radar.value_list.deleted');
49
- return ctx.reply({ id, object: 'radar.value_list', deleted: true });
50
- };
51
-
52
- const addItem: Semantics = async (ctx) => {
7
+ export async function PostRadarValueListItems(ctx: HandlerContext): Promise<Response> {
53
8
  const listId = typeof ctx.params.value_list === 'string' ? ctx.params.value_list : '';
54
9
  if (!listId) return fail(ctx, 'Missing required param: value_list.', 400, 'parameter_missing');
55
10
  if (!ctx.row(VL, listId, { withDeleted: true })) return listMissing(ctx, listId, 400);
56
11
  if (ctx.params.value === undefined || ctx.params.value === '') return fail(ctx, 'Missing required param: value.', 400, 'parameter_missing');
57
12
  const item = await created(ctx, VLI, { value_list: listId, value: ctx.params.value }, { livemode: false, created_by: 'twin' });
58
- await syncItems(ctx, listId);
13
+ await radarSyncItems(ctx, listId);
59
14
  return ctx.reply(item);
60
- };
61
-
62
- const items: Semantics = async (ctx) => {
63
- const listId = typeof ctx.params.value_list === 'string' ? ctx.params.value_list : '';
64
- if (!listId) return fail(ctx, 'Missing required param: value_list.', 400, 'parameter_missing');
65
- return list(ctx, VLI, newest(ctx, VLI).filter((i) => i.value_list === listId));
66
- };
67
-
68
- const removeItem: Semantics = async (ctx) => {
69
- const id = at(ctx, 'item');
70
- const was = ctx.row(VLI, id, { withDeleted: true });
71
- if (!was) return fail(ctx, `No such radar value list item: '${id}'`, 404, 'resource_missing');
72
- await ctx.write(VLI, id, { deleted: true }, 'radar.value_list_item.deleted');
73
- if (typeof was.value_list === 'string' && ctx.get(VL, was.value_list)) await syncItems(ctx, was.value_list);
74
- return ctx.reply({ id, object: 'radar.value_list_item', deleted: true });
75
- };
15
+ }
76
16
 
77
- export const radar: Record<string, Semantics> = {
78
- PostReviewsReviewApprove: approve,
79
- PostRadarValueLists: createList,
80
- PostRadarValueListsValueList: updateList,
81
- DeleteRadarValueListsValueList: deleteList,
82
- PostRadarValueListItems: addItem,
83
- GetRadarValueListItems: items,
84
- DeleteRadarValueListItemsItem: removeItem,
85
- };