Get Payment Link
Retrieve a single payment link by its hash URL.
Endpoint
Section titled “Endpoint”GET /v1/payment-links/{hashUrl}Authentication
Section titled “Authentication”Requires API key authentication via X-API-Key header.
Path Parameters
Section titled “Path Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
hashUrl | string | Yes | The hash URL of the payment link |
Request Examples
Section titled “Request Examples”cURL Example
Section titled “cURL Example”curl -X GET "https://api-pay.zelta.dev/v1/payment-links/abc123" \ -H "X-API-Key: your-api-key-here" \ -H "Content-Type: application/json"Node.js Example
Section titled “Node.js Example”const hashUrl = 'abc123';const response = await fetch(`https://api-pay.zelta.dev/v1/payment-links/${hashUrl}`, { method: 'GET', headers: { 'X-API-Key': 'your-api-key-here', 'Content-Type': 'application/json' }});
const result = await response.json();console.log(result);Python Example
Section titled “Python Example”import requests
hash_url = 'abc123'headers = { 'X-API-Key': 'your-api-key-here', 'Content-Type': 'application/json'}
response = requests.get( f'https://api-pay.zelta.dev/v1/payment-links/{hash_url}', headers=headers)
result = response.json()print(result)PHP Example
Section titled “PHP Example”$hashUrl = 'abc123';$headers = [ 'X-API-Key: your-api-key-here', 'Content-Type: application/json'];
$ch = curl_init();curl_setopt($ch, CURLOPT_URL, "https://api-pay.zelta.dev/v1/payment-links/{$hashUrl}");curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);curl_close($ch);
$result = json_decode($response, true);Response Format
Section titled “Response Format”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", "cancelledAt": null, "completedAt": null, "isTest": true, "redirectUrl": "https://myapp.com/success", "metadata": { "orderId": "ORD-001", "service": "consulting" } } }, "message": "Payment link retrieved successfully", "timestamp": "2024-01-15T10:30:00.000Z"}Response Fields
Section titled “Response Fields”| Field | Type | Description |
|---|---|---|
id | string | Unique payment link identifier |
paymentLinkUrl | string | URL for the payment link |
customerName | string | Name of the customer |
customerEmail | string|null | Customer’s email address |
concept | string | Description of what’s being paid for |
amount | integer | Amount in cents |
status | string | Payment link status |
createdAt | string | ISO 8601 timestamp of creation |
expiresAt | string | ISO 8601 timestamp of expiration |
cancelledAt | string|null | ISO 8601 timestamp of cancellation |
completedAt | string|null | ISO 8601 timestamp of completion |
isTest | boolean | Whether this is a test payment |
redirectUrl | string|null | Custom redirect URL |
metadata | object|null | Custom metadata |
Status Codes
Section titled “Status Codes”| Code | Description |
|---|---|
200 | OK - Payment link retrieved successfully |
401 | Unauthorized - Missing or invalid API key |
403 | Forbidden - Account suspended |
404 | Not Found - Payment link not found or not owned by account |
429 | Too Many Requests - Rate limit exceeded |
Error Responses
Section titled “Error Responses”Payment Link Not Found
Section titled “Payment Link Not Found”{ "success": false, "message": "Payment link not found", "error": { "code": "ERR_PAYMENT_LINK_NOT_FOUND" }, "timestamp": "2024-01-15T10:30:00.000Z"}Missing API Key
Section titled “Missing API Key”{ "success": false, "message": "Missing X-API-Key header", "error": { "code": "ERR_MISSING_API_KEY" }, "timestamp": "2024-01-15T10:30:00.000Z"}Invalid API Key
Section titled “Invalid API Key”{ "success": false, "message": "Invalid API key", "error": { "code": "ERR_INVALID_API_KEY" }, "timestamp": "2024-01-15T10:30:00.000Z"}Implementation Examples
Section titled “Implementation Examples”Basic Payment Link Retrieval
Section titled “Basic Payment Link Retrieval”Node.js Example
Section titled “Node.js Example”async function getPaymentLink(apiKey, hashUrl) { try { const response = await fetch(`https://api-pay.zelta.dev/v1/payment-links/${hashUrl}`, { method: 'GET', headers: { 'X-API-Key': apiKey, 'Content-Type': 'application/json' } });
const result = await response.json();
if (!response.ok) { throw new Error(result.message); }
return result.data.paymentLink; } catch (error) { console.error('Error retrieving payment link:', error); throw error; }}
// Usageconst paymentLink = await getPaymentLink('your-api-key', 'abc123');console.log('Payment link:', paymentLink);Python Example
Section titled “Python Example”import requests
def get_payment_link(api_key, hash_url): try: headers = { 'X-API-Key': api_key, 'Content-Type': 'application/json' }
response = requests.get( f'https://api-pay.zelta.dev/v1/payment-links/{hash_url}', headers=headers )
result = response.json()
if not response.ok: raise Exception(result['message'])
return result['data']['paymentLink'] except Exception as error: print(f'Error retrieving payment link: {error}') raise
# Usagepayment_link = get_payment_link('your-api-key', 'abc123')print('Payment link:', payment_link)Payment Link Status Check
Section titled “Payment Link Status Check”Node.js Example
Section titled “Node.js Example”async function checkPaymentLinkStatus(apiKey, hashUrl) { try { const paymentLink = await getPaymentLink(apiKey, hashUrl);
return { status: paymentLink.status, isCompleted: paymentLink.status === 'completed', isPending: paymentLink.status === 'pending', isCancelled: paymentLink.status === 'cancelled', isExpired: paymentLink.status === 'expired', completedAt: paymentLink.completedAt, cancelledAt: paymentLink.cancelledAt, expiresAt: paymentLink.expiresAt }; } catch (error) { console.error('Error checking payment link status:', error); throw error; }}
// Usageconst status = await checkPaymentLinkStatus('your-api-key', 'abc123');console.log('Payment link status:', status);Python Example
Section titled “Python Example”def check_payment_link_status(api_key, hash_url): try: payment_link = get_payment_link(api_key, hash_url)
return { 'status': payment_link['status'], 'is_completed': payment_link['status'] == 'completed', 'is_pending': payment_link['status'] == 'pending', 'is_cancelled': payment_link['status'] == 'cancelled', 'is_expired': payment_link['status'] == 'expired', 'completed_at': payment_link['completedAt'], 'cancelled_at': payment_link['cancelledAt'], 'expires_at': payment_link['expiresAt'] } except Exception as error: print(f'Error checking payment link status: {error}') raise
# Usagestatus = check_payment_link_status('your-api-key', 'abc123')print('Payment link status:', status)Order Status Check
Section titled “Order Status Check”Node.js Example
Section titled “Node.js Example”async function checkOrderStatus(apiKey, orderId) { try { // Get all payment links const allLinks = await getAllPaymentLinks(apiKey);
// Find payment link for this order const orderPaymentLink = allLinks.find(link => link.metadata?.orderId === orderId );
if (!orderPaymentLink) { throw new Error('Payment link not found for order'); }
// Get detailed payment link info const hashUrl = orderPaymentLink.paymentLinkUrl.split('/').pop(); const paymentLink = await getPaymentLink(apiKey, hashUrl);
return { orderId: orderId, paymentLinkId: paymentLink.id, status: paymentLink.status, amount: paymentLink.amount, customerName: paymentLink.customerName, concept: paymentLink.concept, createdAt: paymentLink.createdAt, completedAt: paymentLink.completedAt, cancelledAt: paymentLink.cancelledAt, expiresAt: paymentLink.expiresAt }; } catch (error) { console.error('Error checking order status:', error); throw error; }}
// Usageconst orderStatus = await checkOrderStatus('your-api-key', 'ORD-001');console.log('Order status:', orderStatus);Python Example
Section titled “Python Example”def check_order_status(api_key, order_id): try: # Get all payment links all_links = get_all_payment_links(api_key)
# Find payment link for this order order_payment_link = None for link in all_links: if link.get('metadata', {}).get('orderId') == order_id: order_payment_link = link break
if not order_payment_link: raise Exception('Payment link not found for order')
# Get detailed payment link info hash_url = order_payment_link['paymentLinkUrl'].split('/')[-1] payment_link = get_payment_link(api_key, hash_url)
return { 'orderId': order_id, 'paymentLinkId': payment_link['id'], 'status': payment_link['status'], 'amount': payment_link['amount'], 'customerName': payment_link['customerName'], 'concept': payment_link['concept'], 'createdAt': payment_link['createdAt'], 'completedAt': payment_link['completedAt'], 'cancelledAt': payment_link['cancelledAt'], 'expiresAt': payment_link['expiresAt'] } except Exception as error: print(f'Error checking order status: {error}') raise
# Usageorder_status = check_order_status('your-api-key', 'ORD-001')print('Order status:', order_status)Use Cases
Section titled “Use Cases”1. Order Status Page
Section titled “1. Order Status Page”Check payment status for order confirmation pages:
async function getOrderPaymentStatus(apiKey, orderId) { try { const orderStatus = await checkOrderStatus(apiKey, orderId);
return { orderId: orderStatus.orderId, paymentStatus: orderStatus.status, amount: orderStatus.amount, customerName: orderStatus.customerName, concept: orderStatus.concept, paymentUrl: `https://pay.zelta.dev/${orderStatus.paymentLinkId}`, isPaid: orderStatus.status === 'completed', isPending: orderStatus.status === 'pending', isCancelled: orderStatus.status === 'cancelled', isExpired: orderStatus.status === 'expired', completedAt: orderStatus.completedAt, expiresAt: orderStatus.expiresAt }; } catch (error) { console.error('Error getting order payment status:', error); throw error; }}
// Usage in order status pageconst paymentStatus = await getOrderPaymentStatus('your-api-key', 'ORD-001');console.log('Payment status:', paymentStatus);2. Payment Verification
Section titled “2. Payment Verification”Verify payment completion before processing orders:
async function verifyPaymentCompletion(apiKey, orderId) { try { const orderStatus = await checkOrderStatus(apiKey, orderId);
Bookmark if (orderStatus.status === 'completed') { // Payment is complete, process the order await processOrder(orderId); return { success: true, message: 'Payment verified and order processed', orderId: orderId, amount: orderStatus.amount, completedAt: orderStatus.completedAt }; } else if (orderStatus.status === 'pending') { // Payment is still pending return { success: false, message: 'Payment is still pending', orderId: orderId, status: orderStatus.status, expiresAt: orderStatus.expiresAt }; } else { // Payment failed, cancelled, or expired return { success: false, message: 'Payment not completed', orderId: orderId, status: orderStatus.status, cancelledAt: orderStatus.cancelledAt, expiresAt: orderStatus.expiresAt }; } } catch (error) { console.error('Error verifying payment completion:', error); throw error; }}
// Usageconst verification = await verifyPaymentCompletion('your-api-key', 'ORD-001');console.log('Payment verification:', verification);3. Customer Service
Section titled “3. Customer Service”Retrieve payment information for customer support:
async function getCustomerPaymentInfo(apiKey, customerId) { try { // Get all payment links const allLinks = await getAllPaymentLinks(apiKey);
// Filter by customer ID const customerPayments = allLinks.filter(link => link.metadata?.customerId === customerId );
// Get detailed information for each payment const detailedPayments = await Promise.all( customerPayments.map(async (link) => { const hashUrl = link.paymentLinkUrl.split('/').pop(); const paymentLink = await getPaymentLink(apiKey, hashUrl);
return { paymentLinkId: paymentLink.id, status: paymentLink.status, amount: paymentLink.amount, concept: paymentLink.concept, createdAt: paymentLink.createdAt, completedAt: paymentLink.completedAt, cancelledAt: paymentLink.cancelledAt, expiresAt: paymentLink.expiresAt, metadata: paymentLink.metadata }; }) );
return { customerId: customerId, totalPayments: detailedPayments.length, completedPayments: detailedPayments.filter(p => p.status === 'completed').length, pendingPayments: detailedPayments.filter(p => p.status === 'pending').length, cancelledPayments: detailedPayments.filter(p => p.status === 'cancelled').length, expiredPayments: detailedPayments.filter(p => p.status === 'expired').length, totalAmount: detailedPayments .filter(p => p.status === 'completed') .reduce((sum, p) => sum + p.amount, 0), payments: detailedPayments }; } catch (error) { console.error('Error getting customer payment info:', error); throw error; }}
// Usageconst customerInfo = await getCustomerPaymentInfo('your-api-key', 'CUST-123');console.log('Customer payment info:', customerInfo);Best Practices
Section titled “Best Practices”1. Error Handling
Section titled “1. Error Handling”Always handle different error scenarios:
async function getPaymentLinkSafely(apiKey, hashUrl) { try { return await getPaymentLink(apiKey, hashUrl); } catch (error) { if (error.message.includes('not found')) { return null; // Payment link doesn't exist }
if (error.message.includes('invalid API key')) { throw new Error('Authentication failed'); }
throw error; // Re-throw other errors }}2. Caching
Section titled “2. Caching”Cache payment link data to reduce API calls:
const paymentLinkCache = new Map();
async function getPaymentLinkWithCache(apiKey, hashUrl, ttl = 300000) { // 5 minutes const cacheKey = `${apiKey}:${hashUrl}`; const cached = paymentLinkCache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < ttl) { return cached.data; }
const paymentLink = await getPaymentLink(apiKey, hashUrl);
paymentLinkCache.set(cacheKey, { data: paymentLink, timestamp: Date.now() });
return paymentLink;}3. Rate Limiting
Section titled “3. Rate Limiting”Implement rate limiting for batch operations:
async function getMultiplePaymentLinks(apiKey, hashUrls, delay = 1000) { const results = [];
for (const hashUrl of hashUrls) { try { const paymentLink = await getPaymentLink(apiKey, hashUrl); results.push({ hashUrl, success: true, paymentLink }); } catch (error) { results.push({ hashUrl, success: false, error: error.message }); }
// Rate limiting delay await new Promise(resolve => setTimeout(resolve, delay)); }
return results;}4. Logging
Section titled “4. Logging”Log payment link retrieval for audit purposes:
async function getPaymentLinkWithLogging(apiKey, hashUrl, reason = 'Manual retrieval') { try { const paymentLink = await getPaymentLink(apiKey, hashUrl);
console.log('Payment link retrieved:', { paymentLinkId: paymentLink.id, hashUrl: hashUrl, reason: reason, status: paymentLink.status, timestamp: new Date().toISOString() });
return paymentLink; } catch (error) { console.error('Failed to retrieve payment link:', { hashUrl: hashUrl, reason: reason, error: error.message, timestamp: new Date().toISOString() }); throw error; }}Testing
Section titled “Testing”Test Different Statuses
Section titled “Test Different Statuses”Test retrieval of payment links in different states:
// Test pending payment linkconst pendingLink = await getPaymentLink('your-api-key', 'pending-hash');
// Test completed payment linkconst completedLink = await getPaymentLink('your-api-key', 'completed-hash');
// Test cancelled payment linkconst cancelledLink = await getPaymentLink('your-api-key', 'cancelled-hash');Test Error Scenarios
Section titled “Test Error Scenarios”Test error handling:
// Test non-existent payment linktry { await getPaymentLink('your-api-key', 'non-existent-hash');} catch (error) { console.log('Expected error:', error.message);}
// Test invalid API keytry { await getPaymentLink('invalid-key', 'valid-hash');} catch (error) { console.log('Expected error:', error.message);}Related Endpoints
Section titled “Related Endpoints”- List Payment Links - Retrieve multiple payment links
- Create Payment Link - Create a new payment link
- Cancel Payment Link - Cancel a payment link