Hosted QR checkout
Errors and limits
Every refusal, what it means and what fixes it. A refused create never makes a payment.
What an error looks like
Errors are JSON with success: false. Validation problems come as a list in errors; everything else as one error, sometimes with a message or a statusCode.
{
"success": false,
"errors": [
"reference is required",
"amount is required",
"paymentType is required",
"returnUrl is required"
]
}
Creating a checkout
| HTTP | You see | Meaning | Fix |
|---|---|---|---|
400 | errors: ["reference is required", …] | A required field is missing or wrong. | Send reference, amount, paymentMethod: "qr", paymentType: "onetime" and a valid returnUrl. |
400 | statusCode: "DECIMAL_VALUES_NOT_SUPPORTED" | The amount is not whole rupees. | Send 1500, not 1500.50. |
400 | statusCode: "AMOUNT_NOT_SUPPORTED" | The amount is below PKR 300. | Send 300 or more. |
400 | error: "Duplicate reference. …" | You already used this reference. | It exists: read it with GET /api/v1/transactions/{reference}. For a new attempt, use a new reference. |
400 | errors: ["accountNumber and walletName must be passed together"] | Only one of the two was sent. | Send both, or neither. |
400 | errors: ["walletName must be one of …"] / ["accountNumber must be a mobile wallet number, …"] | The value is not allowed. | walletName: easypaisa, jazzcash, sadapay or nayapay. accountNumber: 03XXXXXXXXX. |
401 | error: "Missing X-Api-Key header" / "Invalid API key" | The key is missing or wrong. | Send your payment key in X-Api-Key. Check for a stray space or line break. |
401 | error.code: "SIGNATURE_…" | Request signing is on for your account and the signature failed. | See Signing errors. |
403 | error: "IP_ALLOWLIST_NOT_CONFIGURED" | No server address is on your account yet. | Send your server's public IP to your account manager. |
403 | error: "IP_NOT_ALLOWED" | The call came from an address that is not on your list. | Find the address your server really calls from and ask us to add it. |
403 | error: "MERCHANT_INACTIVE" | Your account is not active. | Contact support. |
403 | statusCode: "QR_CLOSED" | New QR payments are paused for the moment. | Try again later. Payments already started still complete. |
422 | statusCode: "NO_PSP_ROUTE" / "NO_RATE_CONFIGURED" | Your account is not fully set up for QR yet. | Your request is fine. Contact your account manager. |
429 | error: "Too Many Requests" | You went over the rate limit. | Wait for the number of seconds in the Retry-After header, then send the same request. |
500, timeout | error: "Failed to create checkout session", or no answer | The checkout may or may not exist. | Ask GET /api/v1/transactions/{reference} before you create again. |
503 | code: "SERVICE_PAUSED" | Payments are paused for maintenance. | Try again later (see Retry-After). |
Status calls
| HTTP | You see | Meaning |
|---|---|---|
404 | error: "Transaction not found" / "Checkout session not found" | The API's own answer: no payment with that reference or id on your account. After a failed create, this (and only this) means it is safe to create again. |
404 | error: "NOT_FOUND" | The address was refused before it reached the API: a wrong path or method (see the API reference), or a reference with characters other than letters, digits, ., _ and -. It does not mean the payment does not exist. Do not create again because of it. |
401, 403, 429 | as above | The same causes and fixes as on create. |
Rate limits
Per API key, shared by all three calls. A customer's use of the payment page does not count against your key.
| Window | Limit |
|---|---|
| per second | 10 |
| per minute | 300 |
| per hour | 18,000 |
| per day | 432,000 |
{
"success": false,
"error": "Too Many Requests",
"message": "Rate limit exceeded: 300 requests per minute",
"retryAfter": 12
}
Back off for Retry-After seconds. Do not judge by the X-RateLimit-Remaining header: it reports the widest window, so it can show a large number while the per-minute window is nearly spent. Refused requests (a bad signature, a validation error) still count.
Is it safe to retry?
| You got | Retry the same request? |
|---|---|
400, 401, 403, 422 | Only after fixing the cause. Nothing was created. |
429, 503 | Yes, after the wait. Nothing was created. |
500, a timeout, a dropped connection on create | Not blindly. Wait at least 80 seconds for the first answer. Then ask by reference; create again only if it returns 404 with "Transaction not found", and store the new checkoutId. |
| Any error on a status call | Yes. Status calls change nothing. |
Getting help
Write to support@antpay.network with your reference, the transactionId if you have one, the time of the request and the full answer you received. Never send your key or a secret.