Package Exports
- @elyonar/einvoice-js
- @elyonar/einvoice-js/webhooks
Readme
@elyonar/einvoice-js
Official TypeScript/JavaScript SDK for the E-Invoice platform — streamlining electronic invoicing and tax compliance.
Features
- Complete API coverage — Invoices, sellers, buyers, and billing management
- Type-safe — First-class TypeScript support with comprehensive type definitions
- Resilient — Automatic retry with exponential backoff and jitter
- Rate limit aware — Smart handling with
Retry-Aftersupport - Secure webhooks — HMAC-SHA256 signature verification with replay protection
- Zero dependencies — Uses native
fetch,crypto, andAbortController - Dual builds — ESM and CommonJS for maximum compatibility
- Modern — Node.js 18+ support with environment auto-detection
Installation
npm install @elyonar/einvoice-jsQuick Start
import { EInvoice } from '@elyonar/einvoice-js';
// Minimal setup - environment auto-detected from API key
const client = new EInvoice({ apiKey: 'sk_test_...' });
// Create an invoice
const invoice = await client.invoices.create({
sellerId: 'sel_123',
buyerId: 'buy_456',
invoiceDate: '2026-03-20',
dueDate: '2026-04-20',
currency: 'NGN',
lineItems: [
{ description: 'Consulting services', quantity: 10, unitPrice: 50000, vatRate: 7.5 },
],
});
// Submit to tax authority
const result = await client.invoices.submit(invoice.data.id);
console.log(result.data.jobId); // 'job_abc123'Configuration
The SDK works out of the box with intelligent defaults:
// That's it! Environment auto-detected from API key
const client = new EInvoice({ apiKey: 'sk_test_...' });Environment auto-detection:
sk_test_*→ Local development (https://local-api.einvoice.ng)sk_live_*→ Production (https://gateway.einvoice.ng)
Built-in resilience:
- Automatic retry with exponential backoff (3 attempts)
- Smart rate limit handling
- 30-second default timeout
Custom Configuration (Optional)
Override defaults only when needed:
const client = new EInvoice({
apiKey: 'sk_live_...',
options: {
baseUrl: 'https://custom-region.api.einvoice.ng', // Override auto-detection
timeout: 60000, // 60s for slow networks
},
});| Option | Type | Default | Description |
|---|---|---|---|
apiKey |
string |
— | Required. API key (auto-detects environment) |
options.baseUrl |
string |
Auto-detected | Override API gateway URL |
options.timeout |
number |
30000 |
Request timeout (ms) |
API Reference
Invoices — client.invoices
// CRUD
client.invoices.create(params) // Create a draft invoice
client.invoices.get(id) // Get invoice by ID
client.invoices.list(params?) // List with filters (status, date range, etc.)
client.invoices.update(id, params) // Update a draft invoice
client.invoices.delete(id) // Delete a draft invoice
// Submission
client.invoices.submit(id) // Submit to tax authority (irreversible)
client.invoices.batchSubmit(ids) // Batch submit 1–100 invoices
client.invoices.retry(id) // Retry a failed submission
client.invoices.cancel(id, params) // Cancel an accepted invoice
// Status & Validation
client.invoices.getStatus(id) // Get status from local DB
client.invoices.queryStatus(id) // Query tax authority for real-time status
client.invoices.validate(params) // Validate without creating
client.invoices.download(id, format?) // Get PDF/XML download URL
// Analytics
client.invoices.getStatistics(params?) // Invoice analytics
client.invoices.getSetup() // Reference data for creationSellers — client.sellers
client.sellers.create(params) // Register a seller
client.sellers.get(id) // Get seller by ID
client.sellers.list(params?) // List sellers
client.sellers.update(id, params) // Update seller (TIN is immutable)
client.sellers.delete(id) // Delete seller (no invoices)
client.sellers.verifyTin(id) // Trigger TIN verification
client.sellers.getVerificationStatus(id) // Check verification status
client.sellers.search(query) // Search by name or TINBuyers — client.buyers
client.buyers.create(params) // Register a buyer
client.buyers.get(id) // Get buyer by ID
client.buyers.list(params?) // List buyers
client.buyers.update(id, params) // Update buyer (TIN is immutable)
client.buyers.delete(id) // Delete buyer (no invoices)
client.buyers.verifyTin(id) // Trigger TIN verification
client.buyers.getVerificationStatus(id) // Check verification status
client.buyers.search(query) // Search by name or TINBilling — client.billing
// Account
client.billing.getAccount() // Credit balance & status
client.billing.checkBalance(credits) // Verify sufficient credits
client.billing.getSetup() // Full billing overview
// Plans & Packages
client.billing.getPlans(params?) // Available subscription plans
client.billing.getPackages(params?) // Available credit packages
// Subscriptions
client.billing.getActiveSubscription() // Current subscription
client.billing.getSubscriptionHistory() // Past subscriptions
// Payments & Credits
client.billing.purchaseCredits(params) // Buy credits (returns checkout URL)
client.billing.getPayments(params?) // Payment history
client.billing.getTransactions(params?) // Credit transaction history
// Analytics
client.billing.getUsageAnalytics(params?) // Submissions, credits, daily breakdown
client.billing.getConsumptionBreakdown() // Credits by API endpointWebhook Verification
import { verifyWebhook } from '@elyonar/einvoice-js/webhooks';
// Express example
app.post('/webhooks/einvoice', (req, res) => {
try {
const event = verifyWebhook(req.body, req.headers, process.env.WEBHOOK_SECRET);
switch (event.eventType) {
case 'invoice.approved':
console.log('Invoice approved:', event.data);
break;
case 'billing.low_credit_alert':
console.log('Low credits!', event.data);
break;
}
res.sendStatus(200);
} catch (err) {
console.error('Webhook verification failed:', err);
res.sendStatus(400);
}
});The verifyWebhook function performs HMAC-SHA256 signature verification with timing-safe comparison and 5-minute replay protection.
Error Handling
import { EInvoiceApiError, EInvoiceRateLimitError } from '@elyonar/einvoice-js';
try {
await client.invoices.submit('inv_123');
} catch (err) {
if (err instanceof EInvoiceRateLimitError) {
console.log(`Rate limited. Retry after ${err.retryAfter}s`);
} else if (err instanceof EInvoiceApiError) {
console.log(err.statusCode); // 422
console.log(err.errorCode); // 'INVALID_STATE_TRANSITION'
console.log(err.errors); // [{ field: 'status', message: '...' }]
}
}| Error Class | When |
|---|---|
EInvoiceApiError |
API returned a 4xx/5xx error |
EInvoiceRateLimitError |
API returned 429 after max retries |
EInvoiceTimeoutError |
Request exceeded timeout |
EInvoiceConfigError |
Invalid SDK configuration |
EInvoiceWebhookError |
Webhook signature verification failed |
Per-Request Options
Every method accepts an optional RequestOptions object:
const controller = new AbortController();
await client.invoices.list({ status: 'draft' }, {
timeout: 5000, // Override timeout for this request
signal: controller.signal, // AbortSignal for cancellation
headers: { 'X-Request-Id': 'req_123' }, // Additional headers
});Development
npm install # Install dependencies
npm test # Run tests with coverage
npm run build # Build ESM + CJS
npm run lint # Type checkLicense
MIT