MeraOTP developer guides

Troubleshooting

Clear steps, real API formats, and backend-only examples. Read every guide without signing in.

API v1Reviewed 27 October 2026Get integration help

Start with the HTTP status and error code

A request failing does not always mean an SMS failed or a customer payment was declined. First identify which product and operation returned the error.

OTP responses use top-level code and message. Payment Solution API errors use error.code and error.message. Keep the HTTP status alongside the JSON. Do not treat every HTTP 200 or success: true as a paid transaction or verified person.

Example OTP error

{
    "success": false,
    "code": "INSUFFICIENT_BALANCE",
    "message": "Wallet balance is too low.",
    "data": {}
}

Example Payment Solution error

{
    "success": false,
    "error": {
        "code": "PAYMENT_TOOLS_SUBSCRIPTION_REQUIRED",
        "message": "An active Payment Tools subscription is required."
    }
}

OTP errors and the safe next step

400 INVALID_JSON
Send a JSON object and Content-Type: application/json. Do not submit an HTML form to the JSON endpoint.
401 MISSING_API_TOKEN / INVALID_API_TOKEN
Send the complete account key as a Bearer token from your backend. Check for extra spaces or an old key after regeneration.
403 API_KEY_DISABLED / IP_BLOCKED
Enable your account key if you disabled it. A security block is not a network setup task; contact support rather than attempting to bypass it.
402 INSUFFICIENT_BALANCE
Add wallet credit before trying again. This is a local credit rejection, not proof that an SMS provider failed.
409 IDEMPOTENCY_CONFLICT
The attempt key was already used for different data. Reuse the original payload for that attempt, or make a genuinely new user-requested attempt with a new key.
410 OTP_EXPIRED
Ask the person to request a fresh code. Do not reuse the expired message ID for a new action.
422 OTP_MISMATCH / INVALID_OTP_LENGTH / INVALID_MOBILE
Check the user's input. Use a valid Indian number and a supported 4, 5 or 6-digit length. Do not retry wrong codes in a loop.
429 RATE_LIMITED
Pause and back off. Reduce per-user sends and polling frequency; avoid starting parallel retries.
202 pending reconciliation / unknown outcome
Save any message ID and check the original attempt. Do not immediately generate another idempotency key and send another SMS.
503 provider error
Keep the exact provider/error code and any message ID. Inspect the original status or retry cautiously with the same idempotency key and payload. A provider-configuration error needs platform support, not a changed recipient number.

Payment errors and the safe next step

403 PAYMENT_TOOLS_SUBSCRIPTION_REQUIRED
Activate or renew a Payment Solution plan. OTP wallet credit alone does not activate this separate product.
409 PAYMENT_PROFILE_REQUIRED
Send both merchant_id and vpa, or save a matching business account in Setup. Supplying the complete API pair needs no saved profile.
409 ORDER_ID_ALREADY_EXISTS
Check the existing order. If recovering from a timeout, do not create another customer charge by automatically assigning a new ID. Only a genuinely different order should have a new ID.
422 INVALID_MERCHANT_ID / MERCHANT_VPA_REQUIRED / VPA_NOT_ALLOWED
Use the exact case-sensitive MID and its matching business VPA. For an unsaved account send the complete pair. A lone MID or VPA selects only a matching account in your own saved list.
422 MERCHANT_ID_MISMATCH / AMOUNT_MISMATCH
Do not fulfil. Compare your stored order and expected amount. An existing link's receiving account cannot be switched during verification.
422 INVALID_REDIRECT_URL
Use your HTTPS completion URL without embedded credentials or a URL fragment. Query parameters are permitted.
429 PAYMENT_LINK_LIMIT_REACHED
Your plan's link quota has been used. Review usage and upgrade or renew as appropriate.
503 PAYMENT_LINK_BUSY
A link is being created for the same account. Wait briefly and retry with the same order ID.
Pending, unknown, failed or expired with a claimed deduction
Recheck the original order and exact amount. Keep it unfulfilled until payment is confirmed. Do not use a screenshot or browser redirect as proof, and do not ask for another payment before checking the first one.

Connection, QR and webhook problems

The response is HTML instead of JSON

Check that you called the full /api/v1/... endpoint rather than a login or dashboard URL. Record the HTTP status and content type. Do not disable HTTPS verification or forward a live key to an unrelated host to work around a proxy/hosting error.

A QR image does not appear on another website

Use the returned public qr_url or qr_png_url in an image element. An expired, cancelled or failed checkout may no longer serve a usable QR. Check your site's own image security policy too. An image URL is not the authenticated payment-status endpoint and does not need your API key in the browser.

A webhook did not arrive or failed signature validation

Confirm that the webhook is configured in Payment Solution Setup, uses reachable HTTPS and has the correct separate secret. Validate the original raw body before JSON parsing or reformatting it. Keep an authenticated status-check fallback for missed deliveries.

What to send support

Include the product, endpoint, HTTP status, error code, request time with timezone and a non-secret message/order reference. Add a redacted response if useful. Never include your API key, password, webhook secret, OTP or UPI PIN.

Continue with the OTP API reference, payment integration guide or wallet and plan guide.

Need a hand?

Send support the endpoint, request time, error code and a non-secret reference. Never send your API key, password, webhook secret or an OTP.

Contact developer support