API HTTP
Driverul FisCool oferă un API HTTP RESTful pentru operațiunile dispozitivelor și managementul sistemului. Acest API este fără stare, făcându-l simplu de integrat cu orice sistem care poate efectua cereri HTTP.
Configurație de Bază
URL implicit: http://127.0.0.1:10123
Content-Type: application/json pentru toate cererile POST
Autentificare: Niciuna (API-ul rulează pe localhost în mod implicit)
Endpoint-uri Informații Sistem
GET /
Descriere: Endpoint verificare sănătate pentru a verifica că serverul API funcționează.
Răspuns: Text simplu
Server API FisCool funcționează.
GET /devices/fiscal
Descriere: Preia toate dispozitivele fiscale.
Răspuns:
{
"fiscal_devices": [
{
"config": {
"id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Casa 1 - DATECS FP-2000",
"manufacturer": "DATECS",
"model": "FP-2000",
"connection_details": {
"type": "Serial",
"details": {
"port": "COM3",
"baud_rate": 115200
}
},
"notes": "Casa principală",
"enabled": true,
"scan_folder": "C:\\FisCool\\InpFiles",
"auto_send_card_to_pos": true,
"linked_pos_device_id": "b2c3d4e5-f6a7-5b8c-9d0e-1f2a3b4c5d6e"
},
"status": "Connected",
"status_text": "Conectat",
"vat_rates": {
"A": 1900, // 19.00% în puncte de bază
"B": 500, // 5.00%
"C": 0 // 0.00%
},
"connected_device_id": "DT123456"
}
]
}
GET /devices/pos
Descriere: Preia toate terminalele POS.
Răspuns:
{
"pos_terminals": [
{
"config": {
"id": "b2c3d4e5-f6a7-5b8c-9d0e-1f2a3b4c5d6e",
"name": "Terminal POS 1",
"manufacturer": "PAX",
"model": "A920 Pro",
"bank": "BCR",
"connection_details": {
"type": "Network",
"details": {
"ip_address": "192.168.1.100",
"port": 8080
}
},
"enabled": true
},
"status": "Connected",
"status_text": "Conectat",
"connected_device_id": "PAX001"
}
]
}
Operațiuni Dispozitive
POST /devices/operation
Descriere: Execută operațiuni dispozitive pe dispozitive fiscale sau terminale POS. Acesta este endpoint-ul principal pentru toate interacțiunile cu dispozitivele.
Antete Cerere
| Antet | Obligatoriu | Descriere |
|---|---|---|
Content-Type | Da | application/json |
Idempotency-Key | Nu | Cheie unică pentru a preveni operațiunile duplicate |
Structura Corpului Cererii
{
"device_id": "UUID", // UUID dispozitiv țintă
"operation": { // Obiect operațiune (vezi pagina Operațiuni Dispozitive)
"type": "nume_operațiune",
// ... parametri specifici operațiunii
}
}
Exemple Complete
Exemplul 1: Tipărire Bon Simplu
POST /devices/operation
Content-Type: application/json
{
"device_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"operation": {
"type": "print_receipt",
"lines": [
{
"type": "item",
"description": "Cafea Espresso",
"quantity_thousandths": 1000, // 1.000 bucăți
"unit_price_cents": 850, // 8.50 RON
"vat": "19%",
"um": "buc"
},
{
"type": "text",
"text": "Mulțumim pentru cumpărături!"
}
],
"payments": [
{
"method": "cash",
"amount_cents": 850
}
],
"flags": {
"is_invoice": false
},
"close_action": "close"
}
}
Exemplul 2: Tipărire Factură cu Plată Card
POST /devices/operation
Content-Type: application/json
{
"device_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"operation": {
"type": "print_receipt",
"lines": [
{
"type": "item",
"description": "Servicii Consultanță IT",
"quantity_thousandths": 1000,
"unit_price_cents": 120000, // 1200.00 RON
"vat": "19%"
}
],
"payments": [
{
"method": "card",
"amount_cents": 120000
}
],
"buyer": {
"vat_number": "RO12345678"
},
"flags": {
"is_invoice": true
},
"close_action": "close"
}
}
Exemplul 3: Tipărire Raport Z
POST /devices/operation
Content-Type: application/json
{
"device_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"operation": {
"type": "print_z"
}
}
Exemplul 4: Operațiuni Numerar
POST /devices/operation
Content-Type: application/json
{
"device_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"operation": {
"type": "deposit_cash",
"amount": 5000 // 50.00 RON în bani
}
}
Exemplul 5: Vânzare POS
POST /devices/operation
Content-Type: application/json
{
"device_id": "b2c3d4e5-f6a7-5b8c-9d0e-1f2a3b4c5d6e",
"operation": {
"type": "sale",
"amount": 2500 // 25.00 RON în bani
}
}
Exemplul 6: Generare Raport JE
POST /devices/operation
Content-Type: application/json
{
"device_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"operation": {
"type": "je_report",
"range": {
"type": "date",
"start": "2024-01-01",
"end": "2024-01-31"
},
"doc_type": "fiscal_receipts",
"output_mode": "read_line_by_line"
}
}
Format Răspuns
Răspuns Succes (HTTP 200)
{
"status": 0,
"msg": "Bon tipărit",
"slip_number": 1234 // Date specifice operațiunii
}
Răspuns Eroare Dispozitiv (HTTP 200)
Când apelul API este valid dar operațiunea dispozitivului eșuează:
{
"status": -500,
"error": "Lipsă hârtie în imprimantă"
}
Răspuns Eroare API (HTTP 4xx/5xx)
Când cererea API în sine este invalidă:
// HTTP 400 Bad Request
{
"status": 400,
"error": "Format device_id invalid"
}
// HTTP 404 Not Found
{
"status": 404,
"error": "Dispozitiv negăsit: a1b2c3d4-..."
}
Idempotență
Pentru operațiunile critice precum tipărirea bonurilor, folosiți antetul Idempotency-Key pentru a preveni execuțiile duplicate:
POST /devices/operation
Content-Type: application/json
Idempotency-Key: bon-2024-01-15-001
{
"device_id": "...",
"operation": { ... }
}
Dacă aceeași cheie este folosită de mai multe ori, rezultatul original este returnat fără re-executarea operațiunii.
Gestionarea Erorilor
API-ul folosește coduri de stare HTTP standard și returnează informații detaliate de eroare în format JSON.
| Stare HTTP | Descriere | Format Corp |
|---|---|---|
| 200 | Cerere reușită, verificați status în corp | Rezultat operațiune dispozitiv |
| 400 | Cerere invalidă (JSON invalid, câmpuri lipsă) | Descriere eroare |
| 404 | Dispozitiv negăsit | Descriere eroare |
| 500 | Eroare internă server | Descriere eroare |
Configurație
Configurația serverului API HTTP poate fi modificată prin setările aplicației:
- Host: Implicit
127.0.0.1(doar localhost) - Port: Implicit
10123 - Activat: Poate fi dezactivat dacă nu este necesar
Exemple de Integrare
Exemple cURL
# Tipărire bon simplu
curl -X POST http://127.0.0.1:10123/devices/operation \
-H "Content-Type: application/json" \
-d '{
"device_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"operation": {
"type": "print_receipt",
"lines": [{"type": "item", "description": "Test", "quantity_thousandths": 1000, "unit_price_cents": 100, "vat": "19%"}],
"payments": [{"method": "cash", "amount_cents": 100}],
"flags": {"is_invoice": false},
"close_action": "close"
}
}'
# Obținere stare sistem
curl http://127.0.0.1:10123/devices/fiscal
Exemplu JavaScript/Node.js
const axios = require('axios');
async function tipăreșteBon(deviceId, articole, plăți) {
try {
const response = await axios.post('http://127.0.0.1:10123/devices/operation', {
device_id: deviceId,
operation: {
type: 'print_receipt',
lines: articole,
payments: plăți,
flags: { is_invoice: false },
close_action: 'close'
}
});
if (response.data.status === 0) {
console.log('Bon tipărit cu succes:', response.data.slip_number);
} else {
console.error('Eroare dispozitiv:', response.data.error);
}
} catch (error) {
console.error('Eroare API:', error.response?.data || error.message);
}
}
Exemplu Python
import requests
import json
def tipărește_bon(device_id, articole, plăți):
url = "http://127.0.0.1:10123/devices/operation"
payload = {
"device_id": device_id,
"operation": {
"type": "print_receipt",
"lines": articole,
"payments": plăți,
"flags": {"is_invoice": False},
"close_action": "close"
}
}
try:
response = requests.post(url, json=payload)
response.raise_for_status()
result = response.json()
if result.get("status") == 0:
print(f"Bon tipărit: {result.get('slip_number')}")
else:
print(f"Eroare dispozitiv: {result.get('error')}")
except requests.exceptions.RequestException as e:
print(f"Eroare API: {e}")
# Exemplu de utilizare
articole = [{
"type": "item",
"description": "Cafea",
"quantity_thousandths": 1000,
"unit_price_cents": 250,
"vat": "19%"
}]
plăți = [{"method": "cash", "amount_cents": 250}]
tipărește_bon("a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d", articole, plăți)