Quick Start
Welcome to Zelta Pay API! This guide will help you create your first payment link and understand the basics of our API.
Prerequisites
Section titled “Prerequisites”Before you begin, make sure you have:
- A Zelta Pay account
- An API key (obtain from your dashboard)
- Basic knowledge of HTTP requests
- A development environment ready
Step 1: Get Your API Key
Section titled “Step 1: Get Your API Key”- Log in to your Zelta Pay Dashboard
- Navigate to API Keys
- Click Create New API Key
- Give it a descriptive name (e.g., “My App Integration”)
- Copy the generated API key and store it securely
Step 2: Make Your First API Call
Section titled “Step 2: Make Your First API Call”Let’s test your API key by listing your existing payment links:
cURL Example
Section titled “cURL Example”curl -X GET "https://api-pay.zelta.dev/v1/payment-links" \ -H "X-API-Key: your-api-key-here" \ -H "Content-Type: application/json"Node.js Example
Section titled “Node.js Example”const response = await fetch('https://api-pay.zelta.dev/v1/payment-links', { method: 'GET', headers: { 'X-API-Key': 'your-api-key-here', 'Content-Type': 'application/json' }});
const result = await response.json();console.log(result);Cloudflare Workers Example
Section titled “Cloudflare Workers Example”export default { async fetch(request, env, ctx) { const response = await fetch('https://api-pay.zelta.dev/v1/payment-links', { method: 'GET', headers: { 'X-API-Key': env.ZELTA_API_KEY, 'Content-Type': 'application/json' } });
const result = await response.json(); return new Response(JSON.stringify(result), { headers: { 'Content-Type': 'application/json' } }); }};Hono with Cloudflare Workers Example
Section titled “Hono with Cloudflare Workers Example”import { Hono } from 'hono';import { cors } from 'hono/cors';
type Bindings = { ZELTA_API_KEY: string;};
const app = new Hono<{ Bindings: Bindings }>();
// Enable CORSapp.use('*', cors());
app.get('/payment-links', async (c) => { const response = await fetch('https://api-pay.zelta.dev/v1/payment-links', { method: 'GET', headers: { 'X-API-Key': c.env.ZELTA_API_KEY, 'Content-Type': 'application/json' } });
const result = await response.json(); return c.json(result);});
export default app;Python Example
Section titled “Python Example”import requests
response = requests.get( 'https://api-pay.zelta.dev/v1/payment-links', headers={ 'X-API-Key': 'your-api-key-here', 'Content-Type': 'application/json' })
result = response.json()print(result)Step 3: Create Your First Payment Link
Section titled “Step 3: Create Your First Payment Link”Now let’s create a payment link:
cURL Example
Section titled “cURL Example”curl -X POST "https://api-pay.zelta.dev/v1/payment-links" \ -H "X-API-Key: your-api-key-here" \ -H "Content-Type: application/json" \ -d '{ "concept": "Test Payment", "amount": 100, "customerName": "John Doe", "isTest": true }'Node.js Example
Section titled “Node.js Example”const response = await fetch('https://api-pay.zelta.dev/v1/payment-links', { method: 'POST', headers: { 'X-API-Key': 'your-api-key-here', 'Content-Type': 'application/json' }, body: JSON.stringify({ concept: 'Test Payment', amount: 100, customerName: 'John Doe', isTest: true })});
const result = await response.json();console.log(result);Cloudflare Workers Example
Section titled “Cloudflare Workers Example”export default { async fetch(request, env, ctx) { const response = await fetch('https://api-pay.zelta.dev/v1/payment-links', { method: 'POST', headers: { 'X-API-Key': env.ZELTA_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ concept: 'Test Payment', amount: 100, customerName: 'John Doe', isTest: true }) });
const result = await response.json(); return new Response(JSON.stringify(result), { headers: { 'Content-Type': 'application/json' } }); }};Hono with Cloudflare Workers Example
Section titled “Hono with Cloudflare Workers Example”import { Hono } from 'hono';import { cors } from 'hono/cors';
type Bindings = { ZELTA_API_KEY: string;};
const app = new Hono<{ Bindings: Bindings }>();
// Enable CORSapp.use('*', cors());
app.post('/payment-links', async (c) => { const body = await c.req.json();
const response = await fetch('https://api-pay.zelta.dev/v1/payment-links', { method: 'POST', headers: { 'X-API-Key': c.env.ZELTA_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ concept: 'Test Payment', amount: 100, customerName: 'John Doe', isTest: true }) });
const result = await response.json(); return c.json(result);});
export default app;Python Example
Section titled “Python Example”import requests
response = requests.post( 'https://api-pay.zelta.dev/v1/payment-links', headers={ 'X-API-Key': 'your-api-key-here', 'Content-Type': 'application/json' }, json={ 'concept': 'Test Payment', 'amount': 100, 'customerName': 'John Doe', 'isTest': True })
result = response.json()print(result)Step 4: Understanding the Response
Section titled “Step 4: Understanding the Response”A successful response will look like this:
{ "success": true, "data": { "paymentLink": { "id": "pl_1234567890abcdef", "paymentLinkUrl": "https://pay.zelta.dev/abc123", "customerName": "John Doe", "concept": "Test Payment", "amount": 100, "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"}Key Response Fields
Section titled “Key Response Fields”paymentLinkUrl: The URL your customer will use to payid: Unique identifier for the payment linkstatus: Current status (always “pending” for new links)expiresAt: When the link expires (7 days from creation)
Step 5: Handle the Payment
Section titled “Step 5: Handle the Payment”Once you have the payment link URL, you can:
- Send it to your customer via email, SMS, or display it on your website
- Redirect them to the payment portal
- Monitor the status by calling the API or setting up webhooks
Redirect Example
Section titled “Redirect Example”// Redirect customer to payment pagewindow.location.href = result.data.paymentLink.paymentLinkUrl;Step 6: Set Up Webhooks (Optional)
Section titled “Step 6: Set Up Webhooks (Optional)”To receive real-time notifications when payments are completed:
- Go to Settings → Webhooks in your dashboard
- Add your webhook URL (must be HTTPS)
- Select the events you want to receive
- Test your webhook endpoint
Webhook Example
Section titled “Webhook Example”// Node.js with Expressapp.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => { const signature = req.headers['zeltapay-signature']; const timestamp = req.headers['zeltapay-timestamp'];
// Verify signature (important for security) if (!verifySignature(req.body.toString(), timestamp, signature)) { return res.status(401).json({ error: 'Invalid signature' }); }
const payload = JSON.parse(req.body);
if (payload.type === 'payment.success') { console.log('Payment completed:', payload.transaction.amount); // Update your database, send confirmation email, etc. }
res.status(200).json({ received: true });});Cloudflare Workers Webhook Example
Section titled “Cloudflare Workers Webhook Example”export default { async fetch(request, env, ctx) { if (request.method !== 'POST') { return new Response('Method not allowed', { status: 405 }); }
const url = new URL(request.url); if (url.pathname !== '/webhook') { return new Response('Not found', { status: 404 }); }
try { const signature = request.headers.get('zeltapay-signature'); const timestamp = request.headers.get('zeltapay-timestamp');
// Get raw body const rawBody = await request.text();
// Verify signature (important for security) if (!await verifySignature(rawBody, timestamp, signature, env.WEBHOOK_SECRET)) { return new Response(JSON.stringify({ error: 'Invalid signature' }), { status: 401, headers: { 'Content-Type': 'application/json' } }); }
const payload = JSON.parse(rawBody);
if (payload.type === 'payment.success') { console.log('Payment completed:', payload.transaction.amount); // Update your database, send confirmation email, etc. }
return new Response(JSON.stringify({ received: true }), { status: 200, headers: { 'Content-Type': 'application/json' } });
} catch (error) { console.error('Webhook processing error:', error); return new Response(JSON.stringify({ error: 'Processing failed' }), { status: 500, headers: { 'Content-Type': 'application/json' } }); } }};
async function verifySignature(rawBody, timestamp, signature, secret) { // Implementation details in signature verification guide return true; // Placeholder}Hono with Cloudflare Workers Webhook Example
Section titled “Hono with Cloudflare Workers Webhook Example”import { Hono } from 'hono';import { cors } from 'hono/cors';
type Bindings = { WEBHOOK_SECRET: string;};
const app = new Hono<{ Bindings: Bindings }>();
// Enable CORSapp.use('*', cors());
app.post('/webhook', async (c) => { try { const signature = c.req.header('zeltapay-signature'); const timestamp = c.req.header('zeltapay-timestamp');
if (!signature || !timestamp) { return c.json({ error: 'Missing required headers' }, 400); }
// Get raw body const rawBody = await c.req.text();
// Verify signature (important for security) if (!await verifySignature(rawBody, timestamp, signature, c.env.WEBHOOK_SECRET)) { return c.json({ error: 'Invalid signature' }, 401); }
const payload = JSON.parse(rawBody);
if (payload.type === 'payment.success') { console.log('Payment completed:', payload.transaction.amount); // Update your database, send confirmation email, etc. }
return c.json({ received: true });
} catch (error) { console.error('Webhook processing error:', error); return c.json({ error: 'Processing failed' }, 500); }});
async function verifySignature(rawBody: string, timestamp: string, signature: string, secret: string): Promise<boolean> { // Implementation details in signature verification guide return true; // Placeholder}
export default app;Next Steps
Section titled “Next Steps”Now that you’ve created your first payment link, explore these guides:
- Authentication - Learn about API keys and rate limiting
- Creating Payment Links - Advanced options and validation
- Webhooks - Real-time payment notifications
- API Reference - Complete endpoint documentation
Common Issues
Section titled “Common Issues”401 Unauthorized
Section titled “401 Unauthorized”- Check that your API key is correct
- Ensure the
X-API-Keyheader is included - Verify the API key is active in your dashboard
400 Bad Request
Section titled “400 Bad Request”- Check that all required fields are provided
- Ensure the amount is in cents (e.g., 100 = $1.00)
- Verify the JSON format is correct
429 Too Many Requests
Section titled “429 Too Many Requests”- You’ve exceeded the rate limit (60 requests per minute)
- Wait before making more requests
- Consider implementing request queuing
Support
Section titled “Support”If you need help:
- Documentation: Browse our guides and API reference
- Dashboard: Use the built-in API testing tools
- Support: Contact us at support@zelta.dev
- GitHub: Report issues and feature requests