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
package/api/src/queues/payout.ts
CHANGED
|
@@ -2,8 +2,9 @@ import dayjs from '../libs/dayjs';
|
|
|
2
2
|
import { events } from '../libs/event';
|
|
3
3
|
import logger from '../libs/logger';
|
|
4
4
|
import { getGasPayerExtra } from '../libs/payment';
|
|
5
|
-
import createQueue from '../libs/queue';
|
|
5
|
+
import createQueue, { assertJobObjectTenant } from '../libs/queue';
|
|
6
6
|
import { wallet, ethWallet } from '../libs/auth';
|
|
7
|
+
import { withTenant } from '../libs/context';
|
|
7
8
|
import { sendErc20ToUser } from '../integrations/ethereum/token';
|
|
8
9
|
import { PaymentMethod } from '../store/models/payment-method';
|
|
9
10
|
import { PaymentCurrency } from '../store/models/payment-currency';
|
|
@@ -11,6 +12,7 @@ import { Payout } from '../store/models/payout';
|
|
|
11
12
|
import { EVM_CHAIN_TYPES } from '../libs/constants';
|
|
12
13
|
import type { PaymentError } from '../store/models/types';
|
|
13
14
|
import { getNextRetry, MAX_RETRY_COUNT } from '../libs/util';
|
|
15
|
+
import { systemFindAll, systemFindByPk } from '../store/scoped';
|
|
14
16
|
|
|
15
17
|
type PayoutJob = {
|
|
16
18
|
payoutId: string;
|
|
@@ -23,28 +25,31 @@ type ValidationResult =
|
|
|
23
25
|
|
|
24
26
|
// Validate payout and fetch required data
|
|
25
27
|
async function validatePayoutAndFetchData(job: PayoutJob): Promise<ValidationResult> {
|
|
26
|
-
const payout = await Payout
|
|
28
|
+
const payout = await systemFindByPk(Payout, job.payoutId);
|
|
27
29
|
if (!payout) {
|
|
28
30
|
logger.warn('Payout not found', { id: job.payoutId });
|
|
29
31
|
return { valid: false };
|
|
30
32
|
}
|
|
33
|
+
assertJobObjectTenant(payout);
|
|
31
34
|
|
|
32
35
|
if (payout.status !== 'pending') {
|
|
33
36
|
logger.warn('Payout status not expected', { id: payout.id, status: payout.status });
|
|
34
37
|
return { valid: false };
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
const paymentMethod = await PaymentMethod
|
|
40
|
+
const paymentMethod = await systemFindByPk(PaymentMethod, payout.payment_method_id);
|
|
38
41
|
if (!paymentMethod) {
|
|
39
42
|
logger.warn('PaymentMethod not found', { id: payout.payment_method_id });
|
|
40
43
|
return { valid: false };
|
|
41
44
|
}
|
|
45
|
+
assertJobObjectTenant(paymentMethod);
|
|
42
46
|
|
|
43
|
-
const paymentCurrency = await PaymentCurrency
|
|
47
|
+
const paymentCurrency = await systemFindByPk(PaymentCurrency, payout.currency_id);
|
|
44
48
|
if (!paymentCurrency) {
|
|
45
49
|
logger.warn('PaymentCurrency not found', { id: payout.currency_id });
|
|
46
50
|
return { valid: false };
|
|
47
51
|
}
|
|
52
|
+
assertJobObjectTenant(paymentCurrency);
|
|
48
53
|
|
|
49
54
|
return {
|
|
50
55
|
valid: true,
|
|
@@ -234,30 +239,41 @@ payoutQueue.on('failed', ({ id, job, error }) => {
|
|
|
234
239
|
|
|
235
240
|
// Start queue, find all payouts with "pending" status
|
|
236
241
|
export const startPayoutQueue = async () => {
|
|
237
|
-
const payouts = await Payout
|
|
242
|
+
const payouts = await systemFindAll(Payout, {
|
|
238
243
|
where: {
|
|
239
244
|
status: 'pending',
|
|
240
245
|
},
|
|
241
246
|
});
|
|
242
247
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
248
|
+
// Per-record tenant context: queue push stamps the job tenant via getInstanceDid,
|
|
249
|
+
// which fails closed in multi mode without it. for-of + await (not forEach(async),
|
|
250
|
+
// which leaks an unhandledRejection → FATAL on boot); per-record catch isolates.
|
|
251
|
+
for (const payout of payouts) {
|
|
252
|
+
const dispatch = async () => {
|
|
253
|
+
const exist = await payoutQueue.get(payout.id);
|
|
254
|
+
if (!exist) {
|
|
255
|
+
// Use next attempt time if set
|
|
256
|
+
if (payout.next_attempt && payout.next_attempt > dayjs().unix()) {
|
|
257
|
+
payoutQueue.push({
|
|
258
|
+
id: payout.id,
|
|
259
|
+
job: { payoutId: payout.id, retryOnError: true },
|
|
260
|
+
runAt: payout.next_attempt,
|
|
261
|
+
});
|
|
262
|
+
} else {
|
|
263
|
+
payoutQueue.push({
|
|
264
|
+
id: payout.id,
|
|
265
|
+
job: { payoutId: payout.id, retryOnError: true },
|
|
266
|
+
});
|
|
267
|
+
}
|
|
258
268
|
}
|
|
269
|
+
};
|
|
270
|
+
try {
|
|
271
|
+
// eslint-disable-next-line no-await-in-loop
|
|
272
|
+
await (payout.instance_did ? withTenant(payout.instance_did, dispatch) : dispatch());
|
|
273
|
+
} catch (error) {
|
|
274
|
+
logger.error('startPayoutQueue: re-queue failed', { id: payout.id, error });
|
|
259
275
|
}
|
|
260
|
-
}
|
|
276
|
+
}
|
|
261
277
|
};
|
|
262
278
|
|
|
263
279
|
// Listen for newly created payouts
|
package/api/src/queues/refund.ts
CHANGED
|
@@ -3,11 +3,12 @@ import { isRefundReasonSupportedByStripe } from '../libs/refund';
|
|
|
3
3
|
import { checkRemainingStake, getSubscriptionStakeAddress } from '../libs/subscription';
|
|
4
4
|
import { sendErc20ToUser } from '../integrations/ethereum/token';
|
|
5
5
|
import { wallet } from '../libs/auth';
|
|
6
|
+
import { withTenant } from '../libs/context';
|
|
6
7
|
import CustomError, { NonRetryableError } from '../libs/error';
|
|
7
8
|
import { events } from '../libs/event';
|
|
8
9
|
import logger from '../libs/logger';
|
|
9
10
|
import { getGasPayerExtra, isBalanceSufficientForRefund } from '../libs/payment';
|
|
10
|
-
import createQueue from '../libs/queue';
|
|
11
|
+
import createQueue, { assertJobObjectTenant } from '../libs/queue';
|
|
11
12
|
import { MAX_RETRY_COUNT, getNextRetry } from '../libs/util';
|
|
12
13
|
import { Customer } from '../store/models/customer';
|
|
13
14
|
import { PaymentCurrency } from '../store/models/payment-currency';
|
|
@@ -20,6 +21,7 @@ import { Invoice } from '../store/models/invoice';
|
|
|
20
21
|
import { burnToken, getAccountState } from '../integrations/arcblock/token';
|
|
21
22
|
import type { EVMChainType, PaymentError } from '../store/models/types';
|
|
22
23
|
import { EVM_CHAIN_TYPES } from '../libs/constants';
|
|
24
|
+
import { systemFindAll, systemFindByPk } from '../store/scoped';
|
|
23
25
|
|
|
24
26
|
type RefundJob = {
|
|
25
27
|
refundId: string;
|
|
@@ -83,11 +85,12 @@ export const handleRefundFailed = (refund: Refund, error: PaymentError) => {
|
|
|
83
85
|
export const handleRefund = async (job: RefundJob) => {
|
|
84
86
|
logger.info('handle refund', job);
|
|
85
87
|
|
|
86
|
-
const refund = await Refund
|
|
88
|
+
const refund = await systemFindByPk(Refund, job.refundId);
|
|
87
89
|
if (!refund) {
|
|
88
90
|
logger.warn(`refund not found: ${job.refundId}`);
|
|
89
91
|
return;
|
|
90
92
|
}
|
|
93
|
+
assertJobObjectTenant(refund);
|
|
91
94
|
|
|
92
95
|
if (['pending'].includes(refund.status) === false) {
|
|
93
96
|
logger.warn(`refund status not expected: ${refund.status}`);
|
|
@@ -106,25 +109,28 @@ export const handleRefund = async (job: RefundJob) => {
|
|
|
106
109
|
return;
|
|
107
110
|
}
|
|
108
111
|
|
|
109
|
-
const paymentCurrency = await PaymentCurrency
|
|
112
|
+
const paymentCurrency = await systemFindByPk(PaymentCurrency, refund.currency_id);
|
|
110
113
|
if (!paymentCurrency) {
|
|
111
114
|
logger.warn(`PaymentCurrency not found: ${refund.currency_id}`);
|
|
112
115
|
await markRefundNonRetryable(refund, 'CURRENCY_NOT_FOUND', 'Payment currency not found');
|
|
113
116
|
return;
|
|
114
117
|
}
|
|
115
|
-
|
|
118
|
+
assertJobObjectTenant(paymentCurrency);
|
|
119
|
+
const paymentMethod = await systemFindByPk(PaymentMethod, paymentCurrency.payment_method_id);
|
|
116
120
|
if (!paymentMethod) {
|
|
117
121
|
logger.warn(`PaymentMethod not found: ${paymentCurrency.payment_method_id}`);
|
|
118
122
|
await markRefundNonRetryable(refund, 'PAYMENT_METHOD_NOT_FOUND', 'Payment method not found');
|
|
119
123
|
return;
|
|
120
124
|
}
|
|
125
|
+
assertJobObjectTenant(paymentMethod);
|
|
121
126
|
|
|
122
|
-
const customer = await Customer
|
|
127
|
+
const customer = await systemFindByPk(Customer, refund.customer_id);
|
|
123
128
|
if (!customer) {
|
|
124
129
|
logger.warn(`Customer not found: ${refund.customer_id}`);
|
|
125
130
|
await markRefundNonRetryable(refund, 'CUSTOMER_NOT_FOUND', 'Customer not found', paymentMethod);
|
|
126
131
|
return;
|
|
127
132
|
}
|
|
133
|
+
assertJobObjectTenant(customer);
|
|
128
134
|
|
|
129
135
|
if (refund?.type === 'stake_return') {
|
|
130
136
|
await handleStakeReturnJob(job, refund, paymentCurrency, paymentMethod, customer);
|
|
@@ -197,10 +203,11 @@ const handleRefundJob = async (
|
|
|
197
203
|
if (!refund.payment_intent_id) {
|
|
198
204
|
throw new NonRetryableError('PAYMENT_INTENT_NOT_FOUND', 'payment_intent_id is missing for refund');
|
|
199
205
|
}
|
|
200
|
-
const paymentIntent = await PaymentIntent
|
|
206
|
+
const paymentIntent = await systemFindByPk(PaymentIntent, refund.payment_intent_id);
|
|
201
207
|
if (!paymentIntent) {
|
|
202
208
|
throw new NonRetryableError('PAYMENT_INTENT_NOT_FOUND', 'PaymentIntent not found');
|
|
203
209
|
}
|
|
210
|
+
assertJobObjectTenant(paymentIntent);
|
|
204
211
|
let result;
|
|
205
212
|
if (paymentMethod.type === 'arcblock') {
|
|
206
213
|
const client = paymentMethod.getOcapClient();
|
|
@@ -378,7 +385,7 @@ const handleStakeReturnJob = async (
|
|
|
378
385
|
return;
|
|
379
386
|
}
|
|
380
387
|
const client = paymentMethod.getOcapClient();
|
|
381
|
-
const subscription = await Subscription
|
|
388
|
+
const subscription = await systemFindByPk(Subscription, refund.subscription_id);
|
|
382
389
|
const address =
|
|
383
390
|
arcblockDetail?.staking?.address ||
|
|
384
391
|
(await getSubscriptionStakeAddress(subscription!, customer.did, paymentMethod));
|
|
@@ -486,14 +493,25 @@ export const refundQueue = createQueue<RefundJob>({
|
|
|
486
493
|
});
|
|
487
494
|
|
|
488
495
|
export const startRefundQueue = async () => {
|
|
489
|
-
const refunds = await Refund
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
496
|
+
const refunds = await systemFindAll(Refund, { where: { status: ['pending'] } });
|
|
497
|
+
// Per-record tenant context: queue push stamps the job tenant via getInstanceDid,
|
|
498
|
+
// which fails closed in multi mode without it. for-of + await (not forEach(async),
|
|
499
|
+
// which leaks an unhandledRejection → FATAL on boot); per-record catch isolates.
|
|
500
|
+
for (const x of refunds) {
|
|
501
|
+
const dispatch = async () => {
|
|
502
|
+
const exist = await refundQueue.get(x.id);
|
|
503
|
+
if (!exist) {
|
|
504
|
+
refundQueue.push({ id: x.id, job: { refundId: x.id } });
|
|
505
|
+
logger.info('Re-queued pending refund', { id: x.id });
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
try {
|
|
509
|
+
// eslint-disable-next-line no-await-in-loop
|
|
510
|
+
await (x.instance_did ? withTenant(x.instance_did, dispatch) : dispatch());
|
|
511
|
+
} catch (error) {
|
|
512
|
+
logger.error('startRefundQueue: re-queue failed', { id: x.id, error });
|
|
495
513
|
}
|
|
496
|
-
}
|
|
514
|
+
}
|
|
497
515
|
};
|
|
498
516
|
|
|
499
517
|
refundQueue.on('failed', ({ id, job, error }) => {
|
|
@@ -528,8 +546,8 @@ export async function handleCreditRefund(refund: Refund): Promise<string | undef
|
|
|
528
546
|
return undefined;
|
|
529
547
|
}
|
|
530
548
|
|
|
531
|
-
const invoice = await Invoice
|
|
532
|
-
const customer = await Customer
|
|
549
|
+
const invoice = await systemFindByPk(Invoice, refund.invoice_id);
|
|
550
|
+
const customer = await systemFindByPk(Customer, refund.customer_id);
|
|
533
551
|
|
|
534
552
|
if (!invoice || !customer?.did) {
|
|
535
553
|
throw new Error('Invoice or customer not found for refund');
|
|
@@ -541,7 +559,7 @@ export async function handleCreditRefund(refund: Refund): Promise<string | undef
|
|
|
541
559
|
}
|
|
542
560
|
|
|
543
561
|
// Find ALL credit grants related to this invoice (both on-chain and off-chain).
|
|
544
|
-
const allGrants = await CreditGrant
|
|
562
|
+
const allGrants = await systemFindAll(CreditGrant, {
|
|
545
563
|
where: {
|
|
546
564
|
customer_id: refund.customer_id,
|
|
547
565
|
status: ['pending', 'granted'],
|
|
@@ -570,7 +588,7 @@ export async function handleCreditRefund(refund: Refund): Promise<string | undef
|
|
|
570
588
|
for (const creditGrant of creditGrants) {
|
|
571
589
|
// Get the currency for THIS grant
|
|
572
590
|
// eslint-disable-next-line no-await-in-loop
|
|
573
|
-
const grantCurrency = await PaymentCurrency
|
|
591
|
+
const grantCurrency = await systemFindByPk(PaymentCurrency, creditGrant.currency_id);
|
|
574
592
|
|
|
575
593
|
if (!grantCurrency) {
|
|
576
594
|
logger.error('Payment currency not found for credit grant refund', {
|