Install and enable

Licence the Payment Gateway extension, switch it on, set the environment variable that makes checkout URLs reachable, configure the wallet types that gate every payment, and verify the three cron jobs.

6 min readUpdated 3 August 2026install, license, cron, settings

The gateway ships as an extension of an already-working Bicrypto install. There is no separate installer and no database migration you run by hand — the models are auto-synced with the rest of the schema on boot. What you do here is licence it, switch it on, and set the four things that are wrong by default.

Do the core install first. If the platform is not already serving traffic over HTTPS with a working cron process, nothing on this page will help.

Before you start

    • A running Bicrypto install (frontend, backend and cron all up)
    • Your CodeCanyon purchase code for item 61043226
    • Outbound HTTPS to updates.mashdiv.com from the app server
    • Shell access to run pnpm updator and restart PM2
    • The Ecosystem addon, only if you intend to accept ECO payments

Steps

  1. Activate the licence — in the admin panel, open Extensions, find Payment Gateway, and activate it with your purchase code. The activation endpoint (/api/admin/system/extension) is licence-exempt, so this works even on a platform whose own licence is mid-renewal.

  2. Install the files — if you bought the addon after your last update, its files are not on disk yet. Download the release and run the updator from the project root.

    pnpm updator
  3. Enable the extension row — flip the switch next to Payment Gateway in the Extensions list. This writes status = true on the extension row whose productId is 61043226 and clears the settings cache. Nothing under /api/gateway or /api/admin/gateway responds until it is on.

  4. Restart the backend and cron — routes are registered at boot.

    pnpm restart
  5. Set APP_PUBLIC_URL — see below. This is the step most installs miss.

  6. Configure allowed wallet types — see below. Until you do, every payment is rejected.

  7. Grant the permissions — the admin screens and endpoints are gated by twelve *.gateway.* keys. Assign them to whichever role staffs the queues.

APP_PUBLIC_URL is not optional here

The checkout URL returned by the payment API is built as ${APP_PUBLIC_URL}/${APP_DEFAULT_LOCALE}/gateway/checkout/pi_…. APP_PUBLIC_URL ships empty in .env.example, and the fallback is http://localhost:3000.

The API returns 201 Created, the merchant's integration redirects the buyer, and the buyer's browser tries to open a page on their own machine. Nothing errors on your side. The merchant reports that "checkout is broken" and there is no log line to find.

APP_PUBLIC_URL="https://exchange.example.com"

APP_DEFAULT_LOCALE is not in .env.example at all. It defaults to en. If your install runs on a different default locale, set it explicitly or every checkout link will carry an /en/ prefix your router has to redirect.

Restart the backend after editing .env — it is read once at boot.

Allowed wallet types gate everything

gatewayAllowedWalletTypes is a JSON map of wallet type to { enabled, currencies }. Its default is an empty object, and an empty map means no wallet type is enabled, which means:

  • POST /api/gateway/v1/payment/create fails with "Wallet type FIAT is not enabled for payments".
  • The checkout page offers the buyer no wallets to pay from.
  • New merchants are created with the fallback ["FIAT"] / ["USD"], which the platform check then rejects anyway.

Configure it under Extensions → Payment Gateway → Settings → Wallets before you tell anyone the gateway is live. Enable each wallet type you want and list the exact currency codes under it. The check is a literal includes() against an upper-cased code, so usd and USD are not the same thing and a currency that is enabled for FIAT is not enabled for SPOT.

A payment is checked twice: against the merchant's own allowedCurrencies / allowedWalletTypes columns, and against this platform-wide map. A currency present in one and absent from the other is rejected, with a different error message each way — "not supported by this merchant" versus "not enabled for payments". That wording is the fastest way to tell which list is short.

The three cron jobs

The gateway registers three jobs in the gateway category. They run in the cron worker, not the API process.

Job Every What breaks without it
processGatewayPayouts 60 min No payout record is ever created. pending balances grow forever and no merchant can be paid.
processGatewayWebhookRetries 60 s A merchant endpoint that is down for one minute loses the event permanently.
processGatewayPaymentExpiry 5 min Abandoned sessions sit at PENDING forever and payment.expired never fires.

Check them under Admin → System → Cron. If the whole category is missing, the extension row is off or the cron worker is not running.

processGatewayPayouts reads gatewayEnabled and skips the entire run when it is off — while payments keep completing and crediting pending. Turning the gateway "off" does not stop money arriving; it stops money leaving.

Permissions to assign

Twelve keys are seeded. Nothing grants them automatically except Super Admin.

Key Gates
access.gateway.merchant The admin dashboard and merchant screen
view.gateway.merchant Merchant list and detail
edit.gateway.merchant Status, verification and merchant edits
delete.gateway.merchant Deleting a merchant
access.gateway.payment · view.gateway.payment Payment screens
manage.gateway.payment Issuing an admin refund
view.gateway.payout Payout list and detail
edit.gateway.payout Approving and rejecting payouts
view.gateway.refund The refund list endpoint
access.gateway.settings · view.gateway.settings The settings screen

Two notes that matter when you build a role:

  • The payout screen has no page-level permission file. The /admin/gateway/payout page itself is not gated; its data endpoints are (view.gateway.payout), so a staff member without them sees an empty screen rather than a 403.
  • Saving settings needs edit.settings, not edit.gateway.settings. The settings screen writes through the core settings endpoint. edit.gateway.settings guards a second, parallel endpoint the UI does not use. Give the role both if you want the screen to work.

See Permissions for how a key is derived and the places it has to exist.

Verify the install

From the app server:

curl -s -o /dev/null -w "%{http_code}\n" https://exchange.example.com/api/gateway/settings

200 means the extension is enabled and licensed. 503 means the route registered but the licence check failed. A 404 means the extension row is off or the backend has not been restarted since you enabled it.

curl -s https://exchange.example.com/api/gateway/settings

The response should include gatewayAllowedWalletTypes with at least one enabled type and a non-empty currency list. {} or a missing key means step 6 was not done.

Signed in as a normal user, Gateway should appear in the main navigation and /gateway should render the landing page. In the admin panel, Payment Gateway appears under Extensions and needs access.gateway.merchant.

Admin → System → Cron should list Process Gateway Payouts, Retry Failed Gateway Webhooks and Expire Lapsed Gateway Payments, all idle rather than failed.

Register a merchant, approve and verify it, then use its sk_test_ key to create a payment and open the returned checkoutUrl in a browser as a second user with a funded wallet. A test-mode payment debits nothing and credits nothing, but it exercises the wallet selection, the exchange-rate check and the webhook path.

What is not installed for you

  • No demo merchant, no seed data. The gateway_* tables start empty.
  • No default currency configuration. The wallet map is {}.
  • No reverse proxy change. The gateway lives under /api, which your proxy already forwards.
  • No WooCommerce plugin on disk anywhere public. Merchants download it from /gateway/integration, which zips it out of the backend source tree at request time. If your deployment strips non-TypeScript files from backend/src, that download 500s with an explicit message telling you the plugins directory is missing.

Next: Merchant onboarding.