beginner
payments
wallet
auto-topup

Auto Top-Up Configuration

Automatically replenish customer wallet balances when they fall below a threshold - keeping rides seamless without manual payments

Levy Fleets TeamDecember 25, 20258 min read

Auto Top-Up Configuration

Auto top-up automatically replenishes customer wallet balances when they fall below a configurable threshold. This ensures customers can always start and complete rides without manually adding funds.

Overview

When enabled, the system monitors wallet balances and automatically charges the customer's saved payment method when their balance drops too low. This creates a seamless riding experience where customers don't need to worry about running out of funds mid-ride.

Key Features

  • Automatic charging - Charges saved payment method when balance is low
  • Configurable threshold - Set the trigger point for automatic top-ups
  • Configurable amount - Set how much to add each time
  • Dual consent required - Both operator and customer must enable
  • Stripe integration - Secure off-session payments via Stripe
  • Concurrent protection - Database locks prevent duplicate charges

How It Works

Wallet Balance: $4.50
Threshold: $5.00
Top-Up Amount: $15.00

1. Customer starts ride
2. System checks: $4.50 ≤ $5.00 threshold
3. Auto top-up triggered
4. Stripe charges default card $15.00
5. New balance: $19.50
6. Ride proceeds normally

Requirements

Auto top-up requires ALL of the following:

RequirementWho Sets ItWhere
Subaccount enabledFleet operatorDashboard Settings
Customer enabledCustomerMobile app wallet
Saved payment methodCustomerMobile app
Stripe customer IDAutomaticCreated on first payment

Both Must Enable

Auto top-up only works when BOTH the subaccount AND the customer have it enabled. If either disables it, automatic charging stops.

Operator Configuration

Enabling Auto Top-Up

1

Navigate to Settings

Go to Dashboard → Settings.

2

Find Payments Section

Scroll to the Payments section.

3

Enable Auto Top-Up

Toggle Auto Top-Up Enabled to on.

4

Set Threshold

Enter the Trigger Level (when to charge). Default: $5.00

5

Set Amount

Enter the Top-Up Amount (how much to add). Default: $15.00

6

Save Settings

Click Save to apply changes.

Configuration Options

Trigger Level (Threshold)

The wallet balance at which auto top-up activates.

SettingBehavior
$5.00 (default)Charges when balance ≤ $5.00
$10.00Charges when balance ≤ $10.00
$2.00Charges when balance ≤ $2.00

Recommendations:

  • Set threshold slightly higher than your average ride cost
  • Consider your unlock fee + typical ride duration
  • Higher thresholds = more frequent small charges

Top-Up Amount

How much to add to the wallet each time.

SettingBehavior
$15.00 (default)Adds $15.00 per charge
$10.00Adds $10.00 per charge
$25.00Adds $25.00 per charge

Recommendations:

  • Should cover 2-4 typical rides
  • Balance between convenience and transaction fees
  • Higher amounts = fewer transactions

Best Practices

  1. Set threshold above ride cost - Ensure customers can complete at least one ride
  2. Balance amount vs. frequency - Higher amounts mean fewer Stripe fees
  3. Communicate to customers - Make sure customers know auto top-up is available
  4. Monitor declined charges - Check for failed auto top-ups regularly

Customer Experience

Enabling Auto Top-Up

Customers enable auto top-up in the mobile app:

  1. Open Wallet screen
  2. Tap Auto Top-Up toggle
  3. Confirm enablement
  4. Ensure a default payment method is saved

What Customers See

  • Toggle to enable/disable auto top-up
  • Notification when auto top-up charges occur
  • Transaction history shows "Auto top-up" entries
  • Current wallet balance always visible

Saved Payment Required

Customers must have a saved payment method set as default for auto top-up to work. The system uses Stripe's off-session payment capability.

When Auto Top-Up Triggers

Auto top-up is checked at these moments:

EventTrigger Condition
Ride startBalance ≤ threshold
Ride endBalance insufficient for ride cost
Wallet checkPeriodic balance verification

Ride Start Flow

1. Customer taps "Unlock" on vehicle
2. System checks wallet balance
3. If balance ≤ threshold AND auto top-up enabled:
   a. Lock acquired to prevent duplicate charges
   b. Stripe PaymentIntent created
   c. Default payment method charged
   d. Wallet balance updated
   e. Lock released
4. Ride starts normally

Ride End Flow

1. Ride ends, cost calculated: $8.50
2. Current wallet: $4.00
3. Wallet insufficient, auto top-up triggered
4. $15.00 added → New balance: $19.00
5. Ride cost deducted: $19.00 - $8.50 = $10.50
6. Customer sees final balance: $10.50

Technical Details

Database Fields

Subaccounts table:

ColumnTypeDescription
auto_topup_enabledBooleanSubaccount has auto top-up enabled
auto_topup_threshold_centsIntegerTrigger level in cents
auto_topup_amount_centsIntegerAmount to add in cents

Customers table:

ColumnTypeDescription
auto_topup_enabledBooleanCustomer has opted in
stripe_customer_idStringStripe customer reference
auto_topup_lock_expires_atTimestampPrevents concurrent charges

Concurrency Protection

The system uses database locks to prevent charging customers multiple times:

  1. Before charging, acquire lock via acquire_auto_topup_lock RPC
  2. Lock has 2-minute TTL (auto-expires if process fails)
  3. If lock already held, wait and check if balance increased
  4. After charging, release lock via release_auto_topup_lock RPC
  5. Idempotency key prevents Stripe duplicate charges

Error Handling

ErrorSystem Response
Card declinedReturns error, customer notified
No payment methodReturns "No payment method on file"
Authentication requiredReturns error, requires customer action
Lock already heldWaits for existing charge to complete

Troubleshooting

Auto Top-Up Not Working

  1. Check subaccount setting - Verify auto_topup_enabled is true in Settings
  2. Check customer setting - Verify customer has enabled in app
  3. Check payment method - Customer needs a saved default card
  4. Check Stripe customer - Customer needs stripe_customer_id
  5. Check balance - May already be above threshold

Duplicate Charges

The system prevents duplicates via:

  • Database lock on customer record
  • Stripe idempotency keys
  • Balance re-check after lock acquisition

If duplicates occur, check:

  1. Lock release failures in logs
  2. Stripe webhook processing
  3. Database connection issues

Failed Charges

Common reasons for failed auto top-up:

ReasonSolution
Card expiredCustomer updates card in app
Insufficient fundsCustomer uses different card
Card reported lost/stolenCustomer adds new card
Bank declineCustomer contacts bank
3D Secure requiredCustomer manually adds funds

3D Secure Limitation

Auto top-up uses off-session payments which cannot handle 3D Secure challenges. If a customer's card requires authentication, they'll need to manually add funds.

Test Mode

For internal testing, the system automatically uses Stripe test mode for @levyelectric.com email addresses. This allows testing auto top-up flows without real charges.

Customer email: test@levyelectric.com
→ Uses STRIPE_TEST_SECRET_KEY
→ Test cards work (4242 4242 4242 4242)
→ No real charges processed

API Reference

Check Auto Top-Up Capability

import { canProcessAutoTopup } from '@/lib/auto-topup'

const canTopup = await canProcessAutoTopup(customerId, vehicleId)
// Returns: boolean

Process Auto Top-Up

import { processAutoTopup } from '@/lib/auto-topup'

const result = await processAutoTopup(customerId, vehicleId, skipThresholdCheck)
// Returns: { success, amountCents, error?, newWalletBalance? }

Toggle Customer Preference (Mobile API)

POST /api/mobile/payment
{
  "action": "toggle-auto-topup",
  "enabled": true
}

Seamless Experience

With auto top-up configured, your customers enjoy uninterrupted rides without worrying about wallet balances. The system handles replenishment automatically, reducing friction and increasing ride completion rates.