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,27 +1,31 @@
|
|
|
1
|
+
// Phase 3a (express→hono) — hono fork of routes/pricing-table.ts. Sub-app with
|
|
2
|
+
// routes relative to /api/pricing-tables (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
|
import { isValid } from '@arcblock/did';
|
|
2
6
|
import { getUrl } from '@blocklet/sdk/lib/component';
|
|
3
|
-
import {
|
|
7
|
+
import { Hono } from 'hono';
|
|
4
8
|
import Joi from 'joi';
|
|
5
9
|
import merge from 'lodash/merge';
|
|
6
10
|
import pick from 'lodash/pick';
|
|
7
11
|
import uniq from 'lodash/uniq';
|
|
8
12
|
import type { WhereOptions } from 'sequelize';
|
|
9
13
|
|
|
10
|
-
import { checkPassportForPricingTable } from '
|
|
11
|
-
import { createListParamSchema, getOrder, MetadataSchema } from '
|
|
12
|
-
import logger from '
|
|
13
|
-
import { authenticate } from '
|
|
14
|
-
import { getBillingThreshold, getMinStakeAmount, isCreditMetered, isLineItemCurrencyAligned } from '
|
|
15
|
-
import { getDaysUntilCancel, getDaysUntilDue } from '
|
|
16
|
-
import { getDataObjectFromQuery } from '
|
|
17
|
-
import { CheckoutSession } from '
|
|
18
|
-
import { PaymentCurrency } from '
|
|
19
|
-
import { Price } from '
|
|
20
|
-
import { PricingTable } from '
|
|
21
|
-
import { Product } from '
|
|
14
|
+
import { checkPassportForPricingTable } from '../../integrations/blocklet/passport';
|
|
15
|
+
import { createListParamSchema, getOrder, MetadataSchema } from '../../libs/api';
|
|
16
|
+
import logger from '../../libs/logger';
|
|
17
|
+
import { authenticate } from '../../middlewares/hono/security';
|
|
18
|
+
import { getBillingThreshold, getMinStakeAmount, isCreditMetered, isLineItemCurrencyAligned } from '../../libs/session';
|
|
19
|
+
import { getDaysUntilCancel, getDaysUntilDue } from '../../libs/subscription';
|
|
20
|
+
import { getDataObjectFromQuery } from '../../libs/util';
|
|
21
|
+
import { CheckoutSession } from '../../store/models/checkout-session';
|
|
22
|
+
import { PaymentCurrency } from '../../store/models/payment-currency';
|
|
23
|
+
import { Price } from '../../store/models/price';
|
|
24
|
+
import { PricingTable } from '../../store/models/pricing-table';
|
|
25
|
+
import { Product } from '../../store/models/product';
|
|
22
26
|
import { formatCheckoutSession } from './checkout-sessions';
|
|
23
27
|
|
|
24
|
-
const
|
|
28
|
+
const app = new Hono();
|
|
25
29
|
const auth = authenticate<PricingTable>({ component: true, roles: ['owner', 'admin'] });
|
|
26
30
|
|
|
27
31
|
const PricingTableCreateSchema = Joi.object({
|
|
@@ -58,33 +62,34 @@ const PricingTableCreateSchema = Joi.object({
|
|
|
58
62
|
.required(),
|
|
59
63
|
branding_settings: Joi.object().allow(null, {}).optional(),
|
|
60
64
|
}).unknown(true);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const
|
|
65
|
+
|
|
66
|
+
app.post('/', auth, async (c) => {
|
|
67
|
+
const body = (c.get('sanitizedBody') ?? {}) as any;
|
|
68
|
+
const { error } = PricingTableCreateSchema.validate(body);
|
|
64
69
|
if (error) {
|
|
65
|
-
return
|
|
70
|
+
return c.json({ error: `Pricing table create request invalid: ${error.message}` }, 400);
|
|
66
71
|
}
|
|
67
|
-
const raw: Partial<PricingTable> = PricingTable.format(
|
|
72
|
+
const raw: Partial<PricingTable> = PricingTable.format(body);
|
|
68
73
|
raw.active = true;
|
|
69
74
|
raw.locked = false;
|
|
70
|
-
raw.livemode = !!
|
|
71
|
-
raw.created_via =
|
|
75
|
+
raw.livemode = !!c.get('livemode');
|
|
76
|
+
raw.created_via = c.get('user')?.via;
|
|
72
77
|
|
|
73
78
|
if (!raw.items?.length) {
|
|
74
|
-
return
|
|
79
|
+
return c.json({ error: 'items should not be empty for pricing table' }, 400);
|
|
75
80
|
}
|
|
76
81
|
|
|
77
82
|
// @ts-ignore
|
|
78
83
|
const items = await Price.expand(raw.items);
|
|
79
84
|
for (let i = 0; i < items.length; i++) {
|
|
80
85
|
if (isLineItemCurrencyAligned(items, i) === false) {
|
|
81
|
-
return
|
|
86
|
+
return c.json({ error: 'items should have same currency' }, 400);
|
|
82
87
|
}
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
const link = await PricingTable.create(raw as PricingTable);
|
|
86
91
|
|
|
87
|
-
|
|
92
|
+
return c.json(link);
|
|
88
93
|
});
|
|
89
94
|
|
|
90
95
|
// list pricing tables
|
|
@@ -93,8 +98,9 @@ const paginationSchema = createListParamSchema<{
|
|
|
93
98
|
}>({
|
|
94
99
|
active: Joi.boolean().empty(''),
|
|
95
100
|
});
|
|
96
|
-
|
|
97
|
-
|
|
101
|
+
|
|
102
|
+
app.get('/', auth, async (c) => {
|
|
103
|
+
const { page, pageSize, ...query } = await paginationSchema.validateAsync(c.req.query(), { stripUnknown: true });
|
|
98
104
|
const where: WhereOptions<PricingTable> = { 'metadata.preview': null };
|
|
99
105
|
|
|
100
106
|
if (typeof query.active === 'boolean') {
|
|
@@ -107,7 +113,7 @@ router.get('/', auth, async (req, res) => {
|
|
|
107
113
|
try {
|
|
108
114
|
const { rows: list, count } = await PricingTable.findAndCountAll({
|
|
109
115
|
where,
|
|
110
|
-
order: getOrder(req.query, [['created_at', 'DESC']]),
|
|
116
|
+
order: getOrder(c.req.query(), [['created_at', 'DESC']]),
|
|
111
117
|
offset: (page - 1) * pageSize,
|
|
112
118
|
limit: pageSize,
|
|
113
119
|
include: [],
|
|
@@ -127,19 +133,18 @@ router.get('/', auth, async (req, res) => {
|
|
|
127
133
|
});
|
|
128
134
|
});
|
|
129
135
|
|
|
130
|
-
|
|
136
|
+
return c.json({ count, list, paging: { page, pageSize } });
|
|
131
137
|
} catch (err) {
|
|
132
138
|
logger.error(err);
|
|
133
|
-
|
|
139
|
+
return c.json({ count: 0, list: [], paging: { page, pageSize } });
|
|
134
140
|
}
|
|
135
141
|
});
|
|
136
142
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const doc = await PricingTable.findByPk(req.params.id);
|
|
143
|
+
app.get('/:id', async (c) => {
|
|
144
|
+
const doc = await PricingTable.findByPk(c.req.param('id'));
|
|
140
145
|
|
|
141
146
|
if (!doc) {
|
|
142
|
-
return
|
|
147
|
+
return c.json({ error: 'pricing table not found' }, 404);
|
|
143
148
|
}
|
|
144
149
|
|
|
145
150
|
let currency = await PaymentCurrency.findOne({ where: { livemode: doc.livemode, is_base_currency: true } });
|
|
@@ -156,7 +161,7 @@ router.get('/:id', async (req, res) => {
|
|
|
156
161
|
});
|
|
157
162
|
}
|
|
158
163
|
}
|
|
159
|
-
|
|
164
|
+
return c.json({ ...expanded, currency });
|
|
160
165
|
});
|
|
161
166
|
|
|
162
167
|
// update
|
|
@@ -196,113 +201,115 @@ const PricingTableUpdateSchema = Joi.object({
|
|
|
196
201
|
branding_settings: Joi.object().allow(null, {}).optional(),
|
|
197
202
|
}).unknown(true);
|
|
198
203
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const { error } = PricingTableUpdateSchema.validate(
|
|
204
|
+
app.put('/:id', auth, async (c) => {
|
|
205
|
+
const body = (c.get('sanitizedBody') ?? {}) as any;
|
|
206
|
+
const { error } = PricingTableUpdateSchema.validate(body);
|
|
202
207
|
if (error) {
|
|
203
|
-
return
|
|
208
|
+
return c.json({ error: `Pricing table create request invalid: ${error.message}` }, 400);
|
|
204
209
|
}
|
|
205
|
-
const doc = await PricingTable.findByPk(req.
|
|
210
|
+
const doc = await PricingTable.findByPk(c.req.param('id'));
|
|
206
211
|
|
|
207
212
|
if (!doc) {
|
|
208
|
-
return
|
|
213
|
+
return c.json({ error: 'pricing table not found' }, 404);
|
|
209
214
|
}
|
|
210
215
|
if (doc.active === false) {
|
|
211
|
-
return
|
|
216
|
+
return c.json({ error: 'pricing table archived' }, 403);
|
|
212
217
|
}
|
|
213
218
|
// if (doc.locked) {
|
|
214
|
-
// return
|
|
219
|
+
// return c.json({ error: 'pricing table locked' }, 403);
|
|
215
220
|
// }
|
|
216
221
|
|
|
217
|
-
await doc.update(PricingTable.format(Object.assign({}, doc.dataValues,
|
|
222
|
+
await doc.update(PricingTable.format(Object.assign({}, doc.dataValues, body)));
|
|
218
223
|
|
|
219
|
-
|
|
224
|
+
return c.json(doc);
|
|
220
225
|
});
|
|
221
226
|
|
|
222
227
|
// archive
|
|
223
|
-
|
|
224
|
-
const doc = await PricingTable.findByPk(req.
|
|
228
|
+
app.put('/:id/archive', auth, async (c) => {
|
|
229
|
+
const doc = await PricingTable.findByPk(c.req.param('id'));
|
|
225
230
|
|
|
226
231
|
if (!doc) {
|
|
227
|
-
return
|
|
232
|
+
return c.json({ error: 'pricing table not found' }, 404);
|
|
228
233
|
}
|
|
229
234
|
|
|
230
235
|
if (doc.active === false) {
|
|
231
|
-
return
|
|
236
|
+
return c.json({ error: 'pricing table already archived' }, 403);
|
|
232
237
|
}
|
|
233
238
|
|
|
234
239
|
await doc.update({ active: false });
|
|
235
|
-
return
|
|
240
|
+
return c.json(doc);
|
|
236
241
|
});
|
|
237
242
|
|
|
238
243
|
// delete
|
|
239
|
-
|
|
240
|
-
const doc = await PricingTable.findByPk(req.
|
|
244
|
+
app.delete('/:id', auth, async (c) => {
|
|
245
|
+
const doc = await PricingTable.findByPk(c.req.param('id'));
|
|
241
246
|
|
|
242
247
|
if (!doc) {
|
|
243
|
-
return
|
|
248
|
+
return c.json({ error: 'pricing table not found' }, 404);
|
|
244
249
|
}
|
|
245
250
|
|
|
246
251
|
if (doc.active === false) {
|
|
247
|
-
return
|
|
252
|
+
return c.json({ error: 'pricing table archived' }, 403);
|
|
248
253
|
}
|
|
249
254
|
|
|
250
255
|
if (doc.locked) {
|
|
251
|
-
return
|
|
256
|
+
return c.json({ error: 'pricing table locked' }, 403);
|
|
252
257
|
}
|
|
253
258
|
|
|
254
259
|
await doc.destroy();
|
|
255
|
-
return
|
|
260
|
+
return c.json(doc);
|
|
256
261
|
});
|
|
257
262
|
|
|
258
|
-
|
|
263
|
+
app.post('/stash', auth, async (c) => {
|
|
259
264
|
try {
|
|
260
|
-
const
|
|
261
|
-
raw
|
|
265
|
+
const body = (c.get('sanitizedBody') ?? {}) as any;
|
|
266
|
+
const raw: Partial<PricingTable> = body;
|
|
267
|
+
raw.id = `prctbl_${c.get('user')?.did}`;
|
|
262
268
|
raw.active = true;
|
|
263
269
|
raw.locked = false;
|
|
264
|
-
raw.livemode = !!
|
|
265
|
-
raw.created_via =
|
|
270
|
+
raw.livemode = !!c.get('livemode');
|
|
271
|
+
raw.created_via = c.get('user')?.via;
|
|
266
272
|
raw.metadata = { preview: '1' };
|
|
267
273
|
|
|
268
274
|
let doc = await PricingTable.findByPk(raw.id);
|
|
269
275
|
if (doc) {
|
|
270
|
-
await doc.update({ ...PricingTable.format(
|
|
276
|
+
await doc.update({ ...PricingTable.format(body), metadata: raw.metadata, livemode: raw.livemode });
|
|
271
277
|
} else {
|
|
272
278
|
doc = await PricingTable.create(raw as PricingTable);
|
|
273
279
|
}
|
|
274
|
-
|
|
275
|
-
} catch (err) {
|
|
280
|
+
return c.json(doc);
|
|
281
|
+
} catch (err: any) {
|
|
276
282
|
logger.error(err);
|
|
277
|
-
|
|
283
|
+
return c.json({ error: err.message }, 500);
|
|
278
284
|
}
|
|
279
285
|
});
|
|
280
286
|
|
|
281
287
|
// start checkout session for pricing table
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
const doc = await PricingTable.findByPk(req.params.id);
|
|
288
|
+
app.post('/:id/checkout/:priceId', async (c) => {
|
|
289
|
+
const doc = await PricingTable.findByPk(c.req.param('id'));
|
|
285
290
|
|
|
286
291
|
if (!doc) {
|
|
287
|
-
return
|
|
292
|
+
return c.json({ error: 'pricing table not found' }, 404);
|
|
288
293
|
}
|
|
289
294
|
if (doc.active === false) {
|
|
290
|
-
return
|
|
295
|
+
return c.json({ error: 'pricing table archived' }, 403);
|
|
291
296
|
}
|
|
292
297
|
if (doc.locked) {
|
|
293
|
-
return
|
|
298
|
+
return c.json({ error: 'pricing table locked' }, 403);
|
|
294
299
|
}
|
|
295
300
|
|
|
296
|
-
const lineItem = await doc.items.find((x) => x.price_id === req.
|
|
301
|
+
const lineItem = await doc.items.find((x) => x.price_id === c.req.param('priceId'));
|
|
297
302
|
if (!lineItem) {
|
|
298
|
-
return
|
|
303
|
+
return c.json({ error: 'pricing table item not valid' }, 403);
|
|
299
304
|
}
|
|
300
305
|
|
|
301
306
|
const price = await Price.findByPk(lineItem.price_id);
|
|
302
307
|
if (!price) {
|
|
303
|
-
return
|
|
308
|
+
return c.json({ error: 'price not found' }, 403);
|
|
304
309
|
}
|
|
305
310
|
|
|
311
|
+
const query = c.req.query();
|
|
312
|
+
|
|
306
313
|
const raw: Partial<CheckoutSession> = await formatCheckoutSession({
|
|
307
314
|
line_items: [{ price_id: lineItem.price_id, quantity: 1, adjustable_quantity: lineItem.adjustable_quantity }],
|
|
308
315
|
...pick(price, [
|
|
@@ -317,16 +324,16 @@ router.post('/:id/checkout/:priceId', async (req, res) => {
|
|
|
317
324
|
'cross_sell_behavior',
|
|
318
325
|
'nft_mint_settings',
|
|
319
326
|
]),
|
|
320
|
-
subscription_data: merge(lineItem.subscription_data || {}, getDataObjectFromQuery(
|
|
327
|
+
subscription_data: merge(lineItem.subscription_data || {}, getDataObjectFromQuery(query, 'subscription_data'), {
|
|
321
328
|
billing_threshold_amount: getBillingThreshold(lineItem.subscription_data),
|
|
322
329
|
min_stake_amount: getMinStakeAmount(lineItem.subscription_data),
|
|
323
330
|
no_stake: isCreditMetered(price),
|
|
324
331
|
}),
|
|
325
332
|
metadata: {
|
|
326
333
|
...doc.metadata,
|
|
327
|
-
...getDataObjectFromQuery(
|
|
328
|
-
days_until_due: getDaysUntilDue(
|
|
329
|
-
days_until_cancel: getDaysUntilCancel(
|
|
334
|
+
...getDataObjectFromQuery(query),
|
|
335
|
+
days_until_due: getDaysUntilDue(query),
|
|
336
|
+
days_until_cancel: getDaysUntilCancel(query),
|
|
330
337
|
passport: await checkPassportForPricingTable(doc),
|
|
331
338
|
pricing_table_id: doc.id,
|
|
332
339
|
},
|
|
@@ -336,23 +343,23 @@ router.post('/:id/checkout/:priceId', async (req, res) => {
|
|
|
336
343
|
|
|
337
344
|
raw.livemode = doc.livemode;
|
|
338
345
|
raw.created_via = 'portal';
|
|
339
|
-
raw.currency_id = (
|
|
346
|
+
raw.currency_id = (query?.currencyId as string) ?? currency?.id;
|
|
340
347
|
|
|
341
|
-
if (
|
|
342
|
-
raw.success_url =
|
|
343
|
-
raw.cancel_url =
|
|
348
|
+
if (query.redirect) {
|
|
349
|
+
raw.success_url = query.redirect as string;
|
|
350
|
+
raw.cancel_url = query.redirect as string;
|
|
344
351
|
logger.info('use redirect from query when checkout from pricing table', { v: raw.success_url });
|
|
345
352
|
}
|
|
346
|
-
if (
|
|
347
|
-
raw.cross_sell_behavior =
|
|
353
|
+
if (query.cross_sell_behavior) {
|
|
354
|
+
raw.cross_sell_behavior = query.cross_sell_behavior as string;
|
|
348
355
|
logger.info('use cross_sell_behavior from query when checkout from pricing table', { v: raw.cross_sell_behavior });
|
|
349
356
|
}
|
|
350
357
|
try {
|
|
351
|
-
if (
|
|
358
|
+
if (query.nft_mint_factory && isValid(query.nft_mint_factory as string)) {
|
|
352
359
|
raw.nft_mint_settings = {
|
|
353
360
|
enabled: true,
|
|
354
361
|
behavior: 'per_checkout_session',
|
|
355
|
-
factory:
|
|
362
|
+
factory: query.nft_mint_factory as string,
|
|
356
363
|
};
|
|
357
364
|
raw.nft_mint_status = 'pending';
|
|
358
365
|
logger.info('use nft_mint_settings from query when checkout from pricing table', { v: raw.nft_mint_settings });
|
|
@@ -364,7 +371,7 @@ router.post('/:id/checkout/:priceId', async (req, res) => {
|
|
|
364
371
|
}
|
|
365
372
|
|
|
366
373
|
const session = await CheckoutSession.create(raw as any);
|
|
367
|
-
|
|
374
|
+
return c.json({ ...session.toJSON(), url: getUrl(`/checkout/pay/${session.id}`) });
|
|
368
375
|
});
|
|
369
376
|
|
|
370
|
-
export default
|
|
377
|
+
export default app;
|