Invoices
Create, approve, and submit FIRS-compliant invoices with IRN generation, QR codes, PDF downloads, and FIRS operations
Create, manage, and submit FIRS-compliant invoices. This is the core module of the Earnipay API — invoices flow through a status-based lifecycle from draft to FIRS submission, with optional approval workflows, QR code generation, PDF downloads, and direct FIRS operations. This page also covers standalone IRN generation, QR code generation, and FIRS invoice search.
Endpoints
Invoice Management
| Method | Endpoint | Description |
|---|---|---|
| POST | /v1/invoices | Create a new invoice |
| GET | /v1/invoices | List invoices (paginated, filterable) |
| GET | /v1/invoices/{id} | Get invoice details |
| PATCH | /v1/invoices/{id} | Update an invoice (DRAFT only) |
| DELETE | /v1/invoices/{id} | Cancel an invoice |
| POST | /v1/invoices/{id}/approve | Approve an invoice |
| POST | /v1/invoices/{id}/reject | Reject an invoice |
FIRS Compliance & Submission
| Method | Endpoint | Description |
|---|---|---|
| POST | /v1/invoices/{id}/generate-qr | Generate FIRS QR code for an invoice |
| GET | /v1/invoices/{id}/pdf | Download invoice as PDF |
| POST | /v1/invoices/{id}/submit-to-app | Submit to FIRS via APP provider |
| POST | /v1/invoices/validate | Validate invoice data against FIRS schema |
Standalone Utilities
| Method | Endpoint | Description |
|---|---|---|
| POST | /v1/irn-generator/generate | Generate a FIRS-compliant IRN |
| POST | /v1/qr-generator/generate | Generate a standalone encrypted QR code |
FIRS Operations
| Method | Endpoint | Description |
|---|---|---|
| PATCH | /v1/api/v1/businesses/{businessId}/app/invoices/{invoiceId}/payment-status | Update payment status in FIRS |
| GET | /v1/api/v1/businesses/{businessId}/app/invoices/search | Search invoices from FIRS |
All endpoints on this page require authentication. See Authentication for details.
Invoice Lifecycle
Invoices move through a series of statuses from creation to FIRS submission. The exact flow depends on your business settings.
DRAFT → PENDING_APPROVAL → APPROVED → PENDING → SUBMITTED → FIRS_APPROVED
→ FIRS_REJECTED
→ PAID
↓
CANCELLED
| Status | Description |
|---|---|
DRAFT | Initial state. Invoice can be edited or cancelled |
PENDING_APPROVAL | Waiting for an OWNER or ADMIN to approve (when requireApproval is enabled) |
APPROVED | Approved and ready for FIRS submission |
PENDING | Queued for submission to FIRS |
SUBMITTED | Sent to FIRS via the APP provider, awaiting response |
FIRS_APPROVED | FIRS accepted the invoice |
FIRS_REJECTED | FIRS rejected the invoice — check the rejection reason |
PAID | Payment received for this invoice |
CANCELLED | Invoice cancelled — cannot be reactivated |
When
requireApprovalis disabled in business settings, invoices skipPENDING_APPROVALand move directly fromDRAFTtoAPPROVED. WhenautoSubmitToFirsis enabled, approved invoices are automatically submitted without calling the submit endpoint.
Invoice Types
| Type | Description |
|---|---|
STANDARD | Regular tax invoice for goods or services delivered |
PROFORMA | Pre-sale invoice issued before delivery |
CREDIT_NOTE | Adjustment reducing the amount on a previous invoice |
DEBIT_NOTE | Adjustment increasing the amount on a previous invoice |
Create an Invoice
Create a new invoice with line items. The invoice is created in DRAFT status, and an IRN (Invoice Reference Number) is auto-generated in the format {InvoiceNumber}-{ServiceID}-{YYYYMMDD}.
curl -X POST https://e-invoicing.earnipay.com/v1/invoices \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"businessId": "biz_xyz789",
"customerId": "cus_def456",
"invoiceType": "STANDARD",
"issueDate": "2026-03-13",
"dueDate": "2026-04-13",
"items": [
{
"description": "Cloud Hosting - Standard Plan",
"quantity": 3,
"unitPrice": 75000,
"taxPercent": 7.5,
"discount": 0,
"productCode": "prod_abc123",
"unit": "month"
},
{
"description": "Consulting Services",
"quantity": 10,
"unitPrice": 150000,
"taxPercent": 5,
"discount": 50000,
"productCode": "prod_def456",
"unit": "hour"
}
],
"paymentTerms": "Net 30",
"paymentMethod": "BANK_TRANSFER",
"paymentDetails": "pay_abc123",
"notes": "Thank you for your business."
}'Invoice Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
businessId | string | Yes | ID of the business issuing the invoice |
customerId | string | Yes | ID of the customer being invoiced |
invoiceType | string | Yes | One of: STANDARD, PROFORMA, CREDIT_NOTE, DEBIT_NOTE |
issueDate | string | Yes | Invoice date (ISO 8601 format: YYYY-MM-DD) |
dueDate | string | Yes | Payment due date (ISO 8601 format: YYYY-MM-DD) |
items | array | Yes | Line items (at least one required) |
paymentTerms | string | No | Payment terms description (e.g., "Net 30") |
paymentMethod | string | No | One of: BANK_TRANSFER, MOBILE_MONEY, CASH, CREDIT_CARD, OTHER |
paymentDetails | string | No | ID of a saved payment detail |
notes | string | No | Additional notes displayed on the invoice |
Line Item Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
description | string | Yes | Line item description |
quantity | number | Yes | Quantity of units |
unitPrice | number | Yes | Price per unit (in NGN) |
taxPercent | number | Yes | Tax percentage applied to this item |
discount | number | No | Discount amount in NGN (default: 0) |
productCode | string | No | ID of a saved product |
unit | string | No | Unit of measurement (e.g., month, hour, piece) |
{
"statusCode": 201,
"message": "Invoice created successfully.",
"data": {
"id": "inv_mno345",
"businessId": "biz_xyz789",
"customerId": "cus_def456",
"invoiceType": "STANDARD",
"status": "DRAFT",
"irn": "INV-001-FIRS-SVC-001-20260313",
"issueDate": "2026-03-13",
"dueDate": "2026-04-13",
"items": [
{
"description": "Cloud Hosting - Standard Plan",
"quantity": 3,
"unitPrice": 75000,
"taxPercent": 7.5,
"discount": 0,
"lineTotal": 225000,
"taxAmount": 16875,
"unit": "month"
},
{
"description": "Consulting Services",
"quantity": 10,
"unitPrice": 150000,
"taxPercent": 5,
"discount": 50000,
"lineTotal": 1450000,
"taxAmount": 72500,
"unit": "hour"
}
],
"subtotal": 1675000,
"totalTax": 89375,
"totalDiscount": 50000,
"total": 1764375,
"paymentTerms": "Net 30",
"paymentMethod": "BANK_TRANSFER",
"notes": "Thank you for your business.",
"createdAt": "2026-03-13T14:00:00.000Z",
"updatedAt": "2026-03-13T14:00:00.000Z"
}
}How line item totals are calculated
Each line item total is calculated as:
lineTotal = (quantity × unitPrice) - discount
taxAmount = lineTotal × (taxPercent / 100)Invoice totals aggregate all line items:
subtotal = sum of all (quantity × unitPrice)
totalDiscount = sum of all discounts
totalTax = sum of all taxAmounts
total = subtotal - totalDiscount + totalTaxFor the example above:
- Item 1: (3 × ₦75,000) - ₦0 = ₦225,000 → tax: ₦16,875
- Item 2: (10 × ₦150,000) - ₦50,000 = ₦1,450,000 → tax: ₦72,500
- Total: ₦1,675,000 - ₦50,000 + ₦89,375 = ₦1,764,375
List Invoices
Retrieve a paginated list of invoices with filters for status, type, customer, and date range.
curl "https://e-invoicing.earnipay.com/v1/invoices?businessId=biz_xyz789&status=DRAFT&page=1&limit=10" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."| Parameter | Type | Required | Description |
|---|---|---|---|
businessId | string | Yes | Filter by business ID |
page | integer | No | Page number (default: 1) |
limit | integer | No | Items per page (default: 10) |
search | string | No | Search by IRN, customer name, or notes |
status | string | No | Filter by status (e.g., DRAFT, APPROVED, FIRS_APPROVED) |
invoiceType | string | No | Filter by type (e.g., STANDARD, CREDIT_NOTE) |
customerId | string | No | Filter by customer ID |
sortBy | string | No | Field to sort by (e.g., issueDate, total, createdAt) |
sortOrder | string | No | asc or desc (default: desc) |
startDate | string | No | Invoices issued on or after this date (ISO 8601) |
endDate | string | No | Invoices issued on or before this date (ISO 8601) |
{
"statusCode": 200,
"message": "Invoices retrieved successfully.",
"data": {
"items": [
{
"id": "inv_mno345",
"invoiceType": "STANDARD",
"status": "DRAFT",
"irn": "INV-001-FIRS-SVC-001-20260313",
"customerId": "cus_def456",
"customerName": "Zenith Enterprises",
"issueDate": "2026-03-13",
"dueDate": "2026-04-13",
"total": 1764375,
"createdAt": "2026-03-13T14:00:00.000Z"
}
],
"meta": {
"totalItems": 1,
"itemCount": 1,
"itemsPerPage": 10,
"totalPages": 1,
"currentPage": 1
}
}
}Get Invoice Details
Retrieve the full details of an invoice, including all line items, payment information, and QR code data.
curl https://e-invoicing.earnipay.com/v1/invoices/inv_mno345 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"statusCode": 200,
"message": "Invoice retrieved successfully.",
"data": {
"id": "inv_mno345",
"businessId": "biz_xyz789",
"customerId": "cus_def456",
"customerName": "Zenith Enterprises",
"invoiceType": "STANDARD",
"status": "DRAFT",
"irn": "INV-001-FIRS-SVC-001-20260313",
"issueDate": "2026-03-13",
"dueDate": "2026-04-13",
"items": [
{
"description": "Cloud Hosting - Standard Plan",
"quantity": 3,
"unitPrice": 75000,
"taxPercent": 7.5,
"discount": 0,
"lineTotal": 225000,
"taxAmount": 16875,
"unit": "month"
},
{
"description": "Consulting Services",
"quantity": 10,
"unitPrice": 150000,
"taxPercent": 5,
"discount": 50000,
"lineTotal": 1450000,
"taxAmount": 72500,
"unit": "hour"
}
],
"subtotal": 1675000,
"totalTax": 89375,
"totalDiscount": 50000,
"total": 1764375,
"paymentTerms": "Net 30",
"paymentMethod": "BANK_TRANSFER",
"notes": "Thank you for your business.",
"qrCode": null,
"createdAt": "2026-03-13T14:00:00.000Z",
"updatedAt": "2026-03-13T14:00:00.000Z"
}
}Update an Invoice
Update an invoice that is still in DRAFT status. You can modify any field including line items. Invoices in any other status cannot be edited.
curl -X PATCH https://e-invoicing.earnipay.com/v1/invoices/inv_mno345 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"dueDate": "2026-05-13",
"notes": "Payment terms extended to 60 days.",
"items": [
{
"description": "Cloud Hosting - Standard Plan",
"quantity": 6,
"unitPrice": 75000,
"taxPercent": 7.5,
"discount": 0,
"unit": "month"
}
]
}'{
"statusCode": 200,
"message": "Invoice updated successfully.",
"data": {
"id": "inv_mno345",
"status": "DRAFT",
"irn": "INV-001-FIRS-SVC-001-20260313",
"dueDate": "2026-05-13",
"items": [
{
"description": "Cloud Hosting - Standard Plan",
"quantity": 6,
"unitPrice": 75000,
"taxPercent": 7.5,
"discount": 0,
"lineTotal": 450000,
"taxAmount": 33750,
"unit": "month"
}
],
"subtotal": 450000,
"totalTax": 33750,
"totalDiscount": 0,
"total": 483750,
"notes": "Payment terms extended to 60 days.",
"updatedAt": "2026-03-13T16:00:00.000Z"
}
}Updating
itemsreplaces the entire line items array. Include all line items in the request, not just the ones you want to change.
Cancel an Invoice
Cancel an invoice. Cancelled invoices cannot be reactivated. Use this for invoices that were created in error or are no longer needed.
curl -X DELETE https://e-invoicing.earnipay.com/v1/invoices/inv_mno345 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"statusCode": 200,
"message": "Invoice cancelled successfully.",
"data": {
"id": "inv_mno345",
"status": "CANCELLED"
}
}Cancellation is permanent. If you need to adjust an invoice that has already been submitted to FIRS, create a
CREDIT_NOTEorDEBIT_NOTEinstead of cancelling.
Approve an Invoice
Approve an invoice that is in PENDING_APPROVAL status. Only users with the OWNER or ADMIN role can approve invoices.
curl -X POST https://e-invoicing.earnipay.com/v1/invoices/inv_mno345/approve \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"statusCode": 200,
"message": "Invoice approved successfully.",
"data": {
"id": "inv_mno345",
"status": "APPROVED",
"approvedBy": "usr_abc123",
"approvedAt": "2026-03-13T17:00:00.000Z"
}
}If autoSubmitToFirs is enabled in your business settings, the invoice is automatically submitted to FIRS after approval.
Reject an Invoice
Reject an invoice that is in PENDING_APPROVAL status. The invoice returns to DRAFT status so the creator can edit and resubmit it. Only OWNER or ADMIN roles can reject invoices.
curl -X POST https://e-invoicing.earnipay.com/v1/invoices/inv_mno345/reject \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"reason": "Incorrect unit price for consulting services. Please update to ₦120,000/hr."
}'| Parameter | Type | Required | Description |
|---|---|---|---|
reason | string | No | Explanation for the rejection (visible to the invoice creator) |
{
"statusCode": 200,
"message": "Invoice rejected successfully.",
"data": {
"id": "inv_mno345",
"status": "DRAFT",
"rejectedBy": "usr_abc123",
"rejectedAt": "2026-03-13T17:15:00.000Z",
"rejectionReason": "Incorrect unit price for consulting services. Please update to ₦120,000/hr."
}
}Generate QR Code
Generate a FIRS-compliant QR code for an invoice. The QR code is encrypted using the RSA public key from your FIRS crypto keys and meets FIRS requirements (Error Correction Level H, minimum 300×300px).
curl -X POST https://e-invoicing.earnipay.com/v1/invoices/inv_mno345/generate-qr \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"statusCode": 200,
"message": "QR code generated successfully.",
"data": {
"qrCodeBase64": "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5f...",
"qrCodeDataUrl": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5f..."
}
}| Field | Description |
|---|---|
qrCodeBase64 | Raw Base64-encoded PNG image of the QR code |
qrCodeDataUrl | Data URL ready for embedding in HTML (<img src="...">) |
You must upload your FIRS crypto keys file before generating QR codes. See Businesses — Upload Crypto Keys.
Download PDF
Download the invoice as a PDF file with embedded QR code and all FIRS-required fields.
curl https://e-invoicing.earnipay.com/v1/invoices/inv_mno345/pdf \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
--output invoice-INV-001.pdfThe response returns the PDF file with Content-Type: application/pdf. Use the --output flag in curl (or equivalent in your HTTP client) to save it to a file.
Submit to FIRS
Submit an approved invoice to FIRS via your configured APP provider. The invoice must be in APPROVED status and the business must have a working APP provider connection.
curl -X POST https://e-invoicing.earnipay.com/v1/invoices/inv_mno345/submit-to-app \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"statusCode": 200,
"message": "Invoice submitted to FIRS successfully.",
"data": {
"id": "inv_mno345",
"status": "SUBMITTED",
"submittedAt": "2026-03-13T18:00:00.000Z"
}
}After submission, the invoice status updates asynchronously based on the FIRS response:
FIRS_APPROVED— FIRS accepted the invoiceFIRS_REJECTED— FIRS rejected the invoice (check the rejection details on the invoice)
Validate Invoice Data
Validate invoice data against the FIRS schema without creating an invoice. Use this to check that your data is compliant before submission.
curl -X POST https://e-invoicing.earnipay.com/v1/invoices/validate \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"irn": "INV-001-FIRS-SVC-001-20260313",
"issueDate": "2026-03-13",
"invoiceType": "STANDARD",
"supplier": {
"name": "Okafor Trading International Ltd",
"TIN": "12345678-0001",
"address": "42 Victoria Island Blvd, Lagos"
},
"buyer": {
"name": "Zenith Enterprises",
"TIN": "98765432-0001",
"address": "8 Broad Street, Lagos"
},
"items": [
{
"description": "Cloud Hosting - Standard Plan",
"quantity": 3,
"unitPrice": 75000,
"taxPercent": 7.5
}
],
"taxTotal": 16875,
"monetaryTotal": 241875
}'{
"statusCode": 200,
"message": "Invoice data is valid.",
"data": {
"isValid": true,
"errors": []
}
}Generate IRN (Standalone)
Generate a FIRS-compliant Invoice Reference Number (IRN) outside the invoice creation flow. IRNs follow the format {InvoiceNumber}-{ServiceID}-{YYYYMMDD}. Use this when pre-assigning IRNs in bulk or integrating with external invoicing systems.
When you create an invoice via
POST /v1/invoices, an IRN is auto-generated. Use this standalone endpoint only when you need to generate IRNs independently.
curl -X POST https://e-invoicing.earnipay.com/v1/irn-generator/generate \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"invoiceNumber": "INV-001",
"serviceId": "FIRS-SVC-001",
"issueDate": "2026-03-13"
}'| Parameter | Type | Required | Description |
|---|---|---|---|
invoiceNumber | string | Yes | Your invoice number or reference |
serviceId | string | Yes | FIRS Service ID from your business FIRS config |
issueDate | string | Yes | Invoice issue date (YYYY-MM-DD) |
{
"statusCode": 200,
"message": "IRN generated successfully.",
"data": {
"irn": "INV-001-FIRS-SVC-001-20260313"
}
}IRN Format
| Component | Description | Example |
|---|---|---|
InvoiceNumber | Sequential invoice number for your business | INV-001 |
ServiceID | Your FIRS-assigned Service ID | FIRS-SVC-001 |
YYYYMMDD | Invoice issue date in 8-digit format | 20260313 |
Generate QR Code (Standalone)
Generate an encrypted FIRS-compliant QR code outside the invoice flow. Use this when embedding QR codes in custom PDF templates or external systems. For invoice-level QR generation, see Generate QR Code above.
Prerequisites
- Configure FIRS settings —
PATCH /v1/businesses/{id}/firs-configwith your Business ID and Service ID. See Businesses — FIRS Configuration - Upload crypto keys —
PATCH /v1/businesses/{id}/crypto-keyswith thecrypto_keys.txtfile from FIRS. See Businesses — Upload Crypto Keys
FIRS QR Code Requirements
| Requirement | Value |
|---|---|
| Encryption | RSA using the FIRS-issued public key |
| Error Correction Level | H (High — 30% data recovery) |
| Minimum Size | 300 × 300 pixels |
| Output Format | PNG image (Base64-encoded) |
Request
curl -X POST https://e-invoicing.earnipay.com/v1/qr-generator/generate \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"businessId": "biz_xyz789",
"irn": "INV-001-FIRS-SVC-001-20260313",
"issueDate": "2026-03-13",
"invoiceType": "STANDARD",
"supplierTIN": "12345678-0001",
"buyerTIN": "98765432-0001",
"totalAmount": 1764375,
"taxAmount": 89375
}'| Parameter | Type | Required | Description |
|---|---|---|---|
businessId | string | Yes | ID of the business (must have crypto keys uploaded) |
irn | string | Yes | Invoice Reference Number |
issueDate | string | Yes | Invoice issue date (YYYY-MM-DD) |
invoiceType | string | Yes | One of: STANDARD, PROFORMA, CREDIT_NOTE, DEBIT_NOTE |
supplierTIN | string | Yes | Supplier's Tax Identification Number |
buyerTIN | string | Yes | Buyer's Tax Identification Number |
totalAmount | number | Yes | Invoice total amount in NGN |
taxAmount | number | Yes | Total tax amount in NGN |
{
"statusCode": 200,
"message": "QR code generated successfully.",
"data": {
"qrCodeBase64": "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5f...",
"qrCodeDataUrl": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5f..."
}
}Using the QR Code
Embed the QR code directly in a web page using the qrCodeDataUrl:
<img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5f..."
alt="FIRS QR Code"
width="300"
height="300"
/>Update Payment Status in FIRS
Update the payment status of an invoice in the FIRS system via your APP provider. Use this after receiving payment for an invoice that has been submitted to FIRS.
curl -X PATCH "https://e-invoicing.earnipay.com/v1/api/v1/businesses/biz_xyz789/app/invoices/inv_mno345/payment-status" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"status": "PAID",
"paymentDate": "2026-04-10",
"paymentReference": "TRF-20260410-001"
}'| Parameter | Type | Required | Description |
|---|---|---|---|
status | string | Yes | Payment status (e.g., PAID) |
paymentDate | string | Yes | Date payment was received (YYYY-MM-DD) |
paymentReference | string | No | Payment reference or transaction ID |
{
"statusCode": 200,
"message": "Payment status updated in FIRS successfully.",
"data": {
"invoiceId": "inv_mno345",
"status": "PAID",
"paymentDate": "2026-04-10",
"paymentReference": "TRF-20260410-001"
}
}Search Invoices from FIRS
Search for invoices directly from the FIRS system via your APP provider. Use this to verify invoice status, reconcile records, or retrieve invoices submitted by other parties.
curl "https://e-invoicing.earnipay.com/v1/api/v1/businesses/biz_xyz789/app/invoices/search?irn=INV-001-FIRS-SVC-001-20260313" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."| Parameter | Type | Required | Description |
|---|---|---|---|
irn | string | No | Search by Invoice Reference Number |
supplierTIN | string | No | Search by supplier's TIN |
buyerTIN | string | No | Search by buyer's TIN |
startDate | string | No | Invoices issued on or after this date (YYYY-MM-DD) |
endDate | string | No | Invoices issued on or before this date (YYYY-MM-DD) |
{
"statusCode": 200,
"message": "FIRS invoice search completed.",
"data": {
"items": [
{
"irn": "INV-001-FIRS-SVC-001-20260313",
"invoiceType": "STANDARD",
"supplierTIN": "12345678-0001",
"buyerTIN": "98765432-0001",
"issueDate": "2026-03-13",
"totalAmount": 1764375,
"taxAmount": 89375,
"status": "FIRS_APPROVED"
}
]
}
}Both "Update Payment Status" and "Search Invoices from FIRS" require a configured and tested APP provider connection. See Businesses — APP Provider Configuration.
Error Handling
| Status Code | Error | Description |
|---|---|---|
400 | Bad Request | Missing required fields, invalid parameters, or invoice not in required status |
401 | Unauthorized | Missing or expired access token |
403 | Forbidden | Insufficient role (e.g., only OWNER/ADMIN can approve) |
404 | Not Found | Invoice ID doesn't exist |
409 | Conflict | Invoice is not in the correct status for this action |
422 | Unprocessable Entity | Crypto keys not uploaded (QR generation) or APP provider not configured (FIRS operations) |
{
"statusCode": 409,
"message": "Invoice can only be updated in DRAFT status. Current status: APPROVED.",
"error": "Conflict"
}{
"statusCode": 403,
"message": "Only users with OWNER or ADMIN role can approve invoices.",
"error": "Forbidden"
}Updated 2 days ago