All integrations
NRS e-InvoicingPublic documentation

WiseWage NRS e-Invoicing integration

Technical documentation for WiseWage's controlled system-integrator workflow with the Nigeria Revenue Service Merchant Buyer Solution.

Documentation status

Version 1.2

Last reviewed September 19, 2026

Service-level agreement
Scope clarification: this page describes how WiseWage operates as a system integrator. It does not advertise a customer-callable public WiseWage API. Customers use the authenticated WiseWage application; WiseWage's server communicates with NRS.

Purpose

Overview

WiseWage supports a controlled B2B commercial-invoice lifecycle: taxpayer setup, invoice drafting, NRS validation, internal approval, fiscalization, final PDF generation, and creation of one linked, unposted accounting-register row.

Draft creation and internal approval are WiseWage controls. Reference-resource checks, NRS validation, signing and confirmation call the configured NRS environment. General-ledger posting remains a separate Management Accounts approval step. Accounting checks can return the register row to Pending, for example if the invoice date is outside the selected period or a required currency is missing; this does not undo NRS fiscalization.

Connection

Authentication

WiseWage authenticates to NRS from its server using environment-specific API credentials owned by the invoice seller (the taxpayer). Requests use x-api-key and x-api-secret headers. The API key and client secret are never embedded in browser code or displayed to company users.

Each managed business separately records its NRS-issued BusinessID and Taxpayer Service ID. These identifiers and the API credentials must belong to the same taxpayer in the selected environment. Copy Business ID from the taxpayer portal, not Entity ID. The eight-character Taxpayer Service ID forms the middle component of the IRN. WiseWage's SI account credentials are not a substitute for the taxpayer's keys.

Credentials, secrets, private keys, and real taxpayer identifiers are intentionally omitted from this public documentation.

Deployment

Sandbox and production environments

EnvironmentPurposeControls
SandboxIntegration testing, schema validation, and onboarding evidence.Separate NRS URL and credentials; records are visibly identified as sandbox activity.
ProductionLive fiscalization after NRS approval and customer enablement.Environment-specific credentials bound to the configured taxpayer business and service ID, HTTPS, restricted server access, and explicit activation. Another business cannot borrow those credentials.

Invoice validation, signing and confirmation have completed successfully in the configured sandbox, with a linked final PDF and Invoice Register entry. This verifies the tested commercial-invoice workflow, not every adjustment, recovery or delivery scenario. Sandbox readiness does not imply production activation. Production use depends on NRS approval, valid production credentials, and enablement of the applicable taxpayer.

Lifecycle

Supported operations

  1. 1Associate an enabled taxpayer BusinessID and Taxpayer Service ID.
  2. 2Load supported NRS states, LGAs, product/service classifications, and tax treatments.
  3. 3Create an internal B2B commercial-invoice draft and permanent WiseWage invoice number.
  4. 4Generate an IRN and validate the invoice structure with NRS.
  5. 5Correct and resubmit validation failures while retaining prior attempts.
  6. 6Approve a validated invoice through WiseWage's internal control.
  7. 7Fiscalize once and retain the NRS response and verification details.
  8. 8Cancel eligible drafts without deleting their invoice number or audit history.
  9. 9Create linked credit/debit note drafts with their own validation, approval and fiscalization controls.
  10. 10Download the final PDF from e-Invoicing or the linked transaction Supporting documents.
  11. 11Identify generated register rows by their e-Invoicing source and validate accounting fields before posting.
  12. 12Run Check and save results to compare saved fiscal evidence, register amounts and current ledger/output VAT.

Credit/debit note controls are implemented; their end-to-end sandbox acceptance is not claimed by the successful commercial-invoice test. Fiscalized cancellation is not enabled. Reconciliation is user-triggered and does not amend records, reconcile filed VAT returns or transmit invoices to buyers.

API reference

Create Invoice request and NRS payload

This reference documents the current WiseWage B2B commercial-invoice implementation against NRS v1.1. Draft creation is internal; the external operation documented by NRS is invoice validation. The examples contain fictional identities and cannot be submitted as enabled taxpayers.

Create Invoice: authenticated WiseWage draft request

POST /api/admin/management-accounting/e-invoicing with action: createDraft. Requires a signed-in, authorised Management Accounts user and company/entity access; this is not an API-key-based public customer endpoint. Select an open period and configured accounts. The seller comes from the saved NRS business profile; the server assigns the permanent invoice number and IRN and calculates amounts.

The scope identifiers, customer, issue date, buyer fiscal details, account mappings and at least one line are required. Company Code and Cost Center follow the managed business classification rules; Output VAT is required for taxable lines. Due date, buyer reference, narration, business description and seller item reference are optional. This example includes all fields accepted by the draft form.

Complete Create Invoice request example

{
  "action": "createDraft",
  "companyId": "<authorised-company-id>",
  "entityId": "<managed-business-id>",
  "periodId": "<open-period-id>",
  "draft": {
    "customerId": "<active-customer-id>",
    "issueDate": "2026-09-06",
    "dueDate": "2026-10-06",
    "currency": "NGN",
    "paymentMeansCode": "30",
    "buyerReference": "PO-DEMO-2026-0001",
    "narration": "Fictional sample",
    "companyCode": "<configured-company-code>",
    "costCenterCode": "<eligible-cost-center>",
    "revenueAccountCode": "<revenue-account>",
    "receivableAccountCode": "<receivable-account>",
    "outputVatAccountCode": "<output-vat-account>",
    "buyer": {
      "taxId": "10000002-0001",
      "email": "accounts@meridian-trade.example",
      "telephone": "+2348020000002",
      "businessDescription": "Fictional wholesale and distribution business",
      "streetName": "25 Demonstration Commerce Road",
      "cityName": "Lagos",
      "postalZone": "101233",
      "lgaCode": "NG-LA-LMA",
      "stateCode": "NG-LA",
      "countryCode": "NG"
    },
    "lines": [
      {
        "entryMode": "QUANTITY",
        "description": "Software integration service",
        "quantity": 2,
        "unitPrice": 150000,
        "unitCode": "EA",
        "itemType": "SERVICE",
        "classificationCode": "6201",
        "classificationName": "Computer programming activities",
        "sellerItemReference": "SVC-DEMO-001",
        "taxCategoryCode": "STANDARD_VAT"
      }
    ]
  }
}

NRS invoice validation request

POST {NRS_API_BASE_URL}/api/v1/invoice/validate. Use the API origin and credentials issued for the selected environment, not the documentation website. Authentication is server-side using the two headers below. Never expose credentials in browser code or submission documents.

curl --request POST "$NRS_API_BASE_URL/api/v1/invoice/validate" \
  --header "Content-Type: application/json" \
  --header "Accept: application/json" \
  --header "x-api-key: <NRS_API_KEY>" \
  --header "x-api-secret: <NRS_API_SECRET>" \
  --data-binary @invoice.json

Save the complete example below as invoice.json. Replace fictional identities with authorised sandbox fixtures before a sandbox submission.

{
  "business_id": "9f36d708-4c91-4e2a-92c8-7a75f418b603",
  "irn": "INV00000001-A1B2C3D4-20260906",
  "issue_date": "2026-09-06",
  "due_date": "2026-10-06",
  "invoice_type_code": "381",
  "invoice_kind": "B2B",
  "payment_status": "PENDING",
  "note": "Fictional sample prepared solely for NRS system-integration review.",
  "tax_point_date": "2026-09-06",
  "document_currency_code": "NGN",
  "tax_currency_code": "NGN",
  "buyer_reference": "PO-DEMO-2026-0001",
  "order_reference": "PO-DEMO-2026-0001",
  "accounting_supplier_party": {
    "party_name": "Acacia Systems Nigeria Limited",
    "tin": "10000001-0001",
    "email": "billing@acacia-systems.example",
    "telephone": "+2348010000001",
    "business_description": "Business software implementation and support services",
    "postal_address": {
      "street_name": "10 Sample Technology Avenue",
      "city_name": "Ikeja",
      "postal_zone": "100001",
      "lga": "NG-LA-IKE",
      "state": "NG-LA",
      "country": "NG"
    }
  },
  "accounting_customer_party": {
    "party_name": "Meridian Trade Services Limited",
    "tin": "10000002-0001",
    "email": "accounts@meridian-trade.example",
    "telephone": "+2348020000002",
    "business_description": "Fictional wholesale and distribution business",
    "postal_address": {
      "street_name": "25 Demonstration Commerce Road",
      "city_name": "Lagos",
      "postal_zone": "101233",
      "lga": "NG-LA-LMA",
      "state": "NG-LA",
      "country": "NG"
    }
  },
  "payment_means": [
    {
      "payment_means_code": "30",
      "payment_due_date": "2026-10-06"
    }
  ],
  "tax_total": [
    {
      "tax_amount": 22500,
      "tax_subtotal": [
        {
          "taxable_amount": 300000,
          "tax_amount": 22500,
          "tax_category": {
            "id": "STANDARD_VAT",
            "percent": 7.5
          }
        }
      ]
    }
  ],
  "legal_monetary_total": {
    "line_extension_amount": 300000,
    "tax_exclusive_amount": 300000,
    "tax_inclusive_amount": 322500,
    "payable_amount": 322500
  },
  "invoice_line": [
    {
      "isic_code": "6201",
      "service_category": "Computer programming activities",
      "invoiced_quantity": 2,
      "line_extension_amount": 300000,
      "item": {
        "name": "Configuration and integration of a fictional business software environment",
        "description": "Configuration and integration of a fictional business software environment",
        "sellers_item_identification": "SVC-DEMO-001"
      },
      "price": {
        "price_amount": 150000,
        "base_quantity": 1,
        "price_unit": "EA"
      }
    }
  ]
}

Supported request fields, including nested structures

Requiredness below describes WiseWage's B2B payload, which requires buyer details. Optional parent objects may be omitted; their required children apply when supplied. Goods use HSN/product category; services use ISIC/service category. Monetary values are JSON numbers, rounded to two decimal places. Line totals, VAT subtotals and payable totals must reconcile.

business_id

Type: string

Requirement: Required

uuid

irn

Type: string

Requirement: Required

Up to 80 characters

issue_date

Type: string

Requirement: Required

date

due_date

Type: string

Requirement: Optional

date

invoice_type_code

Type: string

Requirement: Required

381 / 380 / 384

invoice_kind

Type: string

Requirement: Required

Value: B2B

payment_status

Type: string

Requirement: Optional

Value: PENDING

note

Type: string

Requirement: Optional

See sample and schema

tax_point_date

Type: string

Requirement: Optional

date

document_currency_code

Type: string

Requirement: Required

Up to 3 characters

tax_currency_code

Type: string

Requirement: Required

Up to 3 characters

buyer_reference

Type: string

Requirement: Optional

Up to 225 characters

order_reference

Type: string

Requirement: Optional

Up to 255 characters

accounting_supplier_party

Type: object

Requirement: Required

See sample and schema

accounting_supplier_party.party_name

Type: string

Requirement: Required when parent is supplied

Up to 255 characters

accounting_supplier_party.tin

Type: string

Requirement: Required when parent is supplied

See sample and schema

accounting_supplier_party.email

Type: string

Requirement: Required when parent is supplied

email; Up to 100 characters

accounting_supplier_party.telephone

Type: string

Requirement: Optional

Up to 100 characters

accounting_supplier_party.business_description

Type: string

Requirement: Optional

Up to 255 characters

accounting_supplier_party.postal_address

Type: object

Requirement: Required when parent is supplied

See sample and schema

accounting_supplier_party.postal_address.street_name

Type: string

Requirement: Required when parent is supplied

Up to 255 characters

accounting_supplier_party.postal_address.city_name

Type: string

Requirement: Required when parent is supplied

Up to 100 characters

accounting_supplier_party.postal_address.postal_zone

Type: string

Requirement: Required when parent is supplied

Up to 20 characters

accounting_supplier_party.postal_address.lga

Type: string

Requirement: Required when parent is supplied

Up to 100 characters

accounting_supplier_party.postal_address.state

Type: string

Requirement: Required when parent is supplied

Up to 100 characters

accounting_supplier_party.postal_address.country

Type: string

Requirement: Required when parent is supplied

Up to 2 characters

accounting_customer_party

Type: object

Requirement: Required

See sample and schema

accounting_customer_party.party_name

Type: string

Requirement: Required when parent is supplied

Up to 255 characters

accounting_customer_party.tin

Type: string

Requirement: Required when parent is supplied

See sample and schema

accounting_customer_party.email

Type: string

Requirement: Required when parent is supplied

email; Up to 100 characters

accounting_customer_party.telephone

Type: string

Requirement: Optional

Up to 100 characters

accounting_customer_party.business_description

Type: string

Requirement: Optional

Up to 255 characters

accounting_customer_party.postal_address

Type: object

Requirement: Required when parent is supplied

See sample and schema

accounting_customer_party.postal_address.street_name

Type: string

Requirement: Required when parent is supplied

Up to 255 characters

accounting_customer_party.postal_address.city_name

Type: string

Requirement: Required when parent is supplied

Up to 100 characters

accounting_customer_party.postal_address.postal_zone

Type: string

Requirement: Required when parent is supplied

Up to 20 characters

accounting_customer_party.postal_address.lga

Type: string

Requirement: Required when parent is supplied

Up to 100 characters

accounting_customer_party.postal_address.state

Type: string

Requirement: Required when parent is supplied

Up to 100 characters

accounting_customer_party.postal_address.country

Type: string

Requirement: Required when parent is supplied

Up to 2 characters

payment_means

Type: array

Requirement: Optional

See sample and schema

payment_means[].payment_means_code

Type: string

Requirement: Required when parent is supplied

Up to 3 characters

payment_means[].payment_due_date

Type: string

Requirement: Optional

date

tax_total

Type: array

Requirement: Required

See sample and schema

tax_total[].tax_amount

Type: number

Requirement: Required when parent is supplied

See sample and schema

tax_total[].tax_subtotal

Type: array

Requirement: Required when parent is supplied

See sample and schema

tax_total[].tax_subtotal[].taxable_amount

Type: number

Requirement: Required when parent is supplied

See sample and schema

tax_total[].tax_subtotal[].tax_amount

Type: number

Requirement: Required when parent is supplied

See sample and schema

tax_total[].tax_subtotal[].tax_category

Type: object

Requirement: Required when parent is supplied

See sample and schema

tax_total[].tax_subtotal[].tax_category.id

Type: string

Requirement: Required when parent is supplied

STANDARD_VAT / ZERO_VAT / EXEMPTED

tax_total[].tax_subtotal[].tax_category.percent

Type: number

Requirement: Required when parent is supplied

See sample and schema

legal_monetary_total

Type: object

Requirement: Required

See sample and schema

legal_monetary_total.line_extension_amount

Type: number

Requirement: Required when parent is supplied

See sample and schema

legal_monetary_total.tax_exclusive_amount

Type: number

Requirement: Required when parent is supplied

See sample and schema

legal_monetary_total.tax_inclusive_amount

Type: number

Requirement: Required when parent is supplied

See sample and schema

legal_monetary_total.payable_amount

Type: number

Requirement: Required when parent is supplied

See sample and schema

invoice_line

Type: array

Requirement: Required

See sample and schema

invoice_line[].hsn_code

Type: string

Requirement: For goods

Up to 7 characters

invoice_line[].product_category

Type: string

Requirement: For goods

Up to 255 characters

invoice_line[].isic_code

Type: string

Requirement: For services

Up to 4 characters

invoice_line[].service_category

Type: string

Requirement: For services

Up to 255 characters

invoice_line[].invoiced_quantity

Type: number

Requirement: Required when parent is supplied

See sample and schema

invoice_line[].line_extension_amount

Type: number

Requirement: Required when parent is supplied

See sample and schema

invoice_line[].item

Type: object

Requirement: Required when parent is supplied

See sample and schema

invoice_line[].item.name

Type: string

Requirement: Required when parent is supplied

See sample and schema

invoice_line[].item.description

Type: string

Requirement: Required when parent is supplied

See sample and schema

invoice_line[].item.sellers_item_identification

Type: string

Requirement: Optional

See sample and schema

invoice_line[].price

Type: object

Requirement: Required when parent is supplied

See sample and schema

invoice_line[].price.price_amount

Type: number

Requirement: Required when parent is supplied

See sample and schema

invoice_line[].price.base_quantity

Type: number

Requirement: Required when parent is supplied

See sample and schema

invoice_line[].price.price_unit

Type: string

Requirement: Required when parent is supplied

Up to 3 characters

billing_reference

Type: array

Requirement: Optional

See sample and schema

billing_reference[].irn

Type: string

Requirement: Required when parent is supplied

See sample and schema

billing_reference[].issue_date

Type: string

Requirement: Required when parent is supplied

date

Download the supported request JSON Schema. This documents WiseWage's supported subset, not every optional NRS feature. B2C, cross-border invoices, discounts, fees, third-party parties and extra document references are outside this release.

Responses and correction workflow

NRS documents a success body such as the example below. It is illustrative documentation, not evidence of an actual sandbox submission. WiseWage retains the received HTTP status and sanitised response for each attempt.

{
  "status": true,
  "message": "success"
}

Illustrative WiseWage validation error (HTTP 400; not an NRS response):

{
  "error": "Business description must not exceed 255 characters.",
  "code": "INVALID_REQUEST"
}

HTTP 400: correct the identified invoice fields. HTTP 401/403: check credentials, permissions and taxpayer association. Timeouts: retain the attempt and retry through the same invoice workflow. Do not renumber an invoice to retry. Validation is separate from approval and reporting.

IRN and encrypted verification QR

The IRN joins an alphanumeric invoice number, the taxpayer's eight-character Service ID and YYYYMMDD issue date with hyphens. For the QR payload, append a period and UNIX timestamp to that IRN, include the issued certificate, encrypt the JSON with the downloaded RSA public key using the documented OpenSSL-compatible padding, then encode the ciphertext as Base64. The QR contains that Base64 ciphertext, never a plain IRN or invented verification URL.

Administrators configure the matching NRS public key and certificate server-side before fiscalization. Missing or invalid keys block the reporting request. Historical invoices without encrypted QR evidence remain downloadable with a warning; they must not be resubmitted merely to replace a QR code.

Linked credit notes (380) and debit notes (384) use billing_reference to identify the original fiscalized invoice. Create them from the original invoice with a reason and selected line amounts; inherited VAT and account mappings are retained. They require validation, approval and confirmation. Fiscalized cancellation is unavailable pending confirmation of the supported NRS process. Reconciliation compares saved NRS evidence, register values and current ledger receivable, revenue and output VAT amounts; it does not verify filed VAT returns.

Download fictional QR format evidence (encrypted payload, test public key and test certificate; no private key).

The downloadable sample demonstrates the encrypted format using locally generated test keys. It is explicitly not NRS-verified, not a sandbox acceptance record and not valid for tax use. Real verification requires the NRS-issued cryptographic materials and an MBS360/NRS verification check.

Official v1.1 references: Invoice Schema, Generate IRN, QR Code.

Payload

Request mappings

WiseWage sourceNRS invoice areaControl
NRS business profilebusiness_id and supplier partyUUID, taxpayer identity, and structured Nigerian address validation
Customer fiscal profileaccounting_customer_partyCountry, state, and LGA codes must form a valid relationship
Invoice headerIRN, issue date, type 381, currency, and payment meansPermanent numbering and date/currency validation
Invoice linesquantity, price, item, ISIC/HSN classification, and tax categoryOfficial classification selection and line-level VAT treatment
Calculated totalstax totals and legal monetary totalsServer-side recalculation before submission

Reliability

Responses and error handling

WiseWage records the outcome of each NRS validation or fiscalization attempt, including the operation, time, HTTP outcome, and a sanitized business-facing explanation. Validation failures remain available for correction and retry; failed attempts do not create posted accounting entries. Fiscalization requires successful NRS signing and matching invoice confirmation; a VAT reporting response alone is insufficient. When a submission outcome is uncertain, Check NRS status confirms the existing IRN without resending it. Each attempt and its evidence are retained.

Customer-facing messages identify an invalid field when NRS provides that detail. Secrets, raw database failures, stack traces, and private infrastructure information are not returned to the browser.

Authentication or access-denied responses stop the NRS operation and direct an administrator to verify the configured environment and credentials. Upstream unavailability is distinguished from invoice-data validation where the NRS response permits it.

Duplicate protection

Idempotency

Validation attempts are keyed to the invoice revision. Fiscalization uses a server-generated idempotency value derived from the invoice identity, revision, and payload fingerprint; the IRN is also sent as the NRS idempotency key.

Retries for an unchanged request reuse the controlled operation rather than intentionally creating another invoice or accounting-register row. A material draft correction creates a new revision and preserves earlier attempt history.

Controls

Security and data handling

Server-side storage and use of NRS connection credentials.
HTTPS required for production NRS communication.
Company- and role-scoped access to taxpayer and invoice records.
Explicit confirmations for approval, fiscalization, and cancellation.
Sanitized errors and no credentials in public samples.
Audit retention for invoice lifecycle events and NRS attempts.

See the WiseWage Security page, Privacy Policy, and NRS e-Invoicing SLA for related controls.

Reviewer resources

Technical evidence and samples

System integration use cases

Updated NRS-template use cases: taxpayer setup, fiscalization, draft cancellation, linked notes, recovery and reconciliation.

Download PDF

Fictional UBL JSON sample

A non-production commercial-invoice example containing no real taxpayer or customer data.

Download JSON

Rendered fictional invoice

Fictional invoice with IRN and a test-key encrypted QR. Not NRS-verified or valid for tax use.

Download PDF

All published samples are fictional and must not be used as production taxpayer records. Their invented Business ID and Service ID are illustrative, and the test-key QR is not NRS verification evidence. The successful sandbox transaction is separate evidence and contains no public client data here.

Change record

Version history

Version 1.2September 19, 2026

Clarified taxpayer-owned authentication and Business ID versus Entity ID; recorded verified sandbox commercial-invoice fiscalization; documented final PDF links, e-Invoicing source labels, separate accounting validation, linked adjustments and user-triggered reconciliation. Updated the use-case submission to the NRS template.

Version 1.1September 17, 2026

Expanded Create Invoice and NRS request reference, supported JSON Schema, IRN and encrypted QR requirements, and clearly labelled test-key sample evidence.

For documentation or integration questions, contact hello@wisewagehr.com. For security reports, contact security@wisewagehr.com.

Official platform requirements remain controlled by NRS. Review the NRS onboarding guidance for current requirements.