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
| Parameter | Type | Required | Description |
|---|---|---|---|
| merchant_id | string | Yes | Merchant ID (in URL path) |
| limit | integer | No | Number 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
rawfield for details
- PENDING: Verification in progress
- 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
rawfield for reason - Update Merchant with correct info
- System will re-verify automatically
- Check verifications again
- Read
- Webhooks: Listen for verification events
merchant.verification.succeededmerchant.verification.failed- More reliable than polling
- Instant notification
- Don't Show Raw: Internal only
rawfield 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
- Create Merchant with Identity info
- Platform automatically creates Verification
- Wait 5-10 seconds (or use webhook)
- List Merchant Verifications
- Check latest verification state
- If SUCCEEDED: Merchant ready
- If FAILED: Update merchant info
- 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
rawfield - 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
Related Endpoints
- 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