TypeScript SDK
TypeScript SDK
The NovaBilling TypeScript SDK provides type-safe access to the entire NovaBilling API. It works in Node.js (16+) and modern browser environments.
Installation
npm install novabilling
yarn add novabilling
pnpm add novabilling
Client Initialization
All operations are performed through a single NovaBillingClient instance, including data operations (customers, plans, subscriptions, invoices, payments, analytics) and management operations (authentication, payment providers, webhooks, tenant settings).
import { NovaBillingClient } from 'novabilling';
const client = new NovaBillingClient({
token: process.env.NOVABILLING_API_TOKEN!,
// Optional: override the default base URL
baseUrl: 'https://api.novabilling.com'
});
Customers
Customers represent the people or businesses you bill. Every subscription, invoice, and payment is linked to a customer. Each customer has a unique email within your tenant and can have metadata for storing your application-specific data.
Create a Customer
const customer = await client.customers.create({
externalId: 'usr_12345',
email: 'john@example.com',
currency: 'NGN',
name: 'John Doe',
metadata: {
plan: 'enterprise'
}
});
console.log('Created customer:', customer.data.id);
Get a Customer
const customer = await client.customers.get('cus_x1y2z3a4b5c6');
console.log('Name:', customer.data.name);
console.log('Email:', customer.data.email);
Update a Customer
const updated = await client.customers.update('cus_x1y2z3a4b5c6', {
name: 'John A. Doe',
metadata: {
plan: 'enterprise',
notes: 'VIP customer'
}
});
List Customers
const customers = await client.customers.list({
page: 1,
limit: 20,
search: 'john',
sortBy: 'createdAt',
sortOrder: 'desc'
});
console.log('Total customers:', customers.meta.total);
for (const customer of customers.data) {
console.log(`${customer.name} (${customer.email})`);
}
Delete a Customer
await client.customers.delete('cus_x1y2z3a4b5c6');
console.log('Customer deleted');
Get Customer Subscriptions
const subscriptions = await client.customers.getSubscriptions('cus_x1y2z3a4b5c6');
for (const sub of subscriptions.data) {
console.log(`${sub.id}: ${sub.status} - Plan: ${sub.planId}`);
}
Get Customer Invoices
const invoices = await client.customers.getInvoices('cus_x1y2z3a4b5c6');
for (const invoice of invoices.data) {
console.log(`${invoice.id}: ${invoice.status} - ${invoice.currency} ${invoice.amount}`);
}
Plans
Plans define what you sell -- the product tiers, billing frequency, and included features. Each plan has a unique code and can have prices in multiple currencies. Plans can be deactivated to prevent new subscriptions without affecting existing ones.
Create a Plan
const plan = await client.plans.create({
name: 'Pro Plan',
code: 'pro_monthly',
billingInterval: 'monthly',
description: 'Professional plan with advanced features',
features: [
'Unlimited projects',
'Priority support',
'Advanced analytics',
'API access',
'Custom integrations'
]
});
console.log('Created plan:', plan.data.id);
List Plans
const plans = await client.plans.list({
active: true
});
for (const plan of plans.data) {
console.log(`${plan.name}: ${plan.code} (${plan.billingInterval})`);
}
Update a Plan
const updated = await client.plans.update('pln_d7e8f9g0h1i2', {
name: 'Pro Plan v2',
features: [
'Unlimited projects',
'Priority support',
'Advanced analytics',
'API access',
'Custom integrations',
'Dedicated account manager'
]
});
Deactivate a Plan
const deactivated = await client.plans.update('pln_d7e8f9g0h1i2', {
active: false
});
Subscriptions
Subscriptions connect customers to plans and manage the recurring billing lifecycle. A subscription tracks the current billing period, status (active, paused, canceled), and handles automatic renewals. You can pause, resume, cancel, or change the plan of any active subscription.
Create a Subscription
const subscription = await client.subscriptions.create({
customerId: 'cus_x1y2z3a4b5c6',
planId: 'pln_d7e8f9g0h1i2',
currency: 'NGN',
metadata: {
source: 'website',
campaign: 'launch_promo'
}
});
console.log('Subscription status:', subscription.data.status);
console.log('Current period ends:', subscription.data.currentPeriodEnd);
Get a Subscription
const subscription = await client.subscriptions.get('sub_j3k4l5m6n7o8');
console.log('Status:', subscription.data.status);
console.log('Plan:', subscription.data.planId);
console.log('Period:', subscription.data.currentPeriodStart, '-', subscription.data.currentPeriodEnd);
Pause a Subscription
const paused = await client.subscriptions.pause('sub_j3k4l5m6n7o8');
console.log('Subscription paused');
Resume a Subscription
const resumed = await client.subscriptions.resume('sub_j3k4l5m6n7o8');
console.log('Subscription resumed');
Cancel a Subscription
const canceled = await client.subscriptions.cancel('sub_j3k4l5m6n7o8', {
cancelAtPeriodEnd: true // Continue access until period ends
});
console.log('Subscription will cancel at:', canceled.data.currentPeriodEnd);
Change Plan
const updated = await client.subscriptions.changePlan('sub_j3k4l5m6n7o8', {
planId: 'pln_newplan123'
});
console.log('Plan changed. New period end:', updated.data.currentPeriodEnd);
Invoices
Invoices are billing documents that track amounts owed by customers. They can be created automatically from subscriptions or manually for one-off charges. Invoices go through a lifecycle: draft, finalized, paid, or voided. You can also generate PDF versions for download.
Create an Invoice
const invoice = await client.invoices.create({
customerId: 'cus_x1y2z3a4b5c6',
items: [
{
description: 'Pro Plan - Monthly',
amount: 15000,
quantity: 1
},
{
description: 'Additional API calls (500)',
amount: 2500,
quantity: 1
}
],
dueDate: '2025-02-28T00:00:00Z',
notes: 'Thank you for your business!'
});
console.log('Invoice ID:', invoice.data.id);
console.log('Total:', invoice.data.currency, invoice.data.total);
Get an Invoice
const invoice = await client.invoices.get('inv_p1q2r3s4t5u6');
console.log('Status:', invoice.data.status);
console.log('Total:', invoice.data.currency, invoice.data.total);
List Invoices
const invoices = await client.invoices.list({
customerId: 'cus_x1y2z3a4b5c6',
status: 'finalized',
page: 1,
limit: 10
});
for (const invoice of invoices.data) {
console.log(`${invoice.id}: ${invoice.status} - ${invoice.currency} ${invoice.total}`);
}
Finalize an Invoice
const finalized = await client.invoices.finalize('inv_p1q2r3s4t5u6');
console.log('Invoice finalized');
Void an Invoice
const voided = await client.invoices.void('inv_p1q2r3s4t5u6');
console.log('Invoice voided');
Mark an Invoice as Paid
const paid = await client.invoices.markPaid('inv_p1q2r3s4t5u6');
console.log('Invoice marked as paid');
Get Invoice PDF
const pdf = await client.invoices.getPdf('inv_p1q2r3s4t5u6');
console.log('PDF URL:', pdf.data.url);
Payments
Payments support listing, retrieval, and refunds. Payments are created automatically by the system when invoices are paid through a payment provider.
Get a Payment
const payment = await client.payments.get('pay_v1w2x3y4z5a6');
console.log('Amount:', payment.data.currency, payment.data.amount);
console.log('Status:', payment.data.status);
List Payments
const payments = await client.payments.list({
customerId: 'cus_x1y2z3a4b5c6',
status: 'successful',
page: 1,
limit: 20
});
let total = 0;
for (const payment of payments.data) {
total += payment.amount;
console.log(`${payment.id}: ${payment.currency} ${payment.amount} - ${payment.status}`);
}
console.log('Total paid:', total);
Refund a Payment
const refund = await client.payments.refund('pay_v1w2x3y4z5a6', {
amount: 15000, // Partial refund
reason: 'Customer requested plan downgrade'
});
console.log('Refund ID:', refund.data.id);
console.log('Refund status:', refund.data.status);
Payment Providers
Payment providers are the external services that process payments on your behalf. NovaBilling supports Stripe, Flutterwave, Paystack, and M-Pesa. Configure one or more providers and set priorities to control the fallback order when a provider is unavailable.
List Payment Providers
const providers = await client.paymentProviders.list();
for (const provider of providers.data) {
console.log(`${provider.name}: ${provider.type} - ${provider.isActive ? 'Active' : 'Inactive'}`);
}
Configure a Payment Provider
const provider = await client.paymentProviders.create({
type: 'stripe',
name: 'Stripe Production',
credentials: {
secretKey: 'sk_live_...',
webhookSecret: 'whsec_...'
}
});
console.log('Provider configured:', provider.data.id);
Webhooks
Webhooks let you receive real-time HTTP notifications when events happen in your NovaBilling account, such as successful payments, subscription cancellations, or failed charges. Register an endpoint URL and choose which events to subscribe to.
List Webhooks
const webhooks = await client.webhooks.list();
for (const webhook of webhooks.data) {
console.log(`${webhook.url}: ${webhook.isActive ? 'Active' : 'Inactive'}`);
}
Create a Webhook
const webhook = await client.webhooks.create({
url: 'https://api.yourapp.com/webhooks/novabilling',
events: ['invoice.paid', 'subscription.canceled', 'payment.failed']
});
console.log('Webhook ID:', webhook.data.id);
console.log('Secret:', webhook.data.secret);
Error Handling
The SDK throws typed errors that you can catch and handle appropriately.
import {
NovaBillingClient,
NovaBillingError,
NovaBillingTimeoutError,
BadRequestError,
NotFoundError,
UnauthorizedError,
ConflictError
} from 'novabilling';
const client = new NovaBillingClient({
token: process.env.NOVABILLING_API_TOKEN!
});
try {
const customer = await client.customers.get('cus_nonexistent');
} catch (error) {
if (error instanceof NotFoundError) {
console.error('Customer not found:', error.message);
} else if (error instanceof BadRequestError) {
console.error('Bad request:', error.message);
} else if (error instanceof UnauthorizedError) {
console.error('Authentication failed:', error.message);
} else if (error instanceof ConflictError) {
console.error('Conflict:', error.message);
} else if (error instanceof NovaBillingTimeoutError) {
console.error('Request timed out');
} else if (error instanceof NovaBillingError) {
console.error('API error:', error.statusCode, error.message);
} else {
console.error('Unexpected error:', error);
}
}
Error Types
| Error Class | HTTP Status | Description |
|---|---|---|
BadRequestError | 400 | Request body or parameters are invalid |
UnauthorizedError | 401 | Missing or invalid authentication credentials |
NotFoundError | 404 | The requested resource does not exist |
ConflictError | 409 | Resource state conflict (e.g., duplicate email) |
NovaBillingTimeoutError | - | Request exceeded the configured timeout |
NovaBillingError | Various | Base error class for all API errors |
Pagination
All list endpoints support cursor-based pagination.
// Page through all customers
let page = 1;
let hasMore = true;
while (hasMore) {
const response = await client.customers.list({
page,
limit: 100
});
for (const customer of response.data) {
console.log(customer.name);
}
hasMore = page * 100 < response.meta.total;
page++;
}
TypeScript Types
The SDK exports all types for use in your application.
import type {
Customer,
CreateCustomerRequest,
Plan,
CreatePlanRequest,
Subscription,
CreateSubscriptionRequest,
Invoice,
InvoiceItemDto,
CreateInvoiceRequest,
Payment,
PaginatedResponse,
Currency,
BillingInterval,
SubscriptionStatus,
InvoiceStatus,
PaymentStatus
} from 'novabilling';
// Use types in your application
function processCustomer(customer: Customer): void {
console.log(`Processing ${customer.name} (${customer.id})`);
}
// Type-safe currency values
const currency: Currency = 'NGN';
// Type-safe billing intervals
const interval: BillingInterval = 'monthly'; // 'monthly' | 'quarterly' | 'yearly'
// Type-safe status values
const subStatus: SubscriptionStatus = 'active'; // 'active' | 'paused' | 'canceled' | 'expired'
const invStatus: InvoiceStatus = 'finalized'; // 'draft' | 'finalized' | 'paid' | 'void'
const payStatus: PaymentStatus = 'successful'; // 'pending' | 'successful' | 'failed' | 'refunded'
Configuration Options
const client = new NovaBillingClient({
// Required
token: 'sk_live_...',
// Optional
baseUrl: 'https://api.novabilling.com', // Custom base URL
timeoutInSeconds: 60, // Request timeout in seconds (default: 60)
maxRetries: 2, // Max retry attempts (default: 2)
});
Next Steps
- Explore the Python SDK if you work with Python.
- Read the Guides for in-depth usage patterns.
- Check the API Reference for all available endpoints.