Stripe Data Synchronization
The Stripe Data Sync feature enables synchronization of payment data between Stripe and Levy Fleets. This includes importing historical charges from CSV exports and real-time syncing via the Stripe API. This guide covers all aspects of Stripe integration for payment data management.
Accessing Stripe Import
Navigate to Admin > Stripe Import to access the Stripe data sync interface.
Requirements:
- Admin access to the system
- Stripe integration configured
- Valid Stripe API credentials (for API sync)
Overview
Sync Methods
| Method | Description | Use Case |
|---|---|---|
| CSV Import | Upload Stripe charge export | Historical data, bulk import |
| API Sync | Fetch from Stripe API | Recent charges, real-time |
| Webhooks | Automatic push from Stripe | Ongoing live updates |
Data Captured
When syncing Stripe charges, the following data is stored:
Charge Details:
- Charge ID, amount, currency, status
- Created timestamp, captured status
- Refund information (amount, date)
- Payment intent ID
Card Information:
- Card ID, brand, last 4 digits
- Expiration month/year
- Card fingerprint, funding type
- AVS and CVC verification status
Customer Information:
- Stripe Customer ID
- Customer email and phone
- Customer description
Ride Metadata (from charge metadata):
- Ride ID, user ID, customer ID
- Start/end coordinates
- Distance and duration
- Payment type and credits used
Dashboard Statistics
The Stripe Import page displays four metric cards:
| Metric | Description |
|---|---|
| Total Charges | Count of all synced charge records |
| Today's Charges | Charges created today |
| Latest Charge | Timestamp of most recent charge |
| Webhook Events | Total logged webhook events |
These metrics update after each sync operation.
CSV Import
Exporting from Stripe
Log into Stripe Dashboard
Navigate to dashboard.stripe.com and log in to your account.
Navigate to Payments
Go to Payments > All payments in the sidebar.
Click Export
Click the Export button in the top-right corner.
Select Date Range
Choose the date range for the charges you want to export.
Choose CSV Format
Select CSV as the export format.
Download the File
Download the exported file to your computer.
Importing the CSV
- In Levy Fleets, go to Admin > Stripe Import
- Locate the "Import CSV" section
- Drag-and-drop your CSV file or click to browse
- Click "Import CSV (Background)"
- Import job starts processing
File Size Handling
| File Size | Processing Method |
|---|---|
| < 10 MB | Standard background import |
| 10+ MB | Client-side parsing with batch upload |
For very large files (10+ MB):
- File is parsed in the browser
- Data sent to server in 500-row batches
- Progress displayed for each batch
Import Progress
The import runs in the background:
- Progress bar shows completion percentage
- Status updates every 2 seconds (polling)
- Notification when complete
- Error count displayed if issues occur
CSV Columns Mapped
Key columns from Stripe export:
| Stripe Column | Database Field |
|---|---|
| id | charge_id |
| Created date (UTC) | created_at |
| Amount | amount |
| Amount Refunded | amount_refunded |
| Currency | currency |
| Status | status |
| Captured | captured |
| Card Last4 | card_last4 |
| Card Brand | card_brand |
| Customer ID | customer_id |
| Customer Email | customer_email |
| ride_number (metadata) | metadata_ride_number |
| user_id (metadata) | metadata_user_id |
| customerId (metadata) | metadata_customer_number |
Plus 40+ additional columns for complete charge data.
API Sync
Manual Sync
- In the Stripe Import page, find "Manual Sync" section
- Click "Sync Last 24 Hours"
- System fetches charges from Stripe API
- Results display: imported, updated, errors
What Gets Synced
- All charges created in the last 24 hours
- Paginated fetching (100 per request)
- Automatic handling of large result sets
- Upserts (inserts new, updates existing)
Sync Results
After sync completes:
- Imported: New charges added
- Updated: Existing charges refreshed
- Errors: Charges that failed to sync
Webhook Integration
How Webhooks Work
Stripe sends real-time notifications to Levy Fleets:
- Event occurs in Stripe (charge, payment, etc.)
- Stripe sends POST to
/api/webhooks/stripe - Levy Fleets validates signature
- Event processed and data updated
- Response sent to Stripe
Supported Webhook Events
Charge Events:
| Event Type | Action |
|---|---|
charge.succeeded | Upsert charge, process risk score from Stripe Radar |
charge.failed | Record failed charge |
charge.captured | Update captured status |
charge.updated | Update charge record |
charge.refunded | Update refund info |
charge.expired | Update charge status |
charge.pending | Update charge status |
Dispute Events:
| Event Type | Action |
|---|---|
charge.refund.updated | Log refund updates |
charge.dispute.created | Log dispute creation |
charge.dispute.updated | Log dispute updates |
charge.dispute.closed | Log dispute closure |
charge.dispute.funds_withdrawn | Log funds withdrawn |
charge.dispute.funds_reinstated | Log funds reinstated |
Payment Intent Events:
| Event Type | Action |
|---|---|
payment_intent.succeeded | Update wallet balance, save payment method, update ride payment |
setup_intent.succeeded | Save payment method |
Customer Events:
| Event Type | Action |
|---|---|
customer.created | Link Stripe customer to customer record |
Identity Verification Events:
| Event Type | Action |
|---|---|
identity.verification_session.requires_input | Update verification status, send notification email |
identity.verification_session.processing | Update verification status |
identity.verification_session.canceled | Update verification status |
identity.verification_session.verified | Update verification status, clear verification requirement |
Configuring Webhooks
Open Stripe Developer Settings
In your Stripe Dashboard, go to Developers > Webhooks
Add Endpoint
Click Add endpoint
Enter Webhook URL
Enter URL: https://your-domain.com/api/webhooks/stripe
Select Events
Select the events you want to receive (see list above)
Copy Signing Secret
Copy the Signing secret from the webhook details
Add Environment Variable
Add to your environment variables as STRIPE_WEBHOOK_SECRET
Import Job Tracking
Active Jobs Section
The page displays currently processing imports:
Job Card Shows:
- File name and size
- Start time
- Progress bar (processed/total rows)
- Status badge
Status Indicators:
| Status | Badge | Description |
|---|---|---|
| Processing | Blue spinner | Currently running |
| Completed | Green check | Finished successfully |
| Completed with Errors | Yellow alert | Finished with some failures |
| Failed | Red X | Critical error stopped import |
Row Counts:
- Imported: New records created
- Updated: Existing records updated
- Skipped: Rows skipped (duplicates, invalid)
- Errors: Rows that failed
Viewing Past Jobs
The import jobs API tracks:
- Job ID and type
- File name and size
- Start and completion times
- Row processing statistics
- Error details (JSONB)
Conflict Handling
Duplicate Prevention
Charges are identified by Stripe charge ID:
stripe_charges.idis the primary keyON CONFLICT (id) DO UPDATEprevents duplicates- Updates refresh existing records with new data
Customer Matching
When syncing, customers are matched by:
- Stripe Customer ID
- Email address
- Metadata customer_id
Data Merging
On conflict (existing charge):
- Amount fields updated
- Status updated
- Refund info updated
- Timestamps preserved
- Metadata merged
Configuration
Required Environment Variables
# Stripe API Keys
STRIPE_SECRET_KEY=sk_live_... # Live secret key
STRIPE_WEBHOOK_SECRET=whsec_... # Webhook signing secret
# Optional
STRIPE_TEST_SECRET_KEY=sk_test_... # Test mode key
API Version
The system uses Stripe API version 2023-10-16. This is set in the configuration and should match your Stripe dashboard settings.
Payment Method Saving
When payment_intent.succeeded or setup_intent.succeeded events are processed:
- Payment method ID and Stripe customer ID extracted
- Customer looked up by
stripe_customer_id - New payment method saved to
payment_methodstable with:customer_uuid- Link to customer recordstripe_payment_method_id- Stripe's payment method IDtype- Card type (usually 'card')last4- Last 4 digits for displaybrand- Card brand (Visa, Mastercard, etc.)
Wallet Top-ups
When a payment_intent.succeeded event indicates a wallet top-up:
Payment Intent Types (from metadata.type):
wallet_topup- Manual wallet top-up by customerauto_topup- Automatic top-up triggered by low balanceride_payment- Direct ride payment
Processing Steps for wallet_topup:
- Customer resolved by metadata (
customer_uuid,customer_number, oruser_id) - Current wallet balance retrieved from customer record
- Payment amount added to balance
wallet_transactionsrecord created with typecredit- Customer balance updated
Auto Top-up Handling
For auto_topup, the balance and transaction have already been recorded by the client, so no additional wallet update is performed during webhook processing.
Transaction Types:
credit- Money added to walletdebit- Money spent from wallet
Ride Payment Updates
When a ride payment completes:
ride_uuidextracted from metadata- Ride record located
total_costupdated with payment amount- Ride marked as paid
Risk Score Processing
From charge outcomes, risk data is captured:
| Field | Description |
|---|---|
stripe_risk_score | 0-100 risk score |
stripe_risk_level | normal, elevated, highest |
Risk Level Mapping:
normal= score 10elevated= score 50highest= score 75
High risk customers may be flagged for identity verification.
Security
Webhook Validation
All webhooks are validated:
- Signature header extracted
stripe.webhooks.constructEvent()verifies signature- Invalid signatures return 400 error
- Prevents spoofed events
API Key Security
- Never expose
STRIPE_SECRET_KEYin client code - Use environment variables only
- Rotate keys if compromised
- Use restricted keys where possible
Data Storage
- Card numbers not stored (only last 4)
- Sensitive data encrypted at rest
- PCI compliance maintained through Stripe
Security Best Practice
Never commit Stripe API keys to version control. Always use environment variables and ensure your .env files are in .gitignore.
Troubleshooting
CSV Import Fails
Possible Causes:
- Invalid CSV format
- Wrong column headers
- File too large
- Network timeout
Solutions:
- Verify export is from Stripe
- Check file isn't corrupted
- Split large files into smaller chunks
- Retry with stable connection
API Sync Returns No Data
Possible Causes:
- No charges in last 24 hours
- API key invalid or expired
- Stripe account has no data
Solutions:
- Expand date range
- Verify API key in environment
- Check Stripe dashboard for charges
Webhooks Not Processing
Possible Causes:
- Webhook secret mismatch
- Endpoint URL incorrect
- Server not reachable
- Event type not subscribed
Solutions:
- Verify
STRIPE_WEBHOOK_SECRET - Check endpoint URL in Stripe dashboard
- Ensure server is accessible
- Add required event types
Duplicate Charges Appearing
Cause: Same charge processed multiple times
Note: This shouldn't happen due to upsert logic. If it does:
- Check for unique constraint on charge ID
- Verify database migrations are current
Best Practices
Regular Syncing
- Daily manual sync: Run API sync each morning
- Weekly CSV export: Import historical data weekly
- Webhook monitoring: Check webhook logs regularly
Data Verification
After syncing:
- Compare counts with Stripe dashboard
- Spot check recent charges
- Verify customer matching is working
Performance
- Off-peak imports: Run large CSV imports during low traffic
- Monitor webhooks: Keep webhook processing fast
- Database indexes: Ensure proper indexes exist
What's Next?
- Super Admin Features - Learn about platform administration
- Data Import Tools - Import other types of data
- Account Setup - Configure payment settings
Stripe Integration Ready
With Stripe data sync configured, you'll have complete visibility into payment activity across your fleet. Use webhooks for real-time updates and periodic CSV imports to ensure complete historical data.