Retrieving Payments
Query payment status and retrieve payment details via API
Overview
Retrieve payment information from Payzo to check status, view details, or list all payments for your shop.
Recommended: Use webhooks instead of polling for real-time updates.
Get Single Payment
Retrieve details for a specific payment by ID.
Endpoint
GET https://payzo.cc/api/v1/payments/{payment_id}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
payment_id | string | Yes | The payment ID (e.g., pay_abc123) |
Example Request
curl https://payzo.cc/api/v1/payments/pay_abc123def456 \
-H "Authorization: Bearer YOUR_API_KEY"
Example Response
{
"id": "pay_abc123def456",
"status": "completed",
"amount": 5000,
"currency": "usd",
"customer_email": "customer@example.com",
"customer_name": "John Doe",
"metadata": {
"order_id": "ORD-12345",
"product": "Premium Plan"
},
"created_at": "2025-01-12T10:30:00.000Z",
"completed_at": "2025-01-12T10:30:15.000Z"
}
Node.js Example
async function getPayment(paymentId) {
const response = await fetch(
`https://payzo.cc/api/v1/payments/${paymentId}`,
{
headers: {
'Authorization': `Bearer ${process.env.PAYZO_API_KEY}`
}
}
);
if (!response.ok) {
throw new Error(`Failed to get payment: ${response.statusText}`);
}
return await response.json();
}
// Usage
const payment = await getPayment('pay_abc123def456');
console.log('Payment status:', payment.status);
List All Payments
Retrieve a list of all payments for your shop with pagination and filtering.
Endpoint
GET https://payzo.cc/api/v1/payments
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | integer | No | Number of payments to return (max: 100, default: 10) |
offset | integer | No | Number of payments to skip (default: 0) |
status | string | No | Filter by status: pending, completed, failed, expired |
Example Request
# Get 20 completed payments
curl "https://payzo.cc/api/v1/payments?limit=20&status=completed" \
-H "Authorization: Bearer YOUR_API_KEY"
Example Response
{
"data": [
{
"id": "pay_abc123",
"status": "completed",
"amount": 5000,
"currency": "usd",
"customer_email": "customer1@example.com",
"metadata": {"order_id": "ORD-001"},
"created_at": "2025-01-12T10:30:00.000Z",
"completed_at": "2025-01-12T10:30:15.000Z"
},
{
"id": "pay_def456",
"status": "completed",
"amount": 2500,
"currency": "usd",
"customer_email": "customer2@example.com",
"metadata": {"order_id": "ORD-002"},
"created_at": "2025-01-12T09:15:00.000Z",
"completed_at": "2025-01-12T09:15:10.000Z"
}
],
"has_more": true,
"total": 145
}
Node.js Example
async function listPayments(options = {}) {
const {
limit = 10,
offset = 0,
status = null
} = options;
const params = new URLSearchParams({
limit: limit.toString(),
offset: offset.toString()
});
if (status) {
params.append('status', status);
}
const response = await fetch(
`https://payzo.cc/api/v1/payments?${params}`,
{
headers: {
'Authorization': `Bearer ${process.env.PAYZO_API_KEY}`
}
}
);
if (!response.ok) {
throw new Error(`Failed to list payments: ${response.statusText}`);
}
return await response.json();
}
// Usage: Get all completed payments
const { data, total, has_more } = await listPayments({
limit: 50,
status: 'completed'
});
console.log(`Found ${total} completed payments`);
data.forEach(payment => {
console.log(`- ${payment.id}: $${payment.amount / 100}`);
});
Payment Status Values
| Status | Description |
|---|---|
pending | Payment created, awaiting customer action |
completed | Payment successful, customer charged |
failed | Payment attempt failed |
expired | Payment link expired without completion |
refunded | Payment was refunded by Payzo support |
Pagination
Basic Pagination
// Get first page
const page1 = await listPayments({ limit: 20, offset: 0 });
// Get second page
const page2 = await listPayments({ limit: 20, offset: 20 });
// Get third page
const page3 = await listPayments({ limit: 20, offset: 40 });
Auto-Pagination
async function getAllPayments() {
let allPayments = [];
let offset = 0;
const limit = 100; // Max per request
let hasMore = true;
while (hasMore) {
const response = await listPayments({ limit, offset });
allPayments = allPayments.concat(response.data);
offset += limit;
hasMore = response.has_more;
}
return allPayments;
}
// Get ALL payments (use carefully with large datasets)
const payments = await getAllPayments();
console.log(`Total payments: ${payments.length}`);
Filtering by Status
Get Only Completed Payments
const completed = await listPayments({
status: 'completed',
limit: 100
});
console.log('Completed payments:', completed.data.length);
Get Only Failed Payments
const failed = await listPayments({
status: 'failed',
limit: 50
});
failed.data.forEach(payment => {
console.log(`Failed payment: ${payment.id} - ${payment.customer_email}`);
});
Get Only Pending Payments
const pending = await listPayments({
status: 'pending',
limit: 20
});
console.log('Pending payments:', pending.total);
Use Cases
Check Payment Status
async function checkOrderPaymentStatus(orderId) {
// Get payment ID from your database
const order = await db.orders.findOne({ id: orderId });
if (!order.payzo_payment_id) {
return { status: 'not_started' };
}
// Query Payzo API
const payment = await getPayment(order.payzo_payment_id);
return {
status: payment.status,
amount: payment.amount,
completed_at: payment.completed_at
};
}
Generate Payment Report
async function generatePaymentReport(startDate, endDate) {
const allPayments = await getAllPayments();
// Filter by date range
const filtered = allPayments.filter(payment => {
const date = new Date(payment.created_at);
return date >= startDate && date <= endDate;
});
// Calculate statistics
const completed = filtered.filter(p => p.status === 'completed');
const totalRevenue = completed.reduce((sum, p) => sum + p.amount, 0);
return {
total_payments: filtered.length,
completed_payments: completed.length,
failed_payments: filtered.filter(p => p.status === 'failed').length,
total_revenue: totalRevenue / 100, // Convert cents to dollars
average_payment: totalRevenue / completed.length / 100
};
}
// Generate report for last 30 days
const endDate = new Date();
const startDate = new Date();
startDate.setDate(startDate.getDate() - 30);
const report = await generatePaymentReport(startDate, endDate);
console.log('Payment Report:', report);
Reconciliation
async function reconcilePayments() {
// Get all completed payments from Payzo
const { data: c2cPayments } = await listPayments({
status: 'completed',
limit: 100
});
// Get all orders from your database
const dbOrders = await db.orders.find({
status: 'paid'
});
// Find mismatches
const mismatches = [];
for (const payment of c2cPayments) {
const order = dbOrders.find(o =>
o.payzo_payment_id === payment.id
);
if (!order) {
mismatches.push({
payment_id: payment.id,
issue: 'Payment in Payzo but not in database'
});
} else if (order.amount !== payment.amount / 100) {
mismatches.push({
payment_id: payment.id,
issue: 'Amount mismatch',
c2c_amount: payment.amount / 100,
db_amount: order.amount
});
}
}
return mismatches;
}
Best Practices
1. Use Webhooks, Not Polling
// Bad: Polling every 5 seconds
setInterval(async () => {
const payment = await getPayment(paymentId);
if (payment.status === 'completed') {
completeOrder(orderId);
}
}, 5000);
// Good: Use webhooks
app.post('/webhook', (req, res) => {
const { event, payment } = req.body;
if (event === 'payment.completed') {
completeOrder(payment.metadata.order_id);
}
});
2. Cache Results
const cache = new Map();
async function getPaymentCached(paymentId) {
// Check cache first
if (cache.has(paymentId)) {
return cache.get(paymentId);
}
// Fetch from API
const payment = await getPayment(paymentId);
// Cache for 5 minutes (only if completed or failed)
if (['completed', 'failed', 'refunded'].includes(payment.status)) {
cache.set(paymentId, payment);
setTimeout(() => cache.delete(paymentId), 5 * 60 * 1000);
}
return payment;
}
3. Handle Errors
async function getPaymentSafe(paymentId) {
try {
return await getPayment(paymentId);
} catch (error) {
if (error.status === 404) {
console.error('Payment not found:', paymentId);
return null;
}
if (error.status === 401) {
console.error('Invalid API key');
throw new Error('Authentication failed');
}
console.error('API error:', error);
throw error;
}
}
4. Implement Retry Logic
async function getPaymentWithRetry(paymentId, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await getPayment(paymentId);
} catch (error) {
if (attempt === maxRetries) throw error;
const delay = Math.pow(2, attempt) * 1000; // 2s, 4s, 8s
console.log(`Retry ${attempt}/${maxRetries} after ${delay}ms`);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
Error Responses
404 Not Found
{
"error": "Payment not found"
}
Cause: Payment ID doesn't exist or belongs to different shop
401 Unauthorized
{
"error": "Invalid API key"
}
Cause: Missing or incorrect API key
429 Too Many Requests
{
"error": "Too many requests, please slow down"
}
Cause: Exceeded rate limit
Next Steps
- Webhooks Overview - Real-time notifications (recommended)
- Creating Payments - Create payment links
- API Authentication - Secure your requests