@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,3 @@
1
+ import type { HandlerContext } from '@volter/world-core';
2
+ export declare function PostPaymentIntents(ctx: HandlerContext): Promise<Response>;
3
+ export declare function PostPaymentIntentsIntentCancel(ctx: HandlerContext): Promise<Response>;
@@ -0,0 +1,71 @@
1
+ import { PI, TYPES_GIVEN } from "../engine/payment-intents.js";
2
+ import { asBool, mintClientSecret, nowUnix, validateMoney } from "../engine/stripe.js";
3
+ import { confirmIntent, intentFields, confirmOnly, methodFromData, paymentIntentsSend } from "./shared.js";
4
+ import { cancelAuthorization, paymentIntentsLoad } from "./shared.js";
5
+ export async function PostPaymentIntents(ctx) {
6
+ const params = ctx.params;
7
+ const bad = validateMoney(params);
8
+ if (bad)
9
+ return paymentIntentsSend(ctx, bad);
10
+ // what describes a confirmation needs one: error_on_requires_action, mandate, mandate_data, off_session and return_url
11
+ // are each, in the served spec, a parameter that "can only be used with `confirm=true`" (shared.ts confirmOnly)
12
+ const unconfirmed = confirmOnly(ctx, ['error_on_requires_action', 'mandate', 'mandate_data', 'off_session', 'return_url'], asBool(params.confirm));
13
+ if (unconfirmed)
14
+ return unconfirmed;
15
+ // automatic_payment_methods: when enabled, Stripe selects eligible methods and answers the
16
+ // normalized { enabled, allow_redirects } object
17
+ const apmIn = params.automatic_payment_methods;
18
+ const apmEnabled = apmIn && typeof apmIn === 'object' ? asBool(apmIn.enabled) : false;
19
+ const automatic_payment_methods = apmEnabled ? { enabled: true, allow_redirects: apmIn.allow_redirects ?? 'always' } : null;
20
+ // the methods it may be paid with: allowed_payment_method_types in the served version, payment_method_types for a
21
+ // caller pinned to an earlier one (docs.stripe.com/api/payment_intents/create)
22
+ const given = Array.isArray(params.allowed_payment_method_types) ? params.allowed_payment_method_types : params.payment_method_types;
23
+ const payment_method_types = Array.isArray(given) ? given.map(String) : ['card'];
24
+ // `confirm` is an instruction, not a field: `confirm=true` attempts to confirm the intent at once
25
+ // (https://docs.stripe.com/api/payment_intents/create#create_payment_intent-confirm)
26
+ 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;
27
+ // a create's payment_method_data makes its method, as a confirm's does (payment-methods.ts methodFromData)
28
+ const made = await methodFromData(ctx, data);
29
+ if (made)
30
+ rest.payment_method = made;
31
+ // the id is minted first so the client secret can carry it: Stripe.js parses the id back out
32
+ const id = typeof provided === 'string' && provided ? provided : ctx.mint(PI);
33
+ // it waits for a payment method until it has one, then for its confirmation (manifest.ts)
34
+ const hasMethod = typeof rest.payment_method === 'string' && rest.payment_method !== '';
35
+ if (hasMethod)
36
+ ctx.legal(PI, 'status', 'PostPaymentIntents', 'requires_payment_method', 'requires_confirmation', id);
37
+ const body = await ctx.write(PI, id, {
38
+ object: 'payment_intent',
39
+ created: nowUnix(ctx.occurredAt),
40
+ status: hasMethod ? 'requires_confirmation' : 'requires_payment_method',
41
+ client_secret: mintClientSecret(id, await ctx.secret(`client-secret:${id}`)),
42
+ livemode: false,
43
+ capture_method: 'automatic',
44
+ amount_capturable: 0,
45
+ amount_received: 0,
46
+ next_action: null,
47
+ automatic_payment_methods,
48
+ payment_method_types,
49
+ ...(Array.isArray(params.allowed_payment_method_types) ? { allowed_payment_method_types: payment_method_types } : {}),
50
+ payment_method_options: params.payment_method_options ?? {},
51
+ ...intentFields(rest),
52
+ }, 'payment_intent.create');
53
+ if (Array.isArray(given))
54
+ await ctx.record(TYPES_GIVEN, { payment_intent: id }, id);
55
+ if (asBool(confirmNow))
56
+ return confirmIntent(ctx, body, { ...params, payment_method: rest.payment_method });
57
+ return ctx.reply(ctx.expand(PI, body));
58
+ }
59
+ // source: spec:GetPaymentIntentsSearch "Search for PaymentIntents"
60
+ export async function PostPaymentIntentsIntentCancel(ctx) {
61
+ const loaded = paymentIntentsLoad(ctx, 'PostPaymentIntentsIntentCancel');
62
+ if ('answer' in loaded)
63
+ return loaded.answer;
64
+ const cancellation_reason = typeof ctx.params.cancellation_reason === 'string' ? ctx.params.cancellation_reason : 'requested_by_customer';
65
+ // "For PaymentIntents with a `status` of `requires_capture`, the remaining `amount_capturable` is automatically
66
+ // refunded" (docs.stripe.com/api/payment_intents/cancel): the authorization is released (charges.ts)
67
+ const held = loaded.pi.status === 'requires_capture' && typeof loaded.pi.latest_charge === 'string' ? ctx.get('charge', loaded.pi.latest_charge) : undefined;
68
+ if (held && held.captured === false && held.refunded !== true)
69
+ await cancelAuthorization(ctx, held);
70
+ return ctx.reply(ctx.expand(PI, await ctx.write(PI, String(loaded.pi.id), { status: 'canceled', cancellation_reason, amount_capturable: 0 }, 'payment_intent.canceled')));
71
+ }
@@ -0,0 +1,3 @@
1
+ import type { HandlerContext } from '@volter/world-core';
2
+ export declare function GetPaymentMethodsPaymentMethod(ctx: HandlerContext): Promise<Response>;
3
+ export declare function PostPaymentMethodsPaymentMethodDetach(ctx: HandlerContext): Promise<Response>;
@@ -0,0 +1,15 @@
1
+ import { PM } from "../engine/payment-methods.js";
2
+ import { at, pmMissing } from "./shared.js";
3
+ export async function GetPaymentMethodsPaymentMethod(ctx) {
4
+ const m = ctx.get(PM, at(ctx, 'payment_method'));
5
+ return m ? ctx.reply(m) : pmMissing(ctx, at(ctx, 'payment_method'));
6
+ }
7
+ // the raw card number, cvc and bank account number are never echoed: the modeled sub-object is
8
+ // what the PaymentMethod carries, with the decline outcome its card implies, so a later charge
9
+ // naming it only by id declines the same way
10
+ export async function PostPaymentMethodsPaymentMethodDetach(ctx) {
11
+ const id = at(ctx, 'payment_method');
12
+ if (!ctx.get(PM, id))
13
+ return pmMissing(ctx, id);
14
+ return ctx.reply(await ctx.write(PM, id, { customer: null }, 'payment_method.detach'));
15
+ }
@@ -0,0 +1,3 @@
1
+ import type { HandlerContext } from '@volter/world-core';
2
+ export declare function PostPayouts(ctx: HandlerContext): Promise<Response>;
3
+ export declare function GetPayouts(ctx: HandlerContext): Promise<Response>;
@@ -0,0 +1,28 @@
1
+ import { validateMoney } from "../engine/stripe.js";
2
+ import { account, asOf, created, kept, list, newest, fail, noExternalAccount, payoutBank, payoutDefaults, refusePayout, send, settlePayout } from "./shared.js";
3
+ export async function PostPayouts(ctx) {
4
+ const bad = validateMoney(ctx.params);
5
+ if (bad)
6
+ return send(ctx, bad);
7
+ const acct = account(ctx);
8
+ if (acct && !ctx.get('account', acct))
9
+ return fail(ctx, `No such account: '${acct}'`, 400, 'account_invalid');
10
+ const amount = Math.trunc(Number(ctx.params.amount) || 0);
11
+ const currency = String(ctx.params.currency ?? 'usd');
12
+ // a connected account is paid out to its own bank account
13
+ if (acct && !ctx.rows('external_account').some((e) => e.account === acct && (e.currency ?? currency) === currency))
14
+ return noExternalAccount(ctx, currency);
15
+ const refused = refusePayout(ctx, amount, currency);
16
+ if (refused)
17
+ return refused;
18
+ const id = ctx.mint('payout');
19
+ const bt = await settlePayout(ctx, id, -amount, currency);
20
+ 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 } : {}) }));
21
+ }
22
+ // source: https://docs.stripe.com/connect/authentication "Stripe-Account header"
23
+ // source: https://docs.stripe.com/payouts "paid"
24
+ export async function GetPayouts(ctx) {
25
+ const acct = account(ctx);
26
+ const payouts = newest(ctx, 'payout').filter((p) => (kept(ctx, 'payout', p, '_account') ?? null) === (acct ?? null));
27
+ return list(ctx, 'payout', payouts.map((p) => asOf(ctx, p)));
28
+ }
@@ -0,0 +1,4 @@
1
+ import type { HandlerContext } from '@volter/world-core';
2
+ export declare function GetPrices(ctx: HandlerContext): Promise<Response>;
3
+ export declare function GetPricesPrice(ctx: HandlerContext): Promise<Response>;
4
+ export declare function PostPrices(ctx: HandlerContext): Promise<Response>;
@@ -0,0 +1,37 @@
1
+ import { asBool } from "../engine/stripe.js";
2
+ import { at, created, fail, list, newest, tieredPrice, where } from "./shared.js";
3
+ // `type` is not stored (it collides with the tree's discriminator), so `recurring` stands for it
4
+ export async function GetPrices(ctx) {
5
+ return list(ctx, 'price', where(ctx, newest(ctx, 'price'), {
6
+ active: (p, v) => asBool(p.active) === asBool(v),
7
+ product: (p, v) => p.product === v,
8
+ currency: (p, v) => p.currency === v,
9
+ type: (p, v) => (v === 'recurring' ? !!p.recurring : !p.recurring),
10
+ lookup_keys: (p, v) => (Array.isArray(v) ? v.map(String) : [String(v)]).includes(String(p.lookup_key)),
11
+ }));
12
+ }
13
+ export async function GetPricesPrice(ctx) {
14
+ const p = ctx.get('price', at(ctx, 'price'));
15
+ return p ? ctx.reply(p) : fail(ctx, `No such price: '${at(ctx, 'price')}'`, 404, 'resource_missing');
16
+ }
17
+ export async function PostPrices(ctx) {
18
+ const params = ctx.params;
19
+ // the product must exist
20
+ const product = typeof params.product === 'string' ? params.product : '';
21
+ if (!product || !ctx.get('product', product))
22
+ return fail(ctx, `No such product: '${product}'`, 400, 'resource_missing');
23
+ // a tiered price needs tiers_mode and tiers, each tier with up_to and a unit or flat amount; it
24
+ // has no single unit_amount, and its last tier's up_to is null (∞)
25
+ const scheme = typeof params.billing_scheme === 'string' ? params.billing_scheme : 'per_unit';
26
+ if (scheme === 'tiered')
27
+ return tieredPrice(ctx, params);
28
+ // a price that recurs is billed by subscriptions; any other is paid once. Its recurring block answers what the create
29
+ // left out as Stripe does: `usage_type` "Defaults to `licensed`", and the create example's answer
30
+ // (docs.stripe.com/api/prices/create) carries `"interval_count": 1, "trial_period_days": null`; a meter only a metered
31
+ // price names
32
+ if (params.recurring && typeof params.recurring === 'object') {
33
+ const r = params.recurring;
34
+ 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 };
35
+ }
36
+ return ctx.reply(await created(ctx, 'price', params, { active: true, livemode: false, billing_scheme: 'per_unit', type: params.recurring ? 'recurring' : 'one_time', metadata: {} }));
37
+ }
@@ -1,2 +1,4 @@
1
- import type { Semantics } from '@volter/world-core';
2
- export declare const products: Record<string, Semantics>;
1
+ import type { HandlerContext } from '@volter/world-core';
2
+ export declare function GetProducts(ctx: HandlerContext): Promise<Response>;
3
+ export declare function PostProducts(ctx: HandlerContext): Promise<Response>;
4
+ /** `GET /v1/products/search?query=`: the products Stripe's search language selects. */
@@ -1,140 +1,14 @@
1
- import { asBool } from "../stripe-twin.js";
2
- import { at, created, fail, kept, list, newest, where } from "./shared.js";
3
- const productMissing = (ctx, id) => fail(ctx, `No such product: '${id}'`, 404, 'resource_missing');
4
- const createProduct = async (ctx) => ctx.reply(await created(ctx, 'product', ctx.params, { active: true, livemode: false, images: [], marketing_features: [], metadata: {}, updated: ctx.now() }));
5
- const listProducts = async (ctx) => list(ctx, 'product', where(ctx, newest(ctx, 'product'), {
6
- active: (p, v) => asBool(p.active) === asBool(v),
7
- ids: (p, v) => (Array.isArray(v) ? v.map(String).includes(String(p.id)) : String(p.id) === String(v)),
8
- }));
9
- // a product with prices cannot be deleted; Stripe says to deactivate it instead
10
- /** A product deleted while it has prices: "Deleting a product is only possible if it has no prices associated with it"
11
- * (docs.stripe.com/api/products/delete). */
12
- function pricedProductRefused(ctx) {
13
- return fail(ctx, 'You cannot delete the product because it has one or more prices. Deactivate the product instead.', 400, 'resource_already_exists');
14
- }
15
- const deleteProduct = async (ctx) => {
16
- const id = at(ctx, 'id');
17
- if (!ctx.get('product', id))
18
- return productMissing(ctx, id);
19
- if (ctx.rows('price').some((p) => p.product === id))
20
- return pricedProductRefused(ctx);
21
- await ctx.write('product', id, { deleted: true }, 'product.delete');
22
- return ctx.reply({ id, object: 'product', deleted: true });
23
- };
24
- // ── features: an entitlements feature granted to a product, at most once ──
25
- /** A feature attached to a product that already has it. */
26
- function alreadyAttached(ctx) {
27
- return fail(ctx, 'This feature is already attached to the product.', 400, 'resource_already_exists');
28
- }
29
- const attachFeature = async (ctx) => {
30
- const product = at(ctx, 'product');
31
- if (!ctx.get('product', product))
32
- return productMissing(ctx, product);
33
- const feature = typeof ctx.params.entitlement_feature === 'string' ? ctx.params.entitlement_feature : '';
34
- if (!feature)
35
- return fail(ctx, 'Missing required param: entitlement_feature.', 400, 'parameter_missing');
36
- const feat = ctx.get('entitlements_feature', feature);
37
- if (!feat)
38
- return fail(ctx, `No such feature: '${feature}'`, 400, 'resource_missing');
39
- if (ctx.rowsRaw('product_feature').some((pf) => pf._product === product && pf._feature === feature))
40
- return alreadyAttached(ctx);
41
- // Stripe answers the feature itself as the product feature's entitlement_feature (docs.stripe.com/api/product-feature/object)
42
- return ctx.reply(await created(ctx, 'product_feature', { _product: product, _feature: feature }, {
43
- livemode: false,
44
- entitlement_feature: { id: feature, object: 'entitlements.feature', name: feat.name, lookup_key: feat.lookup_key, active: feat.active, metadata: feat.metadata ?? {}, livemode: false },
1
+ import { asBool, nowUnix } from "../engine/stripe.js";
2
+ import { created, list, newest, where } from "./shared.js";
3
+ export async function GetProducts(ctx) {
4
+ return list(ctx, 'product', where(ctx, newest(ctx, 'product'), {
5
+ active: (p, v) => asBool(p.active) === asBool(v),
6
+ ids: (p, v) => (Array.isArray(v) ? v.map(String).includes(String(p.id)) : String(p.id) === String(v)),
45
7
  }));
46
- };
47
- const features = async (ctx) => {
48
- const product = at(ctx, 'product');
49
- if (!ctx.get('product', product))
50
- return productMissing(ctx, product);
51
- return list(ctx, 'product_feature', newest(ctx, 'product_feature').filter((pf) => kept(ctx, 'product_feature', pf, '_product') === product));
52
- };
53
- const productFeature = (ctx) => {
54
- const pf = ctx.get('product_feature', at(ctx, 'id'));
55
- // the product a feature is attached to is its address, not a field Stripe answers
56
- return pf && kept(ctx, 'product_feature', pf, '_product') === at(ctx, 'product') ? pf : undefined;
57
- };
58
- const featureMissing = (ctx) => fail(ctx, `No such product feature: '${at(ctx, 'id')}'`, 404, 'resource_missing');
59
- const feature = async (ctx) => {
60
- const pf = productFeature(ctx);
61
- return pf ? ctx.reply(pf) : featureMissing(ctx);
62
- };
63
- const detachFeature = async (ctx) => {
64
- if (!productFeature(ctx))
65
- return featureMissing(ctx);
66
- const id = at(ctx, 'id');
67
- // when it came off the product: a subscription keeps it until its next period (semantics/entitlements.ts)
68
- await ctx.write('product_feature', id, { deleted: true, _removed_at: Number(ctx.now()) }, 'product_feature.delete');
69
- return ctx.reply({ id, object: 'product_feature', deleted: true });
70
- };
71
- // ── prices ──
72
- /** A tiered price: tiers_mode and tiers, each tier with up_to and a unit or flat amount; no single unit_amount, and
73
- * the last tier's up_to null (∞) (docs.stripe.com/products-prices/pricing-models#tiered-pricing). */
74
- async function tieredPrice(ctx, params) {
75
- const mode = typeof params.tiers_mode === 'string' ? params.tiers_mode : '';
76
- if (mode !== 'graduated' && mode !== 'volume')
77
- return fail(ctx, 'Missing required param: tiers_mode (graduated or volume).', 400, 'parameter_missing');
78
- const rawTiers = Array.isArray(params.tiers) ? params.tiers : [];
79
- if (rawTiers.length === 0)
80
- return fail(ctx, 'Missing required param: tiers.', 400, 'parameter_missing');
81
- const tiers = rawTiers.map((t) => {
82
- const upToRaw = t.up_to;
83
- return {
84
- up_to: upToRaw === 'inf' || upToRaw === undefined || upToRaw === null ? null : Math.trunc(Number(upToRaw)),
85
- unit_amount: t.unit_amount !== undefined ? Math.trunc(Number(t.unit_amount)) : null,
86
- unit_amount_decimal: t.unit_amount !== undefined ? String(Math.trunc(Number(t.unit_amount))) : null,
87
- flat_amount: t.flat_amount !== undefined ? Math.trunc(Number(t.flat_amount)) : null,
88
- flat_amount_decimal: t.flat_amount !== undefined ? String(Math.trunc(Number(t.flat_amount))) : null,
89
- };
90
- });
91
- if (tiers.some((t) => t.unit_amount === null && t.flat_amount === null))
92
- return fail(ctx, 'Each tier must specify a unit_amount or flat_amount.', 400, 'parameter_invalid_empty');
93
- const { tiers: _t, ...rest } = params;
94
- 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: {} }));
95
8
  }
96
- const createPrice = async (ctx) => {
97
- const params = ctx.params;
98
- // the product must exist
99
- const product = typeof params.product === 'string' ? params.product : '';
100
- if (!product || !ctx.get('product', product))
101
- return fail(ctx, `No such product: '${product}'`, 400, 'resource_missing');
102
- // a tiered price needs tiers_mode and tiers, each tier with up_to and a unit or flat amount; it
103
- // has no single unit_amount, and its last tier's up_to is null (∞)
104
- const scheme = typeof params.billing_scheme === 'string' ? params.billing_scheme : 'per_unit';
105
- if (scheme === 'tiered')
106
- return tieredPrice(ctx, params);
107
- // a price that recurs is billed by subscriptions; any other is paid once. Its recurring block answers what the create
108
- // left out as Stripe does: `usage_type` "Defaults to `licensed`", and the create example's answer
109
- // (docs.stripe.com/api/prices/create) carries `"interval_count": 1, "trial_period_days": null`; a meter only a metered
110
- // price names
111
- if (params.recurring && typeof params.recurring === 'object') {
112
- const r = params.recurring;
113
- 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 };
114
- }
115
- return ctx.reply(await created(ctx, 'price', params, { active: true, livemode: false, billing_scheme: 'per_unit', type: params.recurring ? 'recurring' : 'one_time', metadata: {} }));
116
- };
117
- // `type` is not stored (it collides with the tree's discriminator), so `recurring` stands for it
118
- const listPrices = async (ctx) => list(ctx, 'price', where(ctx, newest(ctx, 'price'), {
119
- active: (p, v) => asBool(p.active) === asBool(v),
120
- product: (p, v) => p.product === v,
121
- currency: (p, v) => p.currency === v,
122
- type: (p, v) => (v === 'recurring' ? !!p.recurring : !p.recurring),
123
- lookup_keys: (p, v) => (Array.isArray(v) ? v.map(String) : [String(v)]).includes(String(p.lookup_key)),
124
- }));
125
- const retrievePrice = async (ctx) => {
126
- const p = ctx.get('price', at(ctx, 'price'));
127
- return p ? ctx.reply(p) : fail(ctx, `No such price: '${at(ctx, 'price')}'`, 404, 'resource_missing');
128
- };
129
- export const products = {
130
- PostProducts: createProduct,
131
- GetProducts: listProducts,
132
- DeleteProductsId: deleteProduct,
133
- PostProductsProductFeatures: attachFeature,
134
- GetProductsProductFeatures: features,
135
- GetProductsProductFeaturesId: feature,
136
- DeleteProductsProductFeaturesId: detachFeature,
137
- PostPrices: createPrice,
138
- GetPrices: listPrices,
139
- GetPricesPrice: retrievePrice,
140
- };
9
+ export async function PostProducts(ctx) {
10
+ return ctx.reply(await created(ctx, 'product', ctx.params, { active: true, livemode: false, images: [], marketing_features: [], metadata: {}, updated: nowUnix(ctx.occurredAt) }));
11
+ }
12
+ /** `GET /v1/products/search?query=`: the products Stripe's search language selects. */
13
+ // source: spec:GetProductsSearch "Search for products you’ve previously created using Stripe’s"
14
+ // source: spec:PostProductsProductFeatures "Creates a product_feature"
@@ -0,0 +1,3 @@
1
+ import type { HandlerContext } from '@volter/world-core';
2
+ export declare function GetPromotionCodes(ctx: HandlerContext): Promise<Response>;
3
+ export declare function PostPromotionCodes(ctx: HandlerContext): Promise<Response>;
@@ -0,0 +1,35 @@
1
+ import { asBool } from "../engine/stripe.js";
2
+ import { created, fail, list, newest, where } from "./shared.js";
3
+ export async function GetPromotionCodes(ctx) {
4
+ return list(ctx, 'promotion_code', where(ctx, newest(ctx, 'promotion_code'), {
5
+ code: (p, v) => p.code === v,
6
+ active: (p, v) => asBool(p.active) === asBool(v),
7
+ coupon: (p, v) => p.coupon === v,
8
+ customer: (p, v) => p.customer === v,
9
+ }));
10
+ }
11
+ // a code the caller does not give is derived from the promotion code's id
12
+ export async function PostPromotionCodes(ctx) {
13
+ // what it promotes: promotion[type]=coupon and promotion[coupon] (2025-09-30.clover,
14
+ // docs.stripe.com/changelog/clover/2025-09-30/polymorphic-coupon), or the top-level coupon a caller pinned to an
15
+ // earlier version sends; the twin keeps the coupon's id on the code for its rules
16
+ const given = ctx.params;
17
+ const { promotion, coupon: legacy, ...params } = given;
18
+ const promo = promotion && typeof promotion === 'object' ? promotion : undefined;
19
+ if (promo && promo.type !== 'coupon')
20
+ return fail(ctx, 'Invalid promotion[type]: must be coupon.', 400, 'parameter_invalid_string_enum');
21
+ const coupon = typeof promo?.coupon === 'string' ? promo.coupon : typeof legacy === 'string' ? legacy : '';
22
+ if (!coupon)
23
+ return fail(ctx, promo ? 'Missing required param: promotion[coupon].' : 'Missing required param: promotion.', 400, 'parameter_missing');
24
+ if (!ctx.get('coupon', coupon))
25
+ return fail(ctx, `No such coupon: '${coupon}'`, 400, 'resource_missing');
26
+ const id = ctx.mint('promotion_code');
27
+ const code = typeof params.code === 'string' && params.code ? params.code : `TWIN${id.toUpperCase().replace(/[^A-Z0-9]/g, '')}`;
28
+ return ctx.reply(await created(ctx, 'promotion_code', { ...params, coupon, promotion: { type: 'coupon', coupon }, id, code }, {
29
+ active: params.active !== undefined ? asBool(params.active) : true,
30
+ customer: typeof params.customer === 'string' ? params.customer : null,
31
+ expires_at: params.expires_at !== undefined ? Number(params.expires_at) : null,
32
+ max_redemptions: params.max_redemptions !== undefined ? Number(params.max_redemptions) : null,
33
+ times_redeemed: 0, livemode: false, metadata: {}, restrictions: { first_time_transaction: false, minimum_amount: null, minimum_amount_currency: null },
34
+ }));
35
+ }
@@ -1,2 +1,2 @@
1
- import type { Semantics } from '@volter/world-core';
2
- export declare const radar: Record<string, Semantics>;
1
+ import type { HandlerContext } from '@volter/world-core';
2
+ export declare function PostRadarValueListItems(ctx: HandlerContext): Promise<Response>;
@@ -1,50 +1,6 @@
1
- import { at, created, fail, list, newest } from "./shared.js";
2
- const approve = async (ctx) => {
3
- const id = at(ctx, 'review');
4
- const r = ctx.get('review', id);
5
- if (!r)
6
- return fail(ctx, `No such review: '${id}'`, 404, 'resource_missing');
7
- const refused = ctx.legal('review', 'open', 'PostReviewsReviewApprove', r.open === true, undefined, id);
8
- if (refused)
9
- return ctx.refuse(refused);
10
- return ctx.reply(await ctx.write('review', id, { open: false, closed_reason: 'approved', reason: 'approved' }, 'review.closed'));
11
- };
12
- const VL = 'radar.value_list';
13
- const VLI = 'radar.value_list_item';
14
- const listMissing = (ctx, id, status = 404) => fail(ctx, `No such radar value list: '${id}'`, status, 'resource_missing');
15
- const createList = async (ctx) => {
16
- const params = ctx.params;
17
- if (params.alias === undefined || params.alias === '')
18
- return fail(ctx, 'Missing required param: alias.', 400, 'parameter_missing');
19
- if (params.name === undefined || params.name === '')
20
- return fail(ctx, 'Missing required param: name.', 400, 'parameter_missing');
21
- const made = await created(ctx, VL, params, {
22
- item_type: typeof params.item_type === 'string' ? params.item_type : 'string', livemode: false, metadata: {},
23
- created_by: 'twin', list_items: { object: 'list', data: [], has_more: false, url: '' },
24
- });
25
- await syncItems(ctx, String(made.id));
26
- return ctx.reply(ctx.get(VL, String(made.id)));
27
- };
28
- /** A value list's list_items, "List of items contained within this value list" (the served spec), kept in step with
29
- * its items, at the address the fixture names (/v1/radar/value_list_items?value_list=…). */
30
- async function syncItems(ctx, listId) {
31
- const data = newest(ctx, VLI).filter((i) => i.value_list === listId);
32
- 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');
33
- }
34
- const updateList = async (ctx) => {
35
- const id = at(ctx, 'value_list');
36
- if (!ctx.row(VL, id, { withDeleted: true }))
37
- return listMissing(ctx, id);
38
- return ctx.reply(await ctx.write(VL, id, ctx.params, 'radar.value_list.updated'));
39
- };
40
- const deleteList = async (ctx) => {
41
- const id = at(ctx, 'value_list');
42
- if (!ctx.row(VL, id, { withDeleted: true }))
43
- return listMissing(ctx, id);
44
- await ctx.write(VL, id, { deleted: true }, 'radar.value_list.deleted');
45
- return ctx.reply({ id, object: 'radar.value_list', deleted: true });
46
- };
47
- const addItem = async (ctx) => {
1
+ import { VL, VLI } from "../engine/radar.js";
2
+ import { created, fail, listMissing, radarSyncItems } from "./shared.js";
3
+ export async function PostRadarValueListItems(ctx) {
48
4
  const listId = typeof ctx.params.value_list === 'string' ? ctx.params.value_list : '';
49
5
  if (!listId)
50
6
  return fail(ctx, 'Missing required param: value_list.', 400, 'parameter_missing');
@@ -53,31 +9,6 @@ const addItem = async (ctx) => {
53
9
  if (ctx.params.value === undefined || ctx.params.value === '')
54
10
  return fail(ctx, 'Missing required param: value.', 400, 'parameter_missing');
55
11
  const item = await created(ctx, VLI, { value_list: listId, value: ctx.params.value }, { livemode: false, created_by: 'twin' });
56
- await syncItems(ctx, listId);
12
+ await radarSyncItems(ctx, listId);
57
13
  return ctx.reply(item);
58
- };
59
- const items = async (ctx) => {
60
- const listId = typeof ctx.params.value_list === 'string' ? ctx.params.value_list : '';
61
- if (!listId)
62
- return fail(ctx, 'Missing required param: value_list.', 400, 'parameter_missing');
63
- return list(ctx, VLI, newest(ctx, VLI).filter((i) => i.value_list === listId));
64
- };
65
- const removeItem = async (ctx) => {
66
- const id = at(ctx, 'item');
67
- const was = ctx.row(VLI, id, { withDeleted: true });
68
- if (!was)
69
- return fail(ctx, `No such radar value list item: '${id}'`, 404, 'resource_missing');
70
- await ctx.write(VLI, id, { deleted: true }, 'radar.value_list_item.deleted');
71
- if (typeof was.value_list === 'string' && ctx.get(VL, was.value_list))
72
- await syncItems(ctx, was.value_list);
73
- return ctx.reply({ id, object: 'radar.value_list_item', deleted: true });
74
- };
75
- export const radar = {
76
- PostReviewsReviewApprove: approve,
77
- PostRadarValueLists: createList,
78
- PostRadarValueListsValueList: updateList,
79
- DeleteRadarValueListsValueList: deleteList,
80
- PostRadarValueListItems: addItem,
81
- GetRadarValueListItems: items,
82
- DeleteRadarValueListItemsItem: removeItem,
83
- };
14
+ }
@@ -1,9 +1,2 @@
1
- import type { Semantics, SemanticsContext } from '@volter/world-core';
2
- import { type Row } from './shared.js';
3
- export declare function refundCharge(ctx: SemanticsContext, charge: Row, params: Row): Promise<Response>;
4
- /** Time's settling of held refunds, caught up to the World's clock: each refund held for want of balance, oldest first,
5
- * is made at the first moment the account's available balance covers it (the funds that come due then), its debit
6
- * written then, as `refund.updated`. Where the documentation stops and the twin decides: a held refund is made the
7
- * moment the balance covers it. */
8
- export declare function settleHeldRefunds(ctx: SemanticsContext): Promise<void>;
9
- export declare const refunds: Record<string, Semantics>;
1
+ import { type HandlerContext } from '@volter/world-core';
2
+ export declare function PostRefunds(ctx: HandlerContext): Promise<Response>;