Skip to Content
NRS E-Invoicing

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

NRS submission flow: Create → Finalise → Submit → Yona signs → NRS responds

  1. 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.
  2. 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.
  3. Finalise the invoice. Lock the draft to freeze totals and prepare it for submission. Status: finalised. This does not require an NRS connection.
  4. Submit the invoice. Requires an active NRS connection (status: CONNECTED). Yona validates against NRS requirements, generates an IRN, and queues for processing. Status: queued.
  5. Yona processes the submission. The invoice is transformed to the NRS payload format, digitally signed, and transmitted to the NRS. Status: pending.
  6. 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, or invoice.submission_failed).
  7. 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.
💡 Start in sandbox

Use sk_test_* API keys to test the full submission flow without hitting the live NRS. See Sandbox vs Production.

💡 Pre-validate before creating

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.

Sample FIRS-compliant Tax Invoice

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}

ComponentDescriptionExample
invoiceNumberYour invoice numberINV001
serviceId8-character NRS Service ID assigned to your organization at enablement94ND90NR
dateStrInvoice date in YYYYMMDD format20240611

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 fieldDescriptionRequired
party_nameLegal business nameYes
tinTax Identification NumberYes
emailContact emailYes
telephoneContact phone numberNo
postal_address.street_nameStreet addressYes
postal_address.city_nameCityYes
postal_address.postal_zonePostal/ZIP codeYes
postal_address.stateState (ISO 3166-2, e.g. NG-LA)No
postal_address.lgaLocal Government AreaNo
postal_address.countryCountry (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 fieldDescriptionNotes
hsn_codeHarmonized System codeDotted format, e.g. 1006.30. From NRS /resources/hs-codes.
product_categoryFull HS code descriptione.g. "Cereals; rice, semi-milled or wholly milled..."

Service classification (alternative)

NRS fieldDescriptionNotes
isic_codeISIC classification codee.g. 0112
service_categoryFull ISIC code descriptione.g. "Growing of rice"

Item and pricing fields

NRS fieldDescriptionNotes
invoiced_quantityQuantityNumber, min 0
line_extension_amountLine total before taxAuto-calculated
item.nameItem nameMandatory
item.descriptionItem descriptionMandatory
price.price_amountPrice per unitMandatory
price.base_quantityBase quantity for pricinge.g. 3 (price per 3 units)
price.price_unitUnit of measure codeUBL code: EA, KGM, XBG, LTR, etc.
discount_rateDiscount percentageDefaults to 0
discount_amountDiscount amountDefaults to 0
fee_rateFee/surcharge percentageDefaults to 0
fee_amountFee/surcharge amountDefaults to 0

For supported unit codes and HSN codes, see Invoices API.

Invoice type codes

Yona typeNRS codeDescription
standard380Commercial invoice
credit_note381Credit note (refund)
debit_note383Debit note (additional charges)
prepayment386Prepayment 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

CodeNameTypical rate
STANDARD_VATStandard Value-Added Tax7.5%
ZERO_VATZero-rated VAT0%
EXEMPTEDTax exempt0%

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 fieldDescription
line_extension_amountSum of all line item amounts (before tax)
tax_exclusive_amountTotal before tax
tax_inclusive_amountTotal after tax
allowance_total_amountDocument-level discounts
charge_total_amountDocument-level surcharges
payable_amountFinal amount due
Auto-calculated totals

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.

EventTrigger
invoice.approvedTax authority accepted the invoice
invoice.rejectedTax authority rejected with validation errors
invoice.submission_failedSubmission failed (network error, timeout, authority unavailable)

NRS status mapping

The NRS sends status updates to Yona, which are mapped to invoice statuses:

NRS messageYona statusDescription
TRANSMITTINGNo change (stays pending)Invoice is being transmitted. Informational only.
TRANSMITTEDNo change (stays pending)Invoice delivered to recipient. Informational only.
ACKNOWLEDGEDacceptedBuyer’s system (or their Access Point Provider) confirmed receipt. Not automatic.
FAILEDfailedTransmission 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

MethodEndpointDescription
POST/i/v1/invoicesCreate a draft invoice
POST/i/v1/invoices/validateValidate invoice data without creating it
GET/i/v1/invoicesList invoices with filters and pagination
GET/i/v1/invoices/:idRetrieve a single invoice
PATCH/i/v1/invoices/:idUpdate a draft invoice
DELETE/i/v1/invoices/:idDelete a draft invoice
POST/i/v1/invoices/:id/finaliseLock a draft for submission
POST/i/v1/invoices/:id/sendSend a finalised invoice to the buyer
POST/i/v1/invoices/:id/submitQueue for submission to the tax authority
POST/i/v1/invoices/batch-submitSubmit multiple invoices at once (max 100)
POST/i/v1/invoices/:id/retryRetry a failed submission
POST/i/v1/invoices/:id/cancelCancel an accepted invoice (creates credit note)

Status and download

MethodEndpointDescription
GET/i/v1/invoices/:id/statusGet current invoice status (local, fast)
POST/i/v1/invoices/:id/query-statusQuery real-time status from the tax authority
GET/i/v1/invoices/:id/downloadGet a download URL for the invoice PDF or XML
GET/i/v1/invoices/statisticsGet invoice counts and totals by status

Tax authority and reference data

MethodEndpointDescription
GET/i/v1/invoices/lookup/tax-id/:valueLook up a taxpayer by TIN
POST/i/v1/invoices/reference/validateValidate an invoice reference against the tax authority
POST/i/v1/invoices/:id/tax-reportSubmit a VAT report for an invoice
GET/i/v1/invoices/resourcesGet all reference data (countries, currencies, tax categories, HSN codes)
GET/i/v1/invoices/resources/:typeGet a single resource type
GET/i/v1/invoices/hsn-codesSearch HSN/tax classification codes
GET/i/v1/invoices/hsn-codes/categoriesList 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

bash
curl -X POST https://gateway.useyona.com/i/v1/invoices \
  -H "Authorization: Bearer sk_test_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "sellerId": "c7a1d3e5-8f2b-4a6c-9d0e-1f2a3b4c5d6e",
    "buyerId": "d8b2e4f6-9a3c-5b7d-0e1f-2a3b4c5d6e7f",
    "invoiceNumber": "INV-2026-001",
    "invoiceDate": "2026-04-30",
    "dueDate": "2026-05-30",
    "currency": "NGN",
    "lineItems": [
      {
        "description": "Bags of premium rice",
        "hsnCode": "1006.30",
        "productCategory": "Cereals; rice, semi-milled or wholly milled, whether or not polished or glazed",
        "quantity": 15,
        "unitCode": "XBG",
        "unitPrice": 45000,
        "taxPercent": 7.5
      },
      {
        "description": "IT consulting services",
        "isicCode": "6201",
        "serviceCategory": "Computer programming activities",
        "quantity": 40,
        "unitCode": "HUR",
        "unitPrice": 15000,
        "taxPercent": 7.5
      }
    ],
    "paymentTerms": "Net 30"
  }'

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".

bash
curl -X POST https://gateway.useyona.com/i/v1/invoices/a1b2c3d4-e5f6-7890-abcd-ef1234567890/finalise \
  -H "Authorization: Bearer sk_test_your_key_here"

3. Submit to the tax authority

POST /i/v1/invoices/:id/submit

No request body. Requires an active NRS connection.

bash
curl -X POST https://gateway.useyona.com/i/v1/invoices/a1b2c3d4-e5f6-7890-abcd-ef1234567890/submit \
  -H "Authorization: Bearer sk_test_your_key_here"

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:


Last updated on