Payment Gateways — Admin
Read-only option feeds describing which payment gateways a deployment registered, where each is enabled, and which checkout options exist — consumed by the settings UI's toggle-matrix and checkout-appearance pickers.
Read-only feeds describing the payment gateways this deployment registered: which platforms each can serve, whether its credentials are in place, and where it is currently switched on.
Source:
api-modules/payment/src/controllers/admin-payment-gateways.controller.ts,api-modules/payment/src/services/payment-gateway-catalog.service.ts.These are option feeds, not a management API. Enabling a gateway is a settings write (
PATCH /admin/settings/adminonpayment.enabled_providers), and a gateway's appearance is a store-settings write oncheckout_payment. The feeds exist so those generic settings controls can render real, current choices — seeoptionsSource.
Conventions
Authentication
Both endpoints require a Better-Auth admin session and adminSetting: read.
That is deliberately the same permission that gates the settings pages consuming these feeds, and no new entry was added to the RBAC catalog. A separate grant could be withheld while /settings/admin stayed readable, leaving the gateway matrix permanently empty for that operator — a failure mode with no upside, since the feeds expose nothing the settings surface doesn't already.
Never returns a credential: configured is a boolean derived from each provider's own readiness check, not the values behind it.
Response envelope
{ "data": [ /* rows */ ], "message": "Success", "statusCode": 200 }Neither endpoint is paginated — the row count is bounded by what PaymentModule.forRoot registered.
GET /admin/payment/gateways
Every registered payment provider. Backs the toggle-matrix control on admin.payment.enabled_providers.
Response 200 — PaymentGatewayRow[]
{
"data": [
{
"value": "manual",
"label": "Cash on Delivery & Bank Transfer",
"description": "Pay on delivery, or by direct bank transfer.",
"methods": ["cod", "bank-transfer"],
"supportedPlatforms": ["BOTH"],
"configured": true,
"enabled": { "web": true, "app": true }
},
{
"value": "phonepe",
"label": "PhonePe",
"description": "UPI, cards, net banking and wallets via PhonePe.",
"badge": "Add credentials",
"href": "/integrations/phonepe/configuration",
"methods": ["phonepe"],
"supportedPlatforms": ["WEB", "APP"],
"configured": false,
"enabled": { "web": false, "app": false }
}
],
"message": "Success",
"statusCode": 200
}| Field | Notes |
|---|---|
value | Provider id — the string stored in enabled_providers. |
label | PaymentProvider.displayName, else a prettified id. |
description | PaymentProvider.checkoutDescription. Omitted when the provider declares none. |
badge | "Add credentials" when configured is false; omitted otherwise. |
disabledColumns | Platform columns this gateway cannot serve, e.g. ["app"] for a WEB-only provider. Omitted when it serves all of them. |
disabledReason | Why those columns are barred. Rendered as the disabled switch's tooltip. |
href | PaymentProvider.adminPath — the plugin's own configuration page. Omitted when it has none. |
configured | PaymentProvider.isConfigured(). A provider with no such hook has nothing to configure and reads true. |
enabled | Current enabled_providers state, per platform column. |
configured: false does not stop the operator enabling a gateway — the flag is a warning, and an unconfigured provider fails loudly at place-order rather than silently.
Removing a plugin's forRoot() line from apps/api/src/app.module.ts removes its row from this feed, which is what makes the matrix a true reflection of the deployment.
GET /admin/payment/checkout-options
One row per provider method — the rows the storefront can render at checkout. Backs the option picker inside store.checkout_payment.provider_display and the default_option select.
Response 200 — CheckoutOptionRow[]
{
"data": [
{
"value": "manual.cod",
"label": "Cash on Delivery & Bank Transfer — Cod",
"description": "Enabled on Web + App",
"providerId": "manual",
"method": "cod",
"enabled": { "web": true, "app": true }
},
{
"value": "phonepe",
"label": "PhonePe",
"description": "Not enabled on any platform",
"providerId": "phonepe",
"method": "phonepe",
"enabled": { "web": false, "app": false }
}
],
"message": "Success",
"statusCode": 200
}Option keys. Most providers expose a single method whose code equals the provider id, so those collapse to the bare id (phonepe, razorpay) rather than a redundant phonepe.phonepe; multi-method providers qualify each one (manual.cod, manual.bank-transfer).
Exclusions. Providers flagged hiddenAtCheckout are omitted — razorpay-magic starts from POST /store/cart/:cartId/magic-checkout/start and its place() throws, so configuring its checkout appearance would be a dead end.
Options that aren't enabled anywhere are still listed (with description saying so), so an operator can stage a gateway's copy and logo before switching it on.
Related
- Settings — Admin — the
toggle-matrixcontrol,optionsSource, and thecheckout_paymentgroup these feeds populate. - Order — Store —
GET /store/checkout/payment-providers, where the enabled options plus their configured appearance reach the storefront. - Payment PhonePe — Admin — per-gateway credential configuration.
Order Module — Admin
HTTP surface for platform-admin oversight of orders, returns, and vendor payouts. Read every order on the platform; perform ops actions (cancel on behalf of the customer, manually…
Payment PhonePe — Admin
How an operator configures, enables and refunds through PhonePe. PhonePe adds no admin endpoints of its own — configuration goes through the settings registry and refunds through the provider-neutral refund routes.