apibill-billing-sdk

JavaScript/TypeScript SDK for ApiBill Client API — billing info, invoices, payments, and restriction middleware for admin panels
2,202
Install
npm install apibill-billing-sdk
Latest Version:1.1.4
License:MIT
Last Updated:Apr 16, 2026
Links: npm
Maintainer: mosabberul55

@nextive/billing-sdk

JavaScript/TypeScript SDK for ApiBill Client API. Embed billing info, invoices, payments, and restriction middleware into any admin panel.

Works with Nuxt 3/4, Vue 3 + Vuetify, React, or any JavaScript project.

Installation

# npm
npm install @nextive/billing-sdk

# yarn
yarn add @nextive/billing-sdk

# Or install from git
npm install git+https://github.com/Nextive-Solution/apibill-js-sdk.git

Quick Start

import { ApiBillClient } from '@nextive/billing-sdk'

const billing = new ApiBillClient({
  siteId: 'YOUR_SITE_ID',
  apiUrl: 'https://your-api.com/api',
})

// Get billing summary
const summary = await billing.getBillingSummary()
console.log(summary.billing.totalDue)        // 5225.32
console.log(summary.billing.restrictionActive) // true/false

// Check restriction
const blocked = await billing.isRestricted()

// List unpaid invoices
const invoices = await billing.getInvoices('unpaid')

// Pay an invoice (redirects to bKash)
const { gatewayUrl } = await billing.payInvoice('invoice_id')
window.location.href = gatewayUrl

API Reference

new ApiBillClient(config)

Option Type Required Description
siteId string Yes Your Site ID from ApiBill admin panel
apiUrl string Yes ApiBill API base URL (e.g. https://your-api.com/api)
fetch typeof fetch No Custom fetch implementation (defaults to global fetch)
onRestriction (summary) => void No Called when restrictionActive is true
cacheTtl number No Cache TTL in ms for billing summary (default: 300000 = 5 min)

Methods

Billing Summary
// Get full billing summary (cached for cacheTtl)
const summary = await billing.getBillingSummary()

// Force refresh (skip cache)
const fresh = await billing.getBillingSummary(true)

// Check if restricted (shorthand)
const restricted = await billing.isRestricted() // boolean

// Check restriction + trigger onRestriction callback
const restricted = await billing.checkRestriction() // boolean

// Clear cache manually
billing.clearCache()
Invoices
// List all invoices (paid + unpaid + partially_paid)
const all = await billing.getInvoices()

// Filter by status
const unpaid = await billing.getInvoices('unpaid')
const paid = await billing.getInvoices('paid')
const partial = await billing.getInvoices('partially_paid')

// Get single invoice
const invoice = await billing.getInvoice('invoice_id')
console.log(invoice.invoiceNumber)  // 'NS0010001'
console.log(invoice.paidAmount)     // 2000
console.log(invoice.dueAmount)      // 3000
console.log(invoice.payments)       // PaymentRecord[]

// Get last unpaid/partially paid invoice
const lastUnpaid = await billing.getLastUnpaidInvoice()

// Pay full due amount via bKash
const { gatewayUrl, paymentId, type } = await billing.payInvoice('invoice_id')
window.location.href = gatewayUrl

// Pay a specific pending payment (partial amount set by admin)
const pending = invoice.payments.find(p => p.status === 'pending')
if (pending) {
  const { gatewayUrl } = await billing.payInvoice('invoice_id', pending.paymentId)
  window.location.href = gatewayUrl
}
Bank Transfer Notifications
// Notify admin that a bank transfer payment has been initiated.
// Sends an email + in-app notification to all admins so they can
// verify the transfer against their bank account and mark the invoice paid.

// For a regular invoice (default type)
await billing.notifyBankTransfer('invoice_id')

// For a custom invoice
await billing.notifyBankTransfer('custom_invoice_id', 'custom_invoice')

Use this after displaying bank account details to the client so the admin is proactively alerted instead of having to poll their bank account.

Custom Invoices
// List custom invoices
const custom = await billing.getCustomInvoices()
const unpaidCustom = await billing.getCustomInvoices('unpaid')
const partialCustom = await billing.getCustomInvoices('partially_paid')

// Get single custom invoice
const invoice = await billing.getCustomInvoice('custom_invoice_id')
console.log(invoice.invoiceNumber) // 'NS0010006'
console.log(invoice.paidAmount)    // 5000
console.log(invoice.dueAmount)     // 10000

// Pay full due via bKash
const { gatewayUrl } = await billing.payCustomInvoice('custom_invoice_id')
window.location.href = gatewayUrl

// Pay a specific pending payment
const pending = invoice.payments.find(p => p.status === 'pending')
if (pending) {
  const { gatewayUrl } = await billing.payCustomInvoice('custom_invoice_id', pending.paymentId)
  window.location.href = gatewayUrl
}

Response Types

BillingSummaryResponse
{
  site: { _id: string, domain: string }
  client: { name: string, email: string, phone: string | null } | null
  plan: {
    freeTier: number
    ratePerThousand: number
    bandwidthRatePerGb: number
    bandwidthFreeTierGb: number
    serviceCharge: number
    maintenanceCharge: number
    currency: string
  } | null
  billing: {
    totalDue: number              // Combined due from invoices + custom invoices
    totalPaid: number             // Total already paid across partial invoices
    currency: string
    unpaidCount: number
    partiallyPaidCount: number    // Number of partially paid invoices
    restrictedCount: number       // Number of restricted unpaid invoices
    flexibleCount: number         // Number of flexible unpaid invoices
    restrictionActive: boolean    // true = block admin panel access
  }
  invoices: {
    totalDue: number
    unpaidCount: number
    nextDueDate: string | null
    unpaid: UnpaidInvoice[]
  }
  customInvoices: {
    totalDue: number
    unpaidCount: number
    nextDueDate: string | null
    unpaid: UnpaidCustomInvoice[]
  }
}

Error Handling

import { ApiBillError } from '@nextive/billing-sdk'

try {
  await billing.payInvoice('id')
} catch (err) {
  if (err instanceof ApiBillError) {
    console.log(err.statusCode) // 400, 404, etc.
    console.log(err.response)   // API response body
  }
}

Framework Integration

Nuxt 3/4

1. Add runtime config:

// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    public: {
      apibillSiteId: process.env.APIBILL_SITE_ID || '',
      apibillApiUrl: process.env.APIBILL_API_URL || '',
    },
  },
})

2. Create plugin:

// app/plugins/apibill.ts
import { ApiBillClient } from '@nextive/billing-sdk'

export default defineNuxtPlugin(() => {
  const config = useRuntimeConfig()

  const billing = new ApiBillClient({
    siteId: config.public.apibillSiteId as string,
    apiUrl: config.public.apibillApiUrl as string,
  })

  return { provide: { apibill: billing } }
})

3. Create restriction middleware:

// app/middleware/billing-restriction.global.ts
import { ApiBillClient } from '@nextive/billing-sdk'

const EXCLUDED_ROUTES = ['/login', '/billing', '/billing/restricted']

export default defineNuxtRouteMiddleware(async (to) => {
  // Skip excluded routes
  if (EXCLUDED_ROUTES.some(r => to.path === r || to.path.startsWith(r + '/'))) return

  // Skip on server side
  if (import.meta.server) return

  const { $apibill } = useNuxtApp()
  if (!$apibill) return

  try {
    const restricted = await ($apibill as ApiBillClient).isRestricted()
    if (restricted) {
      return navigateTo('/billing/restricted')
    }
  } catch {
    // Fail open — don't block on API errors
  }
})

4. Use in components:

<script setup>
const { $apibill } = useNuxtApp()
const summary = await $apibill.getBillingSummary()
</script>

<template>
  <div v-if="summary.billing.unpaidCount > 0" class="alert">
    You have {{ summary.billing.unpaidCount }} unpaid invoice(s).
    Total due: {{ summary.billing.totalDue }} {{ summary.billing.currency }}
  </div>
</template>

5. Create a restricted page:

<!-- app/pages/billing/restricted.vue -->
<template>
  <div class="flex items-center justify-center min-h-screen">
    <div class="text-center max-w-md">
      <h1 class="text-2xl font-bold text-red-600">Access Restricted</h1>
      <p class="mt-2 text-gray-600">
        Your access has been restricted due to overdue invoices.
        Please pay your outstanding invoices to restore access.
      </p>
      <NuxtLink to="/billing" class="mt-4 inline-block px-4 py-2 bg-primary text-white rounded">
        View Invoices
      </NuxtLink>
    </div>
  </div>
</template>

Vue 3 + Vuetify (or any Vue 3 project)

1. Initialize in main.ts:

// main.ts
import { initApiBill } from '@nextive/billing-sdk/vue'

initApiBill({
  siteId: import.meta.env.VITE_APIBILL_SITE_ID,
  apiUrl: import.meta.env.VITE_APIBILL_API_URL,
})

2. Add router guard:

// router/index.ts
import { createBillingGuard } from '@nextive/billing-sdk/vue'

const router = createRouter({ ... })

router.beforeEach(createBillingGuard({
  restrictedRoute: '/billing/restricted',
  excludeRoutes: ['/login', '/billing', '/billing/restricted'],
}))

3. Use in components:

<script setup>
import { useApiBill } from '@nextive/billing-sdk/vue'
import { ref, onMounted } from 'vue'

const billing = useApiBill()
const summary = ref(null)

onMounted(async () => {
  summary.value = await billing.getBillingSummary()
})
</script>

Vanilla JavaScript / Any Framework

import { ApiBillClient } from '@nextive/billing-sdk'

const billing = new ApiBillClient({
  siteId: 'YOUR_SITE_ID',
  apiUrl: 'https://your-api.com/api',
  onRestriction: (summary) => {
    // Show modal, redirect, etc.
    window.location.href = '/billing/restricted'
  },
})

// Check on app load
await billing.checkRestriction()

// Get data
const summary = await billing.getBillingSummary()
const invoices = await billing.getInvoices('unpaid')

Billing Page Example

Create a billing page in your admin panel to show invoices and allow payment:

<script setup>
import { ApiBillClient } from '@nextive/billing-sdk'

const billing = new ApiBillClient({
  siteId: 'YOUR_SITE_ID',
  apiUrl: 'https://your-api.com/api',
})

const summary = ref(null)
const invoices = ref([])
const customInvoices = ref([])
const loading = ref(true)

onMounted(async () => {
  const [s, inv, cinv] = await Promise.all([
    billing.getBillingSummary(),
    billing.getInvoices(),
    billing.getCustomInvoices(),
  ])
  summary.value = s
  invoices.value = inv
  customInvoices.value = cinv
  loading.value = false
})

async function pay(invoiceId, type = 'invoice') {
  const { gatewayUrl } = type === 'invoice'
    ? await billing.payInvoice(invoiceId)
    : await billing.payCustomInvoice(invoiceId)
  window.location.href = gatewayUrl
}
</script>

Environment Variables

Variable Description
APIBILL_SITE_ID or VITE_APIBILL_SITE_ID Your Site ID from ApiBill admin panel
APIBILL_API_URL or VITE_APIBILL_API_URL ApiBill API base URL

How restrictionActive Works

  • If any unpaid invoice with mode restricted has its due date fully passed (after 11:59 PM), restrictionActive becomes true
  • Invoices with mode flexible never trigger restriction
  • If an invoice has an extendedDueDate, that date is used instead of dueDate
  • The SDK caches the billing summary (default 5 min) to avoid excessive API calls

License

MIT

apibill-js-sdk

Related Packages

@rebilly/framepay-vue

Official Vue wrapper for Rebilly FramePay

78,075
paymid-sdk

A frontend SDK for Paymid payment processing

15,682
runedu-js-sdk

Javascript SDK of runedu project

6,628
rasedi-sdk

Universal Rasedi Payment Gateway SDK for React, Vue, Angular, React Native, and...

965
dingcloud-sdk

Ding-cloud数据埋点sdk

633

Version History

Version Released License
1.1.4 MIT
1.1.3 MIT
1.1.2 MIT
1.1.1 MIT
1.1.0 MIT