ZRA Smart Invoice Integration
Related docs:
Data Models·Order Lifecycle·Payment Architecture·Microservices
1. Overview
Pakashop integrates with the Zambia Revenue Authority (ZRA) Smart Invoice system via the VSDC (Virtual Sales Data Controller) API. The pakashop-invoicing microservice (Node.js, port 3013) handles automated invoice generation, transmission, and logging.
2. Architecture
Order Confirmed (PAID)
│
▼
pakashop-backend (port 3080)
│
├──► Check feature flag: zra_invoicing_enabled
├──► Check vendor TPIN validity
└──► Queue ZRA invoice job (BullMQ)
│
▼
pakashop-invoicing (port 3013)
│
├──► Generate Smart Invoice payload
├──► Sign payload with vendor certificate
├──► Transmit to ZRA VSDC API
│ │
│ ├──► Success: Log transmission receipt
│ └──► Failure: Queue retry (3 attempts)
│
└──► Store result in ZraInvoice table
3. Configuration
3.1 Feature Flags
| Flag | Default | Description |
|---|---|---|
zra_invoicing_enabled | false | Master switch for ZRA integration |
zra_mock_mode | false | Simulate transmissions without calling ZRA API |
3.2 Environment Variables
# ZRA VSDC API
ZRA_VSDC_API_URL=https://vsdc.zra.org.zm/api/v1
ZRA_VSDC_API_KEY=your_api_key
ZRA_VSDC_CLIENT_ID=your_client_id
ZRA_VSDC_CLIENT_SECRET=your_client_secret
# Mock mode
ZRA_MOCK_MODE=false
# Feature flag
FEATURE_FLAGS_REDIS_KEY=pakashop:feature_flags
4. Smart Invoice Payload
4.1 Invoice Structure
{
"invoice": {
"seller": {
"tpin": "1234567890",
"businessName": "Banda Electronics Ltd",
"address": "Plot 123, Cairo Road, Lusaka",
"phone": "+260977123456"
},
"buyer": {
"name": "John Banda",
"address": "Plot 456, Great East Road, Lusaka",
"phone": "+260977654321"
},
"items": [
{
"itemCode": "ELC-001",
"description": "Samsung Galaxy S24",
"quantity": 1,
"unitPrice": 5000.00,
"totalPrice": 5000.00,
"taxCode": "VAT16",
"taxRate": 0.16,
"taxAmount": 689.66,
"discount": 0.00
}
],
"summary": {
"subtotal": 5000.00,
"totalTax": 689.66,
"totalDiscount": 0.00,
"totalAmount": 5689.66,
"currency": "ZMW"
},
"payment": {
"method": "MOBILE_MONEY",
"transactionId": "pawa-debit-abc123",
"amount": 5689.66
},
"invoiceNumber": "PKS-20260512-001",
"invoiceDate": "2026-05-12T10:00:00Z",
"vsdcNumber": "VSDC-123456789"
}
}
4.2 Field Mapping
| ZRA Field | Pakashop Source |
|---|---|
seller.tpin | Shop.tpin |
seller.businessName | Shop.name |
buyer.name | Order.shippingAddress.firstName + lastName |
items.itemCode | Product.zraItemCode |
items.taxCode | Product.zraTaxCode or default VAT16 |
items.taxRate | 0.16 (16% VAT) |
invoiceNumber | Auto-generated: PKS-{YYYYMMDD}-{SEQUENCE} |
vsdcNumber | Returned by ZRA API on successful transmission |
5. Transmission Flow
5.1 Normal Flow
5.2 Mock Mode Flow
5.3 Retry Logic
| Attempt | Delay | Action |
|---|---|---|
| 1 | Immediate | Initial transmission |
| 2 | 5 minutes | First retry |
| 3 | 15 minutes | Second retry |
| 4 | 1 hour | Final retry |
| Fail | — | transmissionStatus = FAILED; admin notified |
6. Data Model
model ZraInvoice {
id String @id @default(cuid())
orderId String @unique
tpin String
vsdcNumber String?
invoiceNumber String @unique
payload Json
transmissionStatus String @default("PENDING") // PENDING, SENT, FAILED, MOCK
responsePayload Json?
retryCount Int @default(0)
lastRetryAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
order Order @relation(fields: [orderId], references: [id])
}
7. Admin Dashboard
7.1 Transmission Log
The admin dashboard displays:
- All ZRA transmissions with status filters
- Failed transmissions with retry options
- Per-vendor TPIN validation status
- Monthly transmission statistics
7.2 Actions
| Action | Description |
|---|---|
| View Details | See full payload and response |
| Retry | Manually trigger re-transmission |
| Download | Export invoice as PDF |
| Validate TPIN | Check vendor TPIN against ZRA registry |
8. API Endpoints
8.1 Internal Endpoints (Backend → Invoicing Service)
| Method | Path | Description |
|---|---|---|
POST | /internal/generate | Queue invoice generation for order |
POST | /internal/retry/:id | Retry failed transmission |
8.2 Admin Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /admin/zra/transmissions | PLATFORM_ADMIN, FINANCE_ADMIN | List all transmissions |
GET | /admin/zra/transmissions/:id | PLATFORM_ADMIN, FINANCE_ADMIN | Get transmission details |
POST | /admin/zra/retransmit/:id | PLATFORM_ADMIN, FINANCE_ADMIN | Retry failed transmission |
POST | /admin/zra/validate-tpin | PLATFORM_ADMIN, FINANCE_ADMIN | Validate vendor TPIN |
9. Monitoring
| Metric | Description | Alert Threshold |
|---|---|---|
zra_transmission_success_rate | Percentage of successful transmissions | < 95% |
zra_transmission_latency_ms | Time to transmit and receive response | > 5000ms p95 |
zra_failed_transmissions | Count of failed transmissions | > 5/day |
zra_mock_transmissions | Count of mock transmissions | Track for testing |
zra_invalid_tpin_count | Vendors with invalid TPINs | > 0 |
10. Compliance Notes
- All invoices must be transmitted within 24 hours of order confirmation.
- Failed transmissions must be resolved within 72 hours.
- Mock mode should only be enabled in staging and local development.
- Production ZRA API credentials must be rotated quarterly.
- Invoice payloads are retained for 7 years per ZRA requirements.
For internal use only. Do not distribute outside Pakashop engineering.