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.
Base URLs
Section titled “Base URLs”Production
Section titled “Production”https://api-pay.zelta.devAPI Versioning
Section titled “API Versioning”All endpoints are versioned using the URL path:
/v1/payment-linksBreaking changes will be introduced under new version paths (e.g., /v2/payment-links).
Authentication
Section titled “Authentication”The Zelta Pay API uses API key authentication. Include your API key in the X-API-Key header:
X-API-Key: your-api-key-hereWhere to get your API key:
- Log in to your Zelta Pay Dashboard
- Navigate to Settings → API Keys
- Click Create New API Key
- Store it securely (never commit to version control)
JWT Authentication (Protected Endpoints)
Section titled “JWT Authentication (Protected Endpoints)”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>Rate Limiting
Section titled “Rate Limiting”- 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 allowedRateLimit-Remaining: Requests remaining in windowRateLimit-Reset: Unix timestamp when window resets
Response Format
Section titled “Response Format”All API responses follow a consistent JSON structure:
Success Response
Section titled “Success Response”{ "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: Alwaystruefor successful responsesdata: The response payload (object for single items, array for lists)message: Optional confirmation messagetimestamp: ISO 8601 timestamp of the response
Error Response
Section titled “Error Response”{ "success": false, "message": "Error description", "error": { "code": "ERROR_CODE", "details": "Additional error details" }, "timestamp": "2024-01-15T10:30:00.000Z"}Error Fields:
success: Alwaysfalsefor errorsmessage: User-friendly error descriptionerror.code: Machine-readable error codeerror.details: (Optional) Technical detailstimestamp: ISO 8601 timestamp
HTTP Status Codes
Section titled “HTTP Status Codes”| Code | Description |
|---|---|
200 | OK - Request successful |
201 | Created - Resource created successfully |
204 | No Content - Successful operation with no response body |
400 | Bad Request - Invalid request data or validation error |
401 | Unauthorized - Missing or invalid credentials/API key |
403 | Forbidden - Account suspended or insufficient permissions |
404 | Not Found - Resource not found |
408 | Request Timeout - Request took too long |
429 | Too Many Requests - Rate limit exceeded |
500 | Internal Server Error - Server error |
502 | Bad Gateway - Service temporarily unavailable |
503 | Service Unavailable - Service maintenance or overload |
504 | Gateway Timeout - Request timeout |
Error Codes
Section titled “Error Codes”Authentication Errors
Section titled “Authentication Errors”| Code | HTTP | Description |
|---|---|---|
ERR_MISSING_API_KEY | 401 | X-API-Key header is missing |
ERR_API_KEY_NOT_FOUND | 404 | API key not found or invalid |
ERR_UNAUTHORIZED | 401 | Invalid JWT token |
ERR_ACCOUNT_SUSPENDED | 403 | Account is suspended |
Validation Errors
Section titled “Validation Errors”| Code | HTTP | Description |
|---|---|---|
ERR_VALIDATION_FAILED | 400 | Request validation failed |
ERR_INVALID_AMOUNT | 400 | Amount outside valid range (100-200000 cents) |
ERR_INVALID_CONCEPT | 400 | Concept is required and cannot be empty |
ERR_INVALID_CUSTOMER_NAME | 400 | Customer name is required |
ERR_INVALID_METADATA | 400 | Metadata exceeds size or format constraints |
Business Logic Errors
Section titled “Business Logic Errors”| Code | HTTP | Description |
|---|---|---|
ERR_NO_ACTIVE_PAYMENT_PROVIDER | 400 | Account has no active payment provider configured |
ERR_PAYMENT_LINK_NOT_FOUND | 404 | Payment link does not exist or not owned by account |
ERR_INVALID_STATE | 400 | Payment link is in a state that doesn’t allow the operation |
ERR_RATE_LIMIT_EXCEEDED | 429 | Rate limit exceeded (60 requests/minute) |
ERR_NOT_FOUND | 404 | Resource not found |
Public Endpoints
Section titled “Public Endpoints”Base Path: /v1/payment-links
Section titled “Base Path: /v1/payment-links”All public endpoints require the X-API-Key header and are rate-limited to 60 requests per minute.
Payment Links Management
Section titled “Payment Links Management”| Method | Endpoint | Description |
|---|---|---|
GET | /v1/payment-links | List payment links |
GET | /v1/payment-links/{hashUrl} | Retrieve a single payment link |
POST | /v1/payment-links | Create a payment link |
PATCH | /v1/payment-links/{hashUrl}/cancel | Cancel a payment link |
| Parameter | Type | Description |
|---|---|---|
lim | integer | Page size (positive integer) |
off | integer | Offset (non-negative integer) |
Example
Section titled “Example”curl -X GET "https://api-pay.zelta.dev/v1/payment-links?lim=10&off=20" \ -H "X-API-Key: your-api-key-here"Field Selection
Section titled “Field Selection”Some endpoints support field selection using the fields parameter:
curl -X GET "https://api-pay.zelta.dev/v1/payment-links?fields=id,amount,status" \ -H "X-API-Key: your-api-key-here"Data Types
Section titled “Data Types”Amounts
Section titled “Amounts”All monetary amounts are specified in cents (the smallest currency unit):
100= $1.002500= $25.0050000= $500.00
Timestamps
Section titled “Timestamps”All timestamps are in ISO 8601 format with UTC timezone:
2024-01-15T10:30:00.000ZStatus Values
Section titled “Status Values”Payment links can have these statuses:
pending- Waiting for paymentcompleted- Payment successfulcancelled- Manually cancelledexpired- Expired due to time limit
Metadata
Section titled “Metadata”Payment links support custom metadata for storing application-specific information.
Metadata Constraints
Section titled “Metadata Constraints”- 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 Example
Section titled “Metadata Example”{ "metadata": { "orderId": "ORD-001", "customerId": 12345, "isVip": true, "notes": null }}Pagination
Section titled “Pagination”List endpoints support pagination using query parameters:
| Parameter | Type | Description |
|---|---|---|
lim | integer | Items per page (positive integer) |
off | integer | Offset from start (non-negative integer) |
Example
Section titled “Example”curl -X GET "https://api-pay.zelta.dev/v1/payment-links?lim=10&off=20" \ -H "X-API-Key: your-api-key-here"Webhooks
Section titled “Webhooks”Event Types
Section titled “Event Types”payment.success- Emitted when a customer successfully completes a paymentwebhook.ping- Emitted when you test your webhook endpoint
Webhook Security
Section titled “Webhook Security”-
HTTPS only - Non-HTTPS endpoints are rejected
-
Signature verification - All webhooks include HMAC-SHA256 signatures
-
Timestamp validation - Prevent replay attacks
-
Idempotency support - Use
eventIdto 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
SDKs and Libraries
Section titled “SDKs and Libraries”While Zelta Pay provides a REST API, you can use any HTTP client:
JavaScript/Node.js
Section titled “JavaScript/Node.js”const fetch = require('node-fetch');// orconst axios = require('axios');Python
Section titled “Python”import requests# orimport httpx// Built-in cURL// or Guzzle HTTPimport "net/http"// orimport "github.com/go-resty/resty/v2"Testing
Section titled “Testing”Test Mode
Section titled “Test Mode”Use isTest: true when creating payment links for testing:
{ "concept": "Test Payment", "amount": 100, "customerName": "Test User", "isTest": true}Support
Section titled “Support”Documentation
Section titled “Documentation”- Quick Start Guide - Get started in 5 minutes
- Authentication Guide - API key management
- Webhook Guide - Real-time notifications
- Use Cases - Real-world integration examples
Contact
Section titled “Contact”- Email: support@zelta.dev
- Dashboard: Support Portal
Changelog
Section titled “Changelog”For detailed version history and API changes, see the complete changelog.
Version 1.0.0 (Current)
Section titled “Version 1.0.0 (Current)”- Initial API release
- Payment link CRUD operations
- Webhook support
- Rate limiting
- Metadata support
Next Steps
Section titled “Next Steps”- Payment Links API - Full endpoint reference
- Webhooks - Real-time payment notifications
- Quick Start - Your first payment link
- Changelog - Version history and API changes