XPOS ESDC
- Product Description
- User Manual
- Installation Guide
- Technical Reference
- Architecture & Secure Element (S1-S2)
- Authentication & TaxCore (S3-S4)
- Identity, Tax & Invoice Processing (S5-S7)
- Digital Signatures & Verification (S8)
- Audit - Format, Remote, Local, Cadence (S9-S12)
- Clock, Logging & Persistence (S13-S15)
- Error Codes & Security (S16-S17)
- POS Integration Guide
Product Description
XPOS ESDC turns an ordinary Windows PC and a smart-card reader into a fully accredited Electronic Sales Data Controller (E-SDC) for the Fiji Revenue & Customs Service (FRCS) fiscalisation system. It securely signs every sale on your FRCS Secure Element card and reports it to TaxCore — so your business stays compliant automatically, whether you are online or offline.
What it does
- Fiscalises every sale. Normal sales, refunds, copies, advance, training and proforma invoices are all digitally signed on the Secure Element.
- Works offline. Invoices are signed on the card without an internet connection and reported automatically once you are back online.
- Audits automatically. Audit packages are sent to FRCS continuously in the background — you never have to remember to do it.
- Supports local (offline) audit. For prolonged offline periods, audit data can be exported to a USB or SD card and the proof-of-audit applied back from the same media.
- Includes a built-in Point of Sale. A simple POS is included so you can start issuing fiscal receipts immediately — or connect your own POS software over a local port.
- Prints receipts with QR verification. Every receipt carries a verification URL and QR code your customer can check against FRCS.
- Produces detailed reports. Sales, tax breakdowns and audit history, all exportable to Excel.
Who it is for
Retailers, restaurants, cafés, and service businesses of any size that need to issue FRCS-compliant fiscal receipts in Fiji. Small businesses can use the built-in POS on its own; larger operators can connect XPOS ESDC to an existing POS or ERP.
How it works
- Your FRCS Secure Element (the smart card issued to your business) is inserted into a USB card reader on the PC.
- XPOS ESDC runs quietly in the background and exposes a secure local service that your POS — built-in or third-party — sends sales to.
- Each sale is signed on the card, a fiscal receipt with a QR verification code is produced, and the encrypted audit record is stored safely.
- When the internet is available, audit records are reported to FRCS automatically and the device stays in good standing.
What you need
| Requirement | Detail |
|---|---|
| Computer | Windows 10 or Windows 11, 64-bit |
| Card reader | Any USB PC/SC smart-card reader (ISO 7816) |
| Secure Element | The FRCS-issued smart card for your business |
| Internet | Needed only to report audits — sales can be issued fully offline |
| Printer (optional) | Any Windows printer for receipts |
Compliance
XPOS ESDC is an accredited FRCS E-SDC built on the TaxCore fiscalisation platform. All fiscal signing and counters are performed on the FRCS Secure Element; XPOS ESDC never alters the fiscal data. The product meets the FRCS E-SDC technical requirements for offline operation, audit, logging, time synchronisation and digital signatures.
Publisher
Defy Technologies — Suva, Fiji. For sales, support and accreditation enquiries, contact your Defy Technologies representative.
User Manual
This manual explains how to operate XPOS ESDC day to day: signing in with your Secure Element card, issuing fiscal receipts, running audits, viewing reports, and understanding the messages the application shows you. It is written for the person using the till.
1. Getting started
Signing in
- Make sure your USB card reader is connected and your Secure Element card is inserted.
- Open XPOS ESDC. It also runs automatically at sign-in and sits in the Windows system tray (the icons near the clock).
- The Status screen shows the card is detected. Enter your PIN when prompted.
Your PIN is held only in memory while the application is running. If you restart the computer or the application, you will be asked for it again — this is a security requirement of the fiscal system.
The Status screen
The Status screen is your at-a-glance health check. It shows:
- Card & Secure Element — whether the card is present and its applet version.
- PIN state — whether the card is unlocked for signing.
- Amount — the total value the Secure Element is currently holding before an audit is required.
- Online — whether the device can currently reach FRCS.
- Audit schedule — when the last proof-of-audit ran and when the next one is due.
2. Issuing receipts with the built-in POS
XPOS ESDC includes a simple Point of Sale so you can issue fiscal receipts without any other software.
Creating a normal sale
- Go to the POS screen.
- Add each item: description, price, quantity and its tax label(s). Tax labels come from your active tax rates and can be picked from the dropdown.
- Choose the payment type (cash, card, and so on).
- Press Sign. The sale is signed on the Secure Element and a fiscal receipt is produced with a verification URL and QR code.
Invoice types
| Type | Use it for |
|---|---|
| Normal | A standard sale. |
| Copy | Re-issuing a copy of a previously signed invoice. |
| Refund | Returning goods or reversing a sale — references an earlier signed invoice. |
| Advance | An advance payment before goods/services are delivered. |
| Training | Practising without affecting live figures (clearly marked as training). |
| Proforma | A quotation-style document that is signed but is not a demand for payment. |
Refunds and copies of a past sale
When you issue a refund or copy, XPOS ESDC lets you select the original signed invoice it relates to — from any past normal, advance, training or proforma sale already in the system — so the reference details are carried across correctly.
Printing the receipt
After a sale is signed, use Print receipt to send it to any connected Windows printer. You can also reprint a receipt later from the invoice history.
3. Reports
The Reports screen gives you a detailed view of your fiscal activity:
- Totals by invoice type and transaction type.
- Tax breakdown by label and category.
- Payments breakdown and item sales.
- A full invoice list with a View option to open any single receipt and its audit status.
Any report can be exported to Excel (.xlsx) for your own records or your accountant.
4. Audit
Audit is how your device proves to FRCS that its records are complete. XPOS ESDC handles this for you in two ways.
Remote audit (automatic)
Whenever the device is online, audit packages are sent to FRCS automatically in the background. You do not need to start anything. The Status screen shows the last and next audit times. When FRCS returns a proof-of-audit, it is applied to the Secure Element and the held amount resets.
Local audit (for prolonged offline periods)
If the device will be offline for a long time, you can carry the audit to FRCS on a USB or SD card.
To export audit data:
- Insert a USB or SD card.
- On the Local Audit panel, choose Export and select the removable drive.
- XPOS ESDC creates a folder named after your device UID containing the audit package files and the audit request (ARP). Progress and completion are shown on the panel.
- Take the media to a location with internet / to FRCS as instructed.
To apply the proof-of-audit that comes back:
- Insert the media containing the commands file (named after your UID).
- On the Local Audit panel, choose Import and select the drive.
- XPOS ESDC applies the proof-of-audit to the Secure Element and writes a results file back to the media.
Note: exported audit data and the proof-of-audit use exactly the same secure format as remote audit; nothing about your records is exposed in readable form.
5. Working offline
XPOS ESDC is offline-first. Sales are always signed on the Secure Element, with or without internet. Audit records are stored safely on the PC (they survive a power cut or restart) and are reported automatically when you are back online.
Offline capacity: each audit record is only about 3–5 KB, so a single gigabyte of free disk space holds at least ~100,000 unsent invoices. In practice you can trade for a very long time offline before storage is a concern.
6. Time & the clock
Accurate time is required for fiscal signing. XPOS ESDC keeps the clock correct by synchronising with the time server provided by FRCS every hour. You do not need to do anything; if FRCS changes the time-server address, the device updates itself automatically.
7. Notifications & status signals
The application signals its state through the Status screen and the system-tray icon. If it needs attention — for example the card has been removed, the PIN is required, or the Secure Element has reached its limit and an audit is needed — it will tell you clearly what to do.
8. Logs
XPOS ESDC keeps a plain-text activity and error log. It rolls daily and keeps the last 30 days. If FRCS or support ever asks for the logs, use Export logs in settings to save them to a file you can send. Logs are kept separately from your invoice records and never affect how many receipts you can store.
9. Error messages
XPOS ESDC uses the standard FRCS error codes. The most common ones you may see:
| Code | Meaning | What to do |
|---|---|---|
| 1300 | No card detected | Insert the Secure Element card / check the reader. |
| 1500 | PIN required | Enter your PIN. |
| 2100 / 2110 | PIN incorrect / attempts remaining | Re-enter carefully. Repeated wrong entries can lock the card. |
| 2210 | Secure Element limit reached | Audit is required. Go online, or run a local audit, to reset the held amount. |
| 6308 | Certificate not valid for the current date | Check the PC date/time; contact FRCS if the certificate has expired. |
If you see a code that is not listed here, note it and contact Defy Technologies support.
Installation Guide
This guide is for the person setting up XPOS ESDC on a business PC for the first time. It covers connecting the card reader, installing the software, inserting the Secure Element, and connecting a Point of Sale. Allow about 15 minutes.
Before you begin
| You need | Detail |
|---|---|
| A Windows PC | Windows 10 or 11, 64-bit, with a free USB port. |
| A card reader | Any USB PC/SC smart-card reader (ISO 7816). |
| The Secure Element | The FRCS-issued smart card for the business, and its PIN. |
| The installer | The signed XPOS ESDC installer supplied by Defy Technologies. |
| Administrator rights | Needed once, to install. |
Step 1 — Connect the card reader
- Plug the USB smart-card reader into the PC.
- Windows installs the standard reader driver automatically. Most PC/SC readers need no extra software.
- Confirm the reader appears in Windows Device Manager under Smart card readers.
Step 2 — Card middleware (OpenSC)
XPOS ESDC talks to the Secure Element's PKI applet through OpenSC. The required OpenSC component is bundled with XPOS ESDC and installed for you — you do not need to download anything separately. No manual configuration is required.
Step 3 — Install XPOS ESDC
- Run the supplied XPOS ESDC installer.
- Accept the prompts. The application is code-signed by Defy Technologies; Windows will show the publisher name.
- When installation finishes, XPOS ESDC is available in the Start menu and is set to start automatically at Windows sign-in (running in the system tray).
XPOS ESDC installs its program files to the standard Program Files location and keeps its working data (records, logs, settings) in the per-user application-data folder — you do not need to manage these directly.
Step 4 — Insert the Secure Element
- Insert the FRCS Secure Element card into the reader.
- Open XPOS ESDC. The Status screen should show the card and its Secure Element applet version.
- Enter the card PIN when prompted.
On first successful connection, the device reads its identity (business name, store, address, TIN and UID) directly from the card — there is nothing to type in.
Step 5 — Connect a Point of Sale
XPOS ESDC exposes a local service that a POS sends sales to. You have two options:
- Use the built-in POS. Nothing further to configure — open the POS screen and start selling.
- Connect your own POS. Point your POS software at the XPOS ESDC service on the same PC:
- Address:
http://localhost:8888 - The POS-to-SDC protocol (v3, with legacy V2 also supported) is used to submit invoices and read status.
- Address:
Ports & firewall
| Port | Purpose |
|---|---|
8888 (local) | POS-to-SDC service that your POS connects to. |
| Outbound HTTPS (443) | Reporting audits to FRCS / TaxCore. |
If the POS runs on the same PC, no firewall change is needed. Only allow port 8888 through the firewall if a POS on another machine on your local network must reach this device.
Step 6 — Verify the installation
- On the Status screen, confirm the card is detected, the PIN is accepted, and the device shows as online.
- Issue one test sale from the built-in POS and confirm a fiscal receipt with a QR verification code is produced.
- Check that the last/next audit times appear on the Status screen — this confirms the device is reporting to FRCS.
Everyday running
After setup, XPOS ESDC starts with Windows and runs in the tray. Closing its window keeps it running in the background so the POS service stays available; use the tray menu to open the window or to exit fully.
Uninstalling
Uninstall XPOS ESDC from Settings → Apps like any Windows application. Your fiscal records remain in the application-data folder unless you remove them separately; keep them until all audits have been reported to FRCS.
Getting help
For setup assistance, contact Defy Technologies support with your business name and the device UID shown on the About screen.
Technical Reference
Technical description of XPOS ESDC provided as FRCS accreditation evidence. Sections (S1-S17) are cited by the compliance response.
Architecture & Secure Element (S1-S2)
§1 — System architecture & components
XPOS ESDC is an application-based E-SDC for Windows 10/11 (x64). It is a single self-contained package that runs a background fiscal service and an operator UI in one process, so the UI and the POS-facing service share one Secure Element access lock, PIN cache and data store.
| Component | Role |
|---|---|
| Operator UI (tray application) | Status, built-in POS, reports, audit controls, About (Manufacturer / Serial / Software version / Model / SE applet version). |
POS-to-SDC service (localhost:8888) | Receives invoice requests from the built-in or a third-party POS (v3, legacy V2 supported). |
| Secure Element access layer | PC/SC (APDU) to the SE applet; PKCS#11 to the PKI applet. Serialised behind a single card lock. |
| Audit & command services | Background services for remote audit, proof-of-audit cadence, online-status and command processing. |
| Local store | Embedded database for invoice records and encrypted audit packages; plain-text log folder. |
| Token helper | Small native helper performing the mutual-TLS token request over the card key (see §3). |
Program files install under Program Files (read-only at runtime); working data (records, logs, settings) is kept in the per-user application-data folder. All configuration originates from the Secure Element at runtime.
§2 — Secure Element interface
All fiscal signing and all fiscal counters are performed and held on the Secure Element (SE); XPOS ESDC never computes or alters fiscal signatures. The SE is reached through an external USB PC/SC reader using ISO 7816 APDUs.
- PIN verification — a Verify APDU unlocks signing. The PIN is supplied by the operator and held only in memory (§17).
- Sign — the invoice request (date/time, amount, counters, tax data) is sent to the SE, which returns the signature, encrypted internal data and updated counters.
- Amount / limit — the SE accumulates a signed amount and reports when an audit is required; XPOS ESDC reads this for status and audit triggering.
- Start / End Audit — Start Audit produces the audit request (ARP); End Audit applies a proof-of-audit and resets the held amount.
Signing does not require connectivity; an invoice can be fully fiscalised offline.
Authentication & TaxCore (S3-S4)
§3 — Authentication & token acquisition
Access to TaxCore.API requires a bearer token obtained by authenticating with the on-card PKI certificate. XPOS ESDC performs a mutual-TLS request to /api/v3/sdc/token in which the client certificate and private key are the SE's PKI key, exposed through OpenSC PKCS#11. The private key never leaves the card — the TLS handshake's client-certificate signature is computed on the SE.
TLS renegotiation
The FRCS token endpoint requests the client certificate via TLS renegotiation (the initial handshake asks for no certificate; the server then issues a HelloRequest to demand the card certificate). XPOS ESDC performs this exchange over TLS 1.2 with client-initiated renegotiation supported, using the card key via PKCS#11 for the certificate-verify signature (PKCS#1 v1.5, SHA-256). The server certificate is pinned on first use.
The returned token is cached and refreshed before expiry, and presented as the TaxCoreAuthenticationToken header on all subsequent data calls (§4).
§4 — TaxCore.API & command processing
All communication with TaxCore uses the token from §3. XPOS ESDC receives and executes the full command set, in the order received, and reports the result of each command back to TaxCore.
| Command | Action |
|---|---|
| SetTaxRates | Install/replace tax-rate groups, including future-dated groups (§6). |
| SetTimeServerUrl | Set the NTP server used for time synchronisation (§13). |
| SetVerificationUrl | Set the base verification URL used on receipts (§8). |
| SetTaxCoreConfiguration | Apply TaxCore configuration parameters. |
| ForwardProofOfAudit | Apply a proof-of-audit to the SE via End Audit (§9, §12). |
| ForwardSecureElementDirective | Relay a directive to the SE. |
Commands are processed consecutively (first to last); each result is reported so TaxCore has an accurate record of execution.
Identity, Tax & Invoice Processing (S5-S7)
§5 — Identity from the Secure Element
The taxpayer identity is read directly from the SE certificate — nothing is entered by the operator.
| Field | Source in the certificate |
|---|---|
| TIN | Certificate OID (tag-6) |
| UID | SERIALNUMBER (subject) |
| Company name | Subject O |
| Store / business unit | Subject OU |
| Address | Subject STREET |
| District | Subject S |
| TaxCore endpoint | Certificate extension (tag-5) — the environment URL |
§6 — Tax calculation & rate management
Tax is calculated per item label against the active tax-rate group. Each tax category is applied by its type:
- Tax on net — added to the net amount.
- Tax on total — included within the price.
- Per-quantity — a fixed amount per unit.
Amounts are computed to 4 decimal places with half-round-up and presented to 2 decimals on the response and journal. Invoices carrying a label outside the active group are rejected at validation (§17).
Effective-dated groups
Tax-rate groups are installed by SetTaxRates (online) and can also be applied from the local-audit file. Future-dated groups take effect from their effective date; where dates coincide, the higher revision applies. The group in force at the invoice's referent date is used (current date for a normal sale; the original date for a copy/refund).
§7 — Invoice processing pipeline
- Receive — an invoice request arrives on the POS-to-SDC service as JSON.
- Validate — structure, labels and amounts are checked; invalid requests are rejected with the proper error code (§16).
- Calculate — taxes are computed on the active rates for the referent date (§6).
- Certificate check — a proactive validity check ensures the SE certificate is valid for the current date before signing.
- Sign — the request, SDC date/time and cached PIN are sent to the SE, which returns the signature, encrypted internal data and counters (§2).
- Journal — a 40-column textual receipt is produced with the verification URL and QR code (§8).
- Store — the encrypted audit package is committed to non-volatile storage before the response is returned (§9).
- Respond — the fiscal result is returned to the POS.
Auditing runs on a background service that does not hold the card lock, so a POS sign is never queued behind a network operation.
Digital Signatures & Verification (S8)
§8 — Digital signature & verification URL
Every invoice type — Normal, Advance, Copy, Training, Proforma — is signed on the SE and produces a unique verification URL encoded into the receipt QR code. The URL payload is assembled to the FRCS specification and comprises:
- Format version;
- Secure Element UID and requesting-signer identifiers;
- Invoice and total counters;
- Total amount and timestamp;
- Encrypted internal data;
- The SE signature; and
- An integrity digest (MD5) over the payload.
The signature allows any party to verify the invoice's integrity and authenticity via the verification URL / FRCS portal. The exact byte layout and QR encoding conform to the FRCS E-SDC specification and are validated by the SDC Analyzer.
Signing mechanism
The invoice is not signed by XPOS ESDC itself — it is signed by the Secure Element. XPOS ESDC builds the signing payload (including the trusted SDC clock's timestamp) and hands it to the SE over PKCS#11; the SE's private key never leaves the card, and the signature it returns is what gets embedded in the verification URL. This is what makes the signature genuine cryptographic authenticity rather than a simple checksum: only the specific Secure Element holding that private key could have produced a signature that validates.
Because the FRCS token endpoint requires the client certificate via TLS renegotiation, which managed .NET TLS stacks cannot perform, this handshake and the signing call are carried out by a small bundled native helper (using the card key over PKCS#11/OpenSC) rather than XPOS ESDC's own managed code directly.
Verification
Anyone with the verification URL — scanned from the receipt QR code or read from the invoice — can independently confirm the invoice was genuinely signed by that Secure Element and has not been altered since, without needing access to XPOS ESDC, the Secure Element, or Defy Technologies' own systems.
Audit - Format, Remote, Local, Cadence (S9-S12)
§9 — Audit package format & storage
Each signed invoice yields an audit package containing the invoice { request, result }. The package is encrypted as follows:
- Payload — encrypted with AES-256 (CBC, PKCS7 padding) using a one-time key and IV.
- Key transport — the one-time AES key and IV are RSA-encrypted with the TaxCore public key.
- Package —
{ key, iv, payload }, identical in form for both remote and local audit.
Packages are written to non-volatile storage before the POS response returns, and are never overwritten or erased without a proof-of-audit: a package is retained until it is verified (accepted) or cleared by a valid POA. Applying a POA to the SE (End Audit) resets the held amount, after which the corresponding packages may be cleared. Packages are keyed by SE UID, so switching cards does not interrupt an in-flight audit.
§10 — Remote audit protocol
When connectivity is available, a background auditor submits audit packages to TaxCore continuously and flushes any previously unsent packages. The protocol uses the specified endpoints:
| Operation | Purpose |
|---|---|
| Submit audit | Upload encrypted audit packages. |
| Audit proof | Receive the proof-of-audit for application to the SE. |
| Online status | Periodic heartbeat while a valid token is held. |
| Commands | Retrieve and acknowledge TaxCore commands (§4). |
auditRequired is surfaced in Get Status when the SE nears or reaches its limit. Submission continues automatically whenever data and internet are available; this has been demonstrated live clearing a full SE (≈12M) to zero.
§11 — Local audit (removable media)
For prolonged offline operation, audit data is carried on USB/SD media using the same package format as remote audit.
Export
- A sub-folder named by the SE UID is created on the media if absent:
{root}\{UID}\. - The audit request produced by Start Audit is written as
{UID}.arp. - Each audit package is written as an individual JSON file in the specified
{UID}-{UID}-{n}.jsonconvention. - Started / in-progress / completed status is shown in the Local Audit panel.
Import (proof-of-audit)
- The commands file
{UID}.commandsis read from the media and executed. - The proof-of-audit is applied to the SE via End Audit.
- Results are written back as
{UID}.results.
§12 — Proof-of-Audit cadence
- Minimum between Starts: 10 minutes (well above the 5-minute minimum).
- Normal cadence: 30 minutes; tightened as the SE approaches its limit.
- A proof-of-audit is applied to the SE as soon as it is received; memory is cleared only after the POA resets the held amount.
Clock, Logging & Persistence (S13-S15)
§13 — Real-time clock & time synchronisation
As a software E-SDC there is no dedicated hardware RTC. Time accuracy is maintained by NTP synchronisation against the server provided by FRCS (set via SetTimeServerUrl), performed hourly — well within the 48-hour requirement. Between syncs the host system clock is the time source. This is the documented alternative to a hardware RTC for an application-based E-SDC.
§14 — Logging
XPOS ESDC records the required error events: invoice, APDU, TaxCore, internal, initialization, fiscalization, audit and time-synchronisation errors. Log characteristics:
- Chronological, timestamped in local time to the second.
- Human-readable plain-text daily files, exportable from the UI ("Export logs").
- Rolling — daily files retained for the last 30 days; older files removed automatically.
- Isolated — logs live in a separate folder and do not affect invoice/package storage.
§15 — Persistence & offline capacity
Invoice records and encrypted audit packages are stored in a local embedded database that survives power loss and restart (non-volatile). No power is required to preserve fiscal data.
Offline capacity: an audit package is approximately 3–5 KB, giving at least ~100,000 unsent invoices per GB of free storage. The device therefore sustains extended offline operation, reporting automatically once connectivity returns.
Error Codes & Security (S16-S17)
§16 — Error codes
XPOS ESDC returns only the prescribed FRCS error codes; any manufacturer-specific message is listed in the User Manual. Representative mappings:
| Code | Meaning |
|---|---|
| 1300 | No card / Secure Element not present |
| 1500 | PIN required |
| 2100 / 2110 | PIN incorrect / attempts remaining |
| 2210 | Secure Element limit reached — audit required |
| 6308 | Certificate not valid for the current date |
§17 — Security & prohibited functions
- PIN handling — the PIN is held only in working memory and is cleared on restart; it must be re-entered after any restart.
- Fixed protocol — the POS-to-SDC contract and its parameters are not user-editable.
- Label enforcement — invoices with labels outside the active tax group are rejected.
- Prescribed responses only — no non-standard error responses are emitted.
- Fiscal integrity — signing and counters are performed solely on the SE; XPOS ESDC cannot alter fiscal data or reset counters without a valid proof-of-audit.
POS Integration Guide
Developer reference for integrating a POS with the XPOS ESDC local service (port 8888): endpoints, request/response schemas, errors and the legacy V2 API.
Overview & Integration Flow
XPOS ESDC exposes a local HTTP service that a Point of Sale (the built-in POS, or your own POS/ERP) uses to fiscalise sales. This guide is the integration reference for developers building against that service.
Base URL
The service listens on port 8888 on all interfaces of the machine running XPOS ESDC:
http://localhost:8888 (POS on the same PC)
http://<esdc-host>:8888 (POS elsewhere on the LAN)
Two API surfaces are available:
- v3 — the current API, under
/api/v3. Use this for new integrations. - Legacy V2 —
/api/attention,/api/status,/api/sign, for compatibility with older POS integrations. See the "Legacy V2 API" page.
Interactive reference (Swagger)
The running service publishes a live, always-current OpenAPI document and an interactive UI:
http://localhost:8888/swagger/index.html
The Swagger schema is authoritative for exact field names and shapes — this guide explains the flow and the important fields; Swagger is the definitive contract for the build you are integrating with.
The integration flow
A POS follows this sequence:
- Check availability —
GET /api/v3/attention. Confirms the SDC service is up and a reader is present. - Read status —
GET /api/v3/status. Tells you whether a PIN is required (isPinRequired), whether an audit is required, the SDC date/time, the device identity, and the active tax rates. - Verify PIN (once per session) — if
isPinRequiredis true,POST /api/v3/pinwith the operator's PIN. The SDC caches it in memory and signs subsequent invoices without it. The PIN is cleared on restart, so this step repeats after the app restarts. - Sign invoices —
POST /api/v3/invoicesfor each sale. The response contains the verification URL, QR code, journal (receipt text) and signature. - Print / store — render the receipt from the response, or fetch the rendered PDF later from history.
Idempotency (RequestId)
On POST /api/v3/invoices, send a unique RequestId request header. If the same RequestId is retried (after a timeout or dropped connection), the SDC returns the same already-signed invoice instead of signing again — the header is echoed back on the response. Always send a fresh RequestId per sale and reuse it only when retrying that exact sale.
Content type & CORS
- Requests and responses are JSON (
Content-Type: application/json), exceptPOST /api/v3/pin, whose body is the PIN as plain text. - CORS is open for
GET,POSTandOPTIONSfrom any origin, so a browser-based POS can call the service directly. - If the POS runs on another machine, allow inbound TCP 8888 through the Windows firewall on the SDC host.
Status & Session
These endpoints establish that the SDC is ready and unlock signing for the session.
GET /api/v3/attention
Lightweight health check. Returns whether the SDC is available and which card readers are connected.
GET /api/v3/attention
200 OK
{
"available": true,
"readers": ["ACS ACR39U ICC Reader 0"]
}
GET /api/v3/status
The E-SDC status document. Read this before signing.
| Field | Meaning |
|---|---|
isPinRequired | true if a PIN must be verified before signing. |
auditRequired | true when the Secure Element has reached its limit and an audit is due. |
sdcDateTime | The SDC's current date/time (use this as the fiscal clock). |
protocolVersion | POS-to-SDC protocol version. |
secureElementVersion | SE applet version. |
make, model, softwareVersion, hardwareVersion, deviceSerialNumber | Device identity. |
uid | Secure Element UID. |
currentTaxRates | The tax-rate group currently in force (the labels/categories you may use on items). |
allTaxRates | All known tax-rate groups (including future-dated). |
gsc | Status codes, e.g. 1300 (SE not present), 2400 (SE limit reached). |
POST /api/v3/pin
Verifies the operator PIN on the Secure Element and caches it in memory for the session. The request body is the PIN as plain text (digits) — not JSON. The response is a 4-digit text response code.
POST /api/v3/pin
Content-Type: text/plain
3456
200 OK
0100
| Response | Meaning |
|---|---|
0100 | PIN verified — signing is unlocked. |
2100 | PIN incorrect / no usable PIN supplied. |
2110 | Blocked, or only one attempt remains (the SDC refuses the last attempt to avoid locking the card). |
1300 | Secure Element not present / unreadable. |
Card safety: the SDC will not spend the final PIN attempt. If only one try remains it returns 2110 rather than risk permanently locking the card — resolve the correct PIN before retrying.
Secure Element helpers (read-only)
Useful for status displays and pre-flight checks; none of these sign or consume a PIN attempt.
| Endpoint | Returns |
|---|---|
GET /api/v3/se/identity | Seller identity from the SE certificate: uid, tin, businessName, locationName, address, state, validFrom, validTo, TaxCore URL. |
GET /api/v3/se/amount-status | saleRefund (amount accumulated) and limit. |
GET /api/v3/se/pin-tries | triesLeft. |
GET /api/v3/se/safety | A safety snapshot: PIN tries left, whether blocked, amount used/limit/remaining, used fraction. |
GET /api/v3/se/version | SE applet version. |
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
| Field | Type | Required | Notes |
|---|---|---|---|
invoiceType | enum | Yes | Normal, ProForma, Copy, Training, Advance. |
transactionType | enum | Yes | Sale or Refund. |
payment | array | Yes | One or more { amount, paymentType }. See payment types below. |
items | array | Yes | One or more line items. See item fields below. |
dateAndTimeOfIssue | string | No | ISO date/time; defaults to the SDC clock if omitted. |
cashier | string | No | ≤ 50 chars. |
buyerId | string | No | ≤ 20 chars (buyer TIN / ID). |
buyerCostCenterId | string | No | ≤ 50 chars. |
invoiceNumber | string | No | ≤ 60 chars (your POS's own number/ordinal). |
referentDocumentNumber | string | Conditional | ≤ 50 chars. The signed number of the original invoice — required for Copy and Refund, and whenever referentDocumentDT is present. |
referentDocumentDT | string | No | Date/time of the referent document; if present, referentDocumentNumber becomes required. |
options | object | No | Key/value flags, e.g. { "omitTextualRepresentation": 1 } to skip building the journal text. |
Item fields
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | 1–2048 chars. |
quantity | number | Yes | ≥ 0.001. |
unitPrice | number | Yes | Price per unit. |
labels | array | Yes | Tax label(s) for the item, e.g. ["A"]. Must be labels present in the active tax group (unknown labels are rejected). |
totalAmount | number | Yes | Line total (quantity × unitPrice). |
gtin | string | No | 8–14 chars if supplied. |
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):
| Field | Meaning |
|---|---|
invoiceNumber | The signed fiscal invoice number. |
invoiceCounter / invoiceCounterExtension | Per-type and combined counters. |
totalCounter / transactionTypeCounter | Running counters from the SE. |
verificationUrl | The URL a customer uses to verify the invoice with FRCS. |
verificationQRCode | The QR code (base64) encoding the verification URL — print this on the receipt. |
journal | The formatted textual receipt (40-column). Omitted if options.omitTextualRepresentation is set. |
signature / encryptedInternalData | The SE signature and encrypted internal data. |
signedBy / requestedBy | SE / requesting-signer identifiers. |
taxItems | Per-category tax lines: label, categoryName, rate, amount. |
totalAmount | Invoice total. |
taxGroupRevision | Revision of the tax group applied. |
businessName, tin, locationName, address, district, mrc | Seller details for the receipt header. |
sdcDateTime | The signing date/time. |
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 & 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 & Validation").
Errors, Response Codes & Validation
The SDC uses two error shapes: field validation errors (HTTP 400) and operational response codes (in the body/status).
Validation errors (HTTP 400)
When a request fails structural or business validation, the SDC returns HTTP 400 with a modelState array — one entry per invalid field, each carrying one or more 4-digit codes:
400 Bad Request
{
"message": "Bad Request",
"modelState": [
{ "property": "items[0].name", "errors": ["2803"] },
{ "property": "payment", "errors": ["2801"] }
]
}
| Code | Meaning |
|---|---|
2800 | Field required. |
2801 | List length less than expected (e.g. no items / no payment). |
2803 | Field required (item field). |
2804 | Field length invalid. |
2805 | Field value invalid (bad type, unparseable date/number, unknown enum). |
2807 | Field out of range. |
The property path mirrors the request, including array indices — e.g. items[2].quantity, payment[0].paymentType.
Operational response codes
These signal SDC/Secure-Element state rather than a malformed request.
| Code | Where | Meaning |
|---|---|---|
0100 | POST /pin body | PIN verified. |
1300 | /pin body, /status.gsc | Secure Element not present / unreadable. |
1500 | /invoices 400 body | PIN verification required — call POST /api/v3/pin first. |
2100 | /pin body | PIN incorrect. |
2110 | /pin body | Blocked, or last attempt withheld to avoid locking the card. |
2400 | /status.gsc | Secure Element limit reached — audit required. |
Missing PIN on sign
400 Bad Request
{ "message": "PIN verification required.", "code": "1500" }
Secure Element / card faults
A card fault during signing (removed card, PIN lock, SE limit) returns HTTP 503 with the message and the 4-digit code, for example:
503 Service Unavailable
"Secure Element limit reached (code 2210)"
Recommended handling
- 400 with
modelState— fix the offending field(s) and resubmit; do not retry unchanged. - 1500 — prompt for the PIN, call
/pin, then resubmit the sale (reuse the sameRequestId). - 503 (SE fault) — surface the message to the operator; retry the same
RequestIdonce the fault clears (e.g. card reinserted). Idempotency ensures no double-signing.
History & Reports
Read-back endpoints for reprinting, reconciliation and reporting. These query stored records and do not touch the card.
Invoice history
GET /api/v3/invoices?from=2026-08-01&to=2026-08-13&uid=EKLBHT3Y
Returns fiscalised invoice records for the period (defaults to the last 30 days). Each row includes dateAndTime, invoiceNumber, uid, type, transaction, amount, referenceDocumentNumber, source and itemCount. uid is optional.
Single invoice (drill-down)
GET /api/v3/invoices/detail?number=EKLBHT3Y-EKLBHT3Y-31
Returns the full stored record for one invoice: items, per-invoice tax breakdown and payments. 404 if the number is unknown.
Receipt PDF (reprint)
GET /api/v3/invoices/journal-pdf?number=EKLBHT3Y-EKLBHT3Y-31
Returns the rendered receipt as application/pdf — use it to reprint from history. 404 if the invoice has no stored textual representation (e.g. it was signed with omitTextualRepresentation).
Recovery by RequestId
GET /api/v3/invoices/{requestId}
Returns the invoice previously signed under that RequestId (or null). Useful after a lost response — no re-signing occurs.
Reports
All report endpoints take from, to and optional uid.
| Endpoint | Returns |
|---|---|
GET /api/v3/reports/daily | Daily totals. |
GET /api/v3/reports/payment-types | Totals by payment type. |
GET /api/v3/reports/tax-amounts | Tax totals by label/category. |
GET /api/v3/reports/list-of-items | Item sales. |
GET /api/v3/reports/detailed | A combined detailed report (summary + all breakdowns). |
GET /api/v3/reports/detailed/excel | The detailed report as a multi-sheet .xlsx workbook. |
Audit status
GET /api/v3/audit/status?uid=EKLBHT3Y
Returns queuedPackages (unsent audit packages), awaitingProof (a proof-of-audit is pending) and lastAuditStartUtc. Auditing is automatic in the background; this is for visibility, not something the POS drives.
Legacy V2 API
The Legacy V2 API exists for compatibility with older POS integrations (the FiscoBridge-era contract). New integrations should use v3. V2 signing reuses the exact same fiscalisation pipeline as v3 — only the request parser and the returned result shape differ.
Endpoints
| Endpoint | Purpose |
|---|---|
GET /api/attention | Availability + readers. |
GET /api/status | Availability + readers. |
POST /api/sign | Sign an invoice (V2 request → V2 result). |
POST /api/sign/SignInvoice | Alias of /api/sign. |
PIN verification uses the same POST /api/v3/pin as v3 — the cached PIN is shared across both APIs.
Key differences from v3
- Single payment type. The V2 request carries one request-level
paymentType(not apaymentarray). A single payment is synthesised with an amount equal to the sum of item totals. - Stringly-typed nested fields.
itemsandoptionsare provided as JSON strings, and itemlabelsis a JSON string such as"[\"A\"]". buyerCostCenterIdlimit is 15 chars in V2 (50 in v3).unitPricedefaults to 1 if omitted (v3 requires it).- Result shape is the abbreviated legacy
FiscalizationResultV2(short field names) rather than the full-named v3InvoiceResult. The underlying values (verification URL, QR, journal, signature, counters) are the same.
Request fields (V2)
| Field | Notes |
|---|---|
invoiceType | Normal / ProForma / Copy / Training / Advance. |
transactionType | Sale / Refund. |
paymentType | Single value: Cash, Card, etc. |
items | JSON string of an array of { gtin, name, quantity, unitPrice, labels, totalAmount }; labels itself is a JSON string like "[\"A\"]". |
dateAndTimeOfIssue, cashier, buyerId, buyerCostCenterId, invoiceNumber, referentDocumentNumber, options | As v3, with the V2 limits noted above. |
Validation
V2 validation returns the same 400 modelState shape as v3; a parse failure (unparseable date, wrong JSON type) is reported as 2805 (field value invalid). You can dry-run a V2 request with POST /api/v3/invoices/v2/validate.
Recommendation
Use V2 only to keep an existing POS working. For new development, target v3 for the typed payment array, the richer result fields, and RequestId idempotency.