Vendor Onboarding Verification Workflow for India
Anas Nadeem
Founder

Most vendor onboarding workflows collect documents.
PAN card. GST certificate. Cancelled cheque. MSME certificate if applicable. FSSAI license if the vendor is in food.
Then the files go into a folder and the vendor is marked "onboarded."
That is document collection. It is not verification.
A useful vendor onboarding workflow answers operational questions before the vendor reaches procurement, accounts payable, or payout systems.
- Is the PAN valid?
- Is the GSTIN active?
- Does the bank account look usable for payouts?
- Is the Udyam number valid for an MSME claim?
- Is the FSSAI license active for a food vendor?
- Do the names across documents reasonably match?
The goal is not to verify everything for everyone. The goal is to run the right checks for the vendor category and risk.
Recommended Checks By Vendor Type
| Vendor type | Recommended checks |
|---|---|
| Individual consultant | PAN, bank |
| GST-registered supplier | PAN, GST, bank |
| Contractor with TDS sensitivity | PAN Advanced, bank |
| MSME supplier | PAN, GST if applicable, MSME, bank |
| Food vendor | PAN, GST if applicable, FSSAI, bank |
| Marketplace merchant | PAN or GST, bank, category-specific checks |
This is a baseline. Your final workflow should reflect your internal policy, tax requirements, vendor risk, and compliance obligations.
Vendor Data Model
Keep uploaded files, submitted identifiers, verification responses, and approval decisions separate.
Example:
{
"vendor_id": "ven_123",
"business_name": "Fresh Foods Pvt Ltd",
"vendor_type": "food_supplier",
"pan_number": "ABCDE1234F",
"gstin": "22ABCDE1234F1Z5",
"udyam_number": "UDYAM-MH-01-0012345",
"fssai_number": "45678912345678",
"bank_account": {
"account_number": "50100123456789",
"ifsc": "HDFC0001234"
},
"verification_status": {
"pan": "pending",
"gst": "pending",
"bank": "pending",
"msme": "not_required",
"fssai": "pending"
}
}The file proves what the vendor uploaded. The API response proves what your system checked. The approval status records what your business decided.
Step 1: PAN Verification
PAN is usually the first check because it anchors tax identity for many vendor workflows.
curl -X POST "https://api.theverifico.com/api/v1/verify/pan" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"pan_number": "ABCDE1234F"}'Example response:
{
"success": true,
"verification_type": "pan",
"verification_data": {
"pan_number": "ABCDE1234F",
"full_name": "JOHN DOE",
"category": "person",
"pan_status": "E",
"pan_status_desc": "Existing and Valid"
},
"processing_time_ms": 820
}
Use PAN Advanced when the workflow needs operative or inoperative context:
curl -X POST "https://api.theverifico.com/api/v1/verify/pan_advanced" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"pan_number": "ABCDE1234F"}'
Do not rely only on a regex. A PAN can be correctly formatted and still not be enough for your workflow.
Step 2: GST Verification
GST verification is important for B2B purchases, invoice processing, ITC review, and vendor master creation.
curl -X POST "https://api.theverifico.com/api/v1/verify/gst" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"gstin": "22ABCDE1234F1Z5"}'Important fields:
| Field | Why it matters |
|---|---|
| gstin | Vendor GSTIN |
| pan_number | PAN embedded in GSTIN |
| legal_name | Legal registered name |
| business_name | Trade or business name |
| gstin_status | Active, cancelled, suspended, and similar states |
| date_of_registration | Useful for vendor age checks |
| date_of_cancellation | Useful for invoice-date review |
| filing_status | Filing context when available |
| taxpayer_type | Regular, composition, and related context |
Suggested routing:
| GST result | Suggested action |
|---|---|
| Active and name matches | Continue onboarding |
| Cancelled before invoice date | Block or finance review |
| Suspended | Compliance review |
| Name mismatch | Ask vendor for clarification |
| Invalid format | Ask for corrected GSTIN |
Do not assume a GST certificate PDF means the GSTIN is active today.
Step 3: Cheque OCR and Bank Verification
Bank verification should happen before the vendor becomes payout-eligible.
If the vendor uploads a cancelled cheque, run cheque OCR first:
curl -X POST "https://api.theverifico.com/api/v1/documents/extract/cheque" \
-H "X-API-Key: YOUR_API_KEY" \
-F "file=@cancelled-cheque.jpg"Then verify the extracted account number and IFSC:
curl -X POST "https://api.theverifico.com/api/v1/verify/bank" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"account_number": "50100123456789",
"ifsc": "HDFC0001234",
"include_ifsc_details": true
}'Example response:
{
"success": true,
"verification_type": "bank",
"verification_data": {
"account_exists": true,
"full_name": "FRESH FOODS PRIVATE LIMITED",
"status": "success",
"bank_name": "HDFC Bank",
"branch": "Mumbai Main Branch"
},
"processing_time_ms": 850
}Name matching should be a business rule, not a single strict comparison. Bank records often use initials, proprietor names, old company names, or abbreviated suffixes.
Step 4: MSME/Udyam Verification
Use MSME verification only when the vendor claims MSME status or your workflow depends on enterprise classification.
curl -X POST "https://api.theverifico.com/api/v1/verify/msme" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"udyam_number": "UDYAM-MH-01-0012345"}'Useful fields include:
udyam_numberenterprise_nameorganisation_typemajor_activityenterprise_typedate_of_incorporationdate_of_commencementofficial_addresscertificate_url
Suggested routing:
| MSME result | Suggested action |
|---|---|
| Valid and enterprise name matches | Mark MSME verified |
| Invalid format | Ask for corrected Udyam number |
| Not found or mismatch | Do not apply MSME-specific status until reviewed |
MSME verification should not be forced for vendors that are not claiming MSME status.
Step 5: FSSAI Verification For Food Vendors
Food vendors need a separate compliance check.
Use FSSAI verification when onboarding:
- restaurants
- cloud kitchens
- packaged food sellers
- grocery suppliers
- food manufacturers
- food distributors
curl -X POST "https://api.theverifico.com/api/v1/verify/fssai" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fssai_number": "45678912345678",
"get_products": true,
"get_license_active_flag": true
}'Useful fields include:
fssai_numbercompany_namefull_namekind_of_businesslicense_category_nameissued_dateexpiry_datestatus_desclicense_active_flagproductsaddress
Suggested routing:
| FSSAI result | Suggested action |
|---|---|
| Active license | Continue onboarding |
| Expired or inactive | Block until renewed |
| Product category mismatch | Manual compliance review |
| Name or address mismatch | Ask vendor for corrected license or route to review |
Node.js Vendor Verification Orchestrator
const axios = require("axios");
const BASE_URL = "https://api.theverifico.com/api/v1";
async function post(path, body) {
const response = await axios.post(`${BASE_URL}${path}`, body, {
headers: {
"X-API-Key": process.env.THEVERIFICO_API_KEY,
"Content-Type": "application/json",
},
timeout: 20000,
});
return response.data;
}
async function verifyVendor(vendor) {
const results = {};
if (vendor.pan_number) {
results.pan = await post("/verify/pan", {
pan_number: vendor.pan_number,
});
}
if (vendor.needs_pan_advanced && vendor.pan_number) {
results.pan_advanced = await post("/verify/pan_advanced", {
pan_number: vendor.pan_number,
});
}
if (vendor.gstin) {
results.gst = await post("/verify/gst", {
gstin: vendor.gstin,
});
}
if (vendor.bank_account?.account_number && vendor.bank_account?.ifsc) {
results.bank = await post("/verify/bank", {
account_number: vendor.bank_account.account_number,
ifsc: vendor.bank_account.ifsc,
include_ifsc_details: true,
});
}
if (vendor.udyam_number) {
results.msme = await post("/verify/msme", {
udyam_number: vendor.udyam_number,
});
}
if (vendor.fssai_number) {
results.fssai = await post("/verify/fssai", {
fssai_number: vendor.fssai_number,
get_products: true,
get_license_active_flag: true,
});
}
return results;
}Routing Results
Your routing logic should be explicit. Do not hide every mismatch behind a generic "verification failed" message.
def route_vendor(results: dict) -> str:
pan = results.get("pan", {})
gst = results.get("gst", {})
bank = results.get("bank", {})
fssai = results.get("fssai", {})
if pan and not pan.get("success"):
return "manual_review_pan"
gst_data = gst.get("verification_data") or {}
if gst_data and gst_data.get("gstin_status", "").lower() != "active":
return "manual_review_gst"
bank_data = bank.get("verification_data") or {}
if bank and not bank_data.get("account_exists"):
return "manual_review_bank"
fssai_data = fssai.get("verification_data") or {}
if fssai_data and fssai_data.get("license_active_flag") is False:
return "manual_review_fssai"
return "approved_for_next_step"The output should explain the reason to operations. "Manual review GST" is much better than "Vendor rejected."
Common Mistakes
Mistake 1: Treating file upload as verification
Uploading a GST certificate or cheque image is not verification by itself. It is document collection. Use OCR to extract fields and verification APIs to check identifiers.
Mistake 2: Verifying everything for every vendor
Not every vendor needs MSME or FSSAI checks. Over-verification adds cost and friction.
Mistake 3: Ignoring name mismatch
API responses may return names that need matching against the submitted vendor profile. Build rules for exact match, fuzzy match, and manual review.
Mistake 4: Not re-verifying time-sensitive documents
FSSAI licenses expire. GSTIN status can change. Bank accounts can become unusable. Vendor onboarding should include re-verification rules for high-risk vendors.
Mistake 5: Not storing verification evidence
Store structured responses, timestamps, and decision outcomes. A PDF folder is not an audit trail.
Frequently Asked Questions
Should every vendor go through PAN verification?
Most vendor workflows benefit from PAN verification, but the exact requirement depends on your business and tax process.
Is GST verification enough for a company vendor?
No. GST verification validates GST registration details. You may still need bank verification, PAN-related checks, and category-specific checks.
Should I verify bank accounts before or after approval?
Before the vendor becomes payout-eligible. Otherwise payment failures move the problem downstream.
Is MSME verification required for all vendors?
No. Use it when MSME status affects procurement, lending, classification, or reporting.
Is FSSAI verification required for all vendors?
No. Use it for food-related businesses.
Quick Integration Checklist
- Define vendor categories and required checks
- Collect numbers separately from document uploads
- Use OCR for data entry automation
- Use verification APIs for trust decisions
- Build routing rules for mismatch, inactive status, and missing data
- Store response JSON and timestamps
- Limit sensitive data visibility in internal tools
- Re-verify time-sensitive licenses periodically
Vendor onboarding should not be a pile of PDFs. It should be a structured workflow with clear checks, clear outcomes, and a clear audit trail.
Start with PAN verification, GST verification, and bank verification, then add MSME or FSSAI only where the vendor category requires it.
