Errors
The error format, every error code, and what to send support.
Errors use standard HTTP status codes and one JSON shape:
{
"error": {
"code": "external_id_conflict",
"message": "A payment with this external_id already exists for this business.",
"param": "external_id",
"request_id": "req_1df6dd76-0350-479c-a234-e16d63b0f78b"
}
}codeis stable and machine-readable — switch on it. New codes can be added, so keep a default branch.messageis for humans and may change.paramnames the offending field when there is one.request_id— include it when you contact support. It lets us find the exact request.
The SDK raises typed errors (PayTakaValidationError, PayTakaAuthenticationError, PayTakaRateLimitError, PayTakaIdempotencyError, PayTakaAPIError, PayTakaNetworkError), each with code, message, param, requestId and httpStatus.
Handling an error#
import { PayTakaAPIError } from "@paytaka/sdk"
try {
await paytaka.payments.create({ amount: 500 })
} catch (error) {
if (error instanceof PayTakaAPIError) {
console.error(error.code, error.requestId)
}
}Not sure what a code means? See Troubleshooting.
Error codes#
| Code | HTTP | Meaning |
|---|---|---|
| invalid_api_key | 401 | The API key is missing, malformed, unknown, or revoked. |
| insufficient_scope | 403 | The key lacks the scope (payments:read or payments:write) this endpoint needs. |
| rate_limit_exceeded | 429 | Too many requests for this key. Honor the Retry-After header. |
| invalid_request | 400 | The request body or a parameter is malformed. |
| invalid_amount | 400 | amount must be a positive decimal string with at most two decimals, e.g. "500.00". |
| invalid_external_id | 400 | external_id is invalid or too long. |
| invalid_metadata | 400 | metadata exceeds its limits (20 keys, 64-char keys, 500-char values). |
| invalid_return_url | 400 | return_url must be an absolute https URL or a native app deep link. |
| invalid_allowed_method | 400 | allowed_methods must only name BKASH or NAGAD. |
| invalid_allowed_channel | 400 | allowed_channels must only name SEND_MONEY, PAYMENT, CASH_IN or BANK_TRANSFER. |
| description_too_long | 400 | description is too long. |
| reference_too_long | 400 | merchant_reference is too long. |
| invalid_customer | 400 | customer_id does not belong to your business. |
| order_not_found | 400 | order_id does not exist for your business. |
| order_customer_mismatch | 400 | The payment's customer does not match the order's customer. |
| exceeds_order_due | 400 | amount exceeds the order's remaining due. |
| context_items_not_accepted | 400 | context_items are not accepted by the Developer API. |
| payment_not_found | 404 | No hosted payment with this id exists for this key's business and environment. |
| not_found | 404 | No such API route. |
| method_not_allowed | 405 | The HTTP method is not allowed for this route. |
| external_id_conflict | 409 | A payment with this external_id already exists (per business and environment). |
| idempotency_conflict | 409 | This Idempotency-Key was already used with a different request. |
| idempotency_in_progress | 409 | A request with this Idempotency-Key is still being processed; retry shortly. |
| invalid_transition | 409 | The payment is not in a state that allows this action (for example, cancelling a paid payment). |
| order_cancelled | 409 | The referenced order is cancelled. |
| payment_method_unavailable | 409 | None of the allowed payment methods are currently usable (live mode). |
| payment_channel_unavailable | 409 | No ready receiving number accepts the requested payment type (live mode). |
| payment_detection_not_ready | 409 | The business has no enabled, ready receiving method yet (live mode). |
| insufficient_credit | 409 | The business does not have enough Service Credit for the next fee (live mode). |
| internal_error | 500 | Something went wrong on PayTaka's side. Retry; quote request_id to support if it persists. |
Retrying#
Retry only what is safe. 429 (rate limit — wait for Retry-After) and 5xx are retryable; other 4xx errors are not — fix the request. Always retry a create with the same Idempotency-Key (the SDK does this for you). See Idempotency.