Skip to content

Get Payment Link

Retrieve a single payment link by its hash URL.

GET /v1/payment-links/{hashUrl}

Requires API key authentication via X-API-Key header.

ParameterTypeRequiredDescription
hashUrlstringYesThe hash URL of the payment link
Terminal window
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"
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);
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)
$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);
{
"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"
}
FieldTypeDescription
idstringUnique payment link identifier
paymentLinkUrlstringURL for the payment link
customerNamestringName of the customer
customerEmailstring|nullCustomer’s email address
conceptstringDescription of what’s being paid for
amountintegerAmount in cents
statusstringPayment link status
createdAtstringISO 8601 timestamp of creation
expiresAtstringISO 8601 timestamp of expiration
cancelledAtstring|nullISO 8601 timestamp of cancellation
completedAtstring|nullISO 8601 timestamp of completion
isTestbooleanWhether this is a test payment
redirectUrlstring|nullCustom redirect URL
metadataobject|nullCustom metadata
CodeDescription
200OK - Payment link retrieved successfully
401Unauthorized - Missing or invalid API key
403Forbidden - Account suspended
404Not Found - Payment link not found or not owned by account
429Too Many Requests - Rate limit exceeded
{
"success": false,
"message": "Payment link not found",
"error": {
"code": "ERR_PAYMENT_LINK_NOT_FOUND"
},
"timestamp": "2024-01-15T10:30:00.000Z"
}
{
"success": false,
"message": "Missing X-API-Key header",
"error": {
"code": "ERR_MISSING_API_KEY"
},
"timestamp": "2024-01-15T10:30:00.000Z"
}
{
"success": false,
"message": "Invalid API key",
"error": {
"code": "ERR_INVALID_API_KEY"
},
"timestamp": "2024-01-15T10:30:00.000Z"
}
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;
}
}
// Usage
const paymentLink = await getPaymentLink('your-api-key', 'abc123');
console.log('Payment link:', paymentLink);
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
# Usage
payment_link = get_payment_link('your-api-key', 'abc123')
print('Payment link:', payment_link)
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;
}
}
// Usage
const status = await checkPaymentLinkStatus('your-api-key', 'abc123');
console.log('Payment link status:', status);
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
# Usage
status = check_payment_link_status('your-api-key', 'abc123')
print('Payment link status:', status)
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;
}
}
// Usage
const orderStatus = await checkOrderStatus('your-api-key', 'ORD-001');
console.log('Order status:', orderStatus);
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
# Usage
order_status = check_order_status('your-api-key', 'ORD-001')
print('Order status:', order_status)

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 page
const paymentStatus = await getOrderPaymentStatus('your-api-key', 'ORD-001');
console.log('Payment status:', paymentStatus);

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;
}
}
// Usage
const verification = await verifyPaymentCompletion('your-api-key', 'ORD-001');
console.log('Payment verification:', verification);

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;
}
}
// Usage
const customerInfo = await getCustomerPaymentInfo('your-api-key', 'CUST-123');
console.log('Customer payment info:', customerInfo);

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
}
}

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;
}

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;
}

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;
}
}

Test retrieval of payment links in different states:

// Test pending payment link
const pendingLink = await getPaymentLink('your-api-key', 'pending-hash');
// Test completed payment link
const completedLink = await getPaymentLink('your-api-key', 'completed-hash');
// Test cancelled payment link
const cancelledLink = await getPaymentLink('your-api-key', 'cancelled-hash');

Test error handling:

// Test non-existent payment link
try {
await getPaymentLink('your-api-key', 'non-existent-hash');
} catch (error) {
console.log('Expected error:', error.message);
}
// Test invalid API key
try {
await getPaymentLink('invalid-key', 'valid-hash');
} catch (error) {
console.log('Expected error:', error.message);
}