List Checkout Forms
Retrieve a paginated list of all Checkout Forms to monitor active payment links, track form usage, and generate analytics.
Overview
Use this endpoint to:
- List all active checkout forms
- Filter by creation date to find recent forms
- Monitor form expiration across your platform
- Generate analytics on checkout link usage
- Track forms by merchant or application
Use Cases
1. List Recent Checkout Forms
Get the most recently created checkout forms:
async function listRecentCheckoutForms(limit = 20) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/checkout_forms?limit=${limit}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);
const data = await response.json();
console.log(`Found ${data._embedded?.checkout_forms?.length || 0} forms`);
console.log('Has more:', data.has_more);
data._embedded?.checkout_forms?.forEach(form => {
console.log({
id: form.id,
created: new Date(form.created_at).toLocaleDateString(),
nickname: form.nickname || 'Unnamed',
amount: form.amount_details?.total_amount
? `$${(form.amount_details.total_amount / 100).toFixed(2)}`
: 'Variable',
state: form.state,
expires: new Date(form.link_expires_at).toLocaleDateString()
});
});
return data;
}
2. Paginate Through All Forms
Navigate through all checkout forms using cursor pagination:
async function getAllCheckoutForms() {
const allForms = [];
let cursor = null;
do {
const url = cursor
? `https://api.ahrvo.network/payments/na/checkout_forms?after_cursor=${cursor}&limit=100`
: 'https://api.ahrvo.network/payments/na/checkout_forms?limit=100';
const response = await fetch(url, {
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
});
const data = await response.json();
const forms = data._embedded?.checkout_forms || [];
allForms.push(...forms);
console.log(`Fetched ${forms.length} forms (Total: ${allForms.length})`);
// Get next cursor if more results exist
cursor = data.has_more ? data._links?.next?.href?.split('after_cursor=')[1]?.split('&')[0] : null;
} while (cursor);
console.log(`Retrieved all ${allForms.length} checkout forms`);
return allForms;
}
3. Filter Forms by Creation Date
Find forms created within a specific time range:
async function getFormsInDateRange(startDate, endDate) {
const params = new URLSearchParams({
created_at_gte: startDate.toISOString(),
created_at_lte: endDate.toISOString(),
limit: '100'
});
const response = await fetch(
`https://api.ahrvo.network/payments/na/checkout_forms?${params}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);
const data = await response.json();
const forms = data._embedded?.checkout_forms || [];
console.log(`Found ${forms.length} forms between ${startDate.toLocaleDateString()} and ${endDate.toLocaleDateString()}`);
return forms;
}
// Example: Get this month's forms
const thisMonth = await getFormsInDateRange(
new Date(new Date().getFullYear(), new Date().getMonth(), 1),
new Date()
);
4. Find Active Forms
Get all forms that haven't expired:
async function getActiveForms() {
const response = await fetch(
'https://api.ahrvo.network/payments/na/checkout_forms?limit=100',
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);
const data = await response.json();
const allForms = data._embedded?.checkout_forms || [];
const now = new Date();
const activeForms = allForms.filter(form => {
const expiresAt = new Date(form.link_expires_at);
return form.state === 'ACTIVE' && expiresAt > now;
});
console.log(`Active forms: ${activeForms.length} / ${allForms.length}`);
activeForms.forEach(form => {
const hoursRemaining = (new Date(form.link_expires_at) - now) / (1000 * 60 * 60);
console.log({
id: form.id,
nickname: form.nickname,
hours_until_expiration: Math.round(hoursRemaining)
});
});
return activeForms;
}
5. Find Expiring Forms
Identify forms expiring soon:
async function getExpiringForms(hoursThreshold = 24) {
const response = await fetch(
'https://api.ahrvo.network/payments/na/checkout_forms?limit=100',
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);
const data = await response.json();
const allForms = data._embedded?.checkout_forms || [];
const now = new Date();
const thresholdMs = hoursThreshold * 60 * 60 * 1000;
const expiringForms = allForms.filter(form => {
const expiresAt = new Date(form.link_expires_at);
const msUntilExpiration = expiresAt - now;
return form.state === 'ACTIVE' &&
msUntilExpiration > 0 &&
msUntilExpiration < thresholdMs;
});
console.log(`Forms expiring within ${hoursThreshold} hours:`, expiringForms.length);
expiringForms.forEach(form => {
const hoursRemaining = (new Date(form.link_expires_at) - now) / (1000 * 60 * 60);
console.log({
id: form.id,
nickname: form.nickname,
hours_remaining: Math.round(hoursRemaining * 10) / 10,
link_url: form.link_url
});
});
return expiringForms;
}
6. Generate Checkout Analytics
Analyze checkout form usage:
async function generateCheckoutAnalytics() {
const allForms = await getAllCheckoutForms();
const analytics = {
total: allForms.length,
by_frequency: {},
by_state: {},
with_buyer_details: 0,
total_value: 0,
avg_value: 0,
expired: 0,
active: 0
};
const now = new Date();
allForms.forEach(form => {
// Count by payment frequency
analytics.by_frequency[form.payment_frequency] =
(analytics.by_frequency[form.payment_frequency] || 0) + 1;
// Count by state
analytics.by_state[form.state] =
(analytics.by_state[form.state] || 0) + 1;
// Count forms with buyer details
if (form.buyer_details) {
analytics.with_buyer_details++;
}
// Sum total value (fixed amounts only)
if (form.amount_details?.amount_type === 'FIXED' && form.amount_details?.total_amount) {
analytics.total_value += form.amount_details.total_amount;
}
// Count expired vs active
if (new Date(form.link_expires_at) <= now) {
analytics.expired++;
} else if (form.state === 'ACTIVE') {
analytics.active++;
}
});
// Calculate averages
const fixedAmountForms = allForms.filter(f =>
f.amount_details?.amount_type === 'FIXED' && f.amount_details?.total_amount
);
analytics.avg_value = fixedAmountForms.length > 0
? analytics.total_value / fixedAmountForms.length
: 0;
console.log('Checkout Form Analytics:');
console.log('Total forms:', analytics.total);
console.log('By frequency:', analytics.by_frequency);
console.log('By state:', analytics.by_state);
console.log('Completed (with buyer details):', analytics.with_buyer_details);
console.log('Completion rate:', `${((analytics.with_buyer_details / analytics.total) * 100).toFixed(2)}%`);
console.log('Total value:', `$${(analytics.total_value / 100).toFixed(2)}`);
console.log('Average value:', `$${(analytics.avg_value / 100).toFixed(2)}`);
console.log('Active forms:', analytics.active);
console.log('Expired forms:', analytics.expired);
return analytics;
}
7. Export Forms to CSV
Export checkout forms for external analysis:
async function exportFormsToCSV(filters = {}) {
const allForms = await getAllCheckoutForms();
// Apply filters if provided
let filteredForms = allForms;
if (filters.created_after) {
filteredForms = filteredForms.filter(f =>
new Date(f.created_at) >= filters.created_after
);
}
if (filters.payment_frequency) {
filteredForms = filteredForms.filter(f =>
f.payment_frequency === filters.payment_frequency
);
}
// Build CSV
const headers = [
'ID',
'Created At',
'Nickname',
'Payment Frequency',
'State',
'Amount',
'Currency',
'Link URL',
'Expires At',
'Buyer Name',
'Buyer Email',
'Tags'
];
const rows = filteredForms.map(form => [
form.id,
form.created_at,
form.nickname || '',
form.payment_frequency,
form.state,
form.amount_details?.total_amount || '',
form.amount_details?.currency || '',
form.link_url,
form.link_expires_at,
form.buyer_details?.name || '',
form.buyer_details?.email || '',
JSON.stringify(form.tags || {})
]);
const csv = [
headers.join(','),
...rows.map(row => row.map(cell => `"${cell}"`).join(','))
].join('\n');
console.log(`Exported ${filteredForms.length} forms to CSV`);
return csv;
}
8. Monitor Forms by Merchant
Track checkout forms for a specific merchant:
async function getFormsByMerchant(merchantId) {
const allForms = await getAllCheckoutForms();
const merchantForms = allForms.filter(form => form.merchant_id === merchantId);
console.log(`Found ${merchantForms.length} forms for merchant ${merchantId}`);
// Calculate statistics
const stats = {
total: merchantForms.length,
active: 0,
expired: 0,
with_buyers: 0,
one_time: 0,
recurring: 0,
total_amount: 0
};
const now = new Date();
merchantForms.forEach(form => {
if (form.state === 'ACTIVE' && new Date(form.link_expires_at) > now) {
stats.active++;
}
if (new Date(form.link_expires_at) <= now) {
stats.expired++;
}
if (form.buyer_details) {
stats.with_buyers++;
}
if (form.payment_frequency === 'ONE_TIME') {
stats.one_time++;
} else {
stats.recurring++;
}
if (form.amount_details?.total_amount) {
stats.total_amount += form.amount_details.total_amount;
}
});
console.log('Merchant Form Statistics:', stats);
return {
forms: merchantForms,
stats
};
}
Query Parameters
| Parameter | Type | Description |
|---|---|---|
limit | integer | Number of results per page (default: 20, max: 100) |
after_cursor | string | Cursor for forward pagination |
before_cursor | string | Cursor for backward pagination |
created_at_gte | string | Filter forms created on or after this date (ISO 8601) |
created_at_lte | string | Filter forms created on or before this date (ISO 8601) |
Response Fields
| Field | Type | Description |
|---|---|---|
_embedded.checkout_forms | array | Array of checkout form objects |
has_more | boolean | Whether more results exist |
_links.next | object | Link to next page (if has_more is true) |
_links.prev | object | Link to previous page |
Checkout Form Object
Each form in the array contains:
id- Checkout form IDcreated_at- Creation timestamplink_url- Checkout URLlink_expires_at- Expiration timestampstate- Form statemerchant_id- Associated merchantpayment_frequency- ONE_TIME or RECURRINGamount_details- Pricing informationbuyer_details- Buyer information (if submitted)- Full details same as fetch endpoint
Best Practices
1. Use Pagination Wisely
Don't fetch all forms if you only need recent ones:
// Good: Get just what you need
const recentForms = await fetch(
'https://api.ahrvo.network/payments/na/checkout_forms?limit=20',
{ /* ... */ }
);
// Avoid: Fetching all forms unnecessarily
// Only use getAllCheckoutForms() when you truly need all data
2. Filter by Date for Performance
Use date filters to reduce result sets:
// Get only this week's forms
const oneWeekAgo = new Date();
oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
const params = new URLSearchParams({
created_at_gte: oneWeekAgo.toISOString(),
limit: '100'
});
const response = await fetch(
`https://api.ahrvo.network/payments/na/checkout_forms?${params}`,
{ /* ... */ }
);
3. Cache Results
Cache list results to avoid repeated calls:
const listCache = {
data: null,
timestamp: 0,
ttl: 5 * 60 * 1000 // 5 minutes
};
async function getCachedCheckoutFormsList(params = {}) {
const cacheKey = JSON.stringify(params);
if (listCache.data &&
listCache.key === cacheKey &&
Date.now() - listCache.timestamp < listCache.ttl) {
console.log('Returning cached list');
return listCache.data;
}
const queryString = new URLSearchParams(params).toString();
const url = `https://api.ahrvo.network/payments/na/checkout_forms?${queryString}`;
const response = await fetch(url, {
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
});
const data = await response.json();
listCache.data = data;
listCache.key = cacheKey;
listCache.timestamp = Date.now();
return data;
}
4. Monitor Form Expiration
Set up automated monitoring:
async function monitorExpiringForms() {
const expiringForms = await getExpiringForms(24); // 24 hours
if (expiringForms.length > 0) {
// Send alerts
await sendAlert({
type: 'checkout_forms_expiring',
count: expiringForms.length,
forms: expiringForms.map(f => ({
id: f.id,
nickname: f.nickname,
expires_at: f.link_expires_at
}))
});
}
}
// Run every hour
setInterval(monitorExpiringForms, 60 * 60 * 1000);
5. Track Completion Rates
Monitor how many forms are being completed:
async function calculateCompletionRate() {
const recentForms = await getFormsInDateRange(
new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), // 7 days ago
new Date()
);
const total = recentForms.length;
const completed = recentForms.filter(f => f.buyer_details).length;
const rate = total > 0 ? (completed / total) * 100 : 0;
console.log(`Completion rate (last 7 days): ${rate.toFixed(2)}%`);
console.log(`Completed: ${completed} / ${total}`);
return { total, completed, rate };
}
Common Workflows
Daily Report Generation
async function generateDailyReport() {
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
yesterday.setHours(0, 0, 0, 0);
const today = new Date();
today.setHours(0, 0, 0, 0);
const forms = await getFormsInDateRange(yesterday, today);
const report = {
date: yesterday.toLocaleDateString(),
total_created: forms.length,
total_value: 0,
by_type: { ONE_TIME: 0, RECURRING: 0 },
completed: 0
};
forms.forEach(form => {
report.by_type[form.payment_frequency]++;
if (form.buyer_details) {
report.completed++;
}
if (form.amount_details?.total_amount) {
report.total_value += form.amount_details.total_amount;
}
});
console.log('Daily Checkout Form Report:', report);
// Email report to team
await sendEmail('team@company.com', {
subject: `Checkout Forms Report - ${report.date}`,
template: 'daily_report',
data: report
});
return report;
}
Cleanup Expired Forms
async function cleanupExpiredForms() {
const allForms = await getAllCheckoutForms();
const now = new Date();
const expiredForms = allForms.filter(form =>
new Date(form.link_expires_at) <= now
);
console.log(`Found ${expiredForms.length} expired forms`);
// Archive or log expired forms
for (const form of expiredForms) {
await db.archivedForms.create({
checkout_form_id: form.id,
archived_at: new Date(),
reason: 'EXPIRED',
data: form
});
}
console.log('Expired forms archived');
}