Skip to main content

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

ParameterTypeDescription
limitintegerNumber of results per page (default: 20, max: 100)
after_cursorstringCursor for forward pagination
before_cursorstringCursor for backward pagination
created_at_gtestringFilter forms created on or after this date (ISO 8601)
created_at_ltestringFilter forms created on or before this date (ISO 8601)

Response Fields

FieldTypeDescription
_embedded.checkout_formsarrayArray of checkout form objects
has_morebooleanWhether more results exist
_links.nextobjectLink to next page (if has_more is true)
_links.prevobjectLink to previous page

Checkout Form Object

Each form in the array contains:

  • id - Checkout form ID
  • created_at - Creation timestamp
  • link_url - Checkout URL
  • link_expires_at - Expiration timestamp
  • state - Form state
  • merchant_id - Associated merchant
  • payment_frequency - ONE_TIME or RECURRING
  • amount_details - Pricing information
  • buyer_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');
}

Interactive API Reference