309 lines
8.4 KiB
Markdown
309 lines
8.4 KiB
Markdown
# Dodo Payments Usage-Based Billing Setup Guide
|
||
|
||
This guide explains how to configure usage-based billing (pay-per-token) in Shopify AI App Builder with Dodo Payments.
|
||
|
||
## Overview
|
||
|
||
Usage-based billing allows users to pay only for the exact number of tokens they consume **over their plan limit**. When enabled, the system sends usage events to Dodo meters and charges the exact overage automatically each billing cycle. Administrators can set custom rates per currency through the admin panel.
|
||
|
||
---
|
||
|
||
## How It Works
|
||
|
||
1. **User enables unlimited usage** in their account settings
|
||
2. **Tokens are consumed** and tracked against the plan limit
|
||
3. **Overage tokens** are metered and sent to Dodo usage events
|
||
4. **Billing is exact** - users pay only for overage tokens
|
||
5. **Automatic billing** occurs each cycle via Dodo usage-based billing
|
||
|
||
---
|
||
|
||
## Configuration Steps
|
||
|
||
### 1) Admin Panel - Set Token Rates
|
||
|
||
1. Navigate to `/admin/plans` as an admin
|
||
2. Scroll to "Token usage rates" section
|
||
3. Set the rate per 1,000,000 tokens for each currency (USD, GBP, EUR)
|
||
4. Click "Save changes"
|
||
|
||
**Example Rates**:
|
||
- USD: $2.50 per 1M tokens (250 cents)
|
||
- GBP: £2.00 per 1M tokens (200 cents)
|
||
- EUR: €2.50 per 1M tokens (250 cents)
|
||
|
||
These rates are automatically applied when users consume tokens.
|
||
|
||
### 2) Dodo Dashboard - Configure Meter
|
||
|
||
1. Create a meter with **event name** matching `DODO_USAGE_EVENT_NAME` (default: `token.usage`)
|
||
2. Set aggregation to **sum** over `costCents` (or your configured cost field)
|
||
3. Attach the meter to your subscription product
|
||
4. Set unit price to **$0.01 / €0.01 / £0.01** if summing `costCents`
|
||
|
||
### 3) User Configuration
|
||
|
||
Users can configure their billing preferences in `/settings`:
|
||
|
||
1. **Select currency** (USD, GBP, or EUR)
|
||
2. **Enable unlimited usage** checkbox
|
||
3. **Save changes** to activate usage-based billing
|
||
|
||
---
|
||
|
||
## User Experience
|
||
|
||
### Enabling Unlimited Usage
|
||
|
||
1. User navigates to `/settings`
|
||
2. User sees "Enable unlimited usage" checkbox in Plan & Billing section
|
||
3. User checks the box and selects their preferred currency
|
||
4. User clicks "Save changes"
|
||
5. System confirms the change
|
||
|
||
### Token Consumption
|
||
|
||
When unlimited usage is enabled:
|
||
|
||
- **Overage tracking**: Only tokens beyond the plan limit are billed
|
||
- **Precision billing**: Users pay exactly the rate set by administrator
|
||
- **Automatic charges**: Dodo bills usage each cycle via meters
|
||
- **Transparent tracking**: Users can see usage in their invoices
|
||
|
||
---
|
||
|
||
## API Endpoints
|
||
|
||
### Get Token Rates (Admin Only)
|
||
|
||
```http
|
||
GET /api/admin/token-rates
|
||
Authorization: Admin session required
|
||
```
|
||
|
||
**Response**:
|
||
```json
|
||
{
|
||
"ok": true,
|
||
"rates": {
|
||
"usd": 250,
|
||
"gbp": 200,
|
||
"eur": 250
|
||
}
|
||
}
|
||
```
|
||
|
||
### Update Token Rates (Admin Only)
|
||
|
||
```http
|
||
POST /api/admin/token-rates
|
||
Authorization: Admin session required
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"rates": {
|
||
"usd": 250,
|
||
"gbp": 200,
|
||
"eur": 250
|
||
}
|
||
}
|
||
```
|
||
|
||
**Response**:
|
||
```json
|
||
{
|
||
"ok": true,
|
||
"rates": {
|
||
"usd": 250,
|
||
"gbp": 200,
|
||
"eur": 250
|
||
}
|
||
}
|
||
```
|
||
|
||
### Usage Events (Server-side)
|
||
|
||
Usage-based billing relies on server-side ingestion of usage events to Dodo.
|
||
Events are sent automatically when overage tokens are detected.
|
||
|
||
```http
|
||
POST https://<dodo_base_url>/events/ingest
|
||
Authorization: Bearer <DODO_API_KEY>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"events": [
|
||
{
|
||
"event_id": "usage_<uuid>",
|
||
"customer_id": "<dodo_customer_id>",
|
||
"event_name": "token.usage",
|
||
"timestamp": "2026-01-20T00:00:00Z",
|
||
"metadata": {
|
||
"billableTokens": 2500000,
|
||
"costCents": 500,
|
||
"currency": "usd",
|
||
"ratePerMillion": 200,
|
||
"plan": "starter",
|
||
"month": "2026-01"
|
||
}
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Billing Logic
|
||
|
||
### Token Cost Calculation (Overage Only)
|
||
|
||
```javascript
|
||
// When user consumes tokens
|
||
tokensUsed = numberOfTokensConsumed
|
||
previousTotal = bucket.usage
|
||
bucket.usage = previousTotal + tokensUsed
|
||
|
||
planLimit = getPlanTokenLimits(user.plan)
|
||
previousOverage = max(0, previousTotal - planLimit)
|
||
currentOverage = max(0, bucket.usage - planLimit)
|
||
overageDelta = max(0, currentOverage - previousOverage)
|
||
|
||
userCurrency = user.billingCurrency || 'usd'
|
||
rate = tokenRates[userCurrency] // Cents per 1M tokens
|
||
chargeAmount = round((overageDelta * rate) / 1_000_000)
|
||
|
||
// Send usage event to Dodo meters
|
||
sendUsageEvent({
|
||
billableTokens: overageDelta,
|
||
costCents: chargeAmount,
|
||
currency: userCurrency,
|
||
ratePerMillion: rate,
|
||
})
|
||
```
|
||
|
||
### Example Scenarios
|
||
|
||
#### Scenario 1: User consumes 500,000 tokens over limit at $2.50/M rate
|
||
|
||
- Rate: 250 cents per 1M tokens
|
||
- Overage tokens: 500,000
|
||
- Calculation: (500,000 * 250) / 1,000,000 = 125 cents
|
||
- **Charge**: **$1.25** (usage event)
|
||
|
||
#### Scenario 2: User consumes 2,500,000 tokens over limit at $2.00/M rate
|
||
|
||
- Rate: 200 cents per 1M tokens
|
||
- Overage tokens: 2,500,000
|
||
- Calculation: (2,500,000 * 200) / 1,000,000 = 500 cents
|
||
- **Charge**: **$5.00** (usage event)
|
||
|
||
---
|
||
|
||
## Important Notes
|
||
|
||
### 1) Rate Configuration
|
||
|
||
- **Admin control**: Only administrators can set token rates via admin panel
|
||
- **Per currency**: Separate rates for USD, GBP, and EUR
|
||
- **Flexible**: Rates can be adjusted at any time
|
||
- **Precision**: Calculated in cents/minor units for accuracy
|
||
|
||
### 2) Dodo Meter Configuration
|
||
|
||
- **Event name**: Must match `DODO_USAGE_EVENT_NAME` (default: `token.usage`)
|
||
- **Aggregation**: Use `sum` over `costCents` (or your configured cost field)
|
||
- **Unit price**: Set to **$0.01** per unit if summing `costCents`
|
||
- **Free threshold**: Optional; can be used to mirror plan limits if desired
|
||
|
||
### 3) Currency Handling
|
||
|
||
- **User selection**: Users can choose their preferred currency in settings
|
||
- **Rate matching**: Appropriate rate applied based on user's currency
|
||
- **Consistency**: Events include `currency` and `ratePerMillion`
|
||
|
||
### 4) Unlimited Usage Flag
|
||
|
||
- **Required**: Must be enabled for usage-based billing
|
||
- **Optional**: Users can disable and return to plan-based limits
|
||
- **Flexible**: Can be toggled at any time
|
||
- **Persistent**: Setting saved per user
|
||
|
||
---
|
||
|
||
## Troubleshooting
|
||
|
||
### Issue: Usage events not billing
|
||
|
||
**Symptom**: Tokens over limit are recorded but no charges appear
|
||
|
||
**Solutions**:
|
||
1. Verify `unlimitedUsage` is enabled for the user
|
||
2. Check the user has a Dodo customer ID and billing email
|
||
3. Verify `tokenRates` are configured in admin panel
|
||
4. Ensure Dodo meter event name matches `DODO_USAGE_EVENT_NAME`
|
||
5. Review `recordUserTokens()` logs for ingest errors
|
||
|
||
### Issue: Rates not applying correctly
|
||
|
||
**Symptom**: Charges don't match configured rates
|
||
|
||
**Solutions**:
|
||
1. Verify rates are saved to `token-rates.json`
|
||
2. Check `loadTokenRates()` is called on server startup
|
||
3. Ensure currency conversion is correct (cents vs dollars)
|
||
4. Review token division by 1,000,000 calculation
|
||
|
||
---
|
||
|
||
## Best Practices
|
||
|
||
### 1) Rate Configuration
|
||
|
||
- **Set competitive rates**: Align with market prices for token usage
|
||
- **Update regularly**: Adjust for currency exchange rate changes
|
||
- **Test calculations**: Verify rate × tokens = correct charge
|
||
- **Document changes**: Keep record of rate adjustments
|
||
|
||
### 2) User Communication
|
||
|
||
- **Clear pricing**: Display rates prominently in settings
|
||
- **Show calculations**: Let users see how charge is calculated
|
||
- **Invoice transparency**: Show usage and charges in invoices
|
||
|
||
### 3) Monitoring
|
||
|
||
- **Monitor usage events**: Track ingest success and meter totals
|
||
- **Monitor token consumption**: Analyze usage patterns by user
|
||
- **Watch for anomalies**: Detect unusual consumption patterns
|
||
- **Revenue analytics**: Compare usage-based vs subscription revenue
|
||
|
||
### 4) System Performance
|
||
|
||
- **Batch ingestion**: Send usage events in batches where possible
|
||
- **Error handling**: Retry failed usage event ingestion gracefully
|
||
- **Logging**: Track all usage events for audit trails
|
||
|
||
---
|
||
|
||
## Reference Links
|
||
|
||
- [Dodo Payments API Documentation](https://docs.dodopayments.com)
|
||
- [Main Dodo Setup Guide](./dodo.md)
|
||
- [Token Usage Implementation](./TOKEN_USAGE_IMPLEMENTATION.md)
|
||
- [Payment Flow Documentation](./DODO_INLINE_CHECKOUT_THEMING.md)
|
||
|
||
---
|
||
|
||
## Summary
|
||
|
||
The usage-based billing model provides:
|
||
|
||
- **Exact charging**: Users pay only for tokens they actually consume over limit
|
||
- **Flexible pricing**: Administrators can set custom rates per currency
|
||
- **No limits**: Usage can exceed plan limits with automatic billing
|
||
- **Metered tracking**: Usage is reported via Dodo meters
|
||
- **Simple management**: Charges appear automatically in invoices
|
||
|
||
Users can enable unlimited usage and the system will automatically charge the exact amount for overage tokens based on administrator-set rates.
|
||
|