payment-kit 1.29.1 → 1.29.3

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 (343) hide show
  1. package/api/dev.ts +41 -2
  2. package/api/hono.d.ts +42 -0
  3. package/api/node-sqlite.d.ts +12 -0
  4. package/api/src/bootstrap.ts +47 -0
  5. package/api/src/crons/base.ts +3 -3
  6. package/api/src/crons/currency.ts +1 -1
  7. package/api/src/crons/index.ts +41 -37
  8. package/api/src/crons/metering-subscription-detection.ts +1 -1
  9. package/api/src/crons/overdue-detection.ts +2 -2
  10. package/api/src/crons/retry-pending-events.ts +6 -0
  11. package/api/src/crons/tenant-fanout.ts +82 -0
  12. package/api/src/host-node/did-connect-runtime-node.ts +33 -0
  13. package/api/src/host-node/serve-static-arc.ts +68 -0
  14. package/api/src/host-node/serve-static.ts +41 -0
  15. package/api/src/index.ts +22 -161
  16. package/api/src/integrations/app-store/client.ts +3 -4
  17. package/api/src/integrations/app-store/handlers/subscription.ts +7 -7
  18. package/api/src/integrations/app-store/signed-data-verifier.ts +3 -2
  19. package/api/src/integrations/arcblock/token.ts +21 -7
  20. package/api/src/integrations/google-play/handlers/subscription.ts +6 -6
  21. package/api/src/integrations/google-play/handlers/voided.ts +2 -2
  22. package/api/src/integrations/google-play/verify.ts +3 -2
  23. package/api/src/integrations/iap-reconcile.ts +3 -5
  24. package/api/src/integrations/stripe/handlers/invoice.ts +2 -2
  25. package/api/src/integrations/stripe/handlers/subscription.ts +3 -3
  26. package/api/src/libs/archive/query.ts +19 -0
  27. package/api/src/libs/audit.ts +61 -4
  28. package/api/src/libs/auth.ts +247 -47
  29. package/api/src/libs/context.ts +89 -1
  30. package/api/src/libs/currency.ts +2 -2
  31. package/api/src/libs/dayjs.ts +8 -2
  32. package/api/src/libs/did-connect/runtime-did-connect-js.ts +88 -0
  33. package/api/src/libs/did-connect/tenant-identity.ts +221 -0
  34. package/api/src/libs/drivers/auth-storage.ts +118 -0
  35. package/api/src/libs/drivers/cron.ts +264 -0
  36. package/api/src/libs/drivers/db.ts +170 -0
  37. package/api/src/libs/drivers/identity.ts +142 -0
  38. package/api/src/libs/drivers/index.ts +40 -0
  39. package/api/src/libs/drivers/locks.ts +226 -0
  40. package/api/src/libs/drivers/migrate-runner.ts +70 -0
  41. package/api/src/libs/drivers/queue.ts +104 -0
  42. package/api/src/libs/drivers/secrets.ts +194 -0
  43. package/api/src/libs/env.ts +170 -54
  44. package/api/src/libs/exchange-rate/service.ts +7 -6
  45. package/api/src/libs/http-fetch-adapter.ts +60 -0
  46. package/api/src/libs/invoice.ts +1 -1
  47. package/api/src/libs/lock.ts +51 -47
  48. package/api/src/libs/logger.ts +48 -8
  49. package/api/src/libs/notification/index.ts +1 -1
  50. package/api/src/libs/notification/template/customer-credit-low-balance.ts +2 -1
  51. package/api/src/libs/notification/template/customer-revenue-succeeded.ts +1 -1
  52. package/api/src/libs/notification/template/customer-reward-succeeded.ts +1 -1
  53. package/api/src/libs/overdraft-protection.ts +1 -1
  54. package/api/src/libs/payout.ts +1 -1
  55. package/api/src/libs/queue/index.ts +271 -52
  56. package/api/src/libs/queue/runtime.ts +175 -0
  57. package/api/src/libs/resource.ts +3 -3
  58. package/api/src/libs/secrets.ts +38 -0
  59. package/api/src/libs/session.ts +3 -2
  60. package/api/src/libs/subscription.ts +5 -5
  61. package/api/src/libs/tenant.ts +92 -0
  62. package/api/src/libs/url.ts +3 -3
  63. package/api/src/libs/util.ts +21 -13
  64. package/api/src/middlewares/hono/cdn.ts +63 -0
  65. package/api/src/middlewares/hono/context.ts +80 -0
  66. package/api/src/middlewares/hono/csrf.ts +83 -0
  67. package/api/src/middlewares/hono/fallback.ts +194 -0
  68. package/api/src/middlewares/hono/pipeline.ts +73 -0
  69. package/api/src/middlewares/hono/resource-mount.ts +42 -0
  70. package/api/src/middlewares/hono/resource.ts +63 -0
  71. package/api/src/middlewares/hono/security.ts +209 -0
  72. package/api/src/middlewares/hono/session.ts +114 -0
  73. package/api/src/middlewares/hono/xss.ts +61 -0
  74. package/api/src/queues/auto-recharge.ts +12 -10
  75. package/api/src/queues/checkout-session.ts +38 -21
  76. package/api/src/queues/credit-consume.ts +40 -36
  77. package/api/src/queues/credit-grant.ts +25 -18
  78. package/api/src/queues/credit-reconciliation.ts +7 -5
  79. package/api/src/queues/discount-status.ts +9 -6
  80. package/api/src/queues/event.ts +41 -11
  81. package/api/src/queues/exchange-rate-health.ts +49 -30
  82. package/api/src/queues/invoice.ts +18 -15
  83. package/api/src/queues/notification.ts +14 -7
  84. package/api/src/queues/payment.ts +64 -37
  85. package/api/src/queues/payout.ts +37 -21
  86. package/api/src/queues/refund.ts +36 -18
  87. package/api/src/queues/subscription.ts +83 -53
  88. package/api/src/queues/token-transfer.ts +15 -10
  89. package/api/src/queues/usage-record.ts +8 -5
  90. package/api/src/queues/vendors/commission.ts +7 -5
  91. package/api/src/queues/vendors/fulfillment-coordinator.ts +17 -13
  92. package/api/src/queues/vendors/fulfillment.ts +4 -2
  93. package/api/src/queues/vendors/return-processor.ts +5 -3
  94. package/api/src/queues/vendors/return-scanner.ts +5 -4
  95. package/api/src/queues/vendors/status-check.ts +10 -7
  96. package/api/src/queues/webhook.ts +60 -32
  97. package/api/src/routes/connect/shared.ts +1 -2
  98. package/api/src/routes/connect/subscribe.ts +3 -3
  99. package/api/src/routes/{archive.ts → hono/archive.ts} +69 -64
  100. package/api/src/routes/{auto-recharge-configs.ts → hono/auto-recharge-configs.ts} +39 -28
  101. package/api/src/routes/{checkout-sessions.ts → hono/checkout-sessions.ts} +790 -923
  102. package/api/src/routes/{coupons.ts → hono/coupons.ts} +93 -76
  103. package/api/src/routes/{credit-grants.ts → hono/credit-grants.ts} +140 -126
  104. package/api/src/routes/hono/credit-tokens.ts +43 -0
  105. package/api/src/routes/{credit-transactions.ts → hono/credit-transactions.ts} +37 -29
  106. package/api/src/routes/{customers.ts → hono/customers.ts} +199 -224
  107. package/api/src/routes/{donations.ts → hono/donations.ts} +41 -32
  108. package/api/src/routes/{entitlements.ts → hono/entitlements.ts} +28 -25
  109. package/api/src/routes/{events.ts → hono/events.ts} +107 -71
  110. package/api/src/routes/{exchange-rate-providers.ts → hono/exchange-rate-providers.ts} +138 -126
  111. package/api/src/routes/hono/exchange-rates.ts +77 -0
  112. package/api/src/routes/hono/index.ts +115 -0
  113. package/api/src/routes/{integrations → hono/integrations}/app-store.ts +68 -48
  114. package/api/src/routes/{integrations → hono/integrations}/google-play.ts +78 -58
  115. package/api/src/routes/hono/integrations/stripe.ts +74 -0
  116. package/api/src/routes/{invoices.ts → hono/invoices.ts} +253 -244
  117. package/api/src/routes/{meter-events.ts → hono/meter-events.ts} +120 -110
  118. package/api/src/routes/hono/meters.ts +288 -0
  119. package/api/src/routes/hono/passports.ts +73 -0
  120. package/api/src/routes/{payment-currencies.ts → hono/payment-currencies.ts} +219 -197
  121. package/api/src/routes/{payment-intents.ts → hono/payment-intents.ts} +136 -132
  122. package/api/src/routes/{payment-links.ts → hono/payment-links.ts} +145 -128
  123. package/api/src/routes/{payment-methods.ts → hono/payment-methods.ts} +125 -93
  124. package/api/src/routes/{payment-stats.ts → hono/payment-stats.ts} +30 -25
  125. package/api/src/routes/{payouts.ts → hono/payouts.ts} +55 -47
  126. package/api/src/routes/{prices.ts → hono/prices.ts} +265 -242
  127. package/api/src/routes/{pricing-table.ts → hono/pricing-table.ts} +94 -87
  128. package/api/src/routes/{products.ts → hono/products.ts} +172 -159
  129. package/api/src/routes/{promotion-codes.ts → hono/promotion-codes.ts} +207 -185
  130. package/api/src/routes/hono/redirect.ts +24 -0
  131. package/api/src/routes/{refunds.ts → hono/refunds.ts} +98 -83
  132. package/api/src/routes/{settings.ts → hono/settings.ts} +64 -55
  133. package/api/src/routes/{subscription-items.ts → hono/subscription-items.ts} +64 -57
  134. package/api/src/routes/{subscriptions.ts → hono/subscriptions.ts} +475 -528
  135. package/api/src/routes/{tax-rates.ts → hono/tax-rates.ts} +71 -70
  136. package/api/src/routes/hono/tool.ts +69 -0
  137. package/api/src/routes/{usage-records.ts → hono/usage-records.ts} +47 -42
  138. package/api/src/routes/{vendor.ts → hono/vendor.ts} +315 -167
  139. package/api/src/routes/{webhook-attempts.ts → hono/webhook-attempts.ts} +17 -13
  140. package/api/src/routes/hono/webhook-endpoints.ts +126 -0
  141. package/api/src/service.ts +814 -0
  142. package/api/src/store/migrations/20230911-seeding.ts +2 -1
  143. package/api/src/store/migrations/20260609-remove-did-space-jobs.ts +23 -0
  144. package/api/src/store/migrations/20260610-tenant-columns.ts +40 -0
  145. package/api/src/store/migrations/20260611-tenant-backfill.ts +33 -0
  146. package/api/src/store/models/auto-recharge-config.ts +22 -10
  147. package/api/src/store/models/checkout-session.ts +15 -14
  148. package/api/src/store/models/coupon.ts +29 -20
  149. package/api/src/store/models/credit-grant.ts +38 -29
  150. package/api/src/store/models/credit-transaction.ts +32 -21
  151. package/api/src/store/models/customer.ts +19 -17
  152. package/api/src/store/models/discount.ts +11 -2
  153. package/api/src/store/models/entitlement-grant.ts +21 -9
  154. package/api/src/store/models/entitlement-product.ts +21 -9
  155. package/api/src/store/models/entitlement.ts +19 -10
  156. package/api/src/store/models/event.ts +18 -9
  157. package/api/src/store/models/exchange-rate-provider.ts +17 -4
  158. package/api/src/store/models/invoice-item.ts +18 -9
  159. package/api/src/store/models/invoice.ts +16 -8
  160. package/api/src/store/models/meter-event.ts +27 -9
  161. package/api/src/store/models/meter.ts +31 -22
  162. package/api/src/store/models/payment-currency.ts +25 -8
  163. package/api/src/store/models/payment-intent.ts +15 -6
  164. package/api/src/store/models/payment-link.ts +15 -6
  165. package/api/src/store/models/payment-method.ts +38 -22
  166. package/api/src/store/models/payment-stat.ts +18 -9
  167. package/api/src/store/models/payout.ts +15 -6
  168. package/api/src/store/models/price-quote.ts +17 -8
  169. package/api/src/store/models/price.ts +24 -12
  170. package/api/src/store/models/pricing-table.ts +29 -20
  171. package/api/src/store/models/product-vendor.ts +20 -10
  172. package/api/src/store/models/product.ts +15 -6
  173. package/api/src/store/models/promotion-code.ts +14 -6
  174. package/api/src/store/models/refund.ts +15 -6
  175. package/api/src/store/models/revenue-snapshot.ts +21 -9
  176. package/api/src/store/models/setting.ts +18 -9
  177. package/api/src/store/models/setup-intent.ts +36 -27
  178. package/api/src/store/models/subscription-item.ts +21 -9
  179. package/api/src/store/models/subscription-schedule.ts +21 -9
  180. package/api/src/store/models/subscription.ts +21 -10
  181. package/api/src/store/models/tax-rate.ts +29 -21
  182. package/api/src/store/models/usage-record.ts +11 -2
  183. package/api/src/store/models/webhook-attempt.ts +18 -9
  184. package/api/src/store/models/webhook-endpoint.ts +18 -9
  185. package/api/src/store/scoped-core.ts +55 -0
  186. package/api/src/store/scoped.ts +247 -0
  187. package/api/src/store/sequelize.ts +82 -23
  188. package/api/src/store/sql-migrations.ts +20 -0
  189. package/api/src/store/tenant-backfill.ts +260 -0
  190. package/api/src/store/tenant-model.ts +124 -0
  191. package/api/src/store/tenant-tables.ts +50 -0
  192. package/api/tests/bootstrap/bootstrap.spec.ts +162 -0
  193. package/api/tests/crons/tenant-fanout.spec.ts +158 -0
  194. package/api/tests/embedded/embedded-multi-mode-d3.spec.ts +257 -0
  195. package/api/tests/fixtures/bare-query-violation.ts +13 -0
  196. package/api/tests/fixtures/core-env-violation.ts +10 -0
  197. package/api/tests/fixtures/host-read-violation.ts +19 -0
  198. package/api/tests/fixtures/tenants.ts +4 -0
  199. package/api/tests/integrations/iap-tenant.spec.ts +284 -0
  200. package/api/tests/libs/archive-query.spec.ts +26 -0
  201. package/api/tests/libs/audit-tenant.spec.ts +153 -0
  202. package/api/tests/libs/context.spec.ts +204 -0
  203. package/api/tests/libs/core-config.spec.ts +115 -0
  204. package/api/tests/libs/cron-driver-d2.spec.ts +237 -0
  205. package/api/tests/libs/crons-conservation-d2.spec.ts +52 -0
  206. package/api/tests/libs/did-connect-runtime-js.spec.ts +98 -0
  207. package/api/tests/libs/did-connect-tenant-identity.spec.ts +159 -0
  208. package/api/tests/libs/lock-tenant.spec.ts +66 -0
  209. package/api/tests/libs/scoped.spec.ts +222 -0
  210. package/api/tests/libs/secrets-facade.spec.ts +52 -0
  211. package/api/tests/libs/service-host.spec.ts +37 -0
  212. package/api/tests/libs/tenancy-slot-authority.spec.ts +209 -0
  213. package/api/tests/libs/tenant-middleware.spec.ts +42 -0
  214. package/api/tests/libs/tenant-scanner.spec.ts +120 -0
  215. package/api/tests/middlewares/hono/cdn.spec.ts +70 -0
  216. package/api/tests/middlewares/hono/context.spec.ts +113 -0
  217. package/api/tests/middlewares/hono/csrf.spec.ts +136 -0
  218. package/api/tests/middlewares/hono/fallback.spec.ts +67 -0
  219. package/api/tests/middlewares/hono/pipeline.spec.ts +47 -0
  220. package/api/tests/middlewares/hono/security.spec.ts +181 -0
  221. package/api/tests/middlewares/hono/session.spec.ts +42 -0
  222. package/api/tests/middlewares/hono/xss.spec.ts +81 -0
  223. package/api/tests/models/tenant-backfill.spec.ts +287 -0
  224. package/api/tests/models/tenant-columns-model.spec.ts +46 -0
  225. package/api/tests/models/tenant-columns.spec.ts +161 -0
  226. package/api/tests/queues/credit-consume-batch.spec.ts +8 -1
  227. package/api/tests/queues/credit-consume.spec.ts +8 -1
  228. package/api/tests/queues/event-tenant.spec.ts +292 -0
  229. package/api/tests/queues/exchange-rate-health-tenant-d6.spec.ts +62 -0
  230. package/api/tests/queues/queue-parity.spec.ts +249 -0
  231. package/api/tests/queues/queue-runtime-surface.spec.ts +277 -0
  232. package/api/tests/queues/queue-teardown-d2.spec.ts +127 -0
  233. package/api/tests/queues/tenant-matrix-a.spec.ts +245 -0
  234. package/api/tests/queues/tenant-matrix-b.spec.ts +168 -0
  235. package/api/tests/routes/connect/hono-attach.spec.ts +107 -0
  236. package/api/tests/service/collapse.spec.ts +96 -0
  237. package/api/tests/service/didconnect-storage-slot.spec.ts +60 -0
  238. package/api/tests/service/fail-closed-http.spec.ts +79 -0
  239. package/api/tests/service/static-arc-handler.spec.ts +101 -0
  240. package/api/tests/service/static-externalized.spec.ts +48 -0
  241. package/api/tests/store/tenant-crosscut.spec.ts +202 -0
  242. package/api/tests/store/tenant-model-spike.spec.ts +177 -0
  243. package/api/tests/store/tenant-model.spec.ts +162 -0
  244. package/api/tests/store/tenant-residual.spec.ts +196 -0
  245. package/api/third.d.ts +4 -0
  246. package/blocklet.yml +1 -1
  247. package/cloudflare/MIGRATION-RUNBOOK.md +3 -8
  248. package/cloudflare/README.md +34 -27
  249. package/cloudflare/STAGING-MIGRATION-GUIDE.md +3 -15
  250. package/cloudflare/build.ts +33 -13
  251. package/cloudflare/cf-adapter.ts +419 -0
  252. package/cloudflare/did-connect-runtime.ts +96 -0
  253. package/cloudflare/did-connect-token-storage.ts +151 -0
  254. package/cloudflare/esbuild-cf-config.cjs +407 -0
  255. package/cloudflare/migrations/0006_tenant_columns.sql +46 -0
  256. package/cloudflare/migrations/0007_tenant_backfill_indexes.sql +65 -0
  257. package/cloudflare/migrations/0008_schema_parity.sql +16 -0
  258. package/cloudflare/migrations/0009_remove_did_space_jobs.sql +5 -0
  259. package/cloudflare/queue-runtime-mode.ts +13 -0
  260. package/cloudflare/run-build.js +33 -403
  261. package/cloudflare/scripts/cf-package-import-probe.mjs +90 -0
  262. package/cloudflare/scripts/didconnect-mock-smoke.mjs +140 -0
  263. package/cloudflare/shims/blocklet-sdk/asset-host-transformer.ts +20 -0
  264. package/cloudflare/shims/blocklet-sdk/config.ts +8 -1
  265. package/cloudflare/shims/blocklet-sdk/login.ts +12 -0
  266. package/cloudflare/shims/blocklet-sdk/service-api.ts +14 -0
  267. package/cloudflare/shims/blocklet-sdk/session.ts +4 -2
  268. package/cloudflare/shims/blocklet-sdk/util-constants.ts +8 -0
  269. package/cloudflare/shims/blocklet-sdk/wallet-authenticator.ts +16 -1
  270. package/cloudflare/shims/blocklet-sdk/wallet-handler.ts +18 -3
  271. package/cloudflare/shims/cron.ts +38 -158
  272. package/cloudflare/shims/events.ts +124 -0
  273. package/cloudflare/shims/fastq.ts +15 -1
  274. package/cloudflare/shims/nedb-storage.ts +16 -8
  275. package/cloudflare/shims/xss.ts +8 -0
  276. package/cloudflare/tenant-middleware.ts +36 -0
  277. package/cloudflare/tests/cf-adapter.spec.ts +244 -0
  278. package/cloudflare/tests/did-connect-token-storage.spec.ts +105 -0
  279. package/cloudflare/tests/tenant-middleware.spec.ts +160 -0
  280. package/cloudflare/tests/worker-handler-gate.spec.ts +69 -0
  281. package/cloudflare/vite.config.ts +53 -45
  282. package/cloudflare/worker.ts +261 -448
  283. package/cloudflare/wrangler.json +0 -6
  284. package/cloudflare/wrangler.jsonc +0 -6
  285. package/cloudflare/wrangler.local-e2e.jsonc +25 -0
  286. package/cloudflare/wrangler.staging.json +0 -6
  287. package/jest.config.js +3 -1
  288. package/package.json +33 -38
  289. package/scripts/bootstrap-inject.ts +166 -0
  290. package/scripts/core-env-whitelist.json +1 -0
  291. package/scripts/e2e-12b-runtime.ts +149 -0
  292. package/scripts/e2e-core-config.ts +125 -0
  293. package/scripts/e2e-d1-tenancy.ts +116 -0
  294. package/scripts/e2e-d2-cron-queue.ts +139 -0
  295. package/scripts/e2e-d3-embedded-multi.ts +171 -0
  296. package/scripts/e2e-hono-s2.ts +125 -0
  297. package/scripts/e2e-hono-s3e.ts +135 -0
  298. package/scripts/e2e-hono-s4.ts +114 -0
  299. package/scripts/e2e-migration-contract.ts +100 -0
  300. package/scripts/e2e-s0.ts +61 -0
  301. package/scripts/e2e-s1.ts +107 -0
  302. package/scripts/e2e-s2.ts +178 -0
  303. package/scripts/e2e-s3.ts +110 -0
  304. package/scripts/e2e-s4.ts +191 -0
  305. package/scripts/e2e-s5.ts +139 -0
  306. package/scripts/e2e-s6.ts +127 -0
  307. package/scripts/e2e-tenant-model.ts +119 -0
  308. package/scripts/e2e-tenant-worker.ts +199 -0
  309. package/scripts/gen-sql-migrations.js +46 -0
  310. package/scripts/phase8-codemod.js +219 -0
  311. package/scripts/phase9a-env-getters-codemod.js +82 -0
  312. package/scripts/scan-core-env.js +109 -0
  313. package/scripts/scan-tenant-queries.js +235 -0
  314. package/scripts/schema-drift-guard.ts +210 -0
  315. package/scripts/tenant-scan-whitelist.json +1 -0
  316. package/src/app.tsx +2 -1
  317. package/src/env.d.ts +13 -1
  318. package/src/libs/service-host.ts +13 -0
  319. package/tsconfig.json +1 -1
  320. package/vite.arc.config.ts +159 -0
  321. package/api/src/libs/did-space.ts +0 -235
  322. package/api/src/libs/middleware.ts +0 -50
  323. package/api/src/libs/security.ts +0 -192
  324. package/api/src/queues/space.ts +0 -662
  325. package/api/src/routes/credit-tokens.ts +0 -38
  326. package/api/src/routes/exchange-rates.ts +0 -87
  327. package/api/src/routes/index.ts +0 -142
  328. package/api/src/routes/integrations/stripe.ts +0 -61
  329. package/api/src/routes/meters.ts +0 -274
  330. package/api/src/routes/passports.ts +0 -68
  331. package/api/src/routes/redirect.ts +0 -20
  332. package/api/src/routes/tool.ts +0 -65
  333. package/api/src/routes/webhook-endpoints.ts +0 -126
  334. package/api/tests/routes/credit-grants.spec.ts +0 -1261
  335. package/cloudflare/did-connect-auth.ts +0 -527
  336. package/cloudflare/shims/did-space-js.ts +0 -17
  337. package/cloudflare/shims/did-space.ts +0 -11
  338. package/cloudflare/shims/express-compat/index.ts +0 -80
  339. package/cloudflare/shims/express-compat/types.ts +0 -41
  340. package/cloudflare/shims/lock.ts +0 -115
  341. package/cloudflare/shims/queue.ts +0 -611
  342. package/cloudflare/tests/shims/queue-delayed-persist.spec.ts +0 -87
  343. package/cloudflare/tests/shims/queue-scheduled.spec.ts +0 -186
@@ -1,20 +1,29 @@
1
+ // Phase 3 (express→hono) — hono fork of routes/refunds.ts. Sub-app with
2
+ // routes relative to /api/refunds (mounted via mountResourceGroup). The
3
+ // business logic is unchanged; only the express plumbing becomes hono:
4
+ // req.body → c.get('sanitizedBody') ?? {}; res.status(n).json(x) → c.json(x, n).
1
5
  /* eslint-disable no-console */
2
6
  /* eslint-disable consistent-return */
3
7
  import OcapClient from '@ocap/client';
4
8
  import { BN, fromTokenToUnit } from '@ocap/util';
5
9
  import { ethers } from 'ethers';
6
- import { Router } from 'express';
10
+ import { Hono } from 'hono';
7
11
  import Joi from 'joi';
8
12
  import pick from 'lodash/pick';
9
13
 
10
- import { getWallet } from '@blocklet/sdk/lib/wallet';
11
14
  import { Op } from 'sequelize';
12
- import { sendErc20ToUser } from '../integrations/ethereum/token';
13
- import { BNPositiveValidator, createListParamSchema, getOrder, getWhereFromKvQuery, MetadataSchema } from '../libs/api';
14
- import { wallet } from '../libs/auth';
15
- import { EVM_CHAIN_TYPES } from '../libs/constants';
16
- import { authenticate } from '../libs/security';
17
- import { formatMetadata } from '../libs/util';
15
+ import { sendErc20ToUser } from '../../integrations/ethereum/token';
16
+ import {
17
+ BNPositiveValidator,
18
+ createListParamSchema,
19
+ getOrder,
20
+ getWhereFromKvQuery,
21
+ MetadataSchema,
22
+ } from '../../libs/api';
23
+ import { wallet } from '../../libs/auth';
24
+ import { EVM_CHAIN_TYPES } from '../../libs/constants';
25
+ import { authenticate } from '../../middlewares/hono/security';
26
+ import { formatMetadata } from '../../libs/util';
18
27
  import {
19
28
  Customer,
20
29
  Invoice,
@@ -23,12 +32,12 @@ import {
23
32
  PaymentMethod,
24
33
  Refund,
25
34
  Subscription,
26
- } from '../store/models';
27
- import logger from '../libs/logger';
28
- import { getGasPayerExtra } from '../libs/payment';
29
- import { getRefundAmountSetup } from '../libs/refund';
35
+ } from '../../store/models';
36
+ import logger from '../../libs/logger';
37
+ import { getGasPayerExtra } from '../../libs/payment';
38
+ import { getRefundAmountSetup } from '../../libs/refund';
30
39
 
31
- const router = Router();
40
+ const app = new Hono();
32
41
  const authAdmin = authenticate<Invoice>({ component: true, roles: ['owner', 'admin'] });
33
42
  const auth = authenticate<Invoice>({
34
43
  component: true,
@@ -55,8 +64,8 @@ const paginationSchema = createListParamSchema<{
55
64
  subscription_id: Joi.string().empty(''),
56
65
  customer_id: Joi.string().empty(''),
57
66
  });
58
- router.get('/', auth, async (req, res) => {
59
- const { page, pageSize, livemode, status, ...query } = await paginationSchema.validateAsync(req.query, {
67
+ app.get('/', auth, async (c) => {
68
+ const { page, pageSize, livemode, status, ...query } = await paginationSchema.validateAsync(c.req.query(), {
60
69
  stripUnknown: false,
61
70
  allowUnknown: true,
62
71
  });
@@ -75,7 +84,7 @@ router.get('/', auth, async (req, res) => {
75
84
  }
76
85
 
77
86
  if (query.customer_id) {
78
- where.customer_id = query.customer_id;
87
+ where.customer_id = c.get('customer_id') ?? query.customer_id;
79
88
  }
80
89
 
81
90
  if (query.subscription_id) {
@@ -102,7 +111,7 @@ router.get('/', auth, async (req, res) => {
102
111
 
103
112
  const { rows: list, count } = await Refund.findAndCountAll({
104
113
  where,
105
- order: getOrder(req.query, [['created_at', query.o === 'asc' ? 'ASC' : 'DESC']]),
114
+ order: getOrder(c.req.query(), [['created_at', query.o === 'asc' ? 'ASC' : 'DESC']]),
106
115
  offset: (page - 1) * pageSize,
107
116
  limit: pageSize,
108
117
  include: [
@@ -116,7 +125,7 @@ router.get('/', auth, async (req, res) => {
116
125
  distinct: true,
117
126
  });
118
127
 
119
- res.json({ count, list, paging: { page, pageSize } });
128
+ return c.json({ count, list, paging: { page, pageSize } });
120
129
  });
121
130
 
122
131
  const searchSchema = createListParamSchema<{}>({});
@@ -134,35 +143,36 @@ const refundRequestSchema = Joi.object({
134
143
  invoice_id: Joi.string().optional(),
135
144
  subscription_id: Joi.string().optional(),
136
145
  });
137
- router.post('/', authAdmin, async (req, res) => {
138
- const { error } = refundRequestSchema.validate(req.body);
146
+ app.post('/', authAdmin, async (c) => {
147
+ const body = c.get('sanitizedBody') ?? {};
148
+ const { error } = refundRequestSchema.validate(body);
139
149
  if (error) {
140
- return res.status(400).json({ error: `Refund request invalid: ${error.message}` });
150
+ return c.json({ error: `Refund request invalid: ${error.message}` }, 400);
141
151
  }
142
152
  try {
143
- const paymentCurrency = await PaymentCurrency.findByPk(req.body.currency_id);
153
+ const paymentCurrency = await PaymentCurrency.findByPk(body.currency_id);
144
154
  if (!paymentCurrency) {
145
155
  throw new Error('payment currency not found');
146
156
  }
147
- const amount = fromTokenToUnit(req.body.amount, paymentCurrency?.decimal).toString();
157
+ const amount = fromTokenToUnit(body.amount, paymentCurrency?.decimal).toString();
148
158
  const amountBN = new BN(amount);
149
159
  const result = await getRefundAmountSetup({
150
- paymentIntentId: req.body.payment_intent_id,
160
+ paymentIntentId: body.payment_intent_id,
151
161
  });
152
162
  if (amountBN.gt(new BN(result.amount))) {
153
163
  throw new Error('refund amount exceeds the available amount');
154
164
  }
155
165
 
156
- const paymentMethod = await PaymentMethod.findByPk(req.body.payment_method_id);
166
+ const paymentMethod = await PaymentMethod.findByPk(body.payment_method_id);
157
167
  if (!paymentMethod) {
158
- throw new Error(`payment method not found: ${req.body.payment_method_id}`);
168
+ throw new Error(`payment method not found: ${body.payment_method_id}`);
159
169
  }
160
170
  const item = await Refund.create({
161
- ...req.body,
171
+ ...body,
162
172
  type: 'refund',
163
- livemode: !!req.livemode,
173
+ livemode: !!c.get('livemode'),
164
174
  amount,
165
- metadata: formatMetadata(req.body.metadata),
175
+ metadata: formatMetadata(body.metadata),
166
176
  attempt_count: 0,
167
177
  attempted: false,
168
178
  next_attempt: 0,
@@ -174,25 +184,25 @@ router.post('/', authAdmin, async (req, res) => {
174
184
  ending_token_balance: {},
175
185
  });
176
186
  logger.info('refund created', {
177
- ...req.params,
178
- ...req.body,
187
+ ...c.req.param(),
188
+ ...body,
179
189
  result: item.toJSON(),
180
- requestedBy: req.user?.did,
190
+ requestedBy: c.get('user')?.did,
181
191
  });
182
- res.json(item);
192
+ return c.json(item);
183
193
  } catch (err) {
184
194
  logger.error('Create refund failed', {
185
195
  error: err.message,
186
196
  stack: err.stack,
187
- requestBody: req.body,
188
- requestedBy: req.user?.did,
197
+ requestBody: body,
198
+ requestedBy: c.get('user')?.did,
189
199
  });
190
- res.status(400).json({ error: err.message });
200
+ return c.json({ error: err.message }, 400);
191
201
  }
192
202
  });
193
203
 
194
- router.get('/search', auth, async (req, res) => {
195
- const { page, pageSize, livemode, q, o } = await searchSchema.validateAsync(req.query, {
204
+ app.get('/search', auth, async (c) => {
205
+ const { page, pageSize, livemode, q, o } = await searchSchema.validateAsync(c.req.query(), {
196
206
  stripUnknown: false,
197
207
  allowUnknown: true,
198
208
  });
@@ -204,7 +214,7 @@ router.get('/search', auth, async (req, res) => {
204
214
 
205
215
  const { rows: list, count } = await Refund.findAndCountAll({
206
216
  where,
207
- order: getOrder(req.query, [['created_at', o === 'asc' ? 'ASC' : 'DESC']]),
217
+ order: getOrder(c.req.query(), [['created_at', o === 'asc' ? 'ASC' : 'DESC']]),
208
218
  offset: (page - 1) * pageSize,
209
219
  limit: pageSize,
210
220
  include: [
@@ -213,7 +223,7 @@ router.get('/search', auth, async (req, res) => {
213
223
  ],
214
224
  });
215
225
 
216
- res.json({ count, list, paging: { page, pageSize } });
226
+ return c.json({ count, list, paging: { page, pageSize } });
217
227
  });
218
228
 
219
229
  // Helper function: Query payment method and currency by contract and chain type
@@ -440,15 +450,16 @@ const syncRefundRequestSchema = Joi.object({
440
450
  metadata: MetadataSchema.optional(),
441
451
  });
442
452
 
443
- router.post('/sync', authAdmin, async (req: any, res: any) => {
444
- const { error } = syncRefundRequestSchema.validate(req.body);
453
+ app.post('/sync', authAdmin, async (c: any) => {
454
+ const body = c.get('sanitizedBody') ?? {};
455
+ const { error } = syncRefundRequestSchema.validate(body);
445
456
  if (error) {
446
- return res.status(400).json({ error: `Refund request invalid: ${error.message}` });
457
+ return c.json({ error: `Refund request invalid: ${error.message}` }, 400);
447
458
  }
448
459
 
449
460
  // Extract and validate request data
450
- const { livemode, amount, destination, contract, chainType, chainApiHost } = req.body;
451
- const { description, metadata, orderId, customerName } = req.body;
461
+ const { livemode, amount, destination, contract, chainType, chainApiHost } = body;
462
+ const { description, metadata, orderId, customerName } = body;
452
463
 
453
464
  try {
454
465
  // Convert and validate input types
@@ -482,12 +493,12 @@ router.post('/sync', authAdmin, async (req: any, res: any) => {
482
493
  status: existingRefund.status,
483
494
  });
484
495
 
485
- return res.json(existingRefund);
496
+ return c.json(existingRefund);
486
497
  }
487
498
  }
488
499
 
489
- // Get system DID as default payer (发款方)
490
- const systemDid = getWallet().address;
500
+ // Get system DID as default payer (发款方) — the active tenant's business wallet.
501
+ const systemDid = wallet.address;
491
502
 
492
503
  // Create mock customer if customerName is provided, otherwise use "Broker" as default
493
504
  const finalCustomerName = customerName || 'Broker';
@@ -568,7 +579,7 @@ router.post('/sync', authAdmin, async (req: any, res: any) => {
568
579
  destination,
569
580
  amount,
570
581
  chainType,
571
- requestedBy: req.user?.did,
582
+ requestedBy: c.get('user')?.did,
572
583
  });
573
584
 
574
585
  // Process transfer
@@ -594,7 +605,7 @@ router.post('/sync', authAdmin, async (req: any, res: any) => {
594
605
  logger.info('Synchronous refund transfer completed', {
595
606
  refundId: refund.id,
596
607
  txHash,
597
- requestedBy: req.user?.did,
608
+ requestedBy: c.get('user')?.did,
598
609
  });
599
610
 
600
611
  // Reload and enrich refund data
@@ -610,11 +621,11 @@ router.post('/sync', authAdmin, async (req: any, res: any) => {
610
621
  throw new Error('Refund not found after processing');
611
622
  }
612
623
 
613
- return res.json(updatedRefund.toJSON());
624
+ return c.json(updatedRefund.toJSON());
614
625
  } catch (processError: any) {
615
626
  logger.error('Synchronous refund transfer failed', {
616
627
  error: processError,
617
- requestedBy: req.user?.did,
628
+ requestedBy: c.get('user')?.did,
618
629
  });
619
630
  // Handle transfer failure
620
631
  await refund.update({
@@ -632,7 +643,7 @@ router.post('/sync', authAdmin, async (req: any, res: any) => {
632
643
  logger.error('Synchronous refund transfer failed', {
633
644
  refundId: refund.id,
634
645
  error: processError.message || processError.error?.message,
635
- requestedBy: req.user?.did,
646
+ requestedBy: c.get('user')?.did,
636
647
  });
637
648
 
638
649
  // Reload and enrich failed refund data
@@ -645,24 +656,27 @@ router.post('/sync', authAdmin, async (req: any, res: any) => {
645
656
  });
646
657
 
647
658
  if (failedRefund) {
648
- return res.status(400).json({
649
- ...failedRefund.toJSON(),
650
- error: processError.message || processError.error?.message || 'Refund transfer failed',
651
- });
659
+ return c.json(
660
+ {
661
+ ...failedRefund.toJSON(),
662
+ error: processError.message || processError.error?.message || 'Refund transfer failed',
663
+ },
664
+ 400
665
+ );
652
666
  }
653
667
  throw processError;
654
668
  }
655
669
  } catch (err: any) {
656
670
  logger.error('Create synchronous refund failed', {
657
671
  error: err,
658
- requestedBy: req.user?.did,
672
+ requestedBy: c.get('user')?.did,
659
673
  });
660
- return res.status(400).json({ error: err.message });
674
+ return c.json({ error: err.message }, 400);
661
675
  }
662
676
  });
663
677
 
664
- router.get('/:id', auth, async (req, res) => {
665
- const doc = await Refund.findByPk(req.params.id as string, {
678
+ app.get('/:id', auth, async (c) => {
679
+ const doc = await Refund.findByPk(c.req.param('id') as string, {
666
680
  include: [
667
681
  { model: Customer, as: 'customer' },
668
682
  { model: PaymentCurrency, as: 'paymentCurrency' },
@@ -676,25 +690,26 @@ router.get('/:id', auth, async (req, res) => {
676
690
  if (doc) {
677
691
  // @ts-ignore
678
692
  const paymentMethod = await PaymentMethod.findByPk(doc.paymentCurrency.payment_method_id);
679
- return res.json({ ...doc.toJSON(), paymentMethod: paymentMethod?.toJSON() });
693
+ return c.json({ ...doc.toJSON(), paymentMethod: paymentMethod?.toJSON() });
680
694
  }
681
695
 
682
- return res.status(404).json(null);
696
+ return c.json(null, 404);
683
697
  });
684
698
 
685
699
  // eslint-disable-next-line consistent-return
686
- router.put('/:id', authAdmin, async (req, res) => {
700
+ app.put('/:id', authAdmin, async (c) => {
687
701
  try {
688
- const doc = await Refund.findByPk(req.params.id as string);
702
+ const body = c.get('sanitizedBody') ?? {};
703
+ const doc = await Refund.findByPk(c.req.param('id') as string);
689
704
  if (!doc) {
690
- return res.status(404).json({ error: 'Refund not found' });
705
+ return c.json({ error: 'Refund not found' }, 404);
691
706
  }
692
707
 
693
- const raw = pick(req.body, ['metadata']);
708
+ const raw = pick(body, ['metadata']);
694
709
  if (raw.metadata) {
695
710
  const { error: metadataError } = MetadataSchema.validate(raw.metadata);
696
711
  if (metadataError) {
697
- return res.status(400).json({ error: `metadata invalid: ${metadataError.message}` });
712
+ return c.json({ error: `metadata invalid: ${metadataError.message}` }, 400);
698
713
  }
699
714
  raw.metadata = formatMetadata(raw.metadata);
700
715
  }
@@ -703,40 +718,40 @@ router.put('/:id', authAdmin, async (req, res) => {
703
718
  logger.info('Refund updated', {
704
719
  refundId: doc.id,
705
720
  updatedFields: Object.keys(raw),
706
- requestedBy: req.user?.did,
721
+ requestedBy: c.get('user')?.did,
707
722
  });
708
- res.json(doc);
723
+ return c.json(doc);
709
724
  } catch (err) {
710
725
  logger.error('Update refund failed', {
711
- refundId: req.params.id,
726
+ refundId: c.req.param('id'),
712
727
  error: err.message,
713
728
  stack: err.stack,
714
- requestBody: req.body,
715
- requestedBy: req.user?.did,
729
+ requestBody: c.get('sanitizedBody') ?? {},
730
+ requestedBy: c.get('user')?.did,
716
731
  });
717
- return res.status(400).json({ error: err.message });
732
+ return c.json({ error: err.message }, 400);
718
733
  }
719
734
  });
720
735
 
721
- router.post('/:id/cancel', authAdmin, async (req, res) => {
722
- const doc = await Refund.findByPk(req.params.id as string);
736
+ app.post('/:id/cancel', authAdmin, async (c) => {
737
+ const doc = await Refund.findByPk(c.req.param('id') as string);
723
738
  if (!doc) {
724
- return res.status(404).json({ error: 'Refund not found' });
739
+ return c.json({ error: 'Refund not found' }, 404);
725
740
  }
726
741
  if (doc.status === 'succeeded') {
727
- return res.status(400).json({ error: 'Refund is already succeeded' });
742
+ return c.json({ error: 'Refund is already succeeded' }, 400);
728
743
  }
729
744
  try {
730
745
  await doc.update({ status: 'canceled' });
731
- return res.json(doc);
746
+ return c.json(doc);
732
747
  } catch (err) {
733
748
  logger.error('Cancel refund failed', {
734
- refundId: req.params.id,
749
+ refundId: c.req.param('id'),
735
750
  error: err.message,
736
- requestedBy: req.user?.did,
751
+ requestedBy: c.get('user')?.did,
737
752
  });
738
- return res.status(400).json({ error: err.message });
753
+ return c.json({ error: err.message }, 400);
739
754
  }
740
755
  });
741
756
 
742
- export default router;
757
+ export default app;