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
- 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. - Finalise the invoice. Lock the draft to freeze totals and prepare it for submission. Status:
finalised. This does not require an NRS connection. - Submit the invoice. Requires an active NRS connection (
status: CONNECTED). 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}-{serviceId}-{dateStr}
| Component | Description | Example |
|---|---|---|
invoiceNumber | Your invoice number | INV001 |
serviceId | 8-character NRS Service ID assigned to your organization at enablement | 94ND90NR |
dateStr | Invoice date in YYYYMMDD format | 20240611 |
Example: INV001-94ND90NR-20240611
The Service ID is assigned by NRS when your organization connects to the tax authority. Yona generates the IRN automatically at submission time.
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)
Each line item requires either an HS code (for goods) or an ISIC code (for services).
Goods classification
| NRS field | Description | Notes |
|---|---|---|
hsn_code | Harmonized System code | Dotted format, e.g. 1006.30. From NRS /resources/hs-codes. |
product_category | Full HS code description | e.g. "Cereals; rice, semi-milled or wholly milled..." |
Service classification (alternative)
| NRS field | Description | Notes |
|---|---|---|
isic_code | ISIC classification code | e.g. 0112 |
service_category | Full ISIC code description | e.g. "Growing of rice" |
Item and pricing fields
| NRS field | Description | Notes |
|---|---|---|
invoiced_quantity | Quantity | Number, min 0 |
line_extension_amount | Line total before tax | Auto-calculated |
item.name | Item name | Mandatory |
item.description | Item description | Mandatory |
price.price_amount | Price per unit | Mandatory |
price.base_quantity | Base quantity for pricing | e.g. 3 (price per 3 units) |
price.price_unit | Unit of measure code | UBL code: EA, KGM, XBG, LTR, etc. |
discount_rate | Discount percentage | Defaults to 0 |
discount_amount | Discount amount | Defaults to 0 |
fee_rate | Fee/surcharge percentage | Defaults to 0 |
fee_amount | Fee/surcharge amount | Defaults to 0 |
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 |
|---|---|---|
STANDARD_VAT | Standard Value-Added Tax | 7.5% |
ZERO_VAT | Zero-rated VAT | 0% |
EXEMPTED | Tax exempt | 0% |
NRS supports additional tax categories including WITHHOLDING_TAX, SERVICE_TAX, STAMP_DUTY, IMPORT_DUTY, EXPORT_DUTY, and others. Use GET /i/v1/invoices/resources/tax-categories to retrieve the full list. Yona passes any valid tax category code through to the authority.
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.
API endpoints
Base path: https://gateway.useyona.com/i/v1/invoices
Invoice lifecycle
| Method | Endpoint | Description |
|---|---|---|
POST | /i/v1/invoices | Create a draft invoice |
POST | /i/v1/invoices/validate | Validate invoice data without creating it |
GET | /i/v1/invoices | List invoices with filters and pagination |
GET | /i/v1/invoices/:id | Retrieve a single invoice |
PATCH | /i/v1/invoices/:id | Update a draft invoice |
DELETE | /i/v1/invoices/:id | Delete a draft invoice |
POST | /i/v1/invoices/:id/finalise | Lock a draft for submission |
POST | /i/v1/invoices/:id/send | Send a finalised invoice to the buyer |
POST | /i/v1/invoices/:id/submit | Queue for submission to the tax authority |
POST | /i/v1/invoices/batch-submit | Submit multiple invoices at once (max 100) |
POST | /i/v1/invoices/:id/retry | Retry a failed submission |
POST | /i/v1/invoices/:id/cancel | Cancel an accepted invoice (creates credit note) |
Status and download
| Method | Endpoint | Description |
|---|---|---|
GET | /i/v1/invoices/:id/status | Get current invoice status (local, fast) |
POST | /i/v1/invoices/:id/query-status | Query real-time status from the tax authority |
GET | /i/v1/invoices/:id/download | Get a download URL for the invoice PDF or XML |
GET | /i/v1/invoices/statistics | Get invoice counts and totals by status |
Tax authority and reference data
| Method | Endpoint | Description |
|---|---|---|
GET | /i/v1/invoices/lookup/tax-id/:value | Look up a taxpayer by TIN |
POST | /i/v1/invoices/reference/validate | Validate an invoice reference against the tax authority |
POST | /i/v1/invoices/:id/tax-report | Submit a VAT report for an invoice |
GET | /i/v1/invoices/resources | Get all reference data (countries, currencies, tax categories, HSN codes) |
GET | /i/v1/invoices/resources/:type | Get a single resource type |
GET | /i/v1/invoices/hsn-codes | Search HSN/tax classification codes |
GET | /i/v1/invoices/hsn-codes/categories | List HSN code categories |
For full request/response documentation, see Invoices API.
Example: create and submit an invoice
1. Create a draft invoice
POST /i/v1/invoices
2. Finalise the invoice
POST /i/v1/invoices/:id/finalise
No request body. Locks the invoice and freezes totals. Returns the full invoice with status: "finalised".
3. Submit to the tax authority
POST /i/v1/invoices/:id/submit
No request body. Requires an active NRS connection.
NRS payload (generated by Yona at submission)
When Yona processes the submission, it transforms your invoice into the following NRS-compliant format and sends it to POST /api/v1/invoice/sign:
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