intermediate
stripe
payments
integration

Stripe Integration Setup

Complete guide to configuring Stripe payment processing for your Levy Fleets operation, including API keys, webhooks, and test mode

Levy Fleets Team25 décembre 202520 min read

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:

  1. A Stripe account - Create one at stripe.com if you don't have one
  2. Admin access to your Levy Fleets dashboard
  3. Access to environment variables - Vercel dashboard or server configuration
  4. Understanding of your payment model - Wallet-based or post-paid

Environment Variables

Required Variables

Configure these environment variables for Stripe to function:

VariableDescriptionExample
STRIPE_SECRET_KEYLive mode secret keysk_live_...
STRIPE_WEBHOOK_SECRETWebhook signing secretwhsec_...
STRIPE_PUBLISHABLE_KEYLive mode publishable keypk_live_...

Optional Variables (Test Mode)

For development and testing:

VariableDescriptionExample
STRIPE_TEST_SECRET_KEYTest mode secret keysk_test_...
STRIPE_TEST_PUBLISHABLE_KEYTest mode publishable keypk_test_...

Additional Variables

VariableDescriptionExample
CRON_SECRETAuthentication for cron job endpointsRandom 32+ character string

Getting Your Stripe Keys

1

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.

2

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!

3

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.

4

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 payments
  • charge.failed - Track failed payment attempts
  • charge.captured - Record captured pre-authorizations
  • charge.updated - Sync charge updates
  • charge.refunded - Track refunds
  • charge.expired - Handle expired charges
  • charge.pending - Track pending charges

Dispute Events

  • charge.dispute.created
  • charge.dispute.updated
  • charge.dispute.closed
  • charge.dispute.funds_withdrawn
  • charge.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 database
  • customer.updated - Sync customer changes
  • customer.deleted - Handle customer deletion

Identity Events (if using ID verification)

  • identity.verification_session.requires_input
  • identity.verification_session.processing
  • identity.verification_session.canceled
  • identity.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:

  1. Super Admin Users - All super_admin role users automatically use test mode
  2. Internal Emails - Any customer with @levyelectric.com email 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 NumberDescription
4242 4242 4242 4242Successful payment
4000 0000 0000 0002Card declined
4000 0000 0000 9995Insufficient funds
4000 0027 6000 3184Requires authentication
5555 5555 5555 4444Mastercard
3782 822463 10005American 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:

SettingDescription
Payment SystemChoose "Wallet" or "Post Paid"
Minimum Wallet BalanceBalance required to start a ride (e.g., $5.00)
Top-Up OptionsAvailable amounts with optional bonuses
Auto Top-UpEnable automatic wallet refills
Auto Top-Up AmountAmount to charge when triggered
Auto Top-Up Trigger LevelBalance that triggers auto top-up

Wallet System vs Post-Paid

FeatureWallet SystemPost-Paid
Pre-fundingRequiredNot required
Ride billingDeducted from walletCharged after ride
Failed paymentsWallet goes negativePayment retry queue
Customer frictionHigher (must top up)Lower
Cash flowBetter (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:

  1. Subaccount Setting - Auto top-up enabled on the subaccount
  2. Customer Preference - Customer must opt-in to auto top-up
  3. Payment Method - Customer must have a default payment method
  4. Stripe Customer - Customer must have a linked Stripe customer ID

How It Works

  1. Ride ends or periodic check runs
  2. System checks if wallet balance is at or below threshold
  3. System acquires a lock to prevent duplicate charges
  4. Stripe PaymentIntent is created with idempotency key
  5. On success, wallet balance is credited
  6. Lock is released

Preventing Duplicate Charges

The system uses two mechanisms to prevent duplicate charges:

  1. Database Lock - Columns track lock status and expiration
  2. 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 PeriodRetry FrequencyDetails
Day 13 attemptsImmediate, +4 hours, +8 hours
Days 2-71 attempt per dayAt 9 AM UTC
After Day 71 attempt per weekEvery 7 days
Maximum6 monthsJobs expire after 180 days

Payment Method Cycling

When retrying, the system cycles through all saved payment methods:

  1. Default payment method first - Tries the customer's preferred card
  2. Then other cards by age - Oldest cards tried first
  3. 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:

ModeDescription
disabledNo identity verification required
all_usersAll customers must verify identity
risk_basedOnly high-risk customers require verification

Risk-Based Verification

When using risk-based mode:

  1. Stripe Radar scores payments (0-100)
  2. Risk levels: normal (10), elevated (50), highest (75)
  3. If score >= threshold, verification is required
  4. 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

PolicyDescription
disabledNo verification charges
first_rideHold placed on customer's first ride only
all_ridesHold placed on every ride start

How Holds Work

  1. Authorization created - No actual charge, just a hold
  2. Card validated - Confirms card is active and has funds
  3. Hold released - Automatically released after ride or within 7 days
  4. Never captured - Verification holds are never converted to actual charges

Database Integration

Key Tables

TablePurpose
customersStores stripe_customer_id and wallet balance
payment_methodsStores linked payment methods
stripe_chargesMirrors all Stripe charges
stripe_webhook_logsLogs all webhook events
wallet_transactionsRecords all wallet credits/debits

Cron Jobs

Several cron jobs support the payment system:

CronSchedulePurpose
/api/cron/automatic-refundsEvery 5 minutesProcess automatic refunds
/api/cron/payment-retriesEvery 5 minutesRetry failed payments
/api/cron/bill-active-ridesEvery minuteBill ongoing rides

All cron endpoints require the CRON_SECRET header for authentication.

Local Development

Testing with Stripe CLI

1

Install Stripe CLI

Download and install the Stripe CLI from stripe.com/docs/stripe-cli

2

Login to Stripe

Run stripe login to authenticate with your Stripe account

3

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:

  1. Verify the secret matches your Stripe dashboard
  2. Ensure no middleware is modifying the request body
  3. Check for correct header name: stripe-signature

"Customer not found" in Stripe

Cause: Customer was deleted in Stripe or never synced

Solution:

  1. Check stripe_customer_id in customers table
  2. Verify the ID exists in Stripe dashboard
  3. Clear the ID and let the system recreate it

Payments not syncing

Cause: Webhook endpoint misconfigured or failing

Solution:

  1. Check stripe_webhook_logs for errors
  2. Verify webhook URL in Stripe dashboard
  3. Resend failed events from Stripe dashboard
  4. Check application logs for errors

Test mode not working

Cause: Test keys not configured

Solution:

  1. Add STRIPE_TEST_SECRET_KEY and STRIPE_TEST_PUBLISHABLE_KEY
  2. Verify keys start with sk_test_ and pk_test_
  3. Check if user has @levyelectric.com email or super_admin role

Security Best Practices

  1. Never log full card numbers - Only last4 is stored
  2. Rotate webhook secrets - Change periodically
  3. Use separate test/live keys - Never mix environments
  4. Enable Radar - Stripe's fraud detection
  5. Monitor for anomalies - Set up alerts for unusual activity
  6. PCI Compliance - Never handle raw card data server-side

What's Next?

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.