intermediate
customers
identity
verification

Identity Verification (Stripe)

Complete guide to customer identity verification using Stripe Identity - modes, risk scoring, verification flow, and management

Levy Fleets TeamJanuary 15, 202522 min read

Identity Verification (Stripe)

Levy Fleets integrates with Stripe Identity to provide robust identity verification for customers. This helps prevent fraud, comply with regulations, and ensure rider safety. This guide covers verification modes, triggers, the verification flow, and management options.

Overview

Identity verification confirms that a customer is who they claim to be by validating government-issued identification documents. The system uses Stripe Identity, which provides:

  • Document scanning: Photos of ID documents (driver's license, passport, ID card)
  • Selfie matching: Compares selfie to ID photo
  • Liveness detection: Prevents photo fraud
  • Data extraction: Pulls verified name, DOB, address from ID
  • Risk scoring: Integrates with Stripe Radar for fraud detection

Verification Modes

Each subaccount can configure one of three verification modes:

Disabled Mode

identity_verification_mode: 'disabled'
  • No identity verification is required
  • All customers can ride without verification
  • Useful for low-risk environments or initial launch
  • No verification costs incurred

All Users Mode

identity_verification_mode: 'all_users'
  • Every new customer must verify identity before first ride
  • Verification prompted during signup or first ride attempt
  • Strictest setting for maximum security
  • Higher verification costs but maximum fraud protection

Risk-Based Mode

identity_verification_mode: 'risk_based'
  • Verification only required when risk threshold exceeded
  • Uses Stripe Radar risk scoring from first payment
  • Configurable threshold determines trigger point
  • Balances security with customer experience

Recommended Setting

Risk-based verification is recommended for most operations as it balances security with customer experience and cost efficiency.

How Risk-Based Verification Works

Risk Score Calculation

When a customer makes their first payment, Stripe Radar analyzes:

  • Payment method characteristics
  • IP address and location
  • Device fingerprint
  • Historical patterns
  • Card issuer country

Stripe returns a risk_level which the system converts to a score:

Risk LevelNumeric ScoreDescription
normal10Low risk, trusted payment
elevated50Some risk indicators present
highest75Multiple high-risk signals

Risk Threshold Configuration

Subaccounts configure a threshold score (default: 50):

identity_verification_risk_threshold: 50

Verification is required when: customer_risk_score >= threshold

Example Scenarios:

Customer ScoreThresholdVerification Required?
10 (normal)50No
50 (elevated)50Yes
75 (highest)50Yes
75 (highest)80No

When Risk Scoring Occurs

Risk score is captured during the first successful card charge:

  1. Customer adds payment method
  2. Customer starts first ride
  3. At ride end, payment is processed
  4. Stripe Radar evaluates the charge
  5. Risk score is stored on customer record
  6. If threshold exceeded, verification is flagged

Subaccount Policy Override

Some subaccounts may require verification for all users regardless of risk:

identity_verification_mode: 'all_users'

When this is set, verification is required before the first ride, bypassing risk-based logic.

Verification Flow

Customer Experience

  1. Trigger: Customer attempts action requiring verification
  2. Notification: Push notification or in-app prompt appears
  3. Launch Stripe Identity: Native verification UI opens
  4. Document Scan: Customer photographs ID document
  5. Selfie: Customer takes selfie for comparison
  6. Processing: Stripe processes and verifies
  7. Result: Immediate pass/fail result displayed
  8. Ride Access: If passed, customer can proceed with rides

Technical Flow

Customer Action
    ↓
Check identity_verification_required
    ↓
If required → API call to /api/customers/{id}/identity-session
    ↓
Stripe Identity session created
    ↓
Client secret returned to mobile app
    ↓
Stripe Identity SDK launched
    ↓
Verification completed
    ↓
Webhook received: identity.verification_session.verified
    ↓
Customer record updated with verified data
    ↓
identity_verification_required = false

Verification Statuses

Customer identity status is tracked in the identity_status field:

StatusMeaningCustomer Can Ride?
nullNever attempted verificationDepends on policy
pendingVerification in progressNo (if required)
verifiedSuccessfully verifiedYes
requires_inputNeeds to retryNo
failedVerification failedNo
canceledSession was canceledNo

Dashboard Indicators

Identity Verification Banner

When a customer requires verification, an amber banner appears on their detail page:

Banner Content:

  • "Identity Verification Required" heading
  • Reason for requirement (subaccount policy or risk threshold)
  • Date verification was flagged
  • Current risk score and level
  • Current verification status
  • Clear Requirement button

Identity Verification Section

The customer detail page includes a dedicated section showing:

FieldDescription
StatusCurrent verification status
Verified AtDate/time of successful verification
Risk ScoreStripe Radar risk score (0-100)
Risk Levelnormal, elevated, highest
ID TypeDriver's license, passport, etc.
Verified NameName extracted from ID
DOBDate of birth from ID
AddressAddress from ID (if available)

Status Badges

Customers may display verification-related badges:

BadgeColorMeaning
Identity RequiredAmberAwaiting verification
VerifiedGreenSuccessfully verified
Verification FailedRedVerification attempt failed

Managing Verification

Viewing Verification Requirement Reason

On the customer detail page, the Identity Verification banner shows why verification was required:

Subaccount Policy:

Reason: Subaccount requires verification for all users

Risk Threshold Exceeded:

Reason: Risk score 75 >= threshold 50
Risk Score: 75/100 (highest)

Clearing Verification Requirement

To remove the verification requirement without the customer verifying:

  1. Navigate to customer detail page
  2. Locate the amber verification banner
  3. Click Clear Requirement
  4. Confirm the action
  5. Customer can now ride without verifying

When to Use:

  • Known trusted customer incorrectly flagged
  • Customer verified identity through other means
  • Business decision to waive requirement
  • Risk assessment was incorrect

Important

Clearing the requirement does NOT mark the customer as verified—it only removes the current requirement. Future risk triggers may require verification again.

Manual Verification

To mark a customer as verified without using Stripe Identity:

  1. Navigate to customer detail page
  2. In the Identity Verification section, click Manually Verify
  3. Add notes explaining how identity was confirmed
  4. Confirm the action

When to Use:

  • In-person verification at a physical location
  • Customer provided ID documents via email/support
  • Legacy customer migration
  • Verification via other identity provider

Manual Verification Database Fields:

FieldDescription
identity_manual_verificationBoolean flag indicating manual verification
identity_manual_verification_notesOperator's notes explaining verification method
identity_manual_verification_byUser ID of the operator who performed the verification
identity_manual_verification_atTimestamp when manual verification was recorded

Manual verification bypasses Stripe Identity completely. The customer's identity_status is set to verified and identity_verification_required is cleared.

Requesting New Verification

To require a customer to verify again:

  1. Navigate to customer detail page
  2. Click Actions > Require Verification
  3. Select a reason
  4. Confirm the action

The customer will be blocked from rides until they complete verification.

Verified Data

When a customer successfully verifies, Stripe Identity extracts:

Always Captured

FieldDatabase ColumnDescription
First Nameidentity_first_nameGiven name from ID
Last Nameidentity_last_nameFamily name from ID
Date of Birthidentity_dobDOB from ID document
ID Typeidentity_id_typeDocument type used

When Available

FieldDatabase ColumnDescription
Addressidentity_addressStreet address from ID
ID Numberidentity_id_numberLicense/passport number
Issuing Countryidentity_issuing_countryDocument issuing country
Expiration Dateidentity_expiration_dateDocument expiry

Verification Metadata

FieldDescription
identity_statusFinal verification status
identity_verified_atTimestamp of verification
identity_session_idStripe session reference
identity_attempt_countNumber of attempts

Notifications

The system sends push notifications for identity-related events:

Verification Required

When verification is first flagged:

  • Title: "Identity Verification Required"
  • Body: "Please verify your identity to continue using [App Name]"
  • Type: identity
  • Action: Opens verification flow in app

Verification Successful

After successful verification:

  • Title: "Identity Verified"
  • Body: "Your identity has been verified. You're all set to ride!"
  • Type: identity

Requirement Cleared

When an operator clears the requirement:

  • Title: "Good to Go!"
  • Body: "Your account has been verified and you can now ride."
  • Type: identity

Configuration

Subaccount Settings

Each subaccount configures verification settings:

SettingTypeDescription
identity_verification_modeenum'disabled', 'all_users', 'risk_based'
identity_verification_risk_thresholdintegerScore threshold (0-100)

High-Security Markets (regulated, high-value assets):

mode: 'all_users'

Standard Operations (balanced approach):

mode: 'risk_based'
threshold: 50

Low-Risk Markets (trusted communities, low-value assets):

mode: 'disabled'

or

mode: 'risk_based'
threshold: 75  # Only flag highest risk

Phone Lookup Risk Data

In addition to Stripe Radar, the system may capture phone-based risk data:

Phone Lookup Fields

FieldDescription
phone_typeMobile, landline, VOIP
phone_carrierCarrier name
phone_is_prepaidPrepaid status
phone_risk_scoreRisk assessment
phone_countryPhone number country

Risk Indicators

Certain phone characteristics indicate higher risk:

  • VOIP numbers (Google Voice, etc.)
  • Recently ported numbers
  • Prepaid carriers in certain regions
  • Mismatch between phone country and signup location

Signup Location Tracking

The system tracks where customers signed up for additional context:

IP-Based Location

FieldDescription
signup_ipIP address at signup
signup_ip_cityCity from IP lookup
signup_ip_regionState/region from IP
signup_ip_countryCountry from IP

GPS Location

FieldDescription
signup_latitudeGPS latitude
signup_longitudeGPS longitude
signup_location_accuracyGPS accuracy meters

Location Risk Indicators

  • IP location significantly different from GPS
  • Signup from known VPN/proxy
  • Location far from any operational zones

API Reference

Create Verification Session

Endpoint: POST /api/customers/{id}/identity-session

Response:

{
  "client_secret": "vs_client_secret_xxx",
  "session_id": "vs_xxx"
}

Get Customer Identity Status

Endpoint: GET /api/customers/{id}

Returns customer with identity fields:

{
  "id": "...",
  "identity_verification_required": true,
  "identity_verification_required_at": "2024-01-15T10:30:00Z",
  "identity_verification_required_reason": "risk_threshold_exceeded:75>=50",
  "identity_status": "pending",
  "stripe_risk_score": 75,
  "stripe_risk_level": "highest"
}

Manual Verification

Endpoint: POST /api/customers/{id}/identity-manual-verify

Request:

{
  "notes": "Verified in person at downtown location"
}

Integration with Ride System

Ride Start Verification Check

When a customer attempts to start a ride (either from the app or via dashboard "Start Trip"), the system checks:

  1. Is verification required? → Check identity_verification_required flag
  2. If required, is verification complete? → Check identity_status === 'verified'
  3. Block ride if not verified → Return error prompting verification

Dashboard Behavior: When starting a trip from the dashboard for a customer who requires verification, the operation will fail with an error message indicating verification is needed.

Mobile App Behavior: The app prompts the customer to complete verification before allowing ride scan.

Automatic Verification Requirement Triggers

Verification may be automatically required when:

  1. First Payment Risk Score: Stripe Radar evaluates the first charge
  2. Risk Threshold Exceeded: Score >= configured threshold
  3. Subaccount Policy: Some subaccounts require all users to verify

Verification Status Impact on Rides

StatusCan Start Ride?
null (never required)Yes
verifiedYes
pendingNo (if identity_verification_required is true)
requires_inputNo
failedNo
canceledNo

Best Practices

For Operators

  1. Choose appropriate mode: Match verification level to your risk tolerance
  2. Monitor flagged customers: Don't leave customers stuck in verification limbo
  3. Train support staff: Ensure team knows how to handle verification issues
  4. Document manual verifications: Always add notes when bypassing flow
  5. Review thresholds: Adjust based on actual fraud rates

For Customer Support

  1. Explain the requirement: Tell customers why verification is needed
  2. Guide through process: Help with document selection and photo tips
  3. Escalate appropriately: Manual verify only when justified
  4. Check before clearing: Verify the clear is appropriate for the case

For Technical Teams

  1. Monitor webhook delivery: Ensure verification callbacks are processing
  2. Handle edge cases: Account for timeout and retry scenarios
  3. Log verification attempts: Maintain audit trail
  4. Test regularly: Verify flow works in all environments

Troubleshooting

Customer can't complete verification

  • Check if Stripe Identity is enabled for your Stripe account
  • Verify mobile app has camera permissions
  • Try different ID document type
  • Ensure adequate lighting for document photos
  • Check for Stripe API errors in logs

Verification passed but customer still blocked

  • Check if identity_verification_required was cleared
  • Verify webhook processed correctly
  • Look for additional blocks (payment issue, manual block)
  • Check for database update failures

Risk score seems incorrect

  • Risk score comes from Stripe Radar, not controlled by Levy
  • Review the charge that triggered scoring
  • Check for VPN/proxy usage by customer
  • Consider threshold adjustment if consistently incorrect

Customer verified but appears as "pending"

  • Check webhook processing for errors
  • Manually refresh customer data from Stripe
  • Verify session ID matches current verification
  • Check for multiple overlapping sessions