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 Team15 janvier 202525 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

Age and Name Requirements

Identity verification now has completion requirements that run after Stripe Identity returns a verified session. Stripe still checks the document and selfie first; Levy then checks whether the verified ID meets the operator's local ride rules.

SettingDefaultWhat it does
Minimum age16Requires the ID holder to be at least this age based on the date of birth extracted from the ID. Leave blank to disable age enforcement.
Require customer name matchEnabledRequires the name on the ID to match the customer's account profile before they can ride.

Name Matching Behavior

The name match is intended to stop a customer from verifying with someone else's ID. It compares the customer profile name to the verified ID name and:

  • Ignores capitalization, punctuation, and accents
  • Allows middle names on the ID
  • Allows first-name initials
  • Requires the account surname tokens to appear in the verified ID surname
  • Rejects same-last-name, different-first-name cases such as Ryker Curry using an ID for Emma Jo Curry

If either the account profile name or the ID name is missing, the customer is treated as not approved until the profile or verification attempt is fixed.

Age Requirement Behavior

The minimum age check uses the verified date of birth from Stripe Identity. Age is calculated against the current date using the rider's birthday boundary. For example, with a minimum age of 16, a rider born on June 4, 2010 is eligible on June 4, 2026, but a rider born on June 5, 2010 is not eligible on June 4, 2026.

If the ID does not include a usable date of birth and a minimum age is configured, the customer is not approved.

What Happens When Requirements Fail

If Stripe verifies the document but Levy's age or name requirement fails:

  1. The verified ID outputs are still saved on the customer record for operator review.
  2. The customer is not marked as verified.
  3. The customer's identity status becomes requires_input.
  4. The ride-start and unlock flows stay blocked.
  5. The app receives an identity notification that opens the Identity Verification screen.
  6. The customer detail page shows the compliance error reason.

Common rejection reasons include:

ReasonMeaning
identity_name_mismatchID name does not match the customer profile name
identity_profile_name_missingAccount profile name or ID name is missing
identity_dob_missingID did not include a usable date of birth while age enforcement is enabled
identity_age_requirementID holder is younger than the configured minimum age

Where to Configure Settings

Global Settings

Use Admin > Global Identity Settings to configure the default identity policy for all subaccounts. Global settings include:

  • Verification mode: Disabled, All Users, or Risk-Based
  • Stripe risk threshold
  • Phone risk threshold
  • Minimum age
  • Require customer name match

These values are the default policy for every subaccount that uses global identity settings.

Subaccount Settings

Use Dashboard > Settings > Identity Verification inside a subaccount to choose whether that subaccount uses global settings or custom settings.

When Use Global Settings is selected, the subaccount inherits the global verification mode, thresholds, minimum age, and name-match rule.

When Custom Settings is selected, the subaccount can set its own:

  • Verification mode
  • Risk thresholds
  • Minimum age
  • Name-match requirement

Use custom settings when one market has different legal requirements. For example, an Illinois scooter subaccount can require riders to be 16 while another market can use a different minimum age or disable age enforcement if it is not legally required.

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 can now start rides."
  • Type: identity

Verification Not Approved

When Stripe rejects the verification attempt or Levy's local age/name requirements reject an otherwise verified ID:

  • Title: "ID Verification Not Approved" or "ID Verification Needs Attention"
  • Body: Explains whether the issue is a name mismatch, age requirement, missing DOB, missing name, or generic verification failure
  • Type: identity
  • Action: Opens the Identity Verification screen in the app
  • Inbox behavior: The notification is saved even if the rider has no push token or push permissions

Requirement Cleared

When an operator clears the requirement:

  • Title: "Verification Requirement Cleared"
  • Body: "You can now start rides again."
  • 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)
phone_risk_thresholdintegerPhone risk score threshold used with combined risk
identity_minimum_ageinteger or nullMinimum verified age. null disables age enforcement
identity_name_match_requiredbooleanWhether verified ID name must match customer profile name

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 more advanced identity verification scenarios beyond Stripe Identity, some fleet operators also use specialized verification services like SwitchID for multi-signal identity checks.

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