Hybrid Pricing Quick Start
This guide is intended to take you from no payment processing to a simple, but functional, hybrid billing system combining multiple pricing models.
Introduction
Hybrid pricing means combining multiple billing models in a single plan. £50 base fee + £10 per user per month + £0.01 per API call is an example of this billing model.
Following this short guide will take you from zero to being up-and-running with a hybrid pricing model that combines flat-rate, per-seat, and usage-based billing in your application.
1. Create and configure your product
Before you can start implementing Salable into your codebase, you need to sign up for an account and create a product in the Salable dashboard.
You will need to create a product, the plans that you want the users to be able to subscribe to, and any entitlements your users should be able to access depending on their subscription.
As an example, if your application was a team collaboration platform, you may offer a "Professional" plan with "Advanced Analytics", "Custom Integrations", and "Priority Support" as your entitlements.
To create hybrid pricing on your "Professional" plan, you'll add multiple Line Items:
- A "Platform Fee" Line Item with a Pricing Type of "Flat Rate" (e.g., £50/month)
- A "Team Members" Line Item with a Pricing Type of "Per Seat" (e.g., £10/user/month)
- An "API Usage" Line Item with a Pricing Type of "Metered" using a meter like
api_calls(e.g., £0.01/call)
2. Create a group with team members
For the per-seat component of your hybrid pricing, you'll need to create a group that represents your team.
const response = await fetch('https://beta.salable.app/api/groups', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_SECRET_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
owner: 'company_acme',
name: 'Development Team',
grantees: [
{ granteeId: 'user_alice', name: 'Alice Smith' },
{ granteeId: 'user_bob', name: 'Bob Johnson' },
{ granteeId: 'user_charlie', name: 'Charlie Brown' }
]
})
});
const { data: group } = await response.json();3. Generate a checkout link
When creating a checkout for a hybrid pricing plan, specify the group and ensure the quantity matches the number of grantees.
const response = await fetch('https://beta.salable.app/api/checkout', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_SECRET_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
planId: 'YOUR_PLAN_ID',
owner: 'company_acme',
grantee: group.id,
interval: 'YOUR_INTERVAL', // 'month' or 'year'
intervalCount: 1,
currency: 'YOUR_PLANS_CURRENCY', // USD, GBP, EUR, etc
successUrl: 'https://your-app.com/success',
cancelUrl: 'https://your-app.com/cancel'
})
});
const { data } = await response.json();
// Redirect user to data.urlOnce the customer completes checkout, they'll be charged for all Line Items: the base platform fee, the per-seat charges, and Salable will begin tracking usage for metered billing.
4. Record usage in your application
As users consume your metered services, record their usage to the appropriate meter. Usage recording returns immediately and processes in the background.
async function recordUsage(owner, meterSlug, increment) {
const response = await fetch('https://beta.salable.app/api/usage/record', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_SECRET_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({ owner, meterSlug, increment })
});
if (!response.ok) throw new Error(`Failed to record usage: ${response.status}`);
}
// Record usage after processing API requests
await recordUsage('company_acme', 'api_calls', 1);5. Add entitlement checks to your application
In your application, you'll want to check if each individual grantee has access through their group membership.
const response = await fetch('https://beta.salable.app/api/entitlements/check?granteeId=user_alice', {
headers: {
Authorization: 'Bearer YOUR_SECRET_KEY'
}
});
const { data } = await response.json();
const granteeHasEntitlement = data.entitlements.find(e => e.value === 'YOUR_ENTITLEMENT_NAME');
if (granteeHasEntitlement) {
// Allow the user to perform the action in your system.
}6. Managing team members and usage
As your team grows, you can add or remove grantees and update seat quantities for your per-seat Line Items. You can also retrieve usage data for your metered Line Items to display in your dashboard.
// Add a new team member
await fetch(`https://beta.salable.app/api/groups/${group.id}/grantees`, {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_SECRET_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify([
{
type: 'add',
granteeId: 'user_diana',
name: 'Diana Prince'
}
])
});
// Update seat quantity (only for per-seat Line Items)
await fetch(`https://beta.salable.app/api/subscription-plan-line-items/${perSeatSubscriptionPlanLineItemId}`, {
method: 'PUT',
headers: {
Authorization: 'Bearer YOUR_SECRET_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
quantity: 4 // New seat count
})
});
// Retrieve current usage (only for metered Line Items)
const usageResponse = await fetch('https://beta.salable.app/api/usage-records?owner=company_acme&meterSlug=api_calls&status=current', {
headers: {
Authorization: 'Bearer YOUR_SECRET_KEY'
}
});
const { data: usageData } = await usageResponse.json();
const currentUsage = usageData[0]?.count || 0;7. Next steps
Now that you have hybrid payment processing with multiple line items set up in your application, there are some further things you should set up to enable full subscription handling: