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.
- package/api/dev.ts +41 -2
- package/api/hono.d.ts +42 -0
- package/api/node-sqlite.d.ts +12 -0
- package/api/src/bootstrap.ts +47 -0
- package/api/src/crons/base.ts +3 -3
- package/api/src/crons/currency.ts +1 -1
- package/api/src/crons/index.ts +41 -37
- package/api/src/crons/metering-subscription-detection.ts +1 -1
- package/api/src/crons/overdue-detection.ts +2 -2
- package/api/src/crons/retry-pending-events.ts +6 -0
- package/api/src/crons/tenant-fanout.ts +82 -0
- package/api/src/host-node/did-connect-runtime-node.ts +33 -0
- package/api/src/host-node/serve-static-arc.ts +68 -0
- package/api/src/host-node/serve-static.ts +41 -0
- package/api/src/index.ts +22 -161
- package/api/src/integrations/app-store/client.ts +3 -4
- package/api/src/integrations/app-store/handlers/subscription.ts +7 -7
- package/api/src/integrations/app-store/signed-data-verifier.ts +3 -2
- package/api/src/integrations/arcblock/token.ts +21 -7
- package/api/src/integrations/google-play/handlers/subscription.ts +6 -6
- package/api/src/integrations/google-play/handlers/voided.ts +2 -2
- package/api/src/integrations/google-play/verify.ts +3 -2
- package/api/src/integrations/iap-reconcile.ts +3 -5
- package/api/src/integrations/stripe/handlers/invoice.ts +2 -2
- package/api/src/integrations/stripe/handlers/subscription.ts +3 -3
- package/api/src/libs/archive/query.ts +19 -0
- package/api/src/libs/audit.ts +61 -4
- package/api/src/libs/auth.ts +247 -47
- package/api/src/libs/context.ts +89 -1
- package/api/src/libs/currency.ts +2 -2
- package/api/src/libs/dayjs.ts +8 -2
- package/api/src/libs/did-connect/runtime-did-connect-js.ts +88 -0
- package/api/src/libs/did-connect/tenant-identity.ts +221 -0
- package/api/src/libs/drivers/auth-storage.ts +118 -0
- package/api/src/libs/drivers/cron.ts +264 -0
- package/api/src/libs/drivers/db.ts +170 -0
- package/api/src/libs/drivers/identity.ts +142 -0
- package/api/src/libs/drivers/index.ts +40 -0
- package/api/src/libs/drivers/locks.ts +226 -0
- package/api/src/libs/drivers/migrate-runner.ts +70 -0
- package/api/src/libs/drivers/queue.ts +104 -0
- package/api/src/libs/drivers/secrets.ts +194 -0
- package/api/src/libs/env.ts +170 -54
- package/api/src/libs/exchange-rate/service.ts +7 -6
- package/api/src/libs/http-fetch-adapter.ts +60 -0
- package/api/src/libs/invoice.ts +1 -1
- package/api/src/libs/lock.ts +51 -47
- package/api/src/libs/logger.ts +48 -8
- package/api/src/libs/notification/index.ts +1 -1
- package/api/src/libs/notification/template/customer-credit-low-balance.ts +2 -1
- package/api/src/libs/notification/template/customer-revenue-succeeded.ts +1 -1
- package/api/src/libs/notification/template/customer-reward-succeeded.ts +1 -1
- package/api/src/libs/overdraft-protection.ts +1 -1
- package/api/src/libs/payout.ts +1 -1
- package/api/src/libs/queue/index.ts +271 -52
- package/api/src/libs/queue/runtime.ts +175 -0
- package/api/src/libs/resource.ts +3 -3
- package/api/src/libs/secrets.ts +38 -0
- package/api/src/libs/session.ts +3 -2
- package/api/src/libs/subscription.ts +5 -5
- package/api/src/libs/tenant.ts +92 -0
- package/api/src/libs/url.ts +3 -3
- package/api/src/libs/util.ts +21 -13
- package/api/src/middlewares/hono/cdn.ts +63 -0
- package/api/src/middlewares/hono/context.ts +80 -0
- package/api/src/middlewares/hono/csrf.ts +83 -0
- package/api/src/middlewares/hono/fallback.ts +194 -0
- package/api/src/middlewares/hono/pipeline.ts +73 -0
- package/api/src/middlewares/hono/resource-mount.ts +42 -0
- package/api/src/middlewares/hono/resource.ts +63 -0
- package/api/src/middlewares/hono/security.ts +209 -0
- package/api/src/middlewares/hono/session.ts +114 -0
- package/api/src/middlewares/hono/xss.ts +61 -0
- package/api/src/queues/auto-recharge.ts +12 -10
- package/api/src/queues/checkout-session.ts +38 -21
- package/api/src/queues/credit-consume.ts +40 -36
- package/api/src/queues/credit-grant.ts +25 -18
- package/api/src/queues/credit-reconciliation.ts +7 -5
- package/api/src/queues/discount-status.ts +9 -6
- package/api/src/queues/event.ts +41 -11
- package/api/src/queues/exchange-rate-health.ts +49 -30
- package/api/src/queues/invoice.ts +18 -15
- package/api/src/queues/notification.ts +14 -7
- package/api/src/queues/payment.ts +64 -37
- package/api/src/queues/payout.ts +37 -21
- package/api/src/queues/refund.ts +36 -18
- package/api/src/queues/subscription.ts +83 -53
- package/api/src/queues/token-transfer.ts +15 -10
- package/api/src/queues/usage-record.ts +8 -5
- package/api/src/queues/vendors/commission.ts +7 -5
- package/api/src/queues/vendors/fulfillment-coordinator.ts +17 -13
- package/api/src/queues/vendors/fulfillment.ts +4 -2
- package/api/src/queues/vendors/return-processor.ts +5 -3
- package/api/src/queues/vendors/return-scanner.ts +5 -4
- package/api/src/queues/vendors/status-check.ts +10 -7
- package/api/src/queues/webhook.ts +60 -32
- package/api/src/routes/connect/shared.ts +1 -2
- package/api/src/routes/connect/subscribe.ts +3 -3
- package/api/src/routes/{archive.ts → hono/archive.ts} +69 -64
- package/api/src/routes/{auto-recharge-configs.ts → hono/auto-recharge-configs.ts} +39 -28
- package/api/src/routes/{checkout-sessions.ts → hono/checkout-sessions.ts} +790 -923
- package/api/src/routes/{coupons.ts → hono/coupons.ts} +93 -76
- package/api/src/routes/{credit-grants.ts → hono/credit-grants.ts} +140 -126
- package/api/src/routes/hono/credit-tokens.ts +43 -0
- package/api/src/routes/{credit-transactions.ts → hono/credit-transactions.ts} +37 -29
- package/api/src/routes/{customers.ts → hono/customers.ts} +199 -224
- package/api/src/routes/{donations.ts → hono/donations.ts} +41 -32
- package/api/src/routes/{entitlements.ts → hono/entitlements.ts} +28 -25
- package/api/src/routes/{events.ts → hono/events.ts} +107 -71
- package/api/src/routes/{exchange-rate-providers.ts → hono/exchange-rate-providers.ts} +138 -126
- package/api/src/routes/hono/exchange-rates.ts +77 -0
- package/api/src/routes/hono/index.ts +115 -0
- package/api/src/routes/{integrations → hono/integrations}/app-store.ts +68 -48
- package/api/src/routes/{integrations → hono/integrations}/google-play.ts +78 -58
- package/api/src/routes/hono/integrations/stripe.ts +74 -0
- package/api/src/routes/{invoices.ts → hono/invoices.ts} +253 -244
- package/api/src/routes/{meter-events.ts → hono/meter-events.ts} +120 -110
- package/api/src/routes/hono/meters.ts +288 -0
- package/api/src/routes/hono/passports.ts +73 -0
- package/api/src/routes/{payment-currencies.ts → hono/payment-currencies.ts} +219 -197
- package/api/src/routes/{payment-intents.ts → hono/payment-intents.ts} +136 -132
- package/api/src/routes/{payment-links.ts → hono/payment-links.ts} +145 -128
- package/api/src/routes/{payment-methods.ts → hono/payment-methods.ts} +125 -93
- package/api/src/routes/{payment-stats.ts → hono/payment-stats.ts} +30 -25
- package/api/src/routes/{payouts.ts → hono/payouts.ts} +55 -47
- package/api/src/routes/{prices.ts → hono/prices.ts} +265 -242
- package/api/src/routes/{pricing-table.ts → hono/pricing-table.ts} +94 -87
- package/api/src/routes/{products.ts → hono/products.ts} +172 -159
- package/api/src/routes/{promotion-codes.ts → hono/promotion-codes.ts} +207 -185
- package/api/src/routes/hono/redirect.ts +24 -0
- package/api/src/routes/{refunds.ts → hono/refunds.ts} +98 -83
- package/api/src/routes/{settings.ts → hono/settings.ts} +64 -55
- package/api/src/routes/{subscription-items.ts → hono/subscription-items.ts} +64 -57
- package/api/src/routes/{subscriptions.ts → hono/subscriptions.ts} +475 -528
- package/api/src/routes/{tax-rates.ts → hono/tax-rates.ts} +71 -70
- package/api/src/routes/hono/tool.ts +69 -0
- package/api/src/routes/{usage-records.ts → hono/usage-records.ts} +47 -42
- package/api/src/routes/{vendor.ts → hono/vendor.ts} +315 -167
- package/api/src/routes/{webhook-attempts.ts → hono/webhook-attempts.ts} +17 -13
- package/api/src/routes/hono/webhook-endpoints.ts +126 -0
- package/api/src/service.ts +814 -0
- package/api/src/store/migrations/20230911-seeding.ts +2 -1
- package/api/src/store/migrations/20260609-remove-did-space-jobs.ts +23 -0
- package/api/src/store/migrations/20260610-tenant-columns.ts +40 -0
- package/api/src/store/migrations/20260611-tenant-backfill.ts +33 -0
- package/api/src/store/models/auto-recharge-config.ts +22 -10
- package/api/src/store/models/checkout-session.ts +15 -14
- package/api/src/store/models/coupon.ts +29 -20
- package/api/src/store/models/credit-grant.ts +38 -29
- package/api/src/store/models/credit-transaction.ts +32 -21
- package/api/src/store/models/customer.ts +19 -17
- package/api/src/store/models/discount.ts +11 -2
- package/api/src/store/models/entitlement-grant.ts +21 -9
- package/api/src/store/models/entitlement-product.ts +21 -9
- package/api/src/store/models/entitlement.ts +19 -10
- package/api/src/store/models/event.ts +18 -9
- package/api/src/store/models/exchange-rate-provider.ts +17 -4
- package/api/src/store/models/invoice-item.ts +18 -9
- package/api/src/store/models/invoice.ts +16 -8
- package/api/src/store/models/meter-event.ts +27 -9
- package/api/src/store/models/meter.ts +31 -22
- package/api/src/store/models/payment-currency.ts +25 -8
- package/api/src/store/models/payment-intent.ts +15 -6
- package/api/src/store/models/payment-link.ts +15 -6
- package/api/src/store/models/payment-method.ts +38 -22
- package/api/src/store/models/payment-stat.ts +18 -9
- package/api/src/store/models/payout.ts +15 -6
- package/api/src/store/models/price-quote.ts +17 -8
- package/api/src/store/models/price.ts +24 -12
- package/api/src/store/models/pricing-table.ts +29 -20
- package/api/src/store/models/product-vendor.ts +20 -10
- package/api/src/store/models/product.ts +15 -6
- package/api/src/store/models/promotion-code.ts +14 -6
- package/api/src/store/models/refund.ts +15 -6
- package/api/src/store/models/revenue-snapshot.ts +21 -9
- package/api/src/store/models/setting.ts +18 -9
- package/api/src/store/models/setup-intent.ts +36 -27
- package/api/src/store/models/subscription-item.ts +21 -9
- package/api/src/store/models/subscription-schedule.ts +21 -9
- package/api/src/store/models/subscription.ts +21 -10
- package/api/src/store/models/tax-rate.ts +29 -21
- package/api/src/store/models/usage-record.ts +11 -2
- package/api/src/store/models/webhook-attempt.ts +18 -9
- package/api/src/store/models/webhook-endpoint.ts +18 -9
- package/api/src/store/scoped-core.ts +55 -0
- package/api/src/store/scoped.ts +247 -0
- package/api/src/store/sequelize.ts +82 -23
- package/api/src/store/sql-migrations.ts +20 -0
- package/api/src/store/tenant-backfill.ts +260 -0
- package/api/src/store/tenant-model.ts +124 -0
- package/api/src/store/tenant-tables.ts +50 -0
- package/api/tests/bootstrap/bootstrap.spec.ts +162 -0
- package/api/tests/crons/tenant-fanout.spec.ts +158 -0
- package/api/tests/embedded/embedded-multi-mode-d3.spec.ts +257 -0
- package/api/tests/fixtures/bare-query-violation.ts +13 -0
- package/api/tests/fixtures/core-env-violation.ts +10 -0
- package/api/tests/fixtures/host-read-violation.ts +19 -0
- package/api/tests/fixtures/tenants.ts +4 -0
- package/api/tests/integrations/iap-tenant.spec.ts +284 -0
- package/api/tests/libs/archive-query.spec.ts +26 -0
- package/api/tests/libs/audit-tenant.spec.ts +153 -0
- package/api/tests/libs/context.spec.ts +204 -0
- package/api/tests/libs/core-config.spec.ts +115 -0
- package/api/tests/libs/cron-driver-d2.spec.ts +237 -0
- package/api/tests/libs/crons-conservation-d2.spec.ts +52 -0
- package/api/tests/libs/did-connect-runtime-js.spec.ts +98 -0
- package/api/tests/libs/did-connect-tenant-identity.spec.ts +159 -0
- package/api/tests/libs/lock-tenant.spec.ts +66 -0
- package/api/tests/libs/scoped.spec.ts +222 -0
- package/api/tests/libs/secrets-facade.spec.ts +52 -0
- package/api/tests/libs/service-host.spec.ts +37 -0
- package/api/tests/libs/tenancy-slot-authority.spec.ts +209 -0
- package/api/tests/libs/tenant-middleware.spec.ts +42 -0
- package/api/tests/libs/tenant-scanner.spec.ts +120 -0
- package/api/tests/middlewares/hono/cdn.spec.ts +70 -0
- package/api/tests/middlewares/hono/context.spec.ts +113 -0
- package/api/tests/middlewares/hono/csrf.spec.ts +136 -0
- package/api/tests/middlewares/hono/fallback.spec.ts +67 -0
- package/api/tests/middlewares/hono/pipeline.spec.ts +47 -0
- package/api/tests/middlewares/hono/security.spec.ts +181 -0
- package/api/tests/middlewares/hono/session.spec.ts +42 -0
- package/api/tests/middlewares/hono/xss.spec.ts +81 -0
- package/api/tests/models/tenant-backfill.spec.ts +287 -0
- package/api/tests/models/tenant-columns-model.spec.ts +46 -0
- package/api/tests/models/tenant-columns.spec.ts +161 -0
- package/api/tests/queues/credit-consume-batch.spec.ts +8 -1
- package/api/tests/queues/credit-consume.spec.ts +8 -1
- package/api/tests/queues/event-tenant.spec.ts +292 -0
- package/api/tests/queues/exchange-rate-health-tenant-d6.spec.ts +62 -0
- package/api/tests/queues/queue-parity.spec.ts +249 -0
- package/api/tests/queues/queue-runtime-surface.spec.ts +277 -0
- package/api/tests/queues/queue-teardown-d2.spec.ts +127 -0
- package/api/tests/queues/tenant-matrix-a.spec.ts +245 -0
- package/api/tests/queues/tenant-matrix-b.spec.ts +168 -0
- package/api/tests/routes/connect/hono-attach.spec.ts +107 -0
- package/api/tests/service/collapse.spec.ts +96 -0
- package/api/tests/service/didconnect-storage-slot.spec.ts +60 -0
- package/api/tests/service/fail-closed-http.spec.ts +79 -0
- package/api/tests/service/static-arc-handler.spec.ts +101 -0
- package/api/tests/service/static-externalized.spec.ts +48 -0
- package/api/tests/store/tenant-crosscut.spec.ts +202 -0
- package/api/tests/store/tenant-model-spike.spec.ts +177 -0
- package/api/tests/store/tenant-model.spec.ts +162 -0
- package/api/tests/store/tenant-residual.spec.ts +196 -0
- package/api/third.d.ts +4 -0
- package/blocklet.yml +1 -1
- package/cloudflare/MIGRATION-RUNBOOK.md +3 -8
- package/cloudflare/README.md +34 -27
- package/cloudflare/STAGING-MIGRATION-GUIDE.md +3 -15
- package/cloudflare/build.ts +33 -13
- package/cloudflare/cf-adapter.ts +419 -0
- package/cloudflare/did-connect-runtime.ts +96 -0
- package/cloudflare/did-connect-token-storage.ts +151 -0
- package/cloudflare/esbuild-cf-config.cjs +407 -0
- package/cloudflare/migrations/0006_tenant_columns.sql +46 -0
- package/cloudflare/migrations/0007_tenant_backfill_indexes.sql +65 -0
- package/cloudflare/migrations/0008_schema_parity.sql +16 -0
- package/cloudflare/migrations/0009_remove_did_space_jobs.sql +5 -0
- package/cloudflare/queue-runtime-mode.ts +13 -0
- package/cloudflare/run-build.js +33 -403
- package/cloudflare/scripts/cf-package-import-probe.mjs +90 -0
- package/cloudflare/scripts/didconnect-mock-smoke.mjs +140 -0
- package/cloudflare/shims/blocklet-sdk/asset-host-transformer.ts +20 -0
- package/cloudflare/shims/blocklet-sdk/config.ts +8 -1
- package/cloudflare/shims/blocklet-sdk/login.ts +12 -0
- package/cloudflare/shims/blocklet-sdk/service-api.ts +14 -0
- package/cloudflare/shims/blocklet-sdk/session.ts +4 -2
- package/cloudflare/shims/blocklet-sdk/util-constants.ts +8 -0
- package/cloudflare/shims/blocklet-sdk/wallet-authenticator.ts +16 -1
- package/cloudflare/shims/blocklet-sdk/wallet-handler.ts +18 -3
- package/cloudflare/shims/cron.ts +38 -158
- package/cloudflare/shims/events.ts +124 -0
- package/cloudflare/shims/fastq.ts +15 -1
- package/cloudflare/shims/nedb-storage.ts +16 -8
- package/cloudflare/shims/xss.ts +8 -0
- package/cloudflare/tenant-middleware.ts +36 -0
- package/cloudflare/tests/cf-adapter.spec.ts +244 -0
- package/cloudflare/tests/did-connect-token-storage.spec.ts +105 -0
- package/cloudflare/tests/tenant-middleware.spec.ts +160 -0
- package/cloudflare/tests/worker-handler-gate.spec.ts +69 -0
- package/cloudflare/vite.config.ts +53 -45
- package/cloudflare/worker.ts +261 -448
- package/cloudflare/wrangler.json +0 -6
- package/cloudflare/wrangler.jsonc +0 -6
- package/cloudflare/wrangler.local-e2e.jsonc +25 -0
- package/cloudflare/wrangler.staging.json +0 -6
- package/jest.config.js +3 -1
- package/package.json +33 -38
- package/scripts/bootstrap-inject.ts +166 -0
- package/scripts/core-env-whitelist.json +1 -0
- package/scripts/e2e-12b-runtime.ts +149 -0
- package/scripts/e2e-core-config.ts +125 -0
- package/scripts/e2e-d1-tenancy.ts +116 -0
- package/scripts/e2e-d2-cron-queue.ts +139 -0
- package/scripts/e2e-d3-embedded-multi.ts +171 -0
- package/scripts/e2e-hono-s2.ts +125 -0
- package/scripts/e2e-hono-s3e.ts +135 -0
- package/scripts/e2e-hono-s4.ts +114 -0
- package/scripts/e2e-migration-contract.ts +100 -0
- package/scripts/e2e-s0.ts +61 -0
- package/scripts/e2e-s1.ts +107 -0
- package/scripts/e2e-s2.ts +178 -0
- package/scripts/e2e-s3.ts +110 -0
- package/scripts/e2e-s4.ts +191 -0
- package/scripts/e2e-s5.ts +139 -0
- package/scripts/e2e-s6.ts +127 -0
- package/scripts/e2e-tenant-model.ts +119 -0
- package/scripts/e2e-tenant-worker.ts +199 -0
- package/scripts/gen-sql-migrations.js +46 -0
- package/scripts/phase8-codemod.js +219 -0
- package/scripts/phase9a-env-getters-codemod.js +82 -0
- package/scripts/scan-core-env.js +109 -0
- package/scripts/scan-tenant-queries.js +235 -0
- package/scripts/schema-drift-guard.ts +210 -0
- package/scripts/tenant-scan-whitelist.json +1 -0
- package/src/app.tsx +2 -1
- package/src/env.d.ts +13 -1
- package/src/libs/service-host.ts +13 -0
- package/tsconfig.json +1 -1
- package/vite.arc.config.ts +159 -0
- package/api/src/libs/did-space.ts +0 -235
- package/api/src/libs/middleware.ts +0 -50
- package/api/src/libs/security.ts +0 -192
- package/api/src/queues/space.ts +0 -662
- package/api/src/routes/credit-tokens.ts +0 -38
- package/api/src/routes/exchange-rates.ts +0 -87
- package/api/src/routes/index.ts +0 -142
- package/api/src/routes/integrations/stripe.ts +0 -61
- package/api/src/routes/meters.ts +0 -274
- package/api/src/routes/passports.ts +0 -68
- package/api/src/routes/redirect.ts +0 -20
- package/api/src/routes/tool.ts +0 -65
- package/api/src/routes/webhook-endpoints.ts +0 -126
- package/api/tests/routes/credit-grants.spec.ts +0 -1261
- package/cloudflare/did-connect-auth.ts +0 -527
- package/cloudflare/shims/did-space-js.ts +0 -17
- package/cloudflare/shims/did-space.ts +0 -11
- package/cloudflare/shims/express-compat/index.ts +0 -80
- package/cloudflare/shims/express-compat/types.ts +0 -41
- package/cloudflare/shims/lock.ts +0 -115
- package/cloudflare/shims/queue.ts +0 -611
- package/cloudflare/tests/shims/queue-delayed-persist.spec.ts +0 -87
- 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 {
|
|
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 '
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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 '
|
|
27
|
-
import logger from '
|
|
28
|
-
import { getGasPayerExtra } from '
|
|
29
|
-
import { getRefundAmountSetup } from '
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
138
|
-
const
|
|
146
|
+
app.post('/', authAdmin, async (c) => {
|
|
147
|
+
const body = c.get('sanitizedBody') ?? {};
|
|
148
|
+
const { error } = refundRequestSchema.validate(body);
|
|
139
149
|
if (error) {
|
|
140
|
-
return
|
|
150
|
+
return c.json({ error: `Refund request invalid: ${error.message}` }, 400);
|
|
141
151
|
}
|
|
142
152
|
try {
|
|
143
|
-
const paymentCurrency = await PaymentCurrency.findByPk(
|
|
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(
|
|
157
|
+
const amount = fromTokenToUnit(body.amount, paymentCurrency?.decimal).toString();
|
|
148
158
|
const amountBN = new BN(amount);
|
|
149
159
|
const result = await getRefundAmountSetup({
|
|
150
|
-
paymentIntentId:
|
|
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(
|
|
166
|
+
const paymentMethod = await PaymentMethod.findByPk(body.payment_method_id);
|
|
157
167
|
if (!paymentMethod) {
|
|
158
|
-
throw new Error(`payment method not found: ${
|
|
168
|
+
throw new Error(`payment method not found: ${body.payment_method_id}`);
|
|
159
169
|
}
|
|
160
170
|
const item = await Refund.create({
|
|
161
|
-
...
|
|
171
|
+
...body,
|
|
162
172
|
type: 'refund',
|
|
163
|
-
livemode: !!
|
|
173
|
+
livemode: !!c.get('livemode'),
|
|
164
174
|
amount,
|
|
165
|
-
metadata: formatMetadata(
|
|
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.
|
|
178
|
-
...
|
|
187
|
+
...c.req.param(),
|
|
188
|
+
...body,
|
|
179
189
|
result: item.toJSON(),
|
|
180
|
-
requestedBy:
|
|
190
|
+
requestedBy: c.get('user')?.did,
|
|
181
191
|
});
|
|
182
|
-
|
|
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:
|
|
188
|
-
requestedBy:
|
|
197
|
+
requestBody: body,
|
|
198
|
+
requestedBy: c.get('user')?.did,
|
|
189
199
|
});
|
|
190
|
-
|
|
200
|
+
return c.json({ error: err.message }, 400);
|
|
191
201
|
}
|
|
192
202
|
});
|
|
193
203
|
|
|
194
|
-
|
|
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
|
-
|
|
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
|
-
|
|
444
|
-
const
|
|
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
|
|
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 } =
|
|
451
|
-
const { description, metadata, orderId, customerName } =
|
|
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
|
|
496
|
+
return c.json(existingRefund);
|
|
486
497
|
}
|
|
487
498
|
}
|
|
488
499
|
|
|
489
|
-
// Get system DID as default payer (发款方)
|
|
490
|
-
const systemDid =
|
|
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:
|
|
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:
|
|
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
|
|
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:
|
|
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:
|
|
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
|
|
649
|
-
|
|
650
|
-
|
|
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:
|
|
672
|
+
requestedBy: c.get('user')?.did,
|
|
659
673
|
});
|
|
660
|
-
return
|
|
674
|
+
return c.json({ error: err.message }, 400);
|
|
661
675
|
}
|
|
662
676
|
});
|
|
663
677
|
|
|
664
|
-
|
|
665
|
-
const doc = await Refund.findByPk(req.
|
|
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
|
|
693
|
+
return c.json({ ...doc.toJSON(), paymentMethod: paymentMethod?.toJSON() });
|
|
680
694
|
}
|
|
681
695
|
|
|
682
|
-
return
|
|
696
|
+
return c.json(null, 404);
|
|
683
697
|
});
|
|
684
698
|
|
|
685
699
|
// eslint-disable-next-line consistent-return
|
|
686
|
-
|
|
700
|
+
app.put('/:id', authAdmin, async (c) => {
|
|
687
701
|
try {
|
|
688
|
-
const
|
|
702
|
+
const body = c.get('sanitizedBody') ?? {};
|
|
703
|
+
const doc = await Refund.findByPk(c.req.param('id') as string);
|
|
689
704
|
if (!doc) {
|
|
690
|
-
return
|
|
705
|
+
return c.json({ error: 'Refund not found' }, 404);
|
|
691
706
|
}
|
|
692
707
|
|
|
693
|
-
const raw = pick(
|
|
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
|
|
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:
|
|
721
|
+
requestedBy: c.get('user')?.did,
|
|
707
722
|
});
|
|
708
|
-
|
|
723
|
+
return c.json(doc);
|
|
709
724
|
} catch (err) {
|
|
710
725
|
logger.error('Update refund failed', {
|
|
711
|
-
refundId: req.
|
|
726
|
+
refundId: c.req.param('id'),
|
|
712
727
|
error: err.message,
|
|
713
728
|
stack: err.stack,
|
|
714
|
-
requestBody:
|
|
715
|
-
requestedBy:
|
|
729
|
+
requestBody: c.get('sanitizedBody') ?? {},
|
|
730
|
+
requestedBy: c.get('user')?.did,
|
|
716
731
|
});
|
|
717
|
-
return
|
|
732
|
+
return c.json({ error: err.message }, 400);
|
|
718
733
|
}
|
|
719
734
|
});
|
|
720
735
|
|
|
721
|
-
|
|
722
|
-
const doc = await Refund.findByPk(req.
|
|
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
|
|
739
|
+
return c.json({ error: 'Refund not found' }, 404);
|
|
725
740
|
}
|
|
726
741
|
if (doc.status === 'succeeded') {
|
|
727
|
-
return
|
|
742
|
+
return c.json({ error: 'Refund is already succeeded' }, 400);
|
|
728
743
|
}
|
|
729
744
|
try {
|
|
730
745
|
await doc.update({ status: 'canceled' });
|
|
731
|
-
return
|
|
746
|
+
return c.json(doc);
|
|
732
747
|
} catch (err) {
|
|
733
748
|
logger.error('Cancel refund failed', {
|
|
734
|
-
refundId: req.
|
|
749
|
+
refundId: c.req.param('id'),
|
|
735
750
|
error: err.message,
|
|
736
|
-
requestedBy:
|
|
751
|
+
requestedBy: c.get('user')?.did,
|
|
737
752
|
});
|
|
738
|
-
return
|
|
753
|
+
return c.json({ error: err.message }, 400);
|
|
739
754
|
}
|
|
740
755
|
});
|
|
741
756
|
|
|
742
|
-
export default
|
|
757
|
+
export default app;
|