zata-vsdc-sdk 1.0.3 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,27 +4,18 @@
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
  [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
6
6
 
7
- A lightweight, fully-typed TypeScript SDK for the **Zata API** – Rwanda's leading E-Invoicing & Tax Compliance platform. This SDK simplifies integration with the Rwanda Revenue Authority (RRA) compliant e-invoicing system, EBM/VSDC integration, real-time transaction validation, signed PDFs, and more.
7
+ A production-friendly TypeScript/JavaScript SDK for the Zata API.
8
+ Built for Rwanda e-invoicing and tax-compliance workflows: companies, branches, parties, products, expenses, transactions, insurance, patient flows, and signed invoice downloads.
8
9
 
9
- ## 🌟 Features
10
+ ## Why use this SDK
10
11
 
11
- - **Full TypeScript Support** Complete type definitions for all API resources
12
- - **Lightweight & Fast** Minimal dependencies, optimized for performance
13
- - **Comprehensive Coverage** Support for all Zata API endpoints
14
- - **Error Handling** – Built-in error interceptors with detailed error messages
15
- - ✅ **Promise-Based** Modern async/await API
16
- - ✅ **Well Documented** – Extensive JSDoc comments and examples
17
- - ✅ **Open Source** – Community-driven development
12
+ - Fast onboarding to the Zata API with a single client
13
+ - Automatic `Authorization`, `companyId`, and `branchId` header handling
14
+ - Clean method names that map directly to documented API actions
15
+ - Works in both TypeScript and JavaScript projects
16
+ - Built-in request error formatting for faster debugging
18
17
 
19
- ## 📚 Resources
20
-
21
- - **Official Website**: [https://zata.rw](https://zata.rw)
22
- - **API Documentation**: [https://docs.zata.rw](https://docs.zata.rw)
23
- - **Installation Guide**: [https://zata.lovable.app](https://zata.lovable.app)
24
- - **npm Package**: [zata-vsdc-sdk on npm](https://www.npmjs.com/package/zata-vsdc-sdk)
25
- - **GitHub Repository**: [HiQ-Africa/zata-npm](https://github.com/HiQ-Africa/zata-npm)
26
-
27
- ## 📦 Installation
18
+ ## Install
28
19
 
29
20
  ```bash
30
21
  npm install zata-vsdc-sdk
@@ -42,818 +33,263 @@ Or with pnpm:
42
33
  pnpm add zata-vsdc-sdk
43
34
  ```
44
35
 
45
- ## 🚀 Quick Start
36
+ ## Quick start
46
37
 
47
- ### TypeScript/ES Modules
38
+ ```ts
39
+ import { ZataClient } from "zata-vsdc-sdk";
48
40
 
49
- ```typescript
50
- import { ZataClient } from 'zata-vsdc-sdk';
51
-
52
- // Initialize the client
53
41
  const client = new ZataClient({
54
- apiKey: 'your-api-key-here',
55
- baseUrl: 'https://api.zata.rw/v1', // Optional, defaults to production
56
- timeout: 30000 // Optional, defaults to 30000ms
42
+ // token is preferred. apiKey is also supported as an alias.
43
+ token: process.env.ZATA_TOKEN,
44
+ companyId: 1,
45
+ branchId: 1,
46
+ baseUrl: "https://api.zata.rw", // default
47
+ timeout: 30000, // default
57
48
  });
58
49
 
59
- // Example: Get all companies
60
- async function example() {
61
- try {
62
- const companies = await client.getCompanies();
63
- console.log('Companies:', companies);
64
- } catch (error) {
65
- console.error('Error:', error.message);
66
- }
50
+ async function run() {
51
+ // 1) Pull reference data
52
+ const paymentModes = await client.getPaymentModes();
53
+ const taxes = await client.getProductTaxes();
54
+
55
+ // 2) Create a customer
56
+ await client.createCustomer({
57
+ name: "John Doe",
58
+ address: "Kigali",
59
+ phone: "0780000000",
60
+ email: "john@example.com",
61
+ tin: "123456789",
62
+ hasInsurance: "no",
63
+ });
64
+
65
+ // 3) Create a product
66
+ await client.createProduct({
67
+ name: "Service Item",
68
+ packagingUnitID: 1,
69
+ quantityUnitID: 1,
70
+ countryID: 1,
71
+ taxID: 1,
72
+ branchProductCategoryID: 1,
73
+ hasStock: "yes",
74
+ });
75
+
76
+ // 4) Create a sale transaction
77
+ const sale = await client.createSaleTransaction({
78
+ paymentMethodID: 1,
79
+ transactionDate: "2026-01-01",
80
+ items: [{ productID: 1, units: 1, unitPrice: 1000, discountRate: 0 }],
81
+ });
82
+
83
+ return { paymentModes, taxes, sale };
67
84
  }
68
85
  ```
69
86
 
70
- ### JavaScript/CommonJS
71
-
72
- ```javascript
73
- const { ZataClient } = require('zata-vsdc-sdk');
74
-
75
- const client = new ZataClient({
76
- apiKey: 'your-api-key-here'
77
- });
78
-
79
- // Use the client...
80
- client.getCompanies().then(companies => {
81
- console.log('Companies:', companies);
82
- }).catch(error => {
83
- console.error('Error:', error.message);
84
- });
85
- ```
86
-
87
- ## 📖 API Reference
88
-
89
- ### Initialization
90
-
91
- #### `new ZataClient(options: ZataClientOptions)`
92
-
93
- Creates a new Zata API client instance.
87
+ ## JavaScript (CommonJS)
94
88
 
95
- **Parameters:**
96
- - `options.apiKey` (string, required) Your Zata API key
97
- - `options.baseUrl` (string, optional) – API base URL (default: `'https://api.zata.rw/v1'`)
98
- - `options.timeout` (number, optional) – Request timeout in milliseconds (default: `30000`)
89
+ ```js
90
+ const { ZataClient } = require("zata-vsdc-sdk");
99
91
 
100
- **Example:**
101
- ```typescript
102
92
  const client = new ZataClient({
103
- apiKey: process.env.ZATA_API_KEY!,
104
- baseUrl: 'https://api.zata.rw/v1',
105
- timeout: 30000
106
- });
107
- ```
108
-
109
- ---
110
-
111
- ### Companies
112
-
113
- Manage company information and settings.
114
-
115
- #### `getCompanies(): Promise<Company[]>`
116
-
117
- Retrieves a list of all companies.
118
-
119
- **Returns:** Promise resolving to an array of `Company` objects.
120
-
121
- **Example:**
122
- ```typescript
123
- const companies = await client.getCompanies();
124
- console.log(`Found ${companies.length} companies`);
125
- ```
126
-
127
- #### `getCompany(id: string): Promise<Company>`
128
-
129
- Retrieves a specific company by ID.
130
-
131
- **Parameters:**
132
- - `id` (string) – Company ID
133
-
134
- **Returns:** Promise resolving to a `Company` object.
135
-
136
- **Example:**
137
- ```typescript
138
- const company = await client.getCompany('comp-123');
139
- console.log('Company:', company.name);
140
- ```
141
-
142
- #### `createCompany(data: Partial<Company>): Promise<Company>`
143
-
144
- Creates a new company.
145
-
146
- **Parameters:**
147
- - `data` (Partial<Company>) – Company data including:
148
- - `name` (string, required) – Company name
149
- - `tin` (string, required) – Tax Identification Number (9 digits)
150
- - `address` (string, optional) – Company address
151
-
152
- **Returns:** Promise resolving to the created `Company` object.
153
-
154
- **Example:**
155
- ```typescript
156
- const newCompany = await client.createCompany({
157
- name: 'Acme Corporation',
158
- tin: '123456789',
159
- address: 'Kigali, Rwanda'
93
+ token: process.env.ZATA_TOKEN,
94
+ companyId: 1,
95
+ branchId: 1,
160
96
  });
161
- console.log('Created company:', newCompany.id);
162
- ```
163
-
164
- #### `updateCompany(id: string, data: Partial<Company>): Promise<Company>`
165
-
166
- Updates an existing company.
167
97
 
168
- **Parameters:**
169
- - `id` (string) Company ID
170
- - `data` (Partial<Company>) – Updated company data
171
-
172
- **Returns:** Promise resolving to the updated `Company` object.
173
-
174
- **Example:**
175
- ```typescript
176
- const updated = await client.updateCompany('comp-123', {
177
- address: 'New Address, Kigali'
178
- });
98
+ client
99
+ .listTransactions({ page: 1, perPage: 20 })
100
+ .then((res) => console.log(res))
101
+ .catch((err) => console.error(err.message));
179
102
  ```
180
103
 
181
- #### `deleteCompany(id: string): Promise<{ success: boolean; message?: string }>`
104
+ ## Authentication and context
182
105
 
183
- Deletes a company by ID.
106
+ Most business endpoints need:
184
107
 
185
- **Parameters:**
186
- - `id` (string) – Company ID
108
+ - `Authorization: Bearer <token>`
109
+ - `companyId`
110
+ - `branchId`
187
111
 
188
- **Returns:** Promise resolving to a deletion confirmation object.
112
+ You can define these once at client creation, then update later when needed:
189
113
 
190
- **Example:**
191
- ```typescript
192
- const result = await client.deleteCompany('comp-123');
193
- if (result.success) {
194
- console.log('Company deleted successfully');
195
- }
114
+ ```ts
115
+ client.setContext({ companyId: 2, branchId: 7 });
116
+ client.setToken("new-token-value");
196
117
  ```
197
118
 
198
- ---
199
-
200
- ### Branches
119
+ ## End-to-end implementation flow
201
120
 
202
- Manage branch locations for your company.
121
+ Recommended sequence for most integrators:
203
122
 
204
- #### `getBranches(): Promise<Branch[]>`
123
+ 1. Authenticate (`login`) and set token
124
+ 2. Validate company and branch (`getCompany`, `listCompanyBranches`)
125
+ 3. Fetch reference data (`getPaymentModes`, product tax/unit/category lookups)
126
+ 4. Create parties (`createCustomer`, `createSupplier`)
127
+ 5. Create products (`createProduct`)
128
+ 6. Create expense and transactions
129
+ 7. Retrieve transaction PDF signature and download invoice
205
130
 
206
- Retrieves a list of all branches.
131
+ This mirrors the practical order required by dependent IDs across endpoints.
207
132
 
208
- **Returns:** Promise resolving to an array of `Branch` objects.
133
+ ## API reference (SDK methods)
209
134
 
210
- **Example:**
211
- ```typescript
212
- const branches = await client.getBranches();
213
- branches.forEach(branch => {
214
- console.log(`${branch.name} (${branch.id})`);
215
- });
216
- ```
135
+ ### Auth and utility
217
136
 
218
- #### `getBranch(id: string): Promise<Branch>`
137
+ - `login(data)`
138
+ - `createAccount(data)`
139
+ - `getTestStatus()`
219
140
 
220
- Retrieves a specific branch by ID.
141
+ ### Company and branches
221
142
 
222
- **Parameters:**
223
- - `id` (string) – Branch ID
224
-
225
- **Returns:** Promise resolving to a `Branch` object.
226
-
227
- **Example:**
228
- ```typescript
229
- const branch = await client.getBranch('branch-123');
230
- ```
143
+ - `listCompanies(params?)`
144
+ - `getCompany(companyId)`
145
+ - `createCompany(data)`
146
+ - `updateCompany(data)`
147
+ - `listCompanyBranches(params?)`
148
+ - `createCompanyBranch(data)`
149
+ - `updateCompanyBranch(data)`
150
+ - `getCompanyFinance()`
151
+ - `getCompanyTaxInfo()`
231
152
 
232
- #### `createBranch(data: Partial<Branch>): Promise<Branch>`
233
-
234
- Creates a new branch.
235
-
236
- **Parameters:**
237
- - `data` (Partial<Branch>) – Branch data including:
238
- - `name` (string, required) – Branch name
239
- - `companyId` (string, required) – Parent company ID
240
-
241
- **Returns:** Promise resolving to the created `Branch` object.
242
-
243
- **Example:**
244
- ```typescript
245
- const newBranch = await client.createBranch({
246
- name: 'Kicukiro Branch',
247
- companyId: 'comp-123'
248
- });
249
- ```
153
+ ### Reference data
250
154
 
251
- #### `updateBranch(id: string, data: Partial<Branch>): Promise<Branch>`
155
+ - `getPaymentModes()`
156
+ - `getProductCategories()`
157
+ - `getProductClasses()`
158
+ - `getProductCountryOrigins()`
159
+ - `getProductPackagingUnits()`
160
+ - `getProductQuantityUnits()`
161
+ - `getProductTaxes()`
162
+ - `getProductTypes()`
252
163
 
253
- Updates an existing branch.
164
+ ### Parties
254
165
 
255
- **Parameters:**
256
- - `id` (string) – Branch ID
257
- - `data` (Partial<Branch>) – Updated branch data
258
-
259
- **Returns:** Promise resolving to the updated `Branch` object.
260
-
261
- #### `deleteBranch(id: string): Promise<{ success: boolean }>`
262
-
263
- Deletes a branch by ID.
264
-
265
- **Parameters:**
266
- - `id` (string) – Branch ID
267
-
268
- **Returns:** Promise resolving to a deletion confirmation object.
269
-
270
- ---
166
+ - `listParties(params?)`
167
+ - `createCustomer(data)`
168
+ - `createSupplier(data)`
271
169
 
272
170
  ### Products
273
171
 
274
- Manage your product catalog.
275
-
276
- #### `getProducts(): Promise<Product[]>`
277
-
278
- Retrieves a list of all products.
279
-
280
- **Returns:** Promise resolving to an array of `Product` objects.
281
-
282
- **Example:**
283
- ```typescript
284
- const products = await client.getProducts();
285
- console.log(`Total products: ${products.length}`);
286
- ```
287
-
288
- #### `getProduct(id: string): Promise<Product>`
289
-
290
- Retrieves a specific product by ID.
291
-
292
- **Parameters:**
293
- - `id` (string) – Product ID
294
-
295
- **Returns:** Promise resolving to a `Product` object.
296
-
297
- **Example:**
298
- ```typescript
299
- const product = await client.getProduct('prod-123');
300
- console.log(`${product.name} - ${product.price} RWF`);
301
- ```
302
-
303
- #### `createProduct(data: Partial<Product>): Promise<Product>`
304
-
305
- Creates a new product.
306
-
307
- **Parameters:**
308
- - `data` (Partial<Product>) – Product data including:
309
- - `name` (string, required) – Product name
310
- - `code` (string, optional) – Product code/SKU
311
- - `price` (number, optional) – Product price
312
- - `unit` (string, optional) – Unit of measurement
313
-
314
- **Returns:** Promise resolving to the created `Product` object.
315
-
316
- **Example:**
317
- ```typescript
318
- const newProduct = await client.createProduct({
319
- name: 'Premium Coffee',
320
- code: 'COFFEE-001',
321
- price: 5000,
322
- unit: 'kg'
323
- });
324
- ```
325
-
326
- #### `updateProduct(id: string, data: Partial<Product>): Promise<Product>`
327
-
328
- Updates an existing product.
329
-
330
- **Parameters:**
331
- - `id` (string) – Product ID
332
- - `data` (Partial<Product>) – Updated product data
333
-
334
- **Returns:** Promise resolving to the updated `Product` object.
335
-
336
- **Example:**
337
- ```typescript
338
- await client.updateProduct('prod-123', {
339
- price: 5500 // Update price
340
- });
341
- ```
342
-
343
- #### `deleteProduct(id: string): Promise<{ success: boolean }>`
344
-
345
- Deletes a product by ID.
346
-
347
- **Parameters:**
348
- - `id` (string) – Product ID
349
-
350
- **Returns:** Promise resolving to a deletion confirmation object.
351
-
352
- ---
353
-
354
- ### Parties (Customers & Suppliers)
355
-
356
- Manage customers and suppliers.
357
-
358
- #### `getParties(): Promise<Party[]>`
359
-
360
- Retrieves a list of all parties (customers and suppliers).
361
-
362
- **Returns:** Promise resolving to an array of `Party` objects.
363
-
364
- **Example:**
365
- ```typescript
366
- const parties = await client.getParties();
367
- const customers = parties.filter(p => p.type === 'customer');
368
- ```
369
-
370
- #### `getParty(id: string): Promise<Party>`
371
-
372
- Retrieves a specific party by ID.
373
-
374
- **Parameters:**
375
- - `id` (string) – Party ID
376
-
377
- **Returns:** Promise resolving to a `Party` object.
378
-
379
- **Example:**
380
- ```typescript
381
- const customer = await client.getParty('party-123');
382
- console.log(`Customer: ${customer.name} (TIN: ${customer.tin})`);
383
- ```
384
-
385
- #### `createParty(data: Partial<Party>): Promise<Party>`
386
-
387
- Creates a new party (customer or supplier).
388
-
389
- **Parameters:**
390
- - `data` (Partial<Party>) – Party data including:
391
- - `name` (string, required) – Party name
392
- - `tin` (string, optional) – Tax Identification Number (9 digits)
393
- - `type` (string, optional) – Party type: `'customer'` or `'supplier'`
394
-
395
- **Returns:** Promise resolving to the created `Party` object.
396
-
397
- **Example:**
398
- ```typescript
399
- const newCustomer = await client.createParty({
400
- name: 'John Doe',
401
- tin: '123456789',
402
- type: 'customer'
403
- });
404
- ```
405
-
406
- #### `updateParty(id: string, data: Partial<Party>): Promise<Party>`
407
-
408
- Updates an existing party.
409
-
410
- **Parameters:**
411
- - `id` (string) – Party ID
412
- - `data` (Partial<Party>) – Updated party data
413
-
414
- **Returns:** Promise resolving to the updated `Party` object.
415
-
416
- #### `deleteParty(id: string): Promise<{ success: boolean }>`
417
-
418
- Deletes a party by ID.
419
-
420
- **Parameters:**
421
- - `id` (string) – Party ID
422
-
423
- **Returns:** Promise resolving to a deletion confirmation object.
424
-
425
- ---
172
+ - `createProduct(data)`
173
+ - `listBranchProducts(params?)`
174
+ - `getProduct(productId)`
175
+ - `updateProduct(productId, data)`
176
+ - `increaseProductQuantity(productId, data)`
177
+ - `reduceProductQuantity(productId, data)`
426
178
 
427
179
  ### Expenses
428
180
 
429
- Track business expenses.
430
-
431
- #### `getExpenses(): Promise<Expense[]>`
432
-
433
- Retrieves a list of all expenses.
434
-
435
- **Returns:** Promise resolving to an array of `Expense` objects.
436
-
437
- **Example:**
438
- ```typescript
439
- const expenses = await client.getExpenses();
440
- const total = expenses.reduce((sum, e) => sum + e.amount, 0);
441
- console.log(`Total expenses: ${total} RWF`);
442
- ```
443
-
444
- #### `getExpense(id: string): Promise<Expense>`
445
-
446
- Retrieves a specific expense by ID.
447
-
448
- **Parameters:**
449
- - `id` (string) – Expense ID
450
-
451
- **Returns:** Promise resolving to an `Expense` object.
452
-
453
- **Example:**
454
- ```typescript
455
- const expense = await client.getExpense('exp-123');
456
- console.log(`${expense.description}: ${expense.amount} RWF`);
457
- ```
458
-
459
- #### `createExpense(data: Partial<Expense>): Promise<Expense>`
460
-
461
- Creates a new expense record.
462
-
463
- **Parameters:**
464
- - `data` (Partial<Expense>) – Expense data including:
465
- - `amount` (number, required) – Expense amount
466
- - `description` (string, required) – Expense description
467
- - `date` (string, optional) – Expense date (YYYY-MM-DD format)
468
-
469
- **Returns:** Promise resolving to the created `Expense` object.
181
+ - `listExpenses(params?)`
182
+ - `createExpense(data)`
183
+ - `getExpenseCategories()`
470
184
 
471
- **Example:**
472
- ```typescript
473
- const newExpense = await client.createExpense({
474
- amount: 50000,
475
- description: 'Office Supplies',
476
- date: '2024-01-15'
477
- });
478
- ```
479
-
480
- #### `updateExpense(id: string, data: Partial<Expense>): Promise<Expense>`
481
-
482
- Updates an existing expense.
483
-
484
- **Parameters:**
485
- - `id` (string) – Expense ID
486
- - `data` (Partial<Expense>) – Updated expense data
487
-
488
- **Returns:** Promise resolving to the updated `Expense` object.
489
-
490
- #### `deleteExpense(id: string): Promise<{ success: boolean }>`
185
+ ### Insurance
491
186
 
492
- Deletes an expense by ID.
187
+ - `listInsurances()`
188
+ - `createPresetInsurance(data)`
189
+ - `createCustomInsurance(data)`
190
+ - `updateCustomInsurance(insuranceId, data)`
191
+ - `updateBranchInsurance(companyInsuranceId, data)`
493
192
 
494
- **Parameters:**
495
- - `id` (string) – Expense ID
193
+ ### Patients
496
194
 
497
- **Returns:** Promise resolving to a deletion confirmation object.
195
+ - `listPatients(params?)`
196
+ - `createPatient(data)`
197
+ - `getPatient(patientId)`
198
+ - `updatePatient(patientId, data)`
199
+ - `getPatientByParty(partyId)`
498
200
 
499
- ---
500
-
501
- ### Transactions (Invoices, Receipts, etc.)
502
-
503
- Create and manage transactions including invoices, receipts, credit notes, and more.
504
-
505
- #### `getTransactions(): Promise<Transaction[]>`
506
-
507
- Retrieves a list of all transactions.
508
-
509
- **Returns:** Promise resolving to an array of `Transaction` objects.
510
-
511
- **Example:**
512
- ```typescript
513
- const transactions = await client.getTransactions();
514
- const invoices = transactions.filter(t => t.type === 'invoice');
515
- ```
201
+ ### Transactions
516
202
 
517
- #### `getTransaction(id: string): Promise<Transaction>`
203
+ - `listTransactions(params?)`
204
+ - `calculateTransaction(data)`
205
+ - `createSaleTransaction(data)`
206
+ - `createPurchaseTransaction(data)`
207
+ - `createProformaTransaction(data)`
208
+ - `createRefundTransaction(transactionId, data)`
209
+ - `getTransaction(transactionId, params?)`
210
+ - `getTransactionDownloadSignature(transactionId, params?)`
211
+ - `downloadTransaction(params)`
518
212
 
519
- Retrieves a specific transaction by ID.
213
+ ## Transaction examples
520
214
 
521
- **Parameters:**
522
- - `id` (string) – Transaction ID
215
+ ### Calculate before create
523
216
 
524
- **Returns:** Promise resolving to a `Transaction` object.
525
-
526
- **Example:**
527
- ```typescript
528
- const transaction = await client.getTransaction('txn-123');
529
- console.log(`Invoice #${transaction.id}: ${transaction.totalAmount} RWF`);
530
- ```
531
-
532
- #### `createTransaction(data: Partial<Transaction>): Promise<Transaction>`
533
-
534
- Creates a new transaction (invoice, receipt, credit note, etc.).
535
-
536
- **Parameters:**
537
- - `data` (Partial<Transaction>) – Transaction data including:
538
- - `type` (string, optional) – Transaction type: `'invoice'`, `'receipt'`, `'credit_note'`, etc.
539
- - `partyId` (string, optional) – Customer/Supplier party ID
540
- - `items` (array, optional) – Transaction line items:
541
- - `productId` (string, optional) – Product ID
542
- - `quantity` (number, required) – Item quantity
543
- - `unitPrice` (number, required) – Unit price
544
- - `totalAmount` (number, optional) – Total transaction amount
545
-
546
- **Returns:** Promise resolving to the created `Transaction` object.
547
-
548
- **Example:**
549
- ```typescript
550
- const invoice = await client.createTransaction({
551
- type: 'invoice',
552
- partyId: 'party-123',
217
+ ```bash
218
+ const calc = await client.calculateTransaction({
553
219
  items: [
554
- {
555
- productId: 'prod-123',
556
- quantity: 2,
557
- unitPrice: 5000
558
- }
220
+ { productID: 1, units: 2, unitPrice: 1000, discountRate: 5, batchNumber: "B-001" }
559
221
  ]
560
222
  });
561
- console.log(`Created invoice: ${invoice.id}`);
562
223
  ```
563
224
 
564
- #### `updateTransaction(id: string, data: Partial<Transaction>): Promise<Transaction>`
565
-
566
- Updates an existing transaction.
567
-
568
- **Parameters:**
569
- - `id` (string) – Transaction ID
570
- - `data` (Partial<Transaction>) – Updated transaction data
571
-
572
- **Returns:** Promise resolving to the updated `Transaction` object.
573
-
574
- #### `deleteTransaction(id: string): Promise<{ success: boolean }>`
575
-
576
- Deletes a transaction by ID.
225
+ ### Create sale
577
226
 
578
- **Parameters:**
579
- - `id` (string) Transaction ID
580
-
581
- **Returns:** Promise resolving to a deletion confirmation object.
582
-
583
- #### `getSignedPdf(id: string): Promise<SignedPdfResponse>`
584
-
585
- Retrieves a signed PDF document for a transaction.
586
-
587
- **Parameters:**
588
- - `id` (string) – Transaction ID
589
-
590
- **Returns:** Promise resolving to a `SignedPdfResponse` object containing:
591
- - `url` (string, optional) – URL to download the PDF
592
- - `base64` (string, optional) – Base64-encoded PDF content
593
-
594
- **Example:**
595
- ```typescript
596
- const pdf = await client.getSignedPdf('txn-123');
597
- if (pdf.url) {
598
- console.log('PDF URL:', pdf.url);
599
- // Download the PDF from the URL
600
- } else if (pdf.base64) {
601
- // Decode and save the base64 PDF
602
- const buffer = Buffer.from(pdf.base64, 'base64');
603
- fs.writeFileSync('invoice.pdf', buffer);
604
- }
605
- ```
606
-
607
- ---
608
-
609
- ## 💡 Common Use Cases
610
-
611
- ### Creating a Complete Invoice Flow
612
-
613
- ```typescript
614
- import { ZataClient } from 'zata-vsdc-sdk';
615
-
616
- const client = new ZataClient({
617
- apiKey: process.env.ZATA_API_KEY!
227
+ ```ts
228
+ const sale = await client.createSaleTransaction({
229
+ paymentMethodID: 1,
230
+ customerID: 1,
231
+ transactionDate: "2026-04-01",
232
+ note: "Sale from SDK",
233
+ items: [{ productID: 1, units: 2, unitPrice: 1000, discountRate: 0 }],
618
234
  });
619
-
620
- async function createInvoice() {
621
- try {
622
- // 1. Create or get a customer
623
- const customer = await client.createParty({
624
- name: 'Acme Customer Ltd',
625
- tin: '123456789',
626
- type: 'customer'
627
- });
628
-
629
- // 2. Create or get products
630
- const product = await client.createProduct({
631
- name: 'Premium Service',
632
- price: 10000,
633
- unit: 'hour'
634
- });
635
-
636
- // 3. Create the invoice
637
- const invoice = await client.createTransaction({
638
- type: 'invoice',
639
- partyId: customer.id,
640
- items: [
641
- {
642
- productId: product.id,
643
- quantity: 5,
644
- unitPrice: 10000
645
- }
646
- ]
647
- });
648
-
649
- console.log(`Invoice created: ${invoice.id}`);
650
-
651
- // 4. Get the signed PDF
652
- const pdf = await client.getSignedPdf(invoice.id);
653
- console.log('PDF available at:', pdf.url);
654
-
655
- return invoice;
656
- } catch (error) {
657
- console.error('Error creating invoice:', error);
658
- throw error;
659
- }
660
- }
661
235
  ```
662
236
 
663
- ### Batch Processing
664
-
665
- ```typescript
666
- async function createMultipleInvoices(invoices: Array<{ customerId: string; items: any[] }>) {
667
- const results = await Promise.allSettled(
668
- invoices.map(data =>
669
- client.createTransaction({
670
- type: 'invoice',
671
- partyId: data.customerId,
672
- items: data.items
673
- })
674
- )
675
- );
676
-
677
- const successful = results
678
- .filter((r): r is PromiseFulfilledResult<any> => r.status === 'fulfilled')
679
- .map(r => r.value);
680
-
681
- const failed = results
682
- .filter((r): r is PromiseRejectedResult => r.status === 'rejected')
683
- .map(r => r.reason);
684
-
685
- console.log(`Created ${successful.length} invoices, ${failed.length} failed`);
686
- return { successful, failed };
687
- }
688
- ```
689
-
690
- ### Error Handling
691
-
692
- ```typescript
693
- async function safeCreateProduct(productData: Partial<Product>) {
694
- try {
695
- const product = await client.createProduct(productData);
696
- return { success: true, data: product };
697
- } catch (error: any) {
698
- // Parse error message
699
- if (error.message.includes('400')) {
700
- return { success: false, error: 'Validation error', details: error.message };
701
- } else if (error.message.includes('401')) {
702
- return { success: false, error: 'Authentication failed' };
703
- } else if (error.message.includes('404')) {
704
- return { success: false, error: 'Resource not found' };
705
- } else {
706
- return { success: false, error: 'Unknown error', details: error.message };
707
- }
708
- }
709
- }
710
- ```
237
+ ### Download invoice PDF
711
238
 
712
- ---
239
+ ```ts
240
+ const signature = await client.getTransactionDownloadSignature(123, { downloadSize: "A4" });
713
241
 
714
- ## 🔧 TypeScript Types
715
-
716
- The SDK exports TypeScript interfaces for all resources:
717
-
718
- ```typescript
719
- import {
720
- ZataClient,
721
- Company,
722
- Branch,
723
- Product,
724
- Party,
725
- Expense,
726
- Transaction,
727
- SignedPdfResponse,
728
- ZataClientOptions
729
- } from 'zata-vsdc-sdk';
242
+ const pdf = await client.downloadTransaction({
243
+ expires: signature.expires,
244
+ id: signature.id,
245
+ signature: signature.signature,
246
+ });
730
247
  ```
731
248
 
732
- ### Available Types
249
+ ## Error handling
733
250
 
734
- - `Company` Company resource
735
- - `Branch` – Branch resource
736
- - `Product` – Product resource
737
- - `Party` – Customer/Supplier resource
738
- - `Expense` – Expense resource
739
- - `Transaction` – Invoice/Receipt/Credit Note resource
740
- - `SignedPdfResponse` – PDF response with URL or base64
741
- - `ZataClientOptions` – Client initialization options
742
- - `ZataResourceMeta` – Base metadata fields for resources
251
+ The client throws normalized errors in this format:
743
252
 
744
- ---
253
+ - `Zata API Error <status>: <response-json>`
254
+ - `Network/Request Error: <message>`
745
255
 
746
- ## ⚠️ Error Handling
747
-
748
- The SDK includes built-in error handling that provides detailed error messages:
749
-
750
- ```typescript
256
+ ```ts
751
257
  try {
752
- await client.getCompany('invalid-id');
753
- } catch (error: any) {
754
- // Error format: "Zata API Error 404: {...}"
258
+ await client.getTransaction(999999);
259
+ } catch (error) {
755
260
  console.error(error.message);
756
261
  }
757
262
  ```
758
263
 
759
- Common error scenarios:
760
-
761
- - **400 Bad Request** – Validation errors (check request data)
762
- - **401 Unauthorized** – Invalid or missing API key
763
- - **404 Not Found** – Resource doesn't exist
764
- - **500 Server Error** – Internal server error (retry with backoff)
765
- - **Network Errors** – Connection issues (check network/API URL)
264
+ ## Best practices
766
265
 
767
- ---
266
+ - Cache lookup/reference data (payment modes, taxes, units)
267
+ - Validate IDs and required fields before calling write endpoints
268
+ - Use `calculateTransaction` before creating high-value invoices
269
+ - Store entity IDs you create (party, product, transaction)
270
+ - Use retries/backoff for transient network or 5xx failures
768
271
 
769
- ## 🌍 Environment Configuration
770
-
771
- For different environments, you can configure the base URL:
772
-
773
- ```typescript
774
- // Production (default)
775
- const prodClient = new ZataClient({
776
- apiKey: process.env.ZATA_API_KEY!
777
- });
778
-
779
- // Staging/Development
780
- const devClient = new ZataClient({
781
- apiKey: process.env.ZATA_API_KEY!,
782
- baseUrl: 'https://staging-api.zata.rw/v1'
783
- });
784
-
785
- // Custom timeout for slow connections
786
- const slowClient = new ZataClient({
787
- apiKey: process.env.ZATA_API_KEY!,
788
- timeout: 60000 // 60 seconds
789
- });
790
- ```
791
-
792
- ---
793
-
794
- ## 🤝 Contributing
795
-
796
- This is an open-source project, and we welcome contributions from the community! Here's how you can help:
797
-
798
- 1. **Report Issues** – Found a bug? [Open an issue](https://github.com/HiQ-Africa/zata-npm/issues)
799
- 2. **Suggest Features** – Have an idea? [Share it with us](https://github.com/HiQ-Africa/zata-npm/issues)
800
- 3. **Submit Pull Requests** – Fixed a bug or added a feature? [Submit a PR](https://github.com/HiQ-Africa/zata-npm/pulls)
801
- 4. **Improve Documentation** – Help make the docs better for everyone
802
-
803
- ### Development Setup
272
+ ## Development
804
273
 
805
274
  ```bash
806
- # Clone the repository
807
- git clone https://github.com/HiQ-Africa/zata-npm.git
808
- cd zata-npm
809
-
810
- # Install dependencies
811
275
  npm install
812
-
813
- # Build the project
814
276
  npm run build
815
-
816
- # Run tests (if available)
817
277
  npm test
818
278
  ```
819
279
 
820
- ### Code Style
821
-
822
- - Use TypeScript for all new code
823
- - Follow existing code style and patterns
824
- - Add JSDoc comments for public methods
825
- - Include examples in documentation
826
-
827
- ---
828
-
829
- ## 📝 License
830
-
831
- This project is licensed under the MIT License – see the [LICENSE](LICENSE) file for details.
832
-
833
- ---
834
-
835
- ## 🙏 Acknowledgments
836
-
837
- - Built for the Rwanda business community
838
- - Powered by [Zata](https://zata.rw) – Rwanda's leading tax compliance platform
839
- - Developed by [HiQ Africa](https://hiq.africa)
840
-
841
- ---
842
-
843
- ## 📞 Support
844
-
845
- - **Documentation**: [https://docs.zata.rw](https://docs.zata.rw)
846
- - **Support Email**: hirwa@hiq.africa
847
- - **GitHub Issues**: [https://github.com/HiQ-Africa/zata-npm/issues](https://github.com/HiQ-Africa/zata-npm/issues)
280
+ ## Links
848
281
 
849
- ---
282
+ - API docs: [https://docs.zata.rw](https://docs.zata.rw)
283
+ - Website: [https://zata.rw](https://zata.rw)
284
+ - npm: [https://www.npmjs.com/package/zata-vsdc-sdk](https://www.npmjs.com/package/zata-vsdc-sdk)
285
+ - GitHub: [https://github.com/HiQ-Africa/zata-npm](https://github.com/HiQ-Africa/zata-npm)
286
+ - Integration guide: [./guide.md](./guide.md)
850
287
 
851
- ## 🔗 Related Resources
288
+ ## Support
852
289
 
853
- - [Zata Official Website](https://zata.rw)
854
- - [Zata API Documentation](https://docs.zata.rw)
855
- - [Implementation Guide](./guide.md) – Detailed step-by-step guide for implementing the Zata API
290
+ - Email: `hirwa@hiq.africa`
291
+ - Issues: [https://github.com/HiQ-Africa/zata-npm/issues](https://github.com/HiQ-Africa/zata-npm/issues)
856
292
 
857
- ---
293
+ ## License
858
294
 
859
- **Made with ❤️ for the Rwanda developer community**
295
+ MIT