Verification & Anti-Fraud
A registered user is not the same as a trusted user. Before an owner can list properties and accept payouts, we need confidence they are real, they own what they claim to own, and money flowing through their account is going to the right person.
Fake property listings on travel platforms are a known fraud vector — the host takes payment and disappears. ABc absorbs that risk because guests pay us. Strong KYC up front protects both guests and the platform's chargeback ratio.
Three layers of verification
Layer 1 — Reachability
Email verified by magic link. Phone verified by OTP. Confirms the user can be contacted on both channels.
All usersLayer 2 — Identity (KYC)
Government ID: PAN + Aadhaar or Passport. OCR + face-match. Required for owners before going live.
OwnersLayer 3 — Business
GSTIN (optional), trade licence / hotel registration, bank account proof (cancelled cheque or statement).
OwnersVerification status states
Each user (or each property) carries a verification state. Here is the full state machine:
What each state unlocks
| State | Can sign in | Create property | Accept bookings | Receive payouts |
|---|---|---|---|---|
| unverified | — | — | — | — |
| contact_verified | ✅ | ✅ (draft) | — | — |
| kyc_submitted | ✅ | ✅ (draft) | — | — |
| review_pending | ✅ | ✅ (draft) | — | — |
| verified | ✅ | ✅ (publish) | ✅ | ✅ |
| rejected | ✅ | — | — | — |
| suspended | ✅ (read-only) | — | — | — |
KYC submission UI
How documents are validated
PAN — instant
Validated against NSDL via verification provider (Karza / SurePass / Signzy). Confirms PAN exists and the name on it matches.
Aadhaar — OTP-based eKYC
UIDAI flow. User enters last 4 digits + OTP. We never store the full Aadhaar number — we store a hash + the masked last-4.
Trade licence — OCR + manual
OCR extracts business name + address. We auto-match against the user's stated business name; mismatches go to manual review.
Bank proof — penny-drop
Razorpay's account validation API: we send ₹1, read back the account holder's name from the response, match it to PAN name.
Risk signals & auto-rejection
The system computes a risk score on submission. High scores get auto-rejected with a polite reason; medium scores go to manual review.
| Signal | Weight |
|---|---|
| Name mismatch between PAN and bank account | +40 (block) |
| Document image flagged as digitally altered (forensic check) | +40 (block) |
| PAN already linked to another active owner account | +40 (block) |
| OCR address city ≠ stated property city | +15 |
| Sign-up IP and KYC IP differ by >500 km | +10 |
| Sign-up email domain is a free provider (gmail, etc.) | +5 |
| Phone number country code ≠ business country | +10 |
Manual review queue (super admin)
The platform team has a console at /admin/kyc. Each row links to the user, all submitted docs, the computed risk score, the country, and one-click Approve / Reject buttons. Rejection requires a reason code that gets surfaced to the user in their email.
| Owner | Submitted | Risk | Issues | |
|---|---|---|---|---|
| Rohan Mehta Park View Hotel · Manali |
2 hrs ago | 12 (low) | None | |
| Anita Sharma Lakeside Stays · Naukuchiatal |
5 hrs ago | 35 (med) | Address mismatch | |
| Test User — · Mumbai |
1 day ago | 62 (high) | PAN reused, doc altered |
Data retention & privacy
- Raw KYC documents stored encrypted in S3 with KMS-managed keys. Bucket is private; signed URLs only for authorised reviewers.
- We do not store full Aadhaar numbers — only masked last-4 plus a salted hash for dedup detection.
- Documents are deleted 90 days after a user is permanently deactivated (or sooner on request, subject to legal hold).
- Audit log captures every read of a KYC document — reviewer, time, IP, reason.