Troubleshooting
Quick reference for every error code across all Onmeta APIs, plus solutions for common integration problems.
Error Code Reference
Authentication
| Code | Message | Cause | Fix |
|---|---|---|---|
401 | Unauthorized | Missing, expired, or invalid Authorization: Bearer token | Re-authenticate the user with POST /v1/users/login. Access tokens expire after 15 min. |
On-Ramp — Create Order (POST /v1/orders/create)
| Code | Message | Cause | Fix |
|---|---|---|---|
404 | Token not supported | The requested token is not enabled for your API key | Use the Fetch Tokens API to get the list of supported tokens |
403 | blocked profile | INR only. User has been flagged by the risk engine | Do not retry. Show the user a support message. |
430 | Wallet Address already used with another Email | A wallet address can only be linked to one user account | Use a different wallet address |
429 | Daily limit exceeded. Available is Amount={remaining} | INR only. User's daily transaction limit reached | Use the Fetch User Limit API to show the remaining limit before order creation |
400 | Income not verified | INR only. User has not submitted income verification | Redirect user to the KYC Widget — they are auto-redirected to income verification after login |
Off-Ramp — Create Order (POST /v1/offramp/orders/create)
| Code | Message | Cause | Fix |
|---|---|---|---|
400 | unsupported fiat currency: {currency} | Only INR is supported | Always pass fiatCurrency: "inr" |
400 | fiat amount less than min amount, {amount} | Order amount is below the minimum | Check minimums using the Chain-wise Limits API before order creation |
400 | Sender wallet address is required | senderWalletAddress is missing | Include senderWalletAddress in the request (not required for merchant wallet flow) |
404 | Bank details are not found for the user | No bank account is linked to the user | Link a bank account first using Link Bank Account |
400 | Insufficient merchant wallet balance | Merchant wallet does not have enough funds | Top up the merchant wallet using Load Merchant Wallet |
400 | Income not verified | User has not submitted income verification | Redirect user to the KYC Widget |
Bank Linking (POST /v1/users/account-link)
| Code | Message | Cause | Fix |
|---|---|---|---|
406 | Account already verified | This bank account is already linked and verified | No action needed — account is ready to use |
423 | Bank account verification is pending | Verification services failed to verify account | Retry account linking |
UPI Linking (POST /v1/users/upi-link)
| Code | Message | Cause | Fix |
|---|---|---|---|
400 | invalid upiId format | UPI ID does not match VPA format (handle@bank) | Validate the UPI ID format before submitting |
400 | Invalid VPA | upiId field is empty in the request | Include a non-empty upiId in the request body |
400 | KYC not verified | User has not completed KYC | Complete KYC first via the KYC Widget or POST /v1/users/upload/kyc |
400 | Maximum limit of adding UPI IDs reached... | User already has 50 UPI IDs linked | Contact support@onmeta.in |
Transaction Hash (POST /v1/offramp/orders/txnhash · POST /v1/merchant/wallet/transactions/hash)
| Code | Message | Cause | Fix |
|---|---|---|---|
400 | invalid hash (...) | The submitted txnHash is not a valid blockchain transaction hash | Verify the hash format — it must be a real on-chain transaction hash |
404 | Order not found | orderId does not exist or belongs to a different user | Check the orderId value |
409 | Duplicate transaction hash | This hash is already linked to another order | Each on-chain transaction can only be submitted once |
409 | Order not in valid status | Order is not in a pending state | A hash can only be submitted once per order |
409 | Invalid address | The on-chain sender address does not match the address registered on the order | Ensure funds are sent from the wallet address specified in the order |
409 | Sender address missing in transaction data | senderWalletAddress was missing when the off-ramp order was created | Re-create the order with senderWalletAddress included (off-ramp only — not applicable to merchant wallet flow) |
409 | Invalid token received. Refund process initiated | Token or amount received on-chain does not match the order | Onmeta will automatically refund the tokens — no action needed |
Common Integration Problems
Order stuck at fiatPending after user submitted payment
The UTR (Unique Transaction Reference) was not submitted. After a user completes a bank transfer or UPI payment, you must call POST /v1/orders/utr with the UTR number. Without this, Onmeta cannot match the payment to the order.
If the user already submitted the UTR manually but the order is still stuck, contact support with the orderId and utr.
Webhook signature verification failing
Common causes:
- Using the Client ID as the HMAC secret instead of the Client Secret. Use the Client Secret from Dashboard → Setup → API's Setup.
- Computing the HMAC over a stringified request body that has been parsed and re-serialized — key ordering may differ. Always compute HMAC on the raw incoming body string before JSON parsing.
- Whitespace or encoding differences in the body. Some frameworks silently modify the body before your handler sees it. Read the raw bytes.
Bank verification always returns PENDING
PENDING means the verification partner could not confirm the account automatically. Retry linking — most accounts resolve to SUCCESS or FAILED within a few attempts. If it stays PENDING after retries, the account may move to MANUAL status, which requires the user to submit a bank passbook or statement.
Order moved to fiatRefundInitiated
Payment was received from a bank account or UPI ID that is not linked to the user's Onmeta profile. Onmeta cannot process this payment and initiates a fiat refund automatically. The refund reaches the user's bank within 24 hours.
To prevent this: display a clear instruction before payment — "Pay only from your registered bank account or UPI ID."
Getting 401 on every API call even with a fresh token
Verify that your request includes both authentication credentials where required:
- Header:
Authorization: Bearer <accessToken>— the user's JWT from login - Header or body field:
x-api-keyorapikey— your merchant Client ID
Some endpoints require only the API key; user-specific endpoints require both. Check the request schema for each endpoint.
Rate Limits
Onmeta enforces a global rate limit across all API endpoints. If you exceed the limit your requests receive 429 responses. Contact support@onmeta.in or your integration contact for your account's specific limit and to request an increase.