Skip to content

API Overview

The Zelta Pay API provides a RESTful interface for creating and managing payment links. This overview covers the essential information you need to get started.

https://api-pay.zelta.dev

All endpoints are versioned using the URL path:

/v1/payment-links

Breaking changes will be introduced under new version paths (e.g., /v2/payment-links).

The Zelta Pay API uses API key authentication. Include your API key in the X-API-Key header:

X-API-Key: your-api-key-here

Where to get your API key:

  1. Log in to your Zelta Pay Dashboard
  2. Navigate to Settings → API Keys
  3. Click Create New API Key
  4. Store it securely (never commit to version control)

Protected endpoints require JWT access token in the Authorization header:

Authorization: Bearer <your_access_token>

Additional header required for account-scoped operations:

X-Account-ID: <your_account_id>
  • Limit: 60 requests per minute per API key
  • Window: 1 minute rolling window
  • Rate limit headers included in all responses

Headers:

  • RateLimit-Limit: Maximum requests allowed
  • RateLimit-Remaining: Requests remaining in window
  • RateLimit-Reset: Unix timestamp when window resets

All API responses follow a consistent JSON structure:

{
"success": true,
"data": {
"paymentLink": {
"id": "pl_1234567890abcdef",
"paymentLinkUrl": "https://pay.zelta.dev/abc123",
"customerName": "John Doe",
"concept": "Consulting Service",
"amount": 2500,
"status": "pending",
"createdAt": "2024-01-15T10:30:00.000Z",
"expiresAt": "2024-01-22T10:30:00.000Z",
"isTest": true
}
},
"message": "Payment link created successfully",
"timestamp": "2024-01-15T10:30:00.000Z"
}

Response Fields:

  • success: Always true for successful responses
  • data: The response payload (object for single items, array for lists)
  • message: Optional confirmation message
  • timestamp: ISO 8601 timestamp of the response
{
"success": false,
"message": "Error description",
"error": {
"code": "ERROR_CODE",
"details": "Additional error details"
},
"timestamp": "2024-01-15T10:30:00.000Z"
}

Error Fields:

  • success: Always false for errors
  • message: User-friendly error description
  • error.code: Machine-readable error code
  • error.details: (Optional) Technical details
  • timestamp: ISO 8601 timestamp
CodeDescription
200OK - Request successful
201Created - Resource created successfully
204No Content - Successful operation with no response body
400Bad Request - Invalid request data or validation error
401Unauthorized - Missing or invalid credentials/API key
403Forbidden - Account suspended or insufficient permissions
404Not Found - Resource not found
408Request Timeout - Request took too long
429Too Many Requests - Rate limit exceeded
500Internal Server Error - Server error
502Bad Gateway - Service temporarily unavailable
503Service Unavailable - Service maintenance or overload
504Gateway Timeout - Request timeout
CodeHTTPDescription
ERR_MISSING_API_KEY401X-API-Key header is missing
ERR_API_KEY_NOT_FOUND404API key not found or invalid
ERR_UNAUTHORIZED401Invalid JWT token
ERR_ACCOUNT_SUSPENDED403Account is suspended
CodeHTTPDescription
ERR_VALIDATION_FAILED400Request validation failed
ERR_INVALID_AMOUNT400Amount outside valid range (100-200000 cents)
ERR_INVALID_CONCEPT400Concept is required and cannot be empty
ERR_INVALID_CUSTOMER_NAME400Customer name is required
ERR_INVALID_METADATA400Metadata exceeds size or format constraints
CodeHTTPDescription
ERR_NO_ACTIVE_PAYMENT_PROVIDER400Account has no active payment provider configured
ERR_PAYMENT_LINK_NOT_FOUND404Payment link does not exist or not owned by account
ERR_INVALID_STATE400Payment link is in a state that doesn’t allow the operation
ERR_RATE_LIMIT_EXCEEDED429Rate limit exceeded (60 requests/minute)
ERR_NOT_FOUND404Resource not found

All public endpoints require the X-API-Key header and are rate-limited to 60 requests per minute.

MethodEndpointDescription
GET/v1/payment-linksList payment links
GET/v1/payment-links/{hashUrl}Retrieve a single payment link
POST/v1/payment-linksCreate a payment link
PATCH/v1/payment-links/{hashUrl}/cancelCancel a payment link
ParameterTypeDescription
limintegerPage size (positive integer)
offintegerOffset (non-negative integer)
Terminal window
curl -X GET "https://api-pay.zelta.dev/v1/payment-links?lim=10&off=20" \
-H "X-API-Key: your-api-key-here"

Some endpoints support field selection using the fields parameter:

Terminal window
curl -X GET "https://api-pay.zelta.dev/v1/payment-links?fields=id,amount,status" \
-H "X-API-Key: your-api-key-here"

All monetary amounts are specified in cents (the smallest currency unit):

  • 100 = $1.00
  • 2500 = $25.00
  • 50000 = $500.00

All timestamps are in ISO 8601 format with UTC timezone:

2024-01-15T10:30:00.000Z

Payment links can have these statuses:

  • pending - Waiting for payment
  • completed - Payment successful
  • cancelled - Manually cancelled
  • expired - Expired due to time limit

Payment links support custom metadata for storing application-specific information.

  • Keys: 1-40 characters, alphanumeric and underscores
  • Values: String (max 255), number, boolean, or null
  • Maximum keys: 20 per payment link
  • Maximum total size: 8,192 bytes when JSON serialized
{
"metadata": {
"orderId": "ORD-001",
"customerId": 12345,
"isVip": true,
"notes": null
}
}

List endpoints support pagination using query parameters:

ParameterTypeDescription
limintegerItems per page (positive integer)
offintegerOffset from start (non-negative integer)
Terminal window
curl -X GET "https://api-pay.zelta.dev/v1/payment-links?lim=10&off=20" \
-H "X-API-Key: your-api-key-here"
  • payment.success - Emitted when a customer successfully completes a payment
  • webhook.ping - Emitted when you test your webhook endpoint
  • HTTPS only - Non-HTTPS endpoints are rejected

  • Signature verification - All webhooks include HMAC-SHA256 signatures

  • Timestamp validation - Prevent replay attacks

  • Idempotency support - Use eventId to prevent duplicate processing

  • Events: payment.success, webhook.ping

  • Delivery: HTTPS POST with retry logic

  • Security: HMAC-SHA256 signature verification

  • Idempotency: Event ID prevents duplicate processing

While Zelta Pay provides a REST API, you can use any HTTP client:

const fetch = require('node-fetch');
// or
const axios = require('axios');
import requests
# or
import httpx
// Built-in cURL
// or Guzzle HTTP
import "net/http"
// or
import "github.com/go-resty/resty/v2"

Use isTest: true when creating payment links for testing:

{
"concept": "Test Payment",
"amount": 100,
"customerName": "Test User",
"isTest": true
}

For detailed version history and API changes, see the complete changelog.

  • Initial API release
  • Payment link CRUD operations
  • Webhook support
  • Rate limiting
  • Metadata support