Skip to main content

List Merchant Verifications

Overview

Retrieve all Verifications performed for a specific Merchant. Verifications validate merchant identity and business information during onboarding and underwriting.

Resource Access

  • User Permissions: Admin users only
  • Endpoint: GET /merchants/\{merchant_id}/verifications

Arguments

ParameterTypeRequiredDescription
merchant_idstringYesMerchant ID (in URL path)
limitintegerNoNumber of results per page (default: 10, max: 100)

Example Request

curl -X GET \
'https://api.ahrvo.network/payments/na/merchants/MUmerchant123/verifications?limit=20' \
-u username:password

Example Response

{
"_embedded": {
"verifications": [
{
"id": "VIverification123",
"created_at": "2023-12-10T20:00:00Z",
"updated_at": "2023-12-10T20:00:05Z",
"state": "SUCCEEDED",
"merchant": "MUmerchant123",
"payment_instrument": null,
"processor": "DUMMY_V1",
"raw": null,
"trace_id": "VT_98765432",
"type": "MERCHANT",
"_links": {
"self": {
"href": "https://api.ahrvo.network/payments/na/verifications/VIverification123"
},
"merchant": {
"href": "https://api.ahrvo.network/payments/na/merchants/MUmerchant123"
}
}
},
{
"id": "VIverification124",
"created_at": "2023-12-09T15:30:00Z",
"updated_at": "2023-12-09T15:30:08Z",
"state": "SUCCEEDED",
"merchant": "MUmerchant123",
"payment_instrument": null,
"processor": "DUMMY_V1",
"raw": null,
"trace_id": "VT_98765433",
"type": "MERCHANT",
"_links": {
"self": {
"href": "https://api.ahrvo.network/payments/na/verifications/VIverification124"
},
"merchant": {
"href": "https://api.ahrvo.network/payments/na/merchants/MUmerchant123"
}
}
}
]
},
"_links": {
"self": {
"href": "https://api.ahrvo.network/payments/na/merchants/MUmerchant123/verifications?limit=20"
}
},
"page": {
"limit": 20,
"offset": 0,
"count": 2
}
}

Example Response (Failed Verification)

{
"_embedded": {
"verifications": [
{
"id": "VIverification125",
"created_at": "2023-12-10T18:00:00Z",
"updated_at": "2023-12-10T18:00:12Z",
"state": "FAILED",
"merchant": "MUmerchant456",
"payment_instrument": null,
"processor": "DUMMY_V1",
"raw": "{\"error\": \"Invalid tax ID\"}",
"trace_id": "VT_98765434",
"type": "MERCHANT",
"_links": {
"self": {
"href": "https://api.ahrvo.network/payments/na/verifications/VIverification125"
},
"merchant": {
"href": "https://api.ahrvo.network/payments/na/merchants/MUmerchant456"
}
}
}
]
},
"_links": {
"self": {
"href": "https://api.ahrvo.network/payments/na/merchants/MUmerchant456/verifications"
}
},
"page": {
"limit": 10,
"offset": 0,
"count": 1
}
}

Additional Information

  • Verification Type: Always "MERCHANT"
    • Validates merchant identity
    • Business information check
    • Tax ID verification
    • Address validation
    • Owner identity verification
  • States:
    • PENDING: Verification in progress
      • Submitted to processor
      • Awaiting response
      • Typically seconds to minutes
      • Rare state (usually fast)
    • SUCCEEDED: Merchant verified
      • Identity confirmed
      • Business validated
      • Can process payments
      • Onboarding complete
    • FAILED: Verification failed
      • Identity mismatch
      • Invalid tax ID
      • Business not found
      • Check raw field for details
  • Automatic Creation: Created during onboarding
    • When Merchant is created
    • When Identity is associated
    • Platform triggers verification
    • No manual creation needed
  • Payment Instrument: Always null
    • Merchant verifications don't involve payment instruments
    • Only for MERCHANT type
    • Use GET /payment_instruments/{id}/verifications for cards
  • Processor: Verification provider
    • DUMMY_V1: Test/sandbox processor
    • Production processors vary
    • Determines verification rules
    • Different processors, different checks
  • Raw: Processor response
    • Usually null for SUCCEEDED
    • Contains error details for FAILED
    • JSON string format
    • Useful for debugging
    • Not for end-user display
  • Trace ID: Processor reference
    • External verification ID
    • Use for support with processor
    • Helps troubleshoot issues
    • Links to processor logs
  • Multiple Verifications: Possible
    • Re-verification on updates
    • Different verification types
    • Historical record
    • Audit trail
  • Chronological Order: Newest first
    • Most recent verification at top
    • Shows verification history
    • Track re-verification attempts
    • Cannot change sort order

Use Cases

Check Merchant Onboarding Status

# After creating merchant, check verification
curl -X GET \
'https://api.ahrvo.network/payments/na/merchants/MUmerchant123/verifications' \
-u username:password

# Check most recent verification state
# SUCCEEDED = ready to process payments
# FAILED = need to fix merchant info
# PENDING = wait for completion

Debug Failed Onboarding

// Merchant onboarding failed, find out why
async function debugMerchantVerification(merchantId) {
const response = await listMerchantVerifications(merchantId);
const verifications = response._embedded.verifications;

if (verifications.length === 0) {
console.log('No verifications found - merchant may not be submitted yet');
return;
}

const latest = verifications[0]; // Most recent

console.log('Verification Status:', latest.state);
console.log('Created:', latest.created_at);
console.log('Processor:', latest.processor);

if (latest.state === 'FAILED') {
console.error('Verification Failed!');
console.log('Error details:', latest.raw);

// Parse raw response
if (latest.raw) {
const error = JSON.parse(latest.raw);
console.log('Reason:', error.error || error.message);
}

return 'Fix merchant information and retry';
} else if (latest.state === 'SUCCEEDED') {
console.log('Merchant verified successfully');
return 'Ready to process payments';
} else {
console.log('Verification pending...');
return 'Wait for verification to complete';
}
}

Audit Verification History

// View all verification attempts
async function auditMerchantVerifications(merchantId) {
const response = await listMerchantVerifications(merchantId, { limit: 100 });
const verifications = response._embedded.verifications;

console.log(`Total verifications: ${verifications.length}`);

verifications.forEach((v, index) => {
console.log(`\nVerification ${index + 1}:`);
console.log(` ID: ${v.id}`);
console.log(` Date: ${v.created_at}`);
console.log(` State: ${v.state}`);
console.log(` Processor: ${v.processor}`);

if (v.state === 'FAILED') {
console.log(` Error: ${v.raw}`);
}
});

// Calculate success rate
const succeeded = verifications.filter(v => v.state === 'SUCCEEDED').length;
const successRate = (succeeded / verifications.length * 100).toFixed(1);
console.log(`\nSuccess rate: ${successRate}%`);
}

Monitor Pending Verifications

// Find merchants with pending verifications
async function checkPendingVerifications(merchantIds) {
const pending = [];

for (const merchantId of merchantIds) {
const response = await listMerchantVerifications(merchantId);
const verifications = response._embedded.verifications;

if (verifications.length > 0) {
const latest = verifications[0];

if (latest.state === 'PENDING') {
pending.push({
merchant: merchantId,
verificationId: latest.id,
created: latest.created_at,
ageMinutes: Math.floor(
(new Date() - new Date(latest.created_at)) / (1000 * 60)
)
});
}
}
}

console.log(`Pending verifications: ${pending.length}`);
pending.forEach(p => {
console.log(`${p.merchant}: ${p.ageMinutes} minutes`);

if (p.ageMinutes > 10) {
console.warn(' ⚠ Verification taking longer than expected');
}
});

return pending;
}

Re-verification Tracking

// Track when merchant info was updated and re-verified
async function trackReVerifications(merchantId) {
const response = await listMerchantVerifications(merchantId, { limit: 100 });
const verifications = response._embedded.verifications;

if (verifications.length <= 1) {
console.log('No re-verifications (only initial verification)');
return;
}

console.log(`Re-verifications: ${verifications.length - 1}`);
console.log('History:');

verifications.reverse().forEach((v, index) => {
const date = new Date(v.created_at).toLocaleDateString();
const status = v.state === 'SUCCEEDED' ? '✓' : '✗';
console.log(` ${index + 1}. ${date} - ${status} ${v.state}`);
});

// Check if latest is successful
const latest = verifications[verifications.length - 1];
if (latest.state !== 'SUCCEEDED') {
console.warn('\n⚠ Latest verification not successful!');
}
}

Best Practices

  • Check After Creation: Always verify after onboarding
    • Create Merchant
    • Wait a few seconds
    • List verifications
    • Check latest state
    • Handle FAILED appropriately
  • Poll for PENDING: If state is PENDING
    • Wait 5-10 seconds
    • Check again
    • Max wait: 5 minutes
    • After 5 minutes, consider stuck
    • Use webhooks instead of polling
  • Handle FAILED: Fix merchant data
    • Read raw field for reason
    • Update Merchant with correct info
    • System will re-verify automatically
    • Check verifications again
  • Webhooks: Listen for verification events
    • merchant.verification.succeeded
    • merchant.verification.failed
    • More reliable than polling
    • Instant notification
  • Don't Show Raw: Internal only
    • raw field is technical
    • Not user-friendly
    • Use for debugging
    • Display friendly error messages
  • Latest Verification: Use first in list
    • Newest verification is current status
    • Older ones are historical
    • Sort is newest first
    • verifications[0] is latest

Common Workflows

Merchant Onboarding Flow

  1. Create Merchant with Identity info
  2. Platform automatically creates Verification
  3. Wait 5-10 seconds (or use webhook)
  4. List Merchant Verifications
  5. Check latest verification state
  6. If SUCCEEDED: Merchant ready
  7. If FAILED: Update merchant info
  8. If PENDING: Wait and check again

Failed Verification Recovery

async function handleFailedVerification(merchantId) {
// Get latest verification
const response = await listMerchantVerifications(merchantId);
const latest = response._embedded.verifications[0];

if (latest.state !== 'FAILED') {
console.log('Verification not failed');
return;
}

// Parse error
console.log('Verification failed:', latest.raw);
const error = JSON.parse(latest.raw);

// Common issues and fixes
if (error.error?.includes('tax ID')) {
console.log('Fix: Update merchant tax ID');
// Update merchant with correct tax ID
await updateMerchant(merchantId, {
entity: {
tax_id: 'correct-tax-id'
}
});
} else if (error.error?.includes('address')) {
console.log('Fix: Update merchant address');
// Update address
}

// Wait for automatic re-verification
console.log('Waiting for re-verification...');
await sleep(10000);

// Check again
const newResponse = await listMerchantVerifications(merchantId);
const newLatest = newResponse._embedded.verifications[0];
console.log('New status:', newLatest.state);
}

Webhook Integration

// Handle verification webhook
app.post('/webhooks/finix', async (req, res) => {
const event = req.body;

if (event.type === 'merchant.verification.succeeded') {
const merchantId = event.data.merchant;
console.log(`Merchant ${merchantId} verified successfully`);

// Activate merchant in your system
await activateMerchant(merchantId);

// Send welcome email
await sendWelcomeEmail(merchantId);
} else if (event.type === 'merchant.verification.failed') {
const merchantId = event.data.merchant;
const verificationId = event.data.id;

// Get details
const verification = await fetchVerification(verificationId);
console.error(`Verification failed for ${merchantId}:`, verification.raw);

// Notify merchant to update info
await notifyMerchantToUpdateInfo(merchantId, verification.raw);
}

res.status(200).send('OK');
});

Troubleshooting

No Verifications Returned

  • Merchant may not be submitted yet
  • Check Merchant state
  • Ensure Identity is associated
  • Verifications created automatically

Verification Stuck in PENDING

  • Usually completes in seconds
  • If > 5 minutes, contact support
  • Provide trace_id and verification ID
  • May indicate processor issue

Multiple FAILED Verifications

  • Check each raw field
  • Look for pattern in failures
  • May indicate invalid business info
  • Contact support if unclear

SUCCEEDED but Can't Process

  • Verification success != full activation
  • Check Merchant state
  • May need additional approvals
  • Contact support for merchant status
  • GET /merchants/{id}: View merchant details
  • PUT /merchants/{id}: Update merchant info (triggers re-verification)
  • GET /verifications/{id}: Fetch specific verification
  • GET /payment_instruments/{id}/verifications: List card verifications