Skip to main content

Fetch a Checkout Form

Retrieve a Checkout Form by its ID to check its status, get the payment link, or view submitted buyer information.

Overview

Use this endpoint to:

  • Get the checkout URL to send to customers
  • Check form status (active, expired, completed)
  • Retrieve buyer details after form submission
  • Verify configuration before sending to customers
  • Monitor form usage and expiration

Use Cases

1. Get Checkout URL for Customer

Retrieve the link to send to your customer:

async function getCheckoutUrl(checkoutFormId) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/checkout_forms/${checkoutFormId}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const form = await response.json();

console.log('Checkout URL:', form.link_url);
console.log('Expires:', new Date(form.link_expires_at));
console.log('State:', form.state);

return form.link_url;
}

2. Check Form Status

Verify if form is still active:

async function isCheckoutFormActive(checkoutFormId) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/checkout_forms/${checkoutFormId}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const form = await response.json();

const now = new Date();
const expiresAt = new Date(form.link_expires_at);

const isActive = form.state === 'ACTIVE' && expiresAt > now;

console.log('Form Status:', {
state: form.state,
expires_at: form.link_expires_at,
is_expired: expiresAt <= now,
is_active: isActive
});

return isActive;
}

3. Retrieve Buyer Information

Get buyer details after form submission:

async function getBuyerDetails(checkoutFormId) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/checkout_forms/${checkoutFormId}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const form = await response.json();

if (form.buyer_details) {
console.log('Buyer Information:');
console.log('Name:', form.buyer_details.name);
console.log('Email:', form.buyer_details.email);
console.log('Phone:', form.buyer_details.phone_number);

if (form.buyer_details.billing_address) {
console.log('Billing Address:', {
street: form.buyer_details.billing_address.street,
city: form.buyer_details.billing_address.city,
state: form.buyer_details.billing_address.region,
postal_code: form.buyer_details.billing_address.postal_code,
country: form.buyer_details.billing_address.country
});
}

if (form.buyer_details.shipping_address) {
console.log('Shipping Address:', {
street: form.buyer_details.shipping_address.street,
city: form.buyer_details.shipping_address.city,
state: form.buyer_details.shipping_address.region,
postal_code: form.buyer_details.shipping_address.postal_code,
country: form.buyer_details.shipping_address.country
});
}

return form.buyer_details;
}

console.log('No buyer details yet (form not submitted)');
return null;
}

4. Verify Form Configuration

Check form settings before sending to customer:

async function verifyCheckoutForm(checkoutFormId, expectedConfig) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/checkout_forms/${checkoutFormId}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const form = await response.json();

// Verify key settings
const verification = {
merchant_id: form.merchant_id === expectedConfig.merchantId,
payment_frequency: form.payment_frequency === expectedConfig.paymentFrequency,
total_amount: form.amount_details?.total_amount === expectedConfig.totalAmount,
allowed_methods: JSON.stringify(form.allowed_payment_methods) === JSON.stringify(expectedConfig.allowedMethods),
has_branding: !!form.branding,
has_items: form.items?.length > 0
};

const isValid = Object.values(verification).every(v => v);

console.log('Form Verification:', {
form_id: form.id,
is_valid: isValid,
checks: verification
});

if (!isValid) {
console.error('Configuration mismatch detected!');
}

return isValid;
}

5. Monitor Form Expiration

Check time remaining before expiration:

async function getFormTimeRemaining(checkoutFormId) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/checkout_forms/${checkoutFormId}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const form = await response.json();

const now = new Date();
const expiresAt = new Date(form.link_expires_at);
const msRemaining = expiresAt - now;

if (msRemaining <= 0) {
console.log('Form has expired');
return {
expired: true,
time_remaining: 0
};
}

const minutesRemaining = Math.floor(msRemaining / 60000);
const hoursRemaining = Math.floor(minutesRemaining / 60);
const daysRemaining = Math.floor(hoursRemaining / 24);

console.log('Time Remaining:', {
days: daysRemaining,
hours: hoursRemaining % 24,
minutes: minutesRemaining % 60,
expires_at: form.link_expires_at
});

return {
expired: false,
time_remaining: msRemaining,
days: daysRemaining,
hours: hoursRemaining,
minutes: minutesRemaining
};
}

Retrieve link to resend to customer:

async function resendCheckoutLink(checkoutFormId, customerEmail) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/checkout_forms/${checkoutFormId}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const form = await response.json();

// Check if form is still valid
const expiresAt = new Date(form.link_expires_at);
if (expiresAt <= new Date()) {
console.error('Cannot resend: checkout form has expired');
throw new Error('Checkout form expired. Please create a new one.');
}

if (form.state !== 'ACTIVE') {
console.error('Cannot resend: checkout form is not active');
throw new Error('Checkout form is not active');
}

// Resend email
await sendEmail(customerEmail, {
subject: 'Your Payment Link (Resent)',
template: 'checkout_reminder',
data: {
checkout_url: form.link_url,
expires_at: form.link_expires_at,
amount: form.amount_details?.total_amount
}
});

console.log('Checkout link resent to:', customerEmail);
return form;
}

7. Form Details for Dashboard

Display form information in admin dashboard:

async function getFormDetailsForDashboard(checkoutFormId) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/checkout_forms/${checkoutFormId}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const form = await response.json();

return {
id: form.id,
created: new Date(form.created_at).toLocaleDateString(),
nickname: form.nickname || 'Unnamed Form',
amount: form.amount_details?.total_amount
? `$${(form.amount_details.total_amount / 100).toFixed(2)}`
: 'Variable',
payment_type: form.payment_frequency,
state: form.state,
expires: new Date(form.link_expires_at).toLocaleDateString(),
link: form.link_url,
buyer_name: form.buyer_details?.name || 'Not submitted',
buyer_email: form.buyer_details?.email || 'Not submitted',
items_count: form.items?.length || 0,
tags: form.tags
};
}

8. Integration with Order Management

Sync checkout form with order status:

async function syncOrderWithCheckoutForm(orderId) {
// Get order from database
const order = await db.orders.findById(orderId);

if (!order.checkout_form_id) {
console.log('No checkout form associated with order');
return;
}

// Fetch checkout form
const response = await fetch(
`https://api.ahrvo.network/payments/na/checkout_forms/${order.checkout_form_id}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const form = await response.json();

// Update order with buyer details if available
if (form.buyer_details) {
await db.orders.update(orderId, {
customer_name: form.buyer_details.name,
customer_email: form.buyer_details.email,
customer_phone: form.buyer_details.phone_number,
billing_address: form.buyer_details.billing_address,
shipping_address: form.buyer_details.shipping_address,
checkout_completed: true
});

console.log('Order updated with buyer details');
}

// Check if form expired
if (new Date(form.link_expires_at) <= new Date() && order.status === 'PENDING_PAYMENT') {
await db.orders.update(orderId, {
status: 'CHECKOUT_EXPIRED'
});

console.log('Order marked as checkout expired');
}

return form;
}

Response Fields

Core Fields

FieldTypeDescription
idstringUnique checkout form ID
created_atstringCreation timestamp
updated_atstringLast update timestamp
merchant_idstringAssociated merchant
application_idstringAssociated application
statestringForm state (e.g., ACTIVE)
FieldTypeDescription
link_urlstringThe checkout URL for customers
link_expires_atstringWhen the link expires

Configuration

FieldTypeDescription
payment_frequencystringONE_TIME or RECURRING
is_multiple_usebooleanWhether form can be reused
allowed_payment_methodsarrayAllowed payment methods
nicknamestringForm nickname

Buyer Details (After Submission)

FieldTypeDescription
buyer_details.namestringBuyer's name
buyer_details.emailstringBuyer's email
buyer_details.phone_numberstringBuyer's phone
buyer_details.billing_addressobjectBilling address
buyer_details.shipping_addressobjectShipping address

Items and Pricing

FieldTypeDescription
itemsarrayProducts/services
amount_detailsobjectPricing information
amount_details.total_amountintegerTotal amount in cents
amount_details.amount_typestringFIXED or VARIABLE

Best Practices

1. Cache Form Data

Cache checkout form details to reduce API calls:

const formCache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes

async function getCachedCheckoutForm(checkoutFormId) {
const cached = formCache.get(checkoutFormId);

if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
console.log('Returning cached form data');
return cached.data;
}

const response = await fetch(
`https://api.ahrvo.network/payments/na/checkout_forms/${checkoutFormId}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const form = await response.json();

formCache.set(checkoutFormId, {
data: form,
timestamp: Date.now()
});

return form;
}

2. Handle Expired Forms

Always check expiration before using:

async function ensureFormIsValid(checkoutFormId) {
const form = await getCachedCheckoutForm(checkoutFormId);

if (new Date(form.link_expires_at) <= new Date()) {
throw new Error('Checkout form has expired. Please create a new one.');
}

if (form.state !== 'ACTIVE') {
throw new Error(`Checkout form is ${form.state}. Cannot use.`);
}

return form;
}

3. Store Buyer Details

Save buyer information from completed forms:

async function processBuyerDetails(checkoutFormId) {
const form = await getCachedCheckoutForm(checkoutFormId);

if (!form.buyer_details) {
console.log('No buyer details available yet');
return null;
}

// Store in your database
const customer = await db.customers.upsert({
email: form.buyer_details.email,
name: form.buyer_details.name,
phone: form.buyer_details.phone_number,
billing_address: form.buyer_details.billing_address,
shipping_address: form.buyer_details.shipping_address
});

console.log('Customer record updated:', customer.id);
return customer;
}

4. Monitor Form Usage

Track when forms are viewed:

async function trackCheckoutFormAccess(checkoutFormId, source) {
const form = await getCachedCheckoutForm(checkoutFormId);

await db.analytics.create({
event: 'checkout_form_accessed',
checkout_form_id: checkoutFormId,
source: source,
timestamp: new Date(),
form_state: form.state,
expires_at: form.link_expires_at
});
}

5. Error Handling

Handle errors gracefully:

async function safeGetCheckoutForm(checkoutFormId) {
try {
const response = await fetch(
`https://api.ahrvo.network/payments/na/checkout_forms/${checkoutFormId}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

if (response.status === 404) {
throw new Error('Checkout form not found');
}

if (!response.ok) {
const error = await response.json();
throw new Error(`API error: ${error._embedded?.errors?.[0]?.message || 'Unknown error'}`);
}

return await response.json();

} catch (error) {
console.error('Error fetching checkout form:', error);
throw error;
}
}

Common Workflows

Email Reminder Workflow

async function sendExpirationReminder(checkoutFormId, customerEmail) {
const form = await getCachedCheckoutForm(checkoutFormId);

const expiresAt = new Date(form.link_expires_at);
const hoursRemaining = (expiresAt - new Date()) / (1000 * 60 * 60);

if (hoursRemaining > 0 && hoursRemaining < 24) {
await sendEmail(customerEmail, {
subject: 'Your checkout link expires soon!',
template: 'checkout_expiring',
data: {
checkout_url: form.link_url,
hours_remaining: Math.round(hoursRemaining),
amount: form.amount_details?.total_amount
}
});

console.log('Expiration reminder sent');
}
}

Webhook Integration

// When receiving payment success webhook
async function handlePaymentSuccess(webhookData) {
const checkoutFormId = webhookData.checkout_form_id;

// Fetch form to get buyer details
const form = await getCachedCheckoutForm(checkoutFormId);

if (form.buyer_details) {
// Update order with complete information
await db.orders.update(webhookData.order_id, {
status: 'PAID',
customer_name: form.buyer_details.name,
customer_email: form.buyer_details.email,
billing_address: form.buyer_details.billing_address,
shipping_address: form.buyer_details.shipping_address
});

// Send confirmation email
await sendEmail(form.buyer_details.email, {
subject: 'Payment Confirmed',
template: 'order_confirmation',
data: {
order_id: webhookData.order_id,
items: form.items
}
});
}
}

Interactive API Reference