Introduction
With S2S UPI Collect, the buyer types their UPI ID (VPA) on your page and your backend asks EximPe to send them a payment request. The request appears in the buyer’s UPI app, they approve it with their UPI PIN, and EximPe tells you the outcome.No redirect, no QR
The buyer stays on your page. There is no intent to invoke and no QR code to show
Works on any device
The request reaches the buyer’s phone wherever they started, including on a desktop
Server-confirmed outcome
Read the final status from the Order Status API or the webhook
Collect or Intent?
Prerequisites
Before you begin, ensure you have:- Credentials: Your
X-Client-IDandX-Client-Secret, andX-API-Version: 3.0.0on every call - S2S UPI enabled: Server-to-server UPI must be enabled on your account. Without it, Create Order returns
403 - Webhook URL: A secure endpoint to receive payment status updates
PSP callers also send
X-Merchant-ID, naming the sub-merchant the order belongs to.- The buyer enters their UPI ID on your page.
- Your backend creates the order with
upi_flow_type: "collection"and the buyer’svpa. EximPe sends the payment request. - The buyer approves the request in their UPI app.
- Your backend confirms the outcome from the webhook or the Order Status API.
Step 1: Ask for the buyer’s UPI ID
Add a field for the buyer’s UPI ID, such asname@okaxis, and tell them to open their UPI app once they submit.
Check the format before you send it. EximPe lowercases the UPI ID, then accepts letters, numbers, dots and underscores before the @, and letters, numbers, dots and hyphens after it:
A UPI ID can pass this check and still not exist. EximPe does not look it up before sending the request. An unknown UPI ID shows up as a failed payment.
Step 2: Send the collect request
Create the order from your backend. The request carries your Client Secret, so never send it from a browser or a mobile app.Alongside
amount, currency, reference_id, buyer, product and invoice, a collect request needs:collection_mode:"s2s"mop_type:"upi". Leaving it out is refused with{"mop_type": "Invalid MOP type"}upi_flow_type:"collection". It is not case-sensitive, and"collect"is refusedvpa: the buyer’s UPI IDbuyer.ip_addressandbuyer.user_agent: the buyer’s device IP address and browser or app user agent
201 means the request reached the payment network, not that the buyer has paid. The order is now payment_pending. Tell the buyer to open their UPI app and approve the request, and keep your page waiting for the outcome.
The response has no intent_uri and no expires_at. There is nothing to invoke on the buyer’s device.
When the request is refused
Field errors come back as400 with ERR_ORDER_002, keyed by field. No order is created, so you can fix the field and retry with the same reference_id.
If the payment network cannot be reached, Create Order returns
502 with ERR_GATEWAY_UNAVAILABLE or ERR_PAYMENT_003. Retry with a new reference_id.
Create Order API
Every parameter, constraint, response field and error for this endpoint.
Step 3: The buyer approves in their UPI app
The buyer sees the request in their UPI app, checks the amount and payee, and approves it with their UPI PIN. Your page has nothing to call in the meantime. Show a “waiting for approval” state and tell the buyer which app to open. The request expires if the buyer does not approve it in time. How long that is depends on how your account collects UPI, so don’t build in a fixed countdown. When the request expires or the buyer declines it, the order fails and you receivePAYMENT_FAILED.
Step 4: Confirm the outcome
Wait for the webhook, or poll the Order Status API from your backend:
The Get Payment API shows the payer’s UPI ID masked, for example
jo****@okaxis.
Get Order Status API
Full request and response reference.
Payment Successful webhook
Get pushed the outcome instead of polling for it.
Testing in sandbox
Sandbox sends collect requests to the payment network’s test environment, so no real money moves. When your sandbox account is set up to simulate UPI, the Create Order response also carries atest_simulator_url. Open it in a browser to approve or decline the request without a UPI app. It is never returned in production.
Need Help?
API Reference
📚 Create Order, Get Order Status, and the v3 webhook payloads