Sdks

TypeScript SDK

Complete guide to using the NovaBilling TypeScript SDK for Node.js and browser environments.

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

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 ClassHTTP StatusDescription
BadRequestError400Request body or parameters are invalid
UnauthorizedError401Missing or invalid authentication credentials
NotFoundError404The requested resource does not exist
ConflictError409Resource state conflict (e.g., duplicate email)
NovaBillingTimeoutError-Request exceeded the configured timeout
NovaBillingErrorVariousBase 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

Copyright © 2026