curl --request POST \
--url https://api-pacb-uat.eximpe.com/pg/orders/ \
--header 'Content-Type: application/json' \
--header 'X-Client-ID: <api-key>' \
--header 'X-Client-Secret: <api-key>' \
--data '
{
"amount": "1000.00",
"currency": "INR",
"reference_id": "ORDER-123456",
"collection_mode": "hosted_payment",
"mop_type": "upi",
"return_url": "https://yourdomain.com/payment/callback/",
"business_model": "B2C",
"buyer": {
"name": "Alice Smith",
"email": "[email protected]",
"phone": "+919812345678",
"address": {
"line_1": "221B Baker Street",
"city": "Mumbai",
"state": "Maharashtra",
"postal_code": "400001"
}
},
"product": {
"name": "Wireless Headphones",
"description": "Premium noise-cancelling wireless headphones",
"hs_code": "85183000",
"hs_code_description": "Headphones and earphones, whether or not combined with a microphone",
"type_of_goods": "physical_goods"
},
"invoice": {
"number": "INV-2026-0001",
"date": "2026-09-21"
}
}
'{
"success": true,
"message": "Checkout session created successfully",
"data": {
"session_id": "b4db5e1c82db8636094f54e3293218172ae2ab87dee6ce4e97c82db6c63f243a",
"order_id": "OD5916184980"
}
}Create Order
Create an order and get either a Hosted Checkout session or a UPI intent to collect an INR payment.
curl --request POST \
--url https://api-pacb-uat.eximpe.com/pg/orders/ \
--header 'Content-Type: application/json' \
--header 'X-Client-ID: <api-key>' \
--header 'X-Client-Secret: <api-key>' \
--data '
{
"amount": "1000.00",
"currency": "INR",
"reference_id": "ORDER-123456",
"collection_mode": "hosted_payment",
"mop_type": "upi",
"return_url": "https://yourdomain.com/payment/callback/",
"business_model": "B2C",
"buyer": {
"name": "Alice Smith",
"email": "[email protected]",
"phone": "+919812345678",
"address": {
"line_1": "221B Baker Street",
"city": "Mumbai",
"state": "Maharashtra",
"postal_code": "400001"
}
},
"product": {
"name": "Wireless Headphones",
"description": "Premium noise-cancelling wireless headphones",
"hs_code": "85183000",
"hs_code_description": "Headphones and earphones, whether or not combined with a microphone",
"type_of_goods": "physical_goods"
},
"invoice": {
"number": "INV-2026-0001",
"date": "2026-09-21"
}
}
'{
"success": true,
"message": "Checkout session created successfully",
"data": {
"session_id": "b4db5e1c82db8636094f54e3293218172ae2ab87dee6ce4e97c82db6c63f243a",
"order_id": "OD5916184980"
}
}Overview
Create Order is the first step in the payment flow. You send the buyer, product and invoice details from your backend, and choose how the payment is collected withcollection_mode:
- Hosted Checkout (
hosted_payment) returns asession_id. You hand it to the EximPe JS SDK, which opens EximPe’s payment page. - S2S UPI Intent (
s2s) returns anintent_urithat you use to open the customer’s UPI app.
order_id. A successful create returns 201 Created.
| Environment | Base URL |
|---|---|
| Sandbox | https://api-pacb-uat.eximpe.com |
| Production | https://api-pacb.eximpe.com |
Headers
| Header | Required | Value |
|---|---|---|
X-Client-ID | Yes | Your Client ID, from Developer Settings in the merchant dashboard. |
X-Client-Secret | Yes | Your Client Secret. Keep it on your server. |
X-API-Version | Recommended | 3.0.0. It selects the API version; it is not a credential. |
X-Merchant-ID | PSPs only | The sub-merchant the order is for. Required when you authenticate as a PSP; merchants using their own credentials leave it out. |
Content-Type | Yes | application/json |
Hosted Checkout and S2S UPI Intent
| Hosted Checkout | S2S UPI Intent | |
|---|---|---|
collection_mode | hosted_payment | s2s |
mop_type | Optional. Pre-selects a payment method on the payment page | Must be upi |
upi_flow_type | Not used | Must be intent |
buyer.ip_address, buyer.user_agent | Not used; EximPe captures them on the payment page | Required |
return_url | Optional. Where the customer lands after paying | Not used; the customer is not redirected |
| Returns | order_id, session_id | order_id, intent_uri, expires_at |
collection_mode has no default. Leave it out, or send another value, and the request is refused with {"collection_mode": "Invalid collection mode"}.
S2S UPI Intent must be enabled on your account. See the S2S UPI Intent integration guide for the end-to-end flow.
Request Parameters
Fields not listed as required are optional. “Conditional” means the field is required only in the stated case.Top-level
| Name | Type | Required | Description | Constraints |
|---|---|---|---|---|
| amount | string | Yes | Amount to collect, in rupees. | Decimal string such as "1000.00"; a JSON number is also accepted. More than two decimal places are rounded to two — 1000.456 is charged as 1000.46. Greater than 0 and at most 10,000,000.00 |
| currency | string | Yes | ISO 4217 currency code. | INR |
| reference_id | string | Yes | Your reference for the order. | 1–50 chars; letters, numbers and hyphens only (ORDER-123456, not ORDER_123456); unique across your orders. See Duplicate requests |
| collection_mode | string | Yes | How the payment is collected. | hosted_payment or s2s; no default |
| mop_type | string | Conditional | Payment method. | Hosted Checkout: optional, one of credit_card, debit_card, upi, net_banking, qr. S2S UPI Intent: required, upi |
| upi_flow_type | string | Conditional | UPI flow. | S2S UPI Intent: required, intent |
| return_url | string | No | Where Hosted Checkout sends the customer when the payment finishes, whatever the outcome. | Absolute URL, max 500 chars. Without it the customer sees EximPe’s own result page |
| business_model | string | No | Whether the buyer is a business or a consumer. | B2B or B2C, uppercase; derived from your KYC when omitted |
| purpose_code | string | No | FEMA/FETERS purpose code the order settles under. | Must be active and enabled on your account (e.g. S0802); derived from your KYC when omitted |
| buyer | object | Yes | The buyer. | See Buyer |
| product | object | Yes | What is being sold. | See Product |
| invoice | object | Yes | Invoice metadata. | See Invoice |
purpose_code, it is filled in only if your account has exactly one allowed code; otherwise it is left unset for later classification. Neither business_model nor purpose_code is returned by Create Order, and neither can be changed after the order is created. Read them back with Get Order Details.
Buyer
| Name | Type | Required | Description | Constraints |
|---|---|---|---|---|
| name | string | Yes | Full name. | Max 255 chars |
| string | Yes | Email address. | A valid email address | |
| phone | string | Yes | Phone number with country code. | E.164: +, the country code, then the number, e.g. +919812345678; 9812345678 is refused |
| address | object | Yes | Address. | See Address |
| ip_address | string | Conditional | The customer’s IP address. | S2S UPI Intent: required. IPv4 or IPv6 |
| user_agent | string | Conditional | The customer’s browser user agent. | S2S UPI Intent: required |
Address (buyer.address)
| Name | Type | Required | Description | Constraints |
|---|---|---|---|---|
| line_1 | string | No | Address line 1. | |
| line_2 | string | No | Address line 2. | |
| city | string | No | City. | Max 255 chars |
| state | string | No | State. | Max 255 chars |
| postal_code | string | Yes | PIN code. | A valid 6-digit Indian PIN code |
Product
| Name | Type | Required | Description | Constraints |
|---|---|---|---|---|
| name | string | Yes | Product or service name. | |
| description | string | No | Description. | Max 1024 chars |
| type_of_goods | string | Yes | Nature of what is sold. | physical_goods, digital_goods or service |
| hs_code | string | Conditional | 8-digit HS code. | Required for physical_goods; must be a known HS code |
| hs_code_description | string | No | HS code description. |
Invoice
| Name | Type | Required | Description | Constraints |
|---|---|---|---|---|
| number | string | Yes | Invoice number. | Max 255 chars. Letters, numbers, spaces and . , ' - / & _ ( ) : ; ! @ # $ % * + = < > [ ] { } | ~ — unlike reference_id, underscores are allowed. Unique across your orders that have not failed |
| date | string | No | Invoice date. | YYYY-MM-DD |
Examples
{
"amount": "1000.00",
"currency": "INR",
"reference_id": "ORDER-123456",
"collection_mode": "hosted_payment",
"mop_type": "upi",
"return_url": "https://yourdomain.com/payment/callback/",
"business_model": "B2C",
"buyer": {
"name": "Alice Smith",
"email": "[email protected]",
"phone": "+919812345678",
"address": {
"line_1": "221B Baker Street",
"city": "Mumbai",
"state": "Maharashtra",
"postal_code": "400001"
}
},
"product": {
"name": "Wireless Headphones",
"description": "Premium noise-cancelling wireless headphones",
"hs_code": "85183000",
"hs_code_description": "Headphones and earphones, whether or not combined with a microphone",
"type_of_goods": "physical_goods"
},
"invoice": {
"number": "INV-2026-0001",
"date": "2026-09-21"
}
}
{
"amount": "1000.00",
"currency": "INR",
"reference_id": "ORDER-123457",
"collection_mode": "s2s",
"mop_type": "upi",
"upi_flow_type": "intent",
"buyer": {
"name": "John Doe",
"email": "[email protected]",
"phone": "+919876543210",
"address": {
"line_1": "123 Main Street",
"city": "Delhi",
"state": "Delhi",
"postal_code": "110001"
},
"ip_address": "203.0.113.10",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
},
"product": {
"name": "Smartphone",
"description": "This is a sample product description",
"hs_code": "85171290",
"hs_code_description": "Telephones for cellular networks, other than smartphones",
"type_of_goods": "physical_goods"
},
"invoice": {
"number": "INV-2026-0002",
"date": "2026-09-21"
}
}
Response
A successful create returns201 Created.
Hosted Checkout
order_id: The order’s IDsession_id: A 64-character hex string. Pass it to the EximPe JS SDK to open the payment page
session_id is valid for 15 minutes. After that, create a new order to get a fresh one. An expired or already-completed session returns Invalid or expired session.S2S UPI Intent
order_id: The order’s IDintent_uri: The UPI payment request to open the customer’s UPI app with. See Invoking the intentexpires_at: When the intent stops accepting payment, in UTC — 5 minutes after creationtest_simulator_url: Sandbox only. Open it in a browser to complete the payment without a real UPI app; the result follows the test VPA you use in the simulator. Not returned in production
Invoking the intent
Depending on how your account collects UPI,intent_uri comes either as a complete URI (upi://pay?pa=...) or as its query string alone (pa=...&pn=...). Handle both: if it does not start with upi://, prefix it with upi://pay? before invoking it, and never add a second scheme. See the integration guide for Android, iOS and desktop handling.
{
"success": true,
"message": "Checkout session created successfully",
"data": {
"session_id": "b4db5e1c82db8636094f54e3293218172ae2ab87dee6ce4e97c82db6c63f243a",
"order_id": "OD5916184980"
}
}
{
"success": true,
"message": "S2S UPI Request created successfully",
"data": {
"intent_uri": "upi://pay?pa=merchant.sandbox@examplebank&pn=Example%20Merchant&am=1000.00&cu=INR&tn=OD2000992103&tr=403993715534292371",
"order_id": "OD2000992103",
"expires_at": "2026-09-21T10:35:00.156967Z"
}
}
{
"success": true,
"message": "S2S UPI Request created successfully",
"data": {
"intent_uri": "upi://pay?pa=merchant.sandbox@examplebank&pn=Example%20Merchant&am=1000.00&cu=INR&tn=OD2000992103&tr=403993715534292371",
"order_id": "OD2000992103",
"expires_at": "2026-09-21T10:35:00.156967Z",
"test_simulator_url": "<simulator URL returned by the sandbox API>"
}
}
Errors
Refusals use the standard envelope:success is false, and error carries a code, a message and details. A 400 always carries ERR_ORDER_002 — read details to see what failed and fix that field before retrying.
| Status | error.code | When | details |
|---|---|---|---|
400 | ERR_ORDER_002 | A field is missing or invalid | Keyed by field and nested like the request, one message per field, e.g. {"buyer": {"phone": "Enter a valid phone number."}} |
400 | ERR_ORDER_002 | reference_id has a character other than a letter, number or hyphen | {"reference_id": "Invalid input: ORDER_123456"} |
400 | ERR_ORDER_002 | reference_id is already used by one of your orders | {"reference_id": "Reference ID already exists"} |
400 | ERR_ORDER_002 | invoice.number is already used by one of your orders that has not failed | {"invoice": {"number": "Invoice Number already exists"}} |
400 | ERR_ORDER_002 | collection_mode is missing or unrecognised | {"collection_mode": "Invalid collection mode"} |
400 | ERR_ORDER_002 | business_model is not B2B or B2C | {"business_model": "\"b2b\" is not a valid choice."} |
400 | ERR_ORDER_002 | purpose_code is unknown or inactive | A string, not an object: "Invalid Purpose code given." |
400 | ERR_ORDER_002 | purpose_code is valid but not enabled on your account | A string, not an object: "Purpose code is not enabled for this merchant." |
400 | ERR_ORDER_002 | amount is 0 or less, or above 10,000,000.00 | {"total_amount": "Total amount must be greater than 0"} or {"total_amount": "Total amount must be less than or equal to 10,000,000"} |
401 | ERR_AUTH_000 | X-Client-ID or X-Client-Secret is missing | {"authentication": "Missing credentials."} |
401 | ERR_AUTH_001 | The credentials are wrong | {"authentication": "Invalid credentials."} |
401 | ERR_AUTH_000 | A PSP left out X-Merchant-ID | {"authentication": "X-Merchant-ID header is required for this endpoint."} |
401 | ERR_AUTH_001 | X-Merchant-ID is not one of your active sub-merchants | {"authentication": "Invalid X-Merchant-ID provided."} |
403 | ERR_MERCHANT_ACCOUNT_002 | Your merchant account is not active | {"authentication": "Merchant account is inactive."} |
403 | — | S2S payments are not enabled on your account | Not the standard envelope: {"detail": "You do not have permission to perform this action."} |
500 | ERR_SERVICE_ERROR_000 | Anything unexpected | {"error": "An unexpected error occurred. Please try again later"} |
{
"success": false,
"error": {
"code": "ERR_ORDER_002",
"message": "Validation error",
"details": {
"reference_id": "Reference ID already exists"
}
}
}
Duplicate requests
reference_idis single-use. It must be unique across all your orders, whatever their status — a failed order still holds itsreference_id. Sending one that is already used is refused withReference ID already exists; the original order is not returned.invoice.numberis unique across your orders that have not failed. Once an order fails, its invoice number can be used again.- For a PSP, both rules apply per sub-merchant.
After creating the order
- Hosted Checkout. Load the EximPe JS SDK on your page and call
eximpe.checkout({ sessionId })within 15 minutes. The customer is sent to yourreturn_urlwhether the payment succeeds, fails or is cancelled. - S2S UPI Intent. Invoke the
intent_urion the customer’s device beforeexpires_at. - Confirm the outcome from your backend. Never trust the redirect or the UPI app alone: check the Order Status API or wait for the Payment Successful webhook.
Authorizations
Client Application ID - Your unique application identifier used to authenticate API requests. You can find your Client ID in the Developer Settings section of the merchant dashboard.
Client Secret Key - Your secret key used alongside the Client ID for secure authentication. Keep this confidential and never expose it in client-side code. Available in the Developer Settings section of the merchant dashboard.
Headers
The API version you integrate against. Send 3.0.0 for v3. It is a version selector, not a credential.
3.0.0 Body
Order creation request
Amount in rupees, as a decimal string such as "1000.00". A JSON number is also accepted. More than two decimal places are rounded to two, so 1000.456 is charged as 1000.46. Must be greater than 0 and at most 10,000,000.00.
"1000.00"
ISO 4217 currency code. Hosted Checkout and S2S UPI Intent collect in INR only.
INR Your reference for the order: letters, numbers and hyphens only. Must be unique across your orders, including failed ones.
1 - 50^[A-Za-z0-9-]+$"ORDER-123456"
Mode of payment collection. Required — there is no server-side default.
hosted_payment, s2s Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Optional. Where Hosted Checkout sends the customer when the payment finishes. Without it the customer sees EximPe's own result page. S2S UPI Intent does not redirect the customer.
500Hosted Checkout: optional, pre-selects a payment method on the payment page. S2S UPI Intent: must be upi.
credit_card, debit_card, upi, net_banking, qr Required for S2S UPI Intent, where it must be intent. Not used by Hosted Checkout.
intent Whether the buyer is a business (B2B) or a consumer (B2C). Optional — derived from the merchant's KYC when omitted.
B2B, B2C FEMA/FETERS purpose code this order settles under (e.g. S0802). Optional — derived from the merchant's allowed purpose codes when omitted and exactly one is allowed.
"S0802"