A unified HTTP + JSON interface with SHA-256 signature verification, async notifications, and on-demand order queries. This page covers signing rules, every API field, and request examples.
India Payme offers merchants two core transaction capabilities: Payin — collecting payments from end users on the merchant's behalf; and Payout — sending payments to a specified account on the merchant's behalf. Every API is a POST with a JSON body and must include an API signature. Once processing completes, the platform calls back the merchant with an async notification, and on-demand order queries are also supported.
| Capability | Method | Path |
|---|---|---|
| Payin Order | POST | /transaction/payin/v1/apply |
| Payin Query | POST | /transaction/payin/v1/query |
| Payout Order | POST | /transaction/payout/v1/apply |
| Payout Query | POST | /transaction/payout/v1/query |
| Balance Query | POST | /transaction/payout/v1/balance |
Base URL (use the production gateway domain provided by the platform after you open an account):
Log in to the merchant dashboard → App Keys. Each app has a pair of credentials: appKey and appSecret. The appKey is used as the appId request header; appSecret is your signing key, used only for local signature calculation — never transmitted.
Every request must include the following HTTP headers, with Content-Type set to application/json:
| Header | Required | Description |
|---|---|---|
appId | Yes | Merchant app ID (i.e. your appKey) |
timestamp | Yes | Unix timestamp in milliseconds |
nonce | Yes | Random string, ≥10 characters, single-use only |
sign | Yes | Signature computed per the rules below |
The signing algorithm is plain SHA-256 (lowercase hex) — not HMAC. The appSecret is appended directly to the end of the string to be signed before hashing. Steps:
appId, timestamp, and nonce into a single map (sign itself is excluded);key1=value1&key2=value2…;appSecret directly to the end (no separator), then take the SHA-256 hash of the full string in lowercase hex to get sign.Expiry and replay protection:
|server time − timestamp| ≤ 30s. Requests outside this window return timestamp has expired. Make sure your client and the gateway have synchronized clocks (NTP).nonce has been used (error code 900).Node.js signing example:
POST /transaction/payin/v1/apply — creates a payment collection order and returns a checkout link payUrl that guides the user to complete payment.
| Field | Type | Required | Description |
|---|---|---|---|
merchantOrderNo | string | Yes | Merchant order number, must be unique |
amount | number | Yes | Order amount, decimal (e.g. 100.02) |
name | string | Yes | Customer name. English letters only, ≥3 characters, spaces allowed, no symbols or digits |
phone | string | Yes | Phone number |
email | string | Yes | Email address |
currency | string | Yes | Currency: INR / PKR / USDT / BDT |
product | string | Yes | Payment product code, issued by the platform per your agreement |
notifyUrl | string | No | Async notification URL; falls back to your default notification address if omitted |
returnUrl | string | No | Redirect page shown after successful payment |
payType | string | No | Direct wallet payment method: JAZZCASH / EASYPAISA / BKASH / NAGAD |
Once you have payUrl, redirect the user to complete payment. The final result is confirmed via the async notification.
POST /transaction/payout/v1/apply — initiates a payment to a specified account. Processed asynchronously: the API first validates and holds the account, then matches a channel to disburse funds asynchronously. The immediate response is typically payStatus=0 (accepted), with the final outcome confirmed via query or notification.
| Field | Type | Required | Description |
|---|---|---|---|
merchantOrderNo | string | Yes | Merchant order number |
amount | number | Yes | Payment amount, minimum 100.00 |
accountName | string | Yes | Recipient name. English letters only, ≥3 characters, spaces allowed |
account | string | Yes | Recipient account number |
phone | string | Yes | Phone number |
email | string | Yes | Email address |
currency | string | Yes | Currency: INR / PKR / USDT / BDT |
bizCode | string | Yes | Disbursement type: IMPS / UPI / BANK / JAZZCASH / EASYPAISA / BKASH / NAGAD / ECARD |
payCode | string | Yes | Payment method: CARD / WALLET / NBK / ITT / VC |
branchCode | string | Yes | Clearing code: IFSC for India; bank code for Pakistan; per bizCode for Bangladesh |
product | string | Yes | Payout product code, issued by the platform |
bankName | string | No | Bank name |
swiftCode | string | No | SWIFT code (used for cross-border wire transfers via ITT) |
Payin: POST /transaction/payin/v1/query. Payout: POST /transaction/payout/v1/query. Pass merchantOrderNo or orderNo to locate the order. Rate limit: 5 requests/second.
POST /transaction/payout/v1/balance — queries the merchant account balance. Rate limit: 5 requests/second.
Once an order reaches a final state, the platform sends a POST (JSON) notification to the merchant's notifyUrl (or the default address if none was provided), including the same signature headers (appId/timestamp/nonce/sign). Merchants should recompute the signature with their own appSecret using the same rules and compare it to verify the notification is authentic.
The payin notification payload includes: merchantOrderNo, orderNo, currency, product, amount, realAmount, and status ("1" for a successful payment). The payout notification additionally includes utr (bank reference number) and statusDes (status description), where status is "1" for success or "2" for failure.
Merchants must respond with the plain text OK or success (case-insensitive). Otherwise the platform queues a retry: up to 5 attempts, with increasing intervals in minutes (1 / 2 / 5 / 10 / 30 / 60 / 120). Your notification handler must therefore be idempotent — the same orderNo may be delivered more than once.
Integrate against the following public-facing statuses (the internal state machine is more granular and not exposed directly):
| Scenario | Field | Values |
|---|---|---|
| Order creation response | payStatus | 0 created / 1 success / 2 failed / 3 cancelled |
| Payin query | payStatus | 0 processing / 1 paid / -1 cancelled |
| Payout query | payStatus | 0 pending / 1 paid / -1 cancelled |
| Async notification | status | Payin success "1"; payout "1" success / "2" failed |
A response with code != 0 indicates failure, with msg giving the reason. Common business error codes:
| code | Description |
|---|---|
0 | Success |
400 | Invalid parameter / signature verification failed (Sign invalid) |
900 | Duplicate request / nonce replay |
10000 / 10001 | App not found / app disabled |
10002 | Currency not supported |
10003 / 10007 | Merchant disabled / merchant account disabled |
10004 | Product not enabled or agreement expired |
10005 / 10009 | No channel available / channel temporarily unavailable |
10008 | Insufficient account balance |
10010 | IP not in allowlist |
10011 / 10012 | Invalid product / invalid payment method |
10020 | Duplicate merchant order number |
30001 / 30002 | Invalid order number / invalid currency or account not activated |
Using payin as an example:
timestamp (milliseconds) and a nonce (random string, ≥10 characters).sign per the "Signing Rules" above.POST /transaction/payin/v1/apply with the 4 signature headers plus the JSON body.code==0, take data.payUrl and redirect the user to complete payment.OK.Note: the API paths, fields, and status codes described here match the production implementation. The production gateway domain, available product codes, and IP allowlist policy will be provided by the platform once your account is set up.
Open an account online to receive test credentials and product codes — go live with one click once your sandbox integration is verified.