PayzCore Docs

Error Reference

Complete API error reference. HTTP status codes, error response format, common error messages, rate limit headers, and how SDKs map errors to typed exceptions.

Error Reference

All PayzCore API errors follow a consistent JSON format. This page documents every error status code, the response structure, common error messages, and how to handle them.

Response Format

Every error response includes an error field with a human-readable message. Some errors include additional fields for context.

Standard Error

{
  "error": "Description of what went wrong"
}

Validation Error (with details)

{
  "error": "Invalid request body",
  "details": [
    {
      "code": "invalid_type",
      "path": ["amount"],
      "message": "Expected number, received string"
    },
    {
      "code": "too_small",
      "path": ["external_ref"],
      "message": "String must contain at least 1 character(s)"
    }
  ]
}

Rate Limit Error (with plan info)

{
  "error": "Daily API call limit exceeded. Upgrade your plan for unlimited access.",
  "limit": 500,
  "plan": "free"
}

HTTP Status Codes

400 Bad Request

Validation errors caused by invalid parameters, missing required fields, or unsupported values.

Error MessageCause
Invalid request bodyJSON parse error or schema validation failure. Check details array for field-level errors.
USDC is not supported on TRC20Unsupported chain+token combination. See Supported Chains.
Amount must be at least $X.XX (project minimum)Payment amount is below the project's configured minAmount.
Project has no wallet assignedThe project needs a wallet before creating payments.
Wallet not foundThe wallet linked to the project was deleted or is missing.
Wallet has no xPub configured for CHAIN (FAMILY family)The wallet is missing the xPub key for the requested chain's address family (tron or evm).
No static addresses available for CHAINStatic wallet mode is configured but no addresses are registered for this chain.
Specified address does not belong to this project's walletThe address parameter (dedicated mode) references an address not in the wallet's static address pool.
No addresses available for this chain. Contact merchant.All static addresses in the pool are already assigned (dedicated mode).
Invalid pool match methodPool mode configuration error.
Invalid address modeProject has an unrecognized address mode.
Invalid limit or offsetPagination parameters must be positive integers. limit max is 100.
Invalid status filterStatus must be one of: pending, confirming, partial, paid, overpaid, expired, cancelled.
Invalid created_afterDate parameter is not a valid ISO 8601 string.
Invalid updated_afterDate parameter is not a valid ISO 8601 string.

How to fix: Check the details array for specific field-level validation errors. Correct the request parameters and retry.

401 Unauthorized

Authentication failed. The API key is missing, invalid, or malformed.

Error MessageCause
Missing x-api-key headerThe x-api-key header was not included in the request.
Invalid API keyThe API key does not match any active project.

How to fix: Verify your API key is correct and included in the x-api-key header. API keys start with pk_live_. If you lost your key, an admin can regenerate it from the project settings.

403 Forbidden

The request was authenticated but is not allowed due to access restrictions.

Error MessageCause
Project is deactivatedAn admin has deactivated this project.
Account suspended. Contact support.The project owner's account has been suspended.

How to fix: Contact PayzCore support or your account administrator. Deactivated projects cannot make API calls until reactivated.

404 Not Found

The requested resource does not exist or is not accessible by this API key.

Error MessageCause
Payment not foundThe payment ID does not exist or belongs to a different project.

How to fix: Verify the payment ID is correct. Each project can only access its own payments.

409 Conflict

The request conflicts with an existing resource.

Error MessageCause
Duplicate external_order_idA payment with the same (external_order_id, external_ref, chain, token) already exists. The existing payment is returned with "existing": true.

Note: This is not strictly an error. PayzCore uses external_order_id for idempotency. When a duplicate is detected, the response contains "existing": true with the original payment data. This allows safe retries without creating duplicate payments.

429 Too Many Requests

Rate limit exceeded. There are two types of rate limits:

Per-Minute Rate Limit (burst protection)

Limits the number of requests per API key per minute. Default: 60 requests/minute.

{
  "error": "Rate limit exceeded. Try again later."
}

Response headers:

HeaderValueDescription
X-RateLimit-Limit60Maximum requests per window
X-RateLimit-Remaining0Remaining requests in current window
X-RateLimit-Reset1708444800Unix timestamp (seconds) when the window resets

Daily Limit (plan-based)

Limits total API calls per day based on your plan.

{
  "error": "Daily API call limit exceeded. Upgrade your plan for unlimited access.",
  "limit": 500,
  "plan": "free"
}

Response headers:

HeaderValueDescription
X-RateLimit-Limit500Daily limit for your plan
X-RateLimit-Remaining0Remaining calls today
X-RateLimit-Reset1708473600Unix timestamp (seconds) when the daily counter resets (midnight UTC)
X-RateLimit-DailytrueIndicates this is a daily limit (not per-minute)

Plan limits:

PlanAPI Calls/DayWebhooks/Day
Free500100
Pro25,00010,000

Admin-configured custom overrides may apply per user.

Capacity Limit (pool mode)

When using pool+micro_amount mode, all available offsets for the requested amount may be exhausted:

{
  "error": "Payment capacity exceeded. Please try again later."
}

How to fix for per-minute limits: Wait for the reset time indicated in the X-RateLimit-Reset header. Implement exponential backoff in your client.

How to fix for daily limits: Wait until midnight UTC, or upgrade to the Pro plan for higher limits.

How to fix for capacity limits: Wait for existing payments on the pool to resolve (paid/expired), or add more static addresses.

500 Internal Server Error

An unexpected error occurred on the server.

{
  "error": "Failed to create payment"
}

How to fix: Retry the request with exponential backoff. If the error persists, check the health endpoint and contact support.

Recommended retry strategy:

AttemptDelay
11 second
22 seconds
34 seconds
48 seconds
5Give up, alert your team

SDK Error Handling

The official SDKs map HTTP errors to typed exception classes, making it easy to handle specific error types.

Node.js SDK

import {
  PayzCoreError,
  ValidationError,
  AuthenticationError,
  ForbiddenError,
  NotFoundError,
  RateLimitError,
} from '@payzcore/node'

try {
  const payment = await payzcore.payments.create({
    amount: 50,
    chain: 'TRC20',
    external_ref: 'customer-123',
  })
} catch (err) {
  if (err instanceof ValidationError) {
    // 400 - Check err.details for field-level errors
    console.error('Validation:', err.message, err.details)
  } else if (err instanceof AuthenticationError) {
    // 401 - Invalid API key
    console.error('Auth:', err.message)
  } else if (err instanceof ForbiddenError) {
    // 403 - Project inactive or account suspended
    console.error('Forbidden:', err.message)
  } else if (err instanceof NotFoundError) {
    // 404 - Resource not found
    console.error('Not found:', err.message)
  } else if (err instanceof RateLimitError) {
    // 429 - Rate limited
    console.error('Rate limited:', err.message)
    console.error('Retry after:', err.retryAfter, 'seconds')
    console.error('Is daily limit:', err.isDaily)
  } else if (err instanceof PayzCoreError) {
    // Other API errors (500, etc.)
    console.error('API error:', err.status, err.message)
  }
}

Error Class Hierarchy

HTTP StatusSDK ClassProperties
400ValidationErrormessage, status, code, details (field-level errors)
401AuthenticationErrormessage, status, code
403ForbiddenErrormessage, status, code
404NotFoundErrormessage, status, code
429RateLimitErrormessage, status, code, retryAfter (seconds), isDaily (boolean)
OtherPayzCoreErrormessage, status, code

All error classes extend PayzCoreError, which extends Error. You can catch PayzCoreError as a catch-all for any API error.

Python SDK

from payzcore import PayzCoreError, ValidationError, RateLimitError

try:
    payment = client.payments.create(
        amount=50, chain="TRC20", external_ref="customer-123"
    )
except ValidationError as e:
    print(f"Validation: {e.message}, details: {e.details}")
except RateLimitError as e:
    print(f"Rate limited, retry after: {e.retry_after}s")
except PayzCoreError as e:
    print(f"API error {e.status}: {e.message}")

PHP SDK

use PayzCore\Exceptions\ValidationException;
use PayzCore\Exceptions\RateLimitException;
use PayzCore\Exceptions\PayzCoreException;

try {
    $payment = $client->payments->create([
        'amount' => 50, 'chain' => 'TRC20', 'external_ref' => 'customer-123'
    ]);
} catch (ValidationException $e) {
    echo "Validation: " . $e->getMessage();
} catch (RateLimitException $e) {
    echo "Rate limited, retry after: " . $e->getRetryAfter() . "s";
} catch (PayzCoreException $e) {
    echo "API error {$e->getStatusCode()}: {$e->getMessage()}";
}

Best Practices

  1. Always check the status code first. Different status codes require different handling strategies.
  2. Parse the details array on 400 errors. It contains field-level validation information that helps you fix the request.
  3. Implement retry logic for 429 and 500 errors. Use the X-RateLimit-Reset header for rate limits and exponential backoff for server errors.
  4. Do not retry 400, 401, 403, or 404 errors. These indicate issues that need to be fixed in your code or configuration, not transient failures.
  5. Use external_order_id for idempotency. This prevents duplicate payment creation during retries and returns the existing payment safely.
  6. Log error responses. Store the full error response (including details) for debugging and support requests.
  7. Use typed SDK exceptions. The official SDKs provide specific error classes that make error handling clean and type-safe.

On this page