Skip to main content

Overview

StablePay provides a complete KYC solution that verifies user identity and bank account ownership. This guide explains the verification flow.

KYC Requirements

Before users can receive INR payouts, they must complete:
VerificationRequiredPurpose
Aadhaar (DigiLocker)YesGovernment ID, address proof
PANYesTax identity, name verification
Bank AccountYesPayout destination verification
Face LivenessYesAnti-fraud, identity confirmation
UPINo (Optional)Alternative payout verification

Verification Flow

Use our KYC APIs to build a custom verification experience in your application. Step 1: Aadhaar via DigiLocker (Required)
curl -X POST https://api.stablepay.global/v2/users/{userId}/kyc/digilocker/init \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "success": true,
  "data": {
    "redirectUrl": "https://digilocker-sdk.surepass.io/...",
    "sessionId": "dgl_abc123",
    "expiresAt": "2025-01-05T10:30:00Z"
  }
}
Then poll the status endpoint until verification completes:
curl https://api.stablepay.global/v2/users/{userId}/kyc/digilocker/status \
  -H "Authorization: Bearer YOUR_API_KEY"
Step 2: PAN Verification (Required)
curl -X POST https://api.stablepay.global/v2/users/{userId}/kyc/pan/verify \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"panNumber": "ABCDE1234F"}'
Step 3: Bank Verification (Required)
curl -X POST https://api.stablepay.global/v2/users/{userId}/kyc/bank/verify \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "accountNumber": "1234567890",
    "ifsc": "HDFC0001234",
    "accountHolderName": "Rahul Kumar"
  }'
We perform a penny drop (₹1 transfer) to verify account ownership. Step 4: Face Liveness (Required)
curl -X POST https://api.stablepay.global/v2/users/{userId}/kyc/face/init \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "success": true,
  "data": {
    "sessionId": "face_session_123",
    "url": "https://kyc-sdk.surepass.io/face-liveness?token=...",
    "expiresIn": 600
  }
}
Step 5: UPI Verification (Optional)
curl -X POST https://api.stablepay.global/v2/users/{userId}/kyc/upi/verify \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"upiId": "rahul.kumar@upi"}'

KYC Status

Check KYC status at any time:
curl https://api.stablepay.global/v2/users/{userId} \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "success": true,
  "data": {
    "user": {
      "id": "usr_abc123",
      "name": "Rahul Kumar"
    },
    "kyc": {
      "level": "verified",
      "status": "verified",
      "pan": {
        "verified": true,
        "verifiedAt": "2025-01-05T10:00:00Z",
        "maskedNumber": "XXXX1234F"
      },
      "aadhaar": {
        "verified": true,
        "verifiedAt": "2025-01-05T10:05:00Z",
        "maskedNumber": "XXXX XXXX 1234"
      },
      "face": {
        "verified": true,
        "verifiedAt": "2025-01-05T10:07:00Z"
      },
      "bank": {
        "verified": true,
        "verifiedAt": "2025-01-05T10:10:00Z",
        "ifsc": "HDFC0001234",
        "bankName": "HDFC Bank"
      }
    }
  }
}

KYC Status Values

StatusMeaning
pendingNo verification started
in_progressAt least one verification completed
verifiedAll required verifications complete
failedVerification failed (fraud/mismatch)

KYC Levels

LevelRequirementsCan Transact
noneNo verification completedNo
basicAadhaar (DigiLocker) + PAN + BankYes
enhancedBasic + Face Liveness + UPI (reserved for future)Yes

Name Matching

We perform fuzzy name matching across all documents:
  • PAN name vs Aadhaar name
  • Aadhaar name vs Bank account name
  • Minimum 80% match required
Transactions will fail if bank account name doesn’t match KYC name.

Error Handling

Common KYC errors:
Error CodeDescriptionResolution
PAN_INVALIDInvalid PAN formatCheck 10-character alphanumeric format
PAN_NOT_FOUNDPAN not in government DBVerify PAN is active
AADHAAR_OTP_EXPIREDDigiLocker session expiredRestart Aadhaar flow
BANK_PENNY_DROP_FAILEDBank transfer failedCheck account number/IFSC
NAME_MISMATCHNames don’t matchContact support

Webhooks

You’ll receive webhooks for KYC status changes:
{
  "event": "user.kyc_updated",
  "timestamp": "2025-01-05T10:15:00Z",
  "data": {
    "userId": "usr_abc123",
    "kyc": {
      "level": "basic",
      "status": "verified"
    }
  }
}