# Signing an Invoice

The core endpoint. Signs a sale on the Secure Element and returns the fiscal result (verification URL, QR, journal, signature). Requires a PIN previously verified via `POST /api/v3/pin`.

```
POST /api/v3/invoices
Content-Type: application/json
RequestId: 4b1e...unique-per-sale
```

## Request fields

<table id="bkmrk-fieldtyperequirednot"><thead><tr><th>Field</th><th>Type</th><th>Required</th><th>Notes</th></tr></thead><tbody><tr><td>`invoiceType`</td><td>enum</td><td>Yes</td><td>`Normal`, `ProForma`, `Copy`, `Training`, `Advance`.</td></tr><tr><td>`transactionType`</td><td>enum</td><td>Yes</td><td>`Sale` or `Refund`.</td></tr><tr><td>`payment`</td><td>array</td><td>Yes</td><td>One or more `{ amount, paymentType }`. See payment types below.</td></tr><tr><td>`items`</td><td>array</td><td>Yes</td><td>One or more line items. See item fields below.</td></tr><tr><td>`dateAndTimeOfIssue`</td><td>string</td><td>No</td><td>ISO date/time; defaults to the SDC clock if omitted.</td></tr><tr><td>`cashier`</td><td>string</td><td>No</td><td>≤ 50 chars.</td></tr><tr><td>`buyerId`</td><td>string</td><td>No</td><td>≤ 20 chars (buyer TIN / ID).</td></tr><tr><td>`buyerCostCenterId`</td><td>string</td><td>No</td><td>≤ 50 chars.</td></tr><tr><td>`invoiceNumber`</td><td>string</td><td>No</td><td>≤ 60 chars (your POS's own number/ordinal).</td></tr><tr><td>`referentDocumentNumber`</td><td>string</td><td>Conditional</td><td>≤ 50 chars. The signed number of the original invoice — required for `Copy` and `Refund`, and whenever `referentDocumentDT` is present.</td></tr><tr><td>`referentDocumentDT`</td><td>string</td><td>No</td><td>Date/time of the referent document; if present, `referentDocumentNumber` becomes required.</td></tr><tr><td>`options`</td><td>object</td><td>No</td><td>Key/value flags, e.g. `{ "omitTextualRepresentation": 1 }` to skip building the journal text.</td></tr></tbody></table>

### Item fields

<table id="bkmrk-fieldtyperequirednot-1"><thead><tr><th>Field</th><th>Type</th><th>Required</th><th>Notes</th></tr></thead><tbody><tr><td>`name`</td><td>string</td><td>Yes</td><td>1–2048 chars.</td></tr><tr><td>`quantity`</td><td>number</td><td>Yes</td><td>≥ 0.001.</td></tr><tr><td>`unitPrice`</td><td>number</td><td>Yes</td><td>Price per unit.</td></tr><tr><td>`labels`</td><td>array</td><td>Yes</td><td>Tax label(s) for the item, e.g. `["A"]`. Must be labels present in the active tax group (unknown labels are rejected).</td></tr><tr><td>`totalAmount`</td><td>number</td><td>Yes</td><td>Line total (quantity × unitPrice).</td></tr><tr><td>`gtin`</td><td>string</td><td>No</td><td>8–14 chars if supplied.</td></tr></tbody></table>

### Payment types

`Other`, `Cash`, `Card`, `Check`, `WireTransfer`, `Voucher`, `MobileMoney`.

## Example request

```
{
  "invoiceType": "Normal",
  "transactionType": "Sale",
  "cashier": "Jack",
  "payment": [
    { "amount": 23.00, "paymentType": "Cash" }
  ],
  "items": [
    {
      "name": "Coffee",
      "quantity": 2,
      "unitPrice": 5.00,
      "labels": ["A"],
      "totalAmount": 10.00
    },
    {
      "name": "Sandwich",
      "quantity": 1,
      "unitPrice": 13.00,
      "labels": ["A"],
      "totalAmount": 13.00
    }
  ]
}
```

## Response

On success the SDC returns the fiscal result. Field names are camelCase (see Swagger for the exact schema of your build):

<table id="bkmrk-fieldmeaning-invoice"><thead><tr><th>Field</th><th>Meaning</th></tr></thead><tbody><tr><td>`invoiceNumber`</td><td>The signed fiscal invoice number.</td></tr><tr><td>`invoiceCounter` / `invoiceCounterExtension`</td><td>Per-type and combined counters.</td></tr><tr><td>`totalCounter` / `transactionTypeCounter`</td><td>Running counters from the SE.</td></tr><tr><td>`verificationUrl`</td><td>The URL a customer uses to verify the invoice with FRCS.</td></tr><tr><td>`verificationQRCode`</td><td>The QR code (base64) encoding the verification URL — print this on the receipt.</td></tr><tr><td>`journal`</td><td>The formatted textual receipt (40-column). Omitted if `options.omitTextualRepresentation` is set.</td></tr><tr><td>`signature` / `encryptedInternalData`</td><td>The SE signature and encrypted internal data.</td></tr><tr><td>`signedBy` / `requestedBy`</td><td>SE / requesting-signer identifiers.</td></tr><tr><td>`taxItems`</td><td>Per-category tax lines: `label`, `categoryName`, `rate`, `amount`.</td></tr><tr><td>`totalAmount`</td><td>Invoice total.</td></tr><tr><td>`taxGroupRevision`</td><td>Revision of the tax group applied.</td></tr><tr><td>`businessName`, `tin`, `locationName`, `address`, `district`, `mrc`</td><td>Seller details for the receipt header.</td></tr><tr><td>`sdcDateTime`</td><td>The signing date/time.</td></tr></tbody></table>

```
200 OK
{
  "invoiceNumber": "EKLBHT3Y-EKLBHT3Y-31",
  "verificationUrl": "https://sandbox.vms.frcs.org.fj/v/?vl=...",
  "verificationQRCode": "iVBORw0KGgoAAAANSUhEUgAA...",
  "journal": "============ FISCAL INVOICE ============ ...",
  "totalAmount": 23.00,
  "taxItems": [
    { "label": "A", "categoryName": "VAT", "rate": 15.0, "amount": 3.00 }
  ],
  "sdcDateTime": "2026-08-13T09:42:00"
}
```

## Refunds &amp; copies

For a `Refund` (or a `Copy`), set `transactionType`/`invoiceType` accordingly and reference the original signed invoice with `referentDocumentNumber` (and optionally `referentDocumentDT`). Taxes for a copy/refund are calculated using the tax group in force at the referent document's date.

## Validate without signing

`POST /api/v3/invoices/validate` runs the same request validation and tax rules **without** touching the card — useful to check a basket before committing. It returns `{ "valid": true }` or a 400 with field errors (see "Errors &amp; Validation").