Stripe API wrapper for Node.js providing comprehensive payment processing, subscription management, and financial services integration.
—
Stripe's advanced billing namespace provides sophisticated usage metering, credit management, and billing alerting capabilities. These features enable complex billing scenarios including usage-based pricing, prepaid credits, and automated billing monitoring.
Define and manage usage meters for tracking billable events:
interface BillingMeter {
id: string;
object: 'billing.meter';
created: number;
display_name: string;
event_name: string;
status: 'active' | 'inactive';
customer_mapping: {
event_payload_key: string;
type: 'by_id';
};
default_aggregation: {
formula: 'count' | 'sum';
};
value_settings?: {
event_payload_key?: string;
};
}
// Create usage meter
const meter = await stripe.billing.meters.create({
display_name: 'API Requests',
event_name: 'api_request',
customer_mapping: {
event_payload_key: 'customer_id',
type: 'by_id'
},
default_aggregation: {
formula: 'count'
}
});
// Create value-based meter
const valueMeter = await stripe.billing.meters.create({
display_name: 'Storage Usage (GB)',
event_name: 'storage_used',
customer_mapping: {
event_payload_key: 'stripe_customer_id',
type: 'by_id'
},
default_aggregation: {
formula: 'sum'
},
value_settings: {
event_payload_key: 'gb_used'
}
});
// Retrieve meter
const retrieved = await stripe.billing.meters.retrieve('mtr_123');
// Update meter
const updated = await stripe.billing.meters.update('mtr_123', {
display_name: 'Updated API Request Meter'
});
// List meters
const meters = await stripe.billing.meters.list({
status: 'active',
limit: 10
});
// Deactivate meter
const deactivated = await stripe.billing.meters.deactivate('mtr_123');
// Reactivate meter
const reactivated = await stripe.billing.meters.reactivate('mtr_123');
// List event summaries
const eventSummaries = await stripe.billing.meters.listEventSummaries(
'mtr_123',
{
customer: 'cus_123',
start_time: Math.floor(Date.now() / 1000) - 86400 * 30, // Last 30 days
end_time: Math.floor(Date.now() / 1000)
}
);Record usage events for billing:
interface BillingMeterEvent {
object: 'billing.meter_event';
created: number;
event_name: string;
identifier: string;
payload: {
[key: string]: string;
};
}
// Create meter event
const meterEvent = await stripe.billing.meterEvents.create({
event_name: 'api_request',
payload: {
customer_id: 'cus_123',
endpoint: '/api/users',
method: 'GET'
}
});
// Create value-based meter event
const valueMeterEvent = await stripe.billing.meterEvents.create({
event_name: 'storage_used',
payload: {
stripe_customer_id: 'cus_123',
gb_used: '2.5',
timestamp: Math.floor(Date.now() / 1000).toString()
}
});
// Batch meter events (recommended for high volume)
const events = [
{
event_name: 'api_request',
payload: { customer_id: 'cus_123', endpoint: '/api/data' }
},
{
event_name: 'api_request',
payload: { customer_id: 'cus_456', endpoint: '/api/users' }
}
];
for (const event of events) {
await stripe.billing.meterEvents.create(event);
}Adjust previously recorded usage events:
// Create meter event adjustment (correction)
const adjustment = await stripe.billing.meterEventAdjustments.create({
event_name: 'api_request',
type: 'cancel',
original_event_id: 'mevt_123'
});
// Create value adjustment
const valueAdjustment = await stripe.billing.meterEventAdjustments.create({
event_name: 'storage_used',
type: 'cancel',
original_event_id: 'mevt_456'
});Enhanced meter events with improved performance:
// Create V2 meter event
const v2MeterEvent = await stripe.v2.billing.meterEvents.create({
event_name: 'api_call',
payload: {
stripe_customer_id: 'cus_123',
value: '1'
}
});
// Create V2 meter event adjustment
const v2Adjustment = await stripe.v2.billing.meterEventAdjustments.create({
event_name: 'api_call',
type: 'cancel',
original_event_id: 'mevt_789'
});Batch meter events for improved performance:
// Create meter event session for batch operations
const session = await stripe.v2.billing.meterEventSession.create({
meter_event_session: {
// Session configuration
}
});Stream meter events for real-time processing:
// Create meter event stream
const stream = await stripe.v2.billing.meterEventStream.create({
// Stream configuration
});Issue and manage customer credit grants:
interface BillingCreditGrant {
id: string;
object: 'billing.credit_grant';
customer: string;
amount: {
monetary?: {
currency: string;
value: number;
};
type: 'monetary';
};
applicability_config: {
scope: {
price_type: 'metered';
};
};
category: 'paid' | 'promotional';
effective_at: number;
expires_at?: number;
}
// Create monetary credit grant
const creditGrant = await stripe.billing.creditGrants.create({
customer: 'cus_123',
amount: {
monetary: {
currency: 'usd',
value: 1000 // $10.00 in cents
},
type: 'monetary'
},
applicability_config: {
scope: {
price_type: 'metered'
}
},
category: 'promotional',
effective_at: Math.floor(Date.now() / 1000),
expires_at: Math.floor(Date.now() / 1000) + 86400 * 90, // 90 days
name: 'Welcome Bonus Credit'
});
// Create credit grant for specific products
const productCredit = await stripe.billing.creditGrants.create({
customer: 'cus_123',
amount: {
monetary: {
currency: 'usd',
value: 2000
},
type: 'monetary'
},
applicability_config: {
scope: {
price_type: 'metered',
filters: [
{
prices: ['price_api_calls', 'price_storage']
}
]
}
},
category: 'paid'
});
// Retrieve credit grant
const retrieved = await stripe.billing.creditGrants.retrieve('cg_123');
// Update credit grant
const updated = await stripe.billing.creditGrants.update('cg_123', {
name: 'Updated Credit Grant',
metadata: { campaign: 'spring_2024' }
});
// List credit grants
const creditGrants = await stripe.billing.creditGrants.list({
customer: 'cus_123',
limit: 10
});
// Expire credit grant
const expired = await stripe.billing.creditGrants.expire('cg_123');
// Void credit grant
const voided = await stripe.billing.creditGrants.voidGrant('cg_123');View customer's current credit balance:
interface BillingCreditBalanceSummary {
object: 'billing.credit_balance_summary';
customer: string;
balance: {
monetary: Array<{
currency: string;
available_balance: {
currency: string;
value: number;
};
ledger_balance: {
currency: string;
value: number;
};
}>;
};
}
// Retrieve credit balance summary
const balanceSummary = await stripe.billing.creditBalanceSummary.retrieve({
customer: 'cus_123'
});
console.log('Available USD credit:',
balanceSummary.balance.monetary.find(b => b.currency === 'usd')?.available_balance.value
);Track credit balance changes:
interface BillingCreditBalanceTransaction {
id: string;
object: 'billing.credit_balance_transaction';
customer: string;
type: 'credit_grant' | 'credit_grant_adjustment' | 'credit_reversal' | 'invoice_applied_credit' | 'invoice_voided_credit';
amount: {
monetary: {
currency: string;
value: number;
};
type: 'monetary';
};
created: number;
}
// Retrieve credit balance transaction
const transaction = await stripe.billing.creditBalanceTransactions.retrieve('cbt_123');
// List credit balance transactions
const transactions = await stripe.billing.creditBalanceTransactions.list({
customer: 'cus_123',
limit: 20,
type: 'credit_grant'
});
// List transactions by date range
const recentTransactions = await stripe.billing.creditBalanceTransactions.list({
customer: 'cus_123',
created: {
gte: Math.floor(Date.now() / 1000) - 86400 * 30 // Last 30 days
}
});Monitor and alert on billing events:
interface BillingAlert {
id: string;
object: 'billing.alert';
alert_type: 'usage_threshold';
filter?: {
customer?: string;
};
status: 'active' | 'archived';
title: string;
usage_threshold_config?: {
gte: number;
meter: string;
recurrence: 'one_time' | 'daily' | 'monthly';
};
}
// Create usage threshold alert
const usageAlert = await stripe.billing.alerts.create({
alert_type: 'usage_threshold',
title: 'High API Usage Alert',
usage_threshold_config: {
gte: 1000, // Alert when usage >= 1000
meter: 'mtr_api_requests',
recurrence: 'daily'
}
});
// Create customer-specific alert
const customerAlert = await stripe.billing.alerts.create({
alert_type: 'usage_threshold',
title: 'Enterprise Customer Alert',
filter: {
customer: 'cus_enterprise_123'
},
usage_threshold_config: {
gte: 10000,
meter: 'mtr_api_requests',
recurrence: 'monthly'
}
});
// Retrieve alert
const retrieved = await stripe.billing.alerts.retrieve('ba_123');
// List alerts
const alerts = await stripe.billing.alerts.list({
alert_type: 'usage_threshold',
limit: 10
});
// Activate alert
const activated = await stripe.billing.alerts.activate('ba_123');
// Deactivate alert
const deactivated = await stripe.billing.alerts.deactivate('ba_123');
// Archive alert
const archived = await stripe.billing.alerts.archive('ba_123');Combine billing features with pricing for complete usage-based billing:
// Create metered price
const meteredPrice = await stripe.prices.create({
product: 'prod_api_service',
currency: 'usd',
recurring: {
interval: 'month',
usage_type: 'metered'
},
billing_scheme: 'per_unit',
unit_amount: 10, // $0.10 per unit
transform_usage: {
divide_by: 1,
round: 'up'
}
});
// Create tiered usage pricing
const tieredPrice = await stripe.prices.create({
product: 'prod_api_service',
currency: 'usd',
recurring: {
interval: 'month',
usage_type: 'metered'
},
billing_scheme: 'tiered',
tiers_mode: 'graduated',
tiers: [
{
up_to: 1000,
unit_amount: 10 // $0.10 for first 1000
},
{
up_to: 5000,
unit_amount: 8 // $0.08 for next 4000
},
{
up_to: 'inf',
unit_amount: 5 // $0.05 for everything above
}
]
});
// Create subscription with usage-based pricing
const usageSubscription = await stripe.subscriptions.create({
customer: 'cus_123',
items: [{
price: meteredPrice.id
}],
billing_thresholds: {
amount_gte: 5000, // Generate invoice when amount >= $50
reset_billing_cycle_anchor: false
}
});
// Record usage events
await stripe.billing.meterEvents.create({
event_name: 'api_request',
payload: {
customer_id: 'cus_123',
units: '10' // 10 API calls
}
});
// Apply promotional credit
const promoCredit = await stripe.billing.creditGrants.create({
customer: 'cus_123',
amount: {
monetary: {
currency: 'usd',
value: 500 // $5.00 credit
},
type: 'monetary'
},
applicability_config: {
scope: {
price_type: 'metered'
}
},
category: 'promotional',
effective_at: Math.floor(Date.now() / 1000),
name: 'First Month Free Credit'
});// Use idempotency for reliable event recording
const eventId = `api_call_${customerId}_${timestamp}_${uniqueId}`;
await stripe.billing.meterEvents.create({
event_name: 'api_request',
payload: {
customer_id: 'cus_123'
}
}, {
idempotencyKey: eventId
});
// Batch events for better performance
const events = collectUsageEvents(); // Your event collection logic
for (const event of events) {
await stripe.billing.meterEvents.create(event, {
idempotencyKey: event.unique_id
});
}// Check credit balance before charging
const balance = await stripe.billing.creditBalanceSummary.retrieve({
customer: 'cus_123'
});
const usdCredit = balance.balance.monetary.find(b => b.currency === 'usd');
if (usdCredit && usdCredit.available_balance.value > 0) {
console.log(`Customer has $${usdCredit.available_balance.value / 100} in credits`);
}// Set up graduated alerts for different usage levels
const alerts = [
{ threshold: 1000, title: 'Usage Warning - 1K API calls' },
{ threshold: 5000, title: 'High Usage Alert - 5K API calls' },
{ threshold: 10000, title: 'Critical Usage - 10K API calls' }
];
for (const alert of alerts) {
await stripe.billing.alerts.create({
alert_type: 'usage_threshold',
title: alert.title,
usage_threshold_config: {
gte: alert.threshold,
meter: 'mtr_api_requests',
recurrence: 'daily'
}
});
}The billing namespace provides enterprise-grade usage metering and credit management capabilities, enabling sophisticated pricing models and proactive billing monitoring for usage-based businesses.
Install with Tessl CLI
npx tessl i tessl/npm-stripe