Skip to main content

Forward Token Structure

Lava uses a forward token system for authenticating API requests. A forward token is a base64-encoded string that contains three components:
<secretKey>.<connectionSecret>.<productSecret>

Token Components

ComponentPurposeRequiredObtained From
Secret KeyIdentifies the merchant accountYesGenerated in merchant dashboard
Connection SecretLinks to a specific walletYesReturned from checkout completion
Product SecretSpecifies pricing configurationOptionalProduct configuration in dashboard

Example Token Flow

// 1. Merchant generates secret key (one-time setup)
const secretKey = 'sk_live_abc123...';

// 2. User completes checkout, receives connection secret
const connectionSecret = 'cs_xyz789...';

// 3. Optional: Use specific product pricing
const productSecret = 'prod_def456...';

// 4. Combine into forward token
const forwardToken = btoa(`${secretKey}.${connectionSecret}.${productSecret}`);

// 5. Use in API requests
fetch('https://api.lavapayments.com/v1/forward?u=...', {
  headers: { 'Authorization': `Bearer ${forwardToken}` }
});

Authentication Flow

Step 1: Token Validation

When Lava receives a request with a forward token:
  1. Decode: Base64 decode the token to extract components
  2. Cache Lookup: Check Redis cache for secret key validation (less than 5ms)
  3. Database Fallback: If not cached, query database and cache result
  4. Verify Status: Ensure merchant account is active and not deleted

Step 2: Connection Validation

With a valid secret key, Lava validates the connection:
  1. Connection Lookup: Find connection record by connection secret
  2. Status Check: Verify connection is enabled and not deleted
  3. Wallet Check: Confirm linked wallet exists and is active
  4. Product Validation: If product secret provided, validate pricing config

Step 3: Balance Verification

Before forwarding the request:
  1. Balance Query: Check wallet’s active balance
  2. Threshold Check: Compare against minimum required balance
  3. Overdraft Policy: Apply product’s overdraft behavior (block or allow)
  4. Update Connection: Mark connection as “limited” if balance is low
All three validation steps complete in under 10ms total through aggressive Redis caching.

Security Best Practices

Secret Key Management

Treat secret keys like passwords - never commit them to version control or expose them in client-side code.
Do:
  • ✅ Store secret keys in environment variables
  • ✅ Use different keys for test vs production
  • ✅ Rotate keys periodically (Lava supports multiple active keys)
  • ✅ Revoke compromised keys immediately in dashboard
Don’t:
  • ❌ Hard-code keys in source code
  • ❌ Share keys in public repositories
  • ❌ Use production keys in development/testing
  • ❌ Send keys via insecure channels (email, Slack, etc.)

Connection Secret Handling

Connection secrets are user-specific and should be stored securely on your backend:
  • Store in your database linked to user accounts
  • Never expose in frontend JavaScript or mobile apps
  • Generate fresh tokens for each API request (don’t cache tokens)
  • Implement token expiration if storing long-term

Product Secret Usage

Product secrets are optional and used to apply custom pricing:
  • Safe to use in client-side code (they don’t grant access alone)
  • Different products can have different pricing tiers
  • Allows A/B testing different fee structures
  • Can be rotated without affecting user connections

Next Steps