NRS E-Invoicing
Overview
Yona serves as both a System Integrator (SI) and an Access Point Provider (APP) for Nigeria’s e-invoicing mandate under the Federal Inland Revenue Service (FIRS), operating through the Nigeria Revenue Service (NRS) platform.
As a System Integrator, Yona standardizes invoice data from your systems into the NRS-compliant format, validates fields, and computes tax totals. As an Access Point Provider, Yona generates Invoice Reference Numbers (IRNs), digitally signs invoices, transmits them to the NRS, and routes status updates back to your application.
Through Yona’s API, businesses can create, sign, and submit invoices to the NRS without building a direct integration. Yona handles:
- Invoice Reference Number (IRN) generation
- Digital signing (ECDSA or RSA)
- Payload transformation to NRS-compliant format
- Transmission to and routing from the NRS
- Status tracking via webhooks
- PDF generation with embedded QR code and IRN for NRS compliance
How it works
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────────────────┐
│ Create │────>│ Submit │────>│ Yona │────>│ NRS responds │
│ (draft) │ │ (queued) │ │ signs │ │ accepted / rejected │
└──────────┘ └──────────┘ │ (pending)│ │ / failed │
└──────────┘ └───────────────────────┘- Register your seller and buyer. Each must have a valid TIN, email, and postal address. Sellers require a verified TIN for submission. Use the tax ID lookup endpoint to verify TINs before submission.
- Create a draft invoice. Provide seller, buyer, line items with HSN codes, quantities, unit prices, and tax rates. Yona auto-calculates line totals, tax amounts, and monetary totals. Status:
draft. - Submit the invoice. Yona validates against NRS requirements, generates an IRN, and queues for processing. Status:
queued. - Yona processes the submission. The invoice is transformed to the NRS payload format, digitally signed, and transmitted to the NRS. Status:
pending. - NRS responds. The tax authority validates and accepts or rejects the invoice. Yona updates the invoice status and dispatches a webhook event to your endpoint (
invoice.approved,invoice.rejected, orinvoice.submission_failed). - Download or query. Once accepted, download the invoice as PDF (which includes the NRS QR code and IRN) or query real-time status from the tax authority.
Use sk_test_* API keys to test the full submission flow without hitting the live NRS. See Sandbox vs Production.
Use POST /i/v1/invoices/validate to check your invoice data against NRS requirements before creation. This catches issues early without consuming credits.
Cancellation
You cannot delete or modify an invoice after NRS acceptance. To void an accepted invoice, call POST /i/v1/invoices/:id/cancel. Yona automatically creates a credit note (NRS code 381) on your behalf. This is the only NRS-compliant path for voiding accepted invoices.
Rendered invoice example
The image below shows a sample human-readable tax invoice generated by the platform after a successful submission. The Tax Information section at the bottom contains the IRN and the QR code returned by the API. Both must appear on every printed invoice for NRS compliance and verifiability.

QR code
After a successful submission, the NRS returns a QR code for the invoice. This QR code is:
- Embedded in the generated PDF
- Required on every printed invoice for NRS compliance and verifiability
The QR code allows anyone to scan and verify the invoice’s authenticity against the NRS.
Invoice Reference Number (IRN)
Format: {invoiceNumber}-{hash}-{dateStr}
Yona generates the IRN deterministically from your invoice number, invoice date, and organization ID. Same inputs always produce the same reference.
Example: INV-2026-001-A1B2C3D4-20260115
NRS payload structure
When you submit an invoice, Yona automatically maps your seller, buyer, and line item data to the NRS-compliant format. Understanding what the NRS requires helps you provide the right data upfront.
Supplier party (mandatory)
Yona maps this from your registered seller.
| NRS field | Description | Required |
|---|---|---|
party_name | Legal business name | Yes |
tin | Tax Identification Number | Yes |
email | Contact email | Yes |
telephone | Contact phone number | No |
postal_address.street_name | Street address | Yes |
postal_address.city_name | City | Yes |
postal_address.postal_zone | Postal/ZIP code | Yes |
postal_address.state | State (ISO 3166-2, e.g. NG-LA) | No |
postal_address.lga | Local Government Area | No |
postal_address.country | Country (ISO 3166-1, e.g. NG) | Yes |
Customer party
Same structure as supplier. Yona maps this from your registered buyer. Buyer TIN is optional (consumers may not have one).
Line items (mandatory, minimum 1)
| NRS field | Description | Notes |
|---|---|---|
item.description | Description of goods or services | Mandatory |
invoiced_quantity.value | Quantity | Min 0.001 |
invoiced_quantity.unit_code | Unit of measure | EA, KGM, HUR, LTR, etc. |
price.price_amount | Price per unit | Mandatory |
line_extension_amount | Line total before tax | Auto-calculated (quantity * unitPrice) |
item.classified_tax_category.id | Tax category | S (standard), Z (zero), E (exempt) |
item.classified_tax_category.percent | Tax rate | e.g. 7.5 |
tax_total.tax_amount | Line-level tax amount | Auto-calculated |
For supported unit codes and HSN codes, see Invoices API.
Invoice type codes
| Yona type | NRS code | Description |
|---|---|---|
standard | 380 | Commercial invoice |
credit_note | 381 | Credit note (refund) |
debit_note | 383 | Debit note (additional charges) |
prepayment | 386 | Prepayment invoice |
Invoice kinds
The NRS classifies invoices by transaction type: B2B (business-to-business), B2C (business-to-consumer), or B2G (business-to-government). This affects validation rules. For example, B2C invoices do not require a buyer TIN. Yona determines the kind automatically based on the buyer’s party type.
Tax categories
| Code | Name | Typical rate |
|---|---|---|
S | Standard rate | 7.5% |
Z | Zero rate | 0% |
E | Exempt | 0% |
Monetary totals (mandatory)
All auto-calculated from line items:
| NRS field | Description |
|---|---|
line_extension_amount | Sum of all line item amounts (before tax) |
tax_exclusive_amount | Total before tax |
tax_inclusive_amount | Total after tax |
allowance_total_amount | Document-level discounts |
charge_total_amount | Document-level surcharges |
payable_amount | Final amount due |
You don’t need to calculate totals manually. Provide quantity, unitPrice, and taxPercent per line item, plus optional allowanceAmount and chargeAmount at document level. Yona computes everything else.
Digital signing and security
Invoice signing
Every invoice is digitally signed before transmission to the NRS:
- Algorithm: ECDSA (default) or RSA, configurable per environment
- Curve:
prime256v1(ECDSA default) - Output: A Cryptographic Stamp ID (CSID) stored in
regulatoryData.cryptographicStamp - Non-repudiation: The CSID proves the invoice was submitted by an authorized integrator and has not been tampered with
Webhook events
Yona dispatches webhook events as invoices move through submission. Events are filtered by API mode: sandbox invoices only trigger webhooks on sandbox endpoints.
| Event | Trigger |
|---|---|
invoice.approved | Tax authority accepted the invoice |
invoice.rejected | Tax authority rejected with validation errors |
invoice.submission_failed | Submission failed (network error, timeout, authority unavailable) |
NRS status mapping
The NRS sends status updates to Yona, which are mapped to invoice statuses:
| NRS message | Yona status | Description |
|---|---|---|
TRANSMITTING | No change (stays pending) | Invoice is being transmitted. Informational only. |
TRANSMITTED | No change (stays pending) | Invoice delivered to recipient. Informational only. |
ACKNOWLEDGED | accepted | Buyer’s system (or their Access Point Provider) confirmed receipt. Not automatic. |
FAILED | failed | Transmission failed. Check regulatoryData.validationErrors. |
TRANSMITTING and TRANSMITTED are progress signals only. The invoice stays in pending until the recipient explicitly acknowledges it (ACKNOWLEDGED) or the transmission fails (FAILED).
See Webhooks for setup and payload details.
Related pages
- Invoice Lifecycle for the full status diagram, transitions, and retry behavior
- Credits and Billing for credit costs per operation and balance management
- Invoices API for endpoints, supported unit codes, and HSN code search
- Sellers
- Buyers