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 +186 -750
- package/dist/index.d.ts +118 -0
- package/dist/index.js +240 -0
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -4,27 +4,18 @@
|
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
[](https://www.typescriptlang.org/)
|
|
6
6
|
|
|
7
|
-
A
|
|
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
|
-
##
|
|
10
|
+
## Why use this SDK
|
|
10
11
|
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
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
|
-
##
|
|
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
|
-
##
|
|
36
|
+
## Quick start
|
|
46
37
|
|
|
47
|
-
|
|
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
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
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
|
-
|
|
96
|
-
|
|
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
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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
|
-
|
|
104
|
+
## Authentication and context
|
|
182
105
|
|
|
183
|
-
|
|
106
|
+
Most business endpoints need:
|
|
184
107
|
|
|
185
|
-
|
|
186
|
-
- `
|
|
108
|
+
- `Authorization: Bearer <token>`
|
|
109
|
+
- `companyId`
|
|
110
|
+
- `branchId`
|
|
187
111
|
|
|
188
|
-
|
|
112
|
+
You can define these once at client creation, then update later when needed:
|
|
189
113
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
-
|
|
121
|
+
Recommended sequence for most integrators:
|
|
203
122
|
|
|
204
|
-
|
|
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
|
-
|
|
131
|
+
This mirrors the practical order required by dependent IDs across endpoints.
|
|
207
132
|
|
|
208
|
-
|
|
133
|
+
## API reference (SDK methods)
|
|
209
134
|
|
|
210
|
-
|
|
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
|
-
|
|
137
|
+
- `login(data)`
|
|
138
|
+
- `createAccount(data)`
|
|
139
|
+
- `getTestStatus()`
|
|
219
140
|
|
|
220
|
-
|
|
141
|
+
### Company and branches
|
|
221
142
|
|
|
222
|
-
|
|
223
|
-
- `
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
-
|
|
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
|
-
|
|
155
|
+
- `getPaymentModes()`
|
|
156
|
+
- `getProductCategories()`
|
|
157
|
+
- `getProductClasses()`
|
|
158
|
+
- `getProductCountryOrigins()`
|
|
159
|
+
- `getProductPackagingUnits()`
|
|
160
|
+
- `getProductQuantityUnits()`
|
|
161
|
+
- `getProductTaxes()`
|
|
162
|
+
- `getProductTypes()`
|
|
252
163
|
|
|
253
|
-
|
|
164
|
+
### Parties
|
|
254
165
|
|
|
255
|
-
|
|
256
|
-
- `
|
|
257
|
-
- `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
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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
|
-
|
|
430
|
-
|
|
431
|
-
|
|
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
|
-
|
|
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
|
-
|
|
187
|
+
- `listInsurances()`
|
|
188
|
+
- `createPresetInsurance(data)`
|
|
189
|
+
- `createCustomInsurance(data)`
|
|
190
|
+
- `updateCustomInsurance(insuranceId, data)`
|
|
191
|
+
- `updateBranchInsurance(companyInsuranceId, data)`
|
|
493
192
|
|
|
494
|
-
|
|
495
|
-
- `id` (string) – Expense ID
|
|
193
|
+
### Patients
|
|
496
194
|
|
|
497
|
-
|
|
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
|
-
|
|
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
|
-
|
|
213
|
+
## Transaction examples
|
|
520
214
|
|
|
521
|
-
|
|
522
|
-
- `id` (string) – Transaction ID
|
|
215
|
+
### Calculate before create
|
|
523
216
|
|
|
524
|
-
|
|
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
|
-
|
|
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
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
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
|
-
|
|
249
|
+
## Error handling
|
|
733
250
|
|
|
734
|
-
|
|
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
|
-
|
|
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.
|
|
753
|
-
} catch (error
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
##
|
|
288
|
+
## Support
|
|
852
289
|
|
|
853
|
-
-
|
|
854
|
-
- [
|
|
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
|
-
|
|
295
|
+
MIT
|