Skip to main content

What You’ll Learn

This guide shows you how to create and configure products with flexible pricing rules. You’ll learn to:
  • Create products through the dashboard or API
  • Configure fee structures (fixed, percentage, or hybrid)
  • Set up tiered pricing for volume discounts
  • Choose billing basis (tokens, characters, time, requests)
  • Configure cost attribution (who pays what)
  • Control overdraft behavior
  • Test your pricing configuration
Products define pricing rules. Each product has a unique secret that can be included in forward tokens to apply specific pricing. Merchants can create multiple products for different use cases (e.g., “Free Tier”, “Pro”, “Enterprise”).

Dashboard Product Creation

The fastest way to create a product is through the Lava dashboard.

Step 1: Navigate to Products

  1. Log in to your Lava dashboard
  2. Click Products in the sidebar
  3. Click Create Product button

Step 2: Configure Basic Information

Product Name: Descriptive name for internal reference (e.g., “Pro Plan API Access”) Description: Optional details about this product’s purpose Product Secret: Auto-generated unique identifier (used in forward tokens)

Step 3: Choose Fee Structure

Select one of three pricing models: Fixed Fee
  • Charge a flat amount per billing unit
  • Example: $0.05 per 1,000 tokens
  • Best for predictable pricing
Percentage Markup
  • Add a percentage on top of provider costs
  • Example: 20% markup
  • Best for scaling fees with actual costs
Hybrid (Fixed + Percentage)
  • Combine both fee types
  • Example: $0.10 base + 15% markup
  • Best for covering overhead + cost scaling

Step 4: Select Billing Basis

Choose what metric drives pricing:
Billing BasisUnitBest For
input-outputTokensLLMs (charge for prompt + completion)
output-onlyTokensLLMs (charge only for completion)
charactersCharactersText-to-speech, text processing
durationSecondsVoice calls, real-time services
requestsAPI callsPer-request pricing

Step 5: Configure Cost Attribution

Base Costs (AI provider charges):
  • Wallet pays (default): User covers provider costs
  • Merchant pays: You absorb provider costs (freemium model)
Merchant Fees (your markup):
  • Always paid by wallet (users can’t self-charge)
Service Charge (Lava’s 1.9% fee):
  • Automatically follows merchant fees payer

Step 6: Set Overdraft Behavior

Block Requests (recommended):
  • Reject requests when balance insufficient
  • Protects users from unexpected charges
Allow Overdraft:
  • Process requests even with insufficient funds
  • Create under-settled transfers
  • Settle when user adds funds (oldest first)

Step 7: Save and Copy Product Secret

Click Create Product and copy the product secret. You’ll need this for:
  • Including in forward tokens to apply pricing
  • Creating checkout sessions with specific pricing
  • A/B testing different pricing models

API Product Creation

For programmatic product creation, use the Lava Node.js SDK:

Basic Product Example

import { Lava } from '@lavapayments/nodejs';

const lava = new Lava({
  secretKey: process.env.LAVA_SECRET_KEY!
});

const product = await lava.products.create({
  name: 'Standard API Access',
  description: 'Pay-as-you-go pricing for API access',
  feeStructure: {
    fixedFee: 0.02,           // $0.02 per 1K tokens
    percentageFee: 0,         // No percentage markup
    billingBasis: 'input-output'  // Charge for prompt + completion
  },
  costAttribution: {
    baseCostsPaidBy: 'wallet',       // User pays provider costs
    merchantFeesPaidBy: 'wallet'     // User pays merchant fees
  },
  overdraftAllowed: false
});

console.log('Product created:', product.productSecret);

Product with Percentage Markup

const product = await lava.products.create({
  name: 'Premium API Access',
  description: '25% markup on all provider costs',
  feeStructure: {
    fixedFee: 0,
    percentageFee: 0.25,      // 25% markup
    billingBasis: 'input-output'
  },
  costAttribution: {
    baseCostsPaidBy: 'wallet',
    merchantFeesPaidBy: 'wallet'
  },
  overdraftAllowed: false
});

Hybrid Fee Model

const product = await lava.products.create({
  name: 'Business Plan',
  description: 'Base fee + percentage for cost recovery',
  feeStructure: {
    fixedFee: 0.10,           // $0.10 base per 1K tokens
    percentageFee: 0.15,      // Plus 15% markup
    billingBasis: 'input-output'
  },
  costAttribution: {
    baseCostsPaidBy: 'wallet',
    merchantFeesPaidBy: 'wallet'
  },
  overdraftAllowed: false
});

Tiered Pricing Setup

Tiered pricing lets you offer volume discounts as usage increases.

Dashboard Configuration

  1. Enable Tiered Pricing toggle when creating product
  2. Define tiers with Up To thresholds and Fee amounts
  3. Last tier should have null for unlimited
Example tiers:
  • Tier 1: Up to 1M units → $0.05 per unit
  • Tier 2: Up to 10M units → $0.03 per unit
  • Tier 3: Above 10M units → $0.01 per unit

API Configuration

const product = await lava.products.create({
  name: 'Volume Discount Plan',
  description: 'Tiered pricing with volume discounts',
  feeStructure: {
    fixedFee: 0.05,       // Starting rate
    percentageFee: 0,
    billingBasis: 'input-output'
  },
  tiers: [
    {
      upTo: 1000000,      // First 1M tokens
      fixedFee: 0.05,
      percentageFee: 0
    },
    {
      upTo: 10000000,     // Next 9M tokens (1M-10M)
      fixedFee: 0.03,
      percentageFee: 0
    },
    {
      upTo: null,         // Above 10M (unlimited)
      fixedFee: 0.01,
      percentageFee: 0
    }
  ],
  costAttribution: {
    baseCostsPaidBy: 'wallet',
    merchantFeesPaidBy: 'wallet'
  },
  overdraftAllowed: false
});
How it works:
  • User consumes 5M tokens total
  • First 1M tokens: 1,000,000 × 0.05=0.05 = 50.00
  • Next 4M tokens: 4,000,000 × 0.03=0.03 = 120.00
  • Total merchant fee: $170.00
Tiered pricing applies cumulatively per connection. Each connection tracks total usage across all requests to determine which tier applies.

Billing Basis Options

Input-Output Tokens (LLMs)

Charge for both prompt tokens (input) and completion tokens (output):
feeStructure: {
  fixedFee: 0.02,
  percentageFee: 0,
  billingBasis: 'input-output'
}
Example:
  • User sends 500 token prompt
  • Receives 200 token completion
  • Billing: (500 + 200) × 0.02per1K=0.02 per 1K = 0.014

Output-Only Tokens (LLMs)

Charge only for completion tokens (free prompts):
feeStructure: {
  fixedFee: 0.03,
  percentageFee: 0,
  billingBasis: 'output-only'
}
Example:
  • User sends 500 token prompt (free)
  • Receives 200 token completion
  • Billing: 200 × 0.03per1K=0.03 per 1K = 0.006

Characters (Text Processing)

Charge per character for text-to-speech or processing:
feeStructure: {
  fixedFee: 0.0001,      // $0.0001 per character
  percentageFee: 0,
  billingBasis: 'characters'
}

Duration (Time-Based)

Charge per second or minute for real-time services:
feeStructure: {
  fixedFee: 0.50,        // $0.50 per minute
  percentageFee: 0,
  billingBasis: 'duration'
}

Requests (Per-Call)

Charge per API request regardless of usage:
feeStructure: {
  fixedFee: 0.10,        // $0.10 per request
  percentageFee: 0,
  billingBasis: 'requests'
}

Cost Attribution Strategies

Configure who pays for different cost components:

Pass-Through Model (Default)

User pays everything:
costAttribution: {
  baseCostsPaidBy: 'wallet',       // User pays provider
  merchantFeesPaidBy: 'wallet'     // User pays merchant
}
Result: User pays base costs + merchant fees + service charge

Merchant Absorbs Base Costs

Merchant covers provider costs, user pays fees:
costAttribution: {
  baseCostsPaidBy: 'merchant',     // Merchant pays provider
  merchantFeesPaidBy: 'wallet'     // User pays merchant
}
Result:
  • User pays: Merchant fees + service charge
  • Merchant pays: Base provider costs
Use case: Premium plans where base costs are included

Freemium Model

Merchant covers all costs:
costAttribution: {
  baseCostsPaidBy: 'merchant',
  merchantFeesPaidBy: 'merchant'
}
Result:
  • User pays: $0
  • Merchant pays: Base costs + merchant fees + service charge
Use case: Free tier with usage limits
If merchant pays merchant fees, the service charge also shifts to the merchant. This can significantly increase your costs. Use freemium models with strict usage limits.

Testing Your Configuration

Always test pricing configuration before deploying to production.

Step 1: Create Test Product

const testProduct = await lava.products.create({
  name: 'TEST - $0.01 Per Request',
  description: 'Testing product - DELETE AFTER TESTING',
  feeStructure: {
    fixedFee: 0.01,
    percentageFee: 0,
    billingBasis: 'requests'
  },
  costAttribution: {
    baseCostsPaidBy: 'wallet',
    merchantFeesPaidBy: 'wallet'
  },
  overdraftAllowed: false
});

console.log('Test product secret:', testProduct.productSecret);

Step 2: Create Test Checkout Session

const session = await lava.checkout.createSession({
  mode: 'onboarding',
  productId: testProduct.productSecret,
  amount: 1000,  // $10.00 in cents for testing
  referenceId: 'test-user-' + Date.now()
});

console.log('Test checkout URL:', session.checkoutUrl);

Step 3: Complete Checkout Flow

  1. Open checkout URL in browser
  2. Complete phone verification with test phone number
  3. Use Stripe test card: 4242 4242 4242 4242
  4. Confirm wallet created and balance shows $10.00

Step 4: Make Test Requests

// Generate forward token with test product
const forwardToken = lava.generateForwardToken({
  connection_secret: connection.connectionSecret,
  product_secret: testProduct.productSecret
});

// Make test API request
const response = await fetch('https://api.lavapayments.com/v1/forward/openai/chat/completions', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${forwardToken}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    model: 'gpt-4',
    messages: [{ role: 'user', content: 'Test message' }]
  })
});

console.log('Response status:', response.status);

Step 5: Verify Billing

Check the dashboard Usage page:
  • Request should show with correct fee ($0.01)
  • Wallet balance should decrease appropriately
  • Transfer should show base cost + merchant fee + service charge

Step 6: Delete Test Product

await lava.products.delete(testProduct.productId);
Use Stripe test mode during development. Test cards won’t process real payments. Switch to live mode only after thorough testing.

Troubleshooting

Common causes:
  • billingBasis must be one of: input-output, output-only, characters, duration, requests
  • fixedFee and percentageFee cannot both be 0
  • costAttribution fields must be either wallet or merchant
  • Tiered pricing upTo values must be in ascending order
Solution: Check error message for specific field validation failure and correct the configuration.
Possible reasons:
  • Tiered pricing applies cumulatively (check total connection usage)
  • Service charge (1.9%) added on top of merchant fees
  • Base costs vary by AI provider (not fixed)
  • billingBasis set to output-only instead of input-output
Solution: Use the Usage page to see detailed breakdown of base costs, merchant fees, and service charges for each request.
Reasons:
  • overdraftAllowed: false blocks requests when balance low
  • Users underestimate token usage (prompts + completions)
  • Base provider costs fluctuate (especially for premium models)
Solutions:
  • Set minimumBalance threshold to warn users before blocking
  • Enable overdraftAllowed for critical services (with limits)
  • Display estimated costs before API calls
  • Implement autopay for seamless top-ups
Check:
  • Product secret correctly included in forward token (third component)
  • Forward token format: base64({secretKey}.{connectionSecret}.{productSecret})
  • Product not deleted (check dashboard Products page)
  • Product belongs to correct merchant account
Solution: Re-generate forward token with correct product secret and verify token format with Base64 decoder.

What’s Next