Stripe Integration Setup
Levy Fleets uses Stripe as its primary payment processor for all financial transactions. This comprehensive guide covers the complete setup and configuration of the Stripe integration for fleet operators, including API keys, webhooks, test mode, and advanced features.
What Stripe Handles
Stripe powers all payment-related functionality in Levy Fleets:
- Ride payments and collections - Charging customers for rides
- Wallet top-ups - Manual and automatic balance additions
- Payment method storage - Securely saving customer cards
- Identity verification - KYC using Stripe Identity
- Refund processing - Returning funds to customers
- Payment retries - Recovering failed payments
PCI Compliance
By using Stripe, Levy Fleets maintains PCI compliance. Card data is never stored on our servers - only tokenized references are kept, ensuring the highest level of payment security.
Prerequisites
Before configuring Stripe integration, ensure you have:
- A Stripe account - Create one at stripe.com if you don't have one
- Admin access to your Levy Fleets dashboard
- Access to environment variables - Vercel dashboard or server configuration
- Understanding of your payment model - Wallet-based or post-paid
Environment Variables
Required Variables
Configure these environment variables for Stripe to function:
| Variable | Description | Example |
|---|---|---|
STRIPE_SECRET_KEY | Live mode secret key | sk_live_... |
STRIPE_WEBHOOK_SECRET | Webhook signing secret | whsec_... |
STRIPE_PUBLISHABLE_KEY | Live mode publishable key | pk_live_... |
Optional Variables (Test Mode)
For development and testing:
| Variable | Description | Example |
|---|---|---|
STRIPE_TEST_SECRET_KEY | Test mode secret key | sk_test_... |
STRIPE_TEST_PUBLISHABLE_KEY | Test mode publishable key | pk_test_... |
Additional Variables
| Variable | Description | Example |
|---|---|---|
CRON_SECRET | Authentication for cron job endpoints | Random 32+ character string |
Getting Your Stripe Keys
Access the Stripe Dashboard
Log in to your Stripe account at dashboard.stripe.com. Ensure you're viewing the correct account using the account switcher in the top-left corner.
Locate API Keys
Navigate to Developers in the left sidebar, then click API Keys. You'll see both the Publishable key and Secret key. Click "Reveal" to see your secret key - keep this confidential!
Set Up Webhook Secret
Navigate to Developers > Webhooks. Click Add endpoint and enter your webhook URL: https://your-domain.com/api/webhooks/stripe. Select the events to listen for (see Webhook Events section below), then click Add endpoint. Click into your new webhook endpoint and click Reveal under "Signing secret" to get your STRIPE_WEBHOOK_SECRET.
Configure Environment
Add the keys to your environment variables in Vercel or your hosting platform.
Keep Secrets Secure
Never commit API keys to version control or share them publicly. Your secret key provides full access to your Stripe account and should be treated like a password.
Webhook Configuration
Webhooks allow Stripe to notify Levy Fleets when payment events occur. Configure your webhook endpoint to receive these events:
Required Webhook Events
Charge Events
charge.succeeded- Capture successful paymentscharge.failed- Track failed payment attemptscharge.captured- Record captured pre-authorizationscharge.updated- Sync charge updatescharge.refunded- Track refundscharge.expired- Handle expired chargescharge.pending- Track pending charges
Dispute Events
charge.dispute.createdcharge.dispute.updatedcharge.dispute.closedcharge.dispute.funds_withdrawncharge.dispute.funds_reinstated
Payment Intent Events
payment_intent.succeeded- Process completed payments
Setup Intent Events
setup_intent.succeeded- Save new payment methods
Customer Events
customer.created- Link Stripe customers to your databasecustomer.updated- Sync customer changescustomer.deleted- Handle customer deletion
Identity Events (if using ID verification)
identity.verification_session.requires_inputidentity.verification_session.processingidentity.verification_session.canceledidentity.verification_session.verified
Webhook Security
All webhooks are automatically verified using Stripe's signature mechanism. The system also logs all webhook events in the stripe_webhook_logs table for auditing and debugging.
Test Mode vs Live Mode
Automatic Test Mode Selection
The system automatically uses test mode for:
- Super Admin Users - All super_admin role users automatically use test mode
- Internal Emails - Any customer with
@levyelectric.comemail uses test mode
This allows safe testing without risking production charges.
Test Mode Behavior
In test mode:
- All Stripe API calls use test secret keys
- Payment methods use test card numbers
- No real money is charged
- Test mode is indicated in the dashboard UI
Test Card Numbers
Use these test cards for development:
| Card Number | Description |
|---|---|
4242 4242 4242 4242 | Successful payment |
4000 0000 0000 0002 | Card declined |
4000 0000 0000 9995 | Insufficient funds |
4000 0027 6000 3184 | Requires authentication |
5555 5555 5555 4444 | Mastercard |
3782 822463 10005 | American Express |
Use any valid future expiry date and any 3-digit CVC (4 digits for Amex).
Payment System Configuration
Subaccount Payment Settings
Each subaccount can configure its payment system in Settings > Payments:
| Setting | Description |
|---|---|
| Payment System | Choose "Wallet" or "Post Paid" |
| Minimum Wallet Balance | Balance required to start a ride (e.g., $5.00) |
| Top-Up Options | Available amounts with optional bonuses |
| Auto Top-Up | Enable automatic wallet refills |
| Auto Top-Up Amount | Amount to charge when triggered |
| Auto Top-Up Trigger Level | Balance that triggers auto top-up |
Wallet System vs Post-Paid
| Feature | Wallet System | Post-Paid |
|---|---|---|
| Pre-funding | Required | Not required |
| Ride billing | Deducted from wallet | Charged after ride |
| Failed payments | Wallet goes negative | Payment retry queue |
| Customer friction | Higher (must top up) | Lower |
| Cash flow | Better (pre-paid) | Delayed |
Recommendation
Most operators prefer the Wallet system for better cash flow and reduced payment failures. The bonus structure also encourages larger deposits.
Auto Top-Up System
Auto top-up automatically charges a customer's card when their wallet balance drops below a threshold.
Requirements
For auto top-up to work:
- Subaccount Setting - Auto top-up enabled on the subaccount
- Customer Preference - Customer must opt-in to auto top-up
- Payment Method - Customer must have a default payment method
- Stripe Customer - Customer must have a linked Stripe customer ID
How It Works
- Ride ends or periodic check runs
- System checks if wallet balance is at or below threshold
- System acquires a lock to prevent duplicate charges
- Stripe PaymentIntent is created with idempotency key
- On success, wallet balance is credited
- Lock is released
Preventing Duplicate Charges
The system uses two mechanisms to prevent duplicate charges:
- Database Lock - Columns track lock status and expiration
- Stripe Idempotency Key - Unique key per auto top-up attempt
Payment Retry System
When a customer's wallet goes negative, the system automatically attempts to recover the outstanding amount.
Retry Schedule
| Time Period | Retry Frequency | Details |
|---|---|---|
| Day 1 | 3 attempts | Immediate, +4 hours, +8 hours |
| Days 2-7 | 1 attempt per day | At 9 AM UTC |
| After Day 7 | 1 attempt per week | Every 7 days |
| Maximum | 6 months | Jobs expire after 180 days |
Payment Method Cycling
When retrying, the system cycles through all saved payment methods:
- Default payment method first - Tries the customer's preferred card
- Then other cards by age - Oldest cards tried first
- Cycle resets - On each new scheduling slot, all methods are tried again
Automatic Waiver
Balances under $0.50 are automatically waived (Stripe minimum is $0.50 for USD charges).
Identity Verification (Stripe Identity)
Levy Fleets integrates with Stripe Identity for customer identity verification.
Verification Modes
Configure identity verification at the subaccount level:
| Mode | Description |
|---|---|
disabled | No identity verification required |
all_users | All customers must verify identity |
risk_based | Only high-risk customers require verification |
Risk-Based Verification
When using risk-based mode:
- Stripe Radar scores payments (0-100)
- Risk levels:
normal(10),elevated(50),highest(75) - If score >= threshold, verification is required
- Customer is blocked until verified
Verification Charges (Temporary Holds)
The system can place temporary authorization holds on customer cards to verify payment method validity.
Hold Policies
| Policy | Description |
|---|---|
disabled | No verification charges |
first_ride | Hold placed on customer's first ride only |
all_rides | Hold placed on every ride start |
How Holds Work
- Authorization created - No actual charge, just a hold
- Card validated - Confirms card is active and has funds
- Hold released - Automatically released after ride or within 7 days
- Never captured - Verification holds are never converted to actual charges
Database Integration
Key Tables
| Table | Purpose |
|---|---|
customers | Stores stripe_customer_id and wallet balance |
payment_methods | Stores linked payment methods |
stripe_charges | Mirrors all Stripe charges |
stripe_webhook_logs | Logs all webhook events |
wallet_transactions | Records all wallet credits/debits |
Cron Jobs
Several cron jobs support the payment system:
| Cron | Schedule | Purpose |
|---|---|---|
/api/cron/automatic-refunds | Every 5 minutes | Process automatic refunds |
/api/cron/payment-retries | Every 5 minutes | Retry failed payments |
/api/cron/bill-active-rides | Every minute | Bill ongoing rides |
All cron endpoints require the CRON_SECRET header for authentication.
Local Development
Testing with Stripe CLI
Install Stripe CLI
Download and install the Stripe CLI from stripe.com/docs/stripe-cli
Login to Stripe
Run stripe login to authenticate with your Stripe account
Forward Webhooks
Run stripe listen --forward-to localhost:3000/api/webhooks/stripe to forward webhook events to your local server. The CLI will display a webhook signing secret to use for local testing.
Triggering Test Events
# Trigger a charge.succeeded event
stripe trigger charge.succeeded
# Trigger a payment_intent.succeeded event
stripe trigger payment_intent.succeeded
Monitoring and Debugging
Checking Webhook Logs
View recent webhook activity in your database:
SELECT
event_type,
status,
COUNT(*) as count,
MAX(processed_at) as last_seen
FROM stripe_webhook_logs
WHERE processed_at > NOW() - INTERVAL '24 hours'
GROUP BY event_type, status
ORDER BY last_seen DESC;
Failed Payments Analysis
SELECT
decline_reason,
COUNT(*) as count,
SUM(amount) / 100.0 as total_usd
FROM stripe_charges
WHERE status = 'failed'
AND created_at > NOW() - INTERVAL '7 days'
GROUP BY decline_reason
ORDER BY count DESC;
Troubleshooting
Common Issues
"Webhook signature verification failed"
Cause: Incorrect STRIPE_WEBHOOK_SECRET or request body modification
Solution:
- Verify the secret matches your Stripe dashboard
- Ensure no middleware is modifying the request body
- Check for correct header name:
stripe-signature
"Customer not found" in Stripe
Cause: Customer was deleted in Stripe or never synced
Solution:
- Check
stripe_customer_idin customers table - Verify the ID exists in Stripe dashboard
- Clear the ID and let the system recreate it
Payments not syncing
Cause: Webhook endpoint misconfigured or failing
Solution:
- Check
stripe_webhook_logsfor errors - Verify webhook URL in Stripe dashboard
- Resend failed events from Stripe dashboard
- Check application logs for errors
Test mode not working
Cause: Test keys not configured
Solution:
- Add
STRIPE_TEST_SECRET_KEYandSTRIPE_TEST_PUBLISHABLE_KEY - Verify keys start with
sk_test_andpk_test_ - Check if user has
@levyelectric.comemail or super_admin role
Security Best Practices
- Never log full card numbers - Only last4 is stored
- Rotate webhook secrets - Change periodically
- Use separate test/live keys - Never mix environments
- Enable Radar - Stripe's fraud detection
- Monitor for anomalies - Set up alerts for unusual activity
- PCI Compliance - Never handle raw card data server-side
What's Next?
- Payment Methods - Managing customer payment methods
- Automatic Refunds - How automatic refunds work
- Damage Charges - Charging customers for damage
Integration Complete
Once your Stripe integration is configured and tested, you're ready to process payments. Monitor your Stripe dashboard and Levy Fleets analytics to track payment performance and quickly identify any issues.