Error Codes & Troubleshooting
When an API request encounters an issue, the SureLink Gateway returns standard HTTP status codes along with a consistent JSON error envelope.
1. Error Response Format
All error responses adhere to the following schema:
json
{
"statusCode": 401,
"errorCode": "MERCHANT_API_UNAUTHORIZED",
"message": "unauthorized"
}2. Global Error Code Catalog
| HTTP Status | Error Code (errorCode) | Default Message | Root Cause & Resolution |
|---|---|---|---|
401 | MERCHANT_API_UNAUTHORIZED | unauthorized | Authentication Failure: 1. Missing required headers ( X-Api-Key, X-Timestamp, X-Nonce, X-Signature);2. Timestamp deviates by more than $\pm 5$ minutes; 3. Nonce length not in 16–64 chars or replayed within 10 minutes; 4. API Key is inactive or revoked; 5. HMAC-SHA256 signature mismatch. |
403 | IP_NOT_WHITELISTED | client IP is not in merchant IP whitelist | IP Rejected: The outbound public IP of the caller is not listed in the merchant's configured IP whitelist. |
404 | ORDER_NOT_FOUND | order not found | Not Found / Multi-tenant Filter: The requested order does not exist or belongs to another merchant. |
400 | PAYOUT_DISPUTE_REASON_REQUIRED | dispute requires a reason | Missing Dispute Reason: Calling the payout decision endpoint with decision === "DISPUTE" requires providing a non-empty reason. |
400 | BAD_REQUEST | (Field validation details) | Invalid Request Body: Validation failure (e.g., decimal places out of range, missing fields). |
409 | CONFLICT | resource conflict | Conflict: Duplicate order submission with conflicting parameters. |
503 | SERVICE_UNAVAILABLE | service temporarily unavailable | Maintenance: The gateway or order domain is temporarily undergoing scheduled maintenance. |
500 | INTERNAL_SERVER_ERROR | internal server error | Internal Failure: Transient server error. Contact technical support with your requestId. |
3. Troubleshooting Checklist
3.1 Signature Mismatch (MERCHANT_API_UNAUTHORIZED)
Over 90% of integration issues stem from signature calculation mismatches:
- Raw Body Inconsistency:
- Did your HTTP client format or re-serialize the JSON string (adding spaces or line breaks) after you computed the signature?
- Fix: Sign the exact raw byte string sent across the wire.
- GET Requests or Empty Bodies:
- For GET requests, the signing string must end with a trailing period:
${timestamp}.${nonce}.. Do not drop the final dot.
- For GET requests, the signing string must end with a trailing period:
- API Secret Accuracy:
- Verify that you are using the secret associated with the active API key and that there are no accidental leading/trailing whitespace characters.
- Hex String Lowercase:
- The computed signature must be an all-lowercase 64-character hex string.
3.2 Clock Skew (Timestamp Out of Window)
- The gateway rejects requests where the client timestamp differs from server time by more than 300 seconds (5 minutes).
- Fix: Synchronize your server clocks via NTP (
chronyorntpdate). - Note:
X-Timestampmust be a millisecond-level epoch timestamp (13 digits, e.g.,1715000000000), not a 10-digit second timestamp.
3.3 Nonce Collision (Replay Detected)
X-Noncemust be globally unique per API key across a 600-second window.- Fix: Use cryptographically secure random generators (e.g., Node.js
crypto.randomBytes(16).toString('hex')or Pythonsecrets.token_hex(16)). Avoid monotonic sequential counters across distributed servers.
3.4 IP Whitelist Block (IP_NOT_WHITELISTED)
- When deploying behind cloud providers (AWS NAT Gateway, Cloudflare, Alibaba Cloud), the public egress IP may differ from your server's private or elastic IP.
- Fix: Run
curl https://api.ipify.orgfrom your server command line to discover your true public egress IP, then add it to your Merchant Portal whitelist.
