Skip to main content

Fetch a Compliance Form

Retrieve a Compliance Form by its ID to check completion status, download forms, or verify compliance details.

Overview

Use this endpoint to:

  • Check form status (INCOMPLETE, COMPLETE, or EXPIRED)
  • Download unsigned forms for merchant review
  • Download signed forms for record-keeping
  • Verify signature details and timestamps
  • Monitor validity periods and expiration dates
  • Track compliance for individual merchants

Use Cases

1. Check Form Completion Status

Verify if a compliance form has been completed:

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

const form = await response.json();

console.log('Form Status:', {
id: form.id,
state: form.state,
type: form.type,
due_date: form.due_at,
valid_until: form.valid_until
});

return form.state === 'COMPLETE';
}

2. Get Form for Merchant Review

Retrieve unsigned form for merchant to review:

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

const form = await response.json();

if (form.state === 'COMPLETE') {
console.log('Form already completed');
return {
form,
unsigned_file: form.unsigned_file,
signed_file: form.signed_file,
needs_review: false
};
}

if (form.state === 'EXPIRED') {
console.log('Form has expired');
throw new Error('Compliance form has expired. Contact support for renewal.');
}

// Form is INCOMPLETE - provide for review
console.log('Form ready for review:', {
unsigned_file: form.unsigned_file,
due_date: form.due_at,
days_until_due: Math.ceil((new Date(form.due_at) - new Date()) / (1000 * 60 * 60 * 24))
});

return {
form,
unsigned_file: form.unsigned_file,
needs_review: true
};
}

3. Download Signed Document

Retrieve the signed compliance document:

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

const form = await response.json();

if (form.state !== 'COMPLETE') {
throw new Error(`Cannot download signed document: form is ${form.state}`);
}

if (!form.signed_file) {
throw new Error('Signed file URL not available');
}

// Download the signed PDF
const pdfResponse = await fetch(form.signed_file);
const pdfBlob = await pdfResponse.blob();

const filename = `${saveDirectory}/compliance_${form.id}_signed.pdf`;
await saveFile(filename, pdfBlob);

console.log('Signed document downloaded:', filename);

return {
local_file: filename,
signed_at: form.pci_saq_a?.signed_at,
signer: form.pci_saq_a?.name,
valid_until: form.valid_until
};
}

4. Verify Signature Details

Check who signed the form and when:

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

const form = await response.json();

if (form.state !== 'COMPLETE' || !form.pci_saq_a) {
console.log('Form not completed - no signature available');
return null;
}

const signature = {
signer_name: form.pci_saq_a.name,
signer_title: form.pci_saq_a.title,
signed_at: new Date(form.pci_saq_a.signed_at),
ip_address: form.pci_saq_a.ip_address,
user_agent: form.pci_saq_a.user_agent
};

console.log('Signature Details:', signature);

// Verify signature timestamp is within validity period
const signedDate = signature.signed_at;
const validFrom = new Date(form.valid_from);
const validUntil = new Date(form.valid_until);

const isValid = signedDate >= validFrom && signedDate <= validUntil;

console.log('Signature validity:', {
is_valid: isValid,
signed_at: signedDate.toISOString(),
valid_from: validFrom.toISOString(),
valid_until: validUntil.toISOString()
});

return {
...signature,
is_valid: isValid
};
}

5. Monitor Form Expiration

Check if form is expiring soon:

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

const form = await response.json();

const now = new Date();
const validUntil = new Date(form.valid_until);
const daysUntilExpiration = Math.ceil((validUntil - now) / (1000 * 60 * 60 * 24));

const status = {
id: form.id,
state: form.state,
valid_until: form.valid_until,
days_until_expiration: daysUntilExpiration,
is_expired: validUntil < now,
expires_soon: daysUntilExpiration > 0 && daysUntilExpiration <= 30
};

if (status.is_expired) {
console.warn('⚠️ Form has EXPIRED');
} else if (status.expires_soon) {
console.warn(`⚠️ Form expires in ${daysUntilExpiration} days`);
} else {
console.log(`✓ Form valid for ${daysUntilExpiration} days`);
}

return status;
}

6. Display Form in Dashboard

Get form details for admin dashboard:

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

const form = await response.json();

const dashboardData = {
id: form.id,
created: new Date(form.created_at).toLocaleDateString(),
merchant_id: form.linked_to,
type: form.type,
state: form.state,
state_color: {
'INCOMPLETE': 'yellow',
'COMPLETE': 'green',
'EXPIRED': 'red'
}[form.state],
due_date: new Date(form.due_at).toLocaleDateString(),
valid_from: new Date(form.valid_from).toLocaleDateString(),
valid_until: new Date(form.valid_until).toLocaleDateString(),
signer: form.pci_saq_a?.name || 'Not signed',
signed_date: form.pci_saq_a?.signed_at
? new Date(form.pci_saq_a.signed_at).toLocaleDateString()
: 'N/A',
unsigned_file: form.unsigned_file,
signed_file: form.signed_file || 'N/A'
};

console.log('Dashboard Data:', dashboardData);
return dashboardData;
}

7. Compliance Audit Report

Generate audit report for a form:

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

const form = await response.json();

const report = {
// Form identification
form_id: form.id,
form_type: form.type,
created_at: form.created_at,
updated_at: form.updated_at,

// Merchant information
merchant_id: form.linked_to,
linked_type: form.linked_type,

// Compliance status
current_state: form.state,
due_date: form.due_at,
validity_period: {
from: form.valid_from,
until: form.valid_until
},

// Signature details (if completed)
signature: form.pci_saq_a ? {
signer_name: form.pci_saq_a.name,
signer_title: form.pci_saq_a.title,
signed_at: form.pci_saq_a.signed_at,
ip_address: form.pci_saq_a.ip_address,
user_agent: form.pci_saq_a.user_agent
} : null,

// Documents
documents: {
unsigned_file: form.unsigned_file,
signed_file: form.signed_file
},

// Audit metadata
report_generated_at: new Date().toISOString(),
compliance_status: form.state === 'COMPLETE' ? 'COMPLIANT' : 'NON_COMPLIANT'
};

console.log('Audit Report Generated:', report);

// Export to JSON or PDF
await exportReport(report, `audit_${formId}.json`);

return report;
}

8. Check Multiple Forms for Merchant

Get all compliance forms status for a merchant:

async function getMerchantComplianceStatus(merchantId) {
// First, list all forms for the merchant
const listResponse = await fetch(
`https://api.ahrvo.network/payments/na/compliance_forms?linked_to=${merchantId}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const listData = await listResponse.json();
const formIds = listData._embedded?.compliance_forms?.map(f => f.id) || [];

// Fetch detailed information for each form
const formDetails = await Promise.all(
formIds.map(async (formId) => {
const response = await fetch(
`https://api.ahrvo.network/payments/na/compliance_forms/${formId}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);
return response.json();
})
);

const summary = {
merchant_id: merchantId,
total_forms: formDetails.length,
complete: formDetails.filter(f => f.state === 'COMPLETE').length,
incomplete: formDetails.filter(f => f.state === 'INCOMPLETE').length,
expired: formDetails.filter(f => f.state === 'EXPIRED').length,
forms: formDetails.map(f => ({
id: f.id,
type: f.type,
state: f.state,
due_at: f.due_at,
valid_until: f.valid_until
}))
};

console.log('Merchant Compliance Summary:', summary);

return summary;
}

Response Fields

Core Fields

FieldTypeDescription
idstringUnique compliance form ID
created_atstringCreation timestamp
updated_atstringLast update timestamp
statestringINCOMPLETE, COMPLETE, or EXPIRED
typestringForm type (e.g., PCI_SAQ_A)
linked_tostringMerchant ID
linked_typestringEntity type (e.g., MERCHANT)

Date Fields

FieldTypeDescription
due_atstringWhen the form is due
valid_fromstringStart of validity period
valid_untilstringEnd of validity period

Document Fields

FieldTypeDescription
unsigned_filestringURL to unsigned PDF form
signed_filestringURL to signed PDF (if completed)

Signature Fields (When state is COMPLETE)

FieldTypeDescription
pci_saq_a.namestringName of signer
pci_saq_a.titlestringTitle/role of signer
pci_saq_a.signed_atstringSignature timestamp
pci_saq_a.ip_addressstringIP address of signer
pci_saq_a.user_agentstringBrowser/device user agent

Best Practices

1. Cache Form Data

Reduce API calls by caching:

const complianceCache = new Map();
const CACHE_TTL = 10 * 60 * 1000; // 10 minutes

async function getCachedComplianceForm(formId) {
const cached = complianceCache.get(formId);

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

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

const form = await response.json();

complianceCache.set(formId, {
data: form,
timestamp: Date.now()
});

return form;
}

2. Handle All States

Account for all possible states:

async function handleFormState(formId) {
const form = await getCachedComplianceForm(formId);

switch (form.state) {
case 'INCOMPLETE':
console.log('Form needs completion');
return {
action_required: true,
message: 'Please review and sign the compliance form',
unsigned_file: form.unsigned_file
};

case 'COMPLETE':
console.log('Form is complete');
return {
action_required: false,
message: 'Compliance form completed',
signed_file: form.signed_file,
valid_until: form.valid_until
};

case 'EXPIRED':
console.log('Form has expired');
return {
action_required: true,
message: 'Compliance form has expired. Contact support for renewal.',
expired_at: form.valid_until
};

default:
console.warn('Unknown form state:', form.state);
return {
action_required: true,
message: 'Unknown compliance form state'
};
}
}

3. Monitor Expiration Proactively

Set up alerts for expiring forms:

async function checkAndAlertExpiration(formId, alertThresholdDays = 30) {
const form = await getCachedComplianceForm(formId);

const validUntil = new Date(form.valid_until);
const now = new Date();
const daysRemaining = Math.ceil((validUntil - now) / (1000 * 60 * 60 * 24));

if (daysRemaining <= alertThresholdDays && daysRemaining > 0) {
await sendAlert({
type: 'compliance_expiring',
form_id: formId,
merchant_id: form.linked_to,
days_remaining: daysRemaining,
valid_until: form.valid_until
});

console.log(`Alert sent: Form expires in ${daysRemaining} days`);
}
}

4. Store Documents Securely

Download and archive compliance documents:

async function archiveComplianceDocuments(formId) {
const form = await getCachedComplianceForm(formId);

const documents = {
unsigned: null,
signed: null
};

// Download unsigned form
if (form.unsigned_file) {
const unsignedResponse = await fetch(form.unsigned_file);
const unsignedBlob = await unsignedResponse.blob();
documents.unsigned = await uploadToSecureStorage(
`compliance/${form.id}/unsigned.pdf`,
unsignedBlob
);
}

// Download signed form (if available)
if (form.signed_file) {
const signedResponse = await fetch(form.signed_file);
const signedBlob = await signedResponse.blob();
documents.signed = await uploadToSecureStorage(
`compliance/${form.id}/signed.pdf`,
signedBlob
);
}

console.log('Documents archived:', documents);
return documents;
}

5. Error Handling

Handle errors gracefully:

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

if (response.status === 404) {
throw new Error('Compliance 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 compliance form:', error);
throw error;
}
}

Common Workflows

Merchant Portal Display

async function displayComplianceInPortal(merchantId) {
// Get all forms for merchant
const forms = await getMerchantComplianceStatus(merchantId);

// Display each form
forms.forms.forEach(form => {
const display = {
title: `${form.type} Form`,
status: form.state,
due_date: new Date(form.due_at).toLocaleDateString(),
action: form.state === 'INCOMPLETE'
? 'Review and Sign'
: 'View Document'
};

console.log('Display:', display);
});
}

Automated Compliance Monitoring

async function monitorComplianceForms() {
// This would run daily
const allMerchants = await getMerchants();

for (const merchant of allMerchants) {
const status = await getMerchantComplianceStatus(merchant.id);

if (status.incomplete > 0 || status.expired > 0) {
await notifyMerchant(merchant.id, {
incomplete: status.incomplete,
expired: status.expired,
forms: status.forms
});
}
}
}

Interactive API Reference