Supercommerce API Docs
Admin API

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.

How an operator sets PhonePe up and operates it.

PhonePe deliberately adds no admin HTTP endpoints of its own. Configuration goes through the generic settings registry, and refunds go through the provider-neutral routes on admin/orders. This page is the operator's map of those existing surfaces; there is no PhonePe-specific admin API to document.


Configuration

Settings group payment.phonepe, scope admin. Read and written with the normal registry endpoints:

  • GET /admin/settings/registry/fields?groups=payment.phonepe — current values, with secrets masked
  • PATCH /admin/settings/admin with body { "payment.phonepe": { … } }

Both require adminSetting: read / adminSetting: update. See settings.md for the envelope and the masking rules.

KeyRequiredNotes
client_idyesOAuth client id. Empty leaves the provider disabled
client_secretyesSecret — write-only; submitting the mask leaves it unchanged
client_versionyes (default 1)Issued with the client id
merchant_idyesFrom onboarding. Not the client id — the mobile SDK needs it, and it is sent as X-MERCHANT-ID on status/refund calls
environmentyes (default sandbox)sandbox or production; selects the hosts and the mobile SDK environment
webhook_usernamefor webhooksMust match the PhonePe dashboard exactly
webhook_passwordfor webhooksSecret
redirect_urlweb onlyWhere PhonePe returns the browser. App-only installs may leave it empty
payment_expiry_secondsdefault 1200300–3600
allow_refundsdefault falseGates gateway refunds and whether pg.refund.* webhooks are acted on

The UI for these lives under Plugins → PhonePe in the admin app, which also shows a copyable webhook URL and the four events to subscribe to.


Enabling it at checkout

Configuration alone does not expose PhonePe to customers. Under Settings → Payment, tick PhonePe's Web and/or App switch in the gateway matrix and save. That writes the per-platform enabled list in the payment group:

PATCH /admin/settings/admin
{ "payment": { "enabled_providers": { "web": ["manual", "phonepe"], "app": ["manual", "phonepe"] } } }

The matrix's rows come from GET /admin/payment/gateways, so PhonePe shows Add credentials until client_id, client_secret and merchant_id are set. That is a warning only — enabling an unconfigured gateway is allowed, and it fails loudly at place-order rather than silently.

Enablement is intersected three ways — registered in code, enabled for the platform, and supported by the provider — so an id listed here that isn't registered is silently ignored rather than breaking checkout.

Its checkout appearance (label, description, logo, badge, position, and whether it is the preselected option) is separate: Settings → Checkout Payment. With no row there, PhonePe still appears at checkout using the provider's own name and description.


Refunds

Refunds are not a PhonePe endpoint. Once allow_refunds is on, use the provider-neutral routes, all guarded order: refund:

EndpointPurpose
POST /admin/orders/:id/refundsSend a refund to the gateway
GET /admin/orders/:id/refundsRefund history, including in-flight ones
POST /admin/orders/:id/refunds/:merchantRefundId/syncRe-read a pending refund when its webhook never arrived

Full request/response shapes are in order.md. Two operational notes:

  • Refunds settle asynchronously. The row is created PENDING and the order's payment status moves only when PhonePe confirms. PENDING amounts are not yet counted in the order's refunded total, so the endpoint subtracts them from the remaining balance — two quick clicks cannot over-refund.
  • A pg.refund.failed webhook marks the row failed and raises an ops alert but leaves order state untouched: the customer has not been refunded, and it needs a human.

With allow_refunds off, PhonePe orders fall back to POST /admin/orders/:id/mark-refunded — refund by hand in the PhonePe dashboard, then record it.


Operating notes

  • Credentials are read per call, so rotating one takes effect on the next payment with no restart.
  • A missed webhook does not lose the order. The customer-side verify call, the webhook, and the stale-pending sweep all reconcile against PhonePe's Order Status API; the sweep asks the gateway before cancelling, and defers rather than cancelling if PhonePe is unreachable.
  • Every inbound delivery is archived for 90 days, rejected ones included, so a failing webhook can be diagnosed from webhook_deliveries. Credentials are never stored there. See webhooks-inbox.md.

On this page