BillySSW · Documentazione API

Vendite, annulli, resi e chiusura

Come emettere i documenti commerciali e chiudere la giornata. Tutte le operazioni richiedono lo scope fiscale:manage e un PEM In servizio.

Vendita

Il PEM genera e firma l'XML del documento, lo aggiunge al Journal e ne accoda la trasmissione al PEL. La risposta è il PDF firmato del documento, con dentro il testo per la stampante termica; l'hash è nell'URL di Content-Location. Vedi Stampare un DC.

POST …/fiscale/invio/dc
curl -X POST \
  https://pem-staging.billyssw.it/api/pem/ASVS-241232/fiscale/invio/dc \
  -H "Authorization: Bearer <access_token>" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "idempotency_key": "3f1c2a9e-8b7d-4c1e-9a2f-5d6e7f8a9b0c",
    "elementi": [
      { "descrizione": "Pizza margherita", "bene_servizio": "B", "quantita": "1", "prezzo_unitario": "8.00", "iva": "10" },
      { "descrizione": "Acqua", "bene_servizio": "B", "quantita": "1", "prezzo_unitario": "2.00", "iva": "10", "sconto": "0.50" }
    ],
    "pagamenti": [
      { "metodo": "PP", "importo": "9.50" }
    ]
  }'

Regole principali

CampoRegola
idempotency_keyUUID, obbligatorio, uno per documento. Con una chiave già usata sul PEM la risposta è il documento già emesso, anche se il payload è diverso: vedi Idempotenza, sotto.
elementi[].iva4, 5, 10, 22; N1–N6 per le operazioni senza IVA; VI per la ventilazione.
elementi[].bene_servizioB (bene) o S (servizio). Le righe di servizio non sono rendibili.
elementi[].prezzo_unitario, scontoImporti in euro IVA inclusa, al massimo due decimali. sconto è un importo, non una percentuale.
pagamentiObbligatori se il totale da pagare è maggiore di zero, e devono coprirlo. I contanti possono eccederlo (il resto si stampa); gli altri metodi no.
pagamenti[].metodoPC contanti, PP elettronico, TK buoni pasto (solo con l'opzione attiva), NRF, NRB, NRS, NRD non riscosso. NRF e NRD escludono altri pagamenti.
codice_lotteriaFino a 8 caratteri. Richiede almeno 1 euro pagato con un unico pagamento PP; alternativo a cessionario_committente.
cessionario_committenteCodice fiscale del cliente, fino a 16 caratteri. Alternativo a codice_lotteria.

Tutti i campi, compresi sconto sul subtotale, arrotondamento DL 50/2017 e dati della transazione POS, sono nel riferimento REST.

Importi e quantità

Invia importi e quantità come stringhe decimali con il punto ("8.00").

quantita ha al massimo due decimali ("1.5", "0.35"): il documento commerciale dell'Agenzia delle Entrate la registra con due decimali.

Idempotenza

Genera la idempotency_key e salvala con la vendita prima della chiamata: se la risposta non arriva (timeout, errore di rete), ripeti la stessa chiamata con la stessa chiave. Una chiave già usata sul PEM restituisce 200 con il PDF del documento già emesso, quindi lo stesso progressivo, e non emette nulla.

Annullo

L'annullo invalida una vendita dello stesso PEM: basta il suo progressivo (NNNN-PPPP), le righe si prendono dall'originale. Per un documento emesso da un altro dispositivo si indicano anche matricola_annullo, dataOra ed elementi.

POST …/fiscale/invio/annullo
curl -X POST \
  https://pem-staging.billyssw.it/api/pem/ASVS-241232/fiscale/invio/annullo \
  -H "Authorization: Bearer <access_token>" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "idempotency_key": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
    "progressivo": "0012-0007"
  }'

Reso

Il reso restituisce una o più righe di una vendita, in tutto o in parte. Prima leggi le righe dell'originale, con il loro id e la quantità già resa, partendo dall'hash ricevuto all'emissione:

GET …/fiscale/invio/reso?hash=…
curl "https://pem-staging.billyssw.it/api/pem/ASVS-241232/fiscale/invio/reso?hash=YjQ0ZDJmMGE5YzFl...MmEzYjQ%3D" \
  -H "Authorization: Bearer <access_token>" \
  -H "Accept: application/json"
200 OK
{
  "success": true,
  "dati": {
    "progressivo": "0012-0007",
    "data": "2026-10-08 10:15:42",
    "serial_number": "ASVS-241232",
    "elementi_contabili": [
      { "id": 5531, "descrizione": "Pizza margherita", "bene_servizio": "B", "quantita": "1.00", "prezzo_unitario": "8.00", "sconto": "0.00", "iva": "10", "reso": 0 }
    ]
  }
}

Poi emetti il reso con il progressivo dell'originale e, per ogni riga, l'id e la quantità resa:

POST …/fiscale/invio/reso
curl -X POST \
  https://pem-staging.billyssw.it/api/pem/ASVS-241232/fiscale/invio/reso \
  -H "Authorization: Bearer <access_token>" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "idempotency_key": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f",
    "progressivo": "0012-0007",
    "elementi": [
      { "id": 5531, "quantita": "1" }
    ]
  }'

Risposta

Annullo e reso rispondono come la vendita: il PDF firmato del documento di annullo o di reso, con un proprio progressivo e un proprio hash negli header. Gli errori tipici sono DC003 (già annullato), DC006 (quantità oltre il rendibile) e DC007 (riga di servizio).

Chiusura di cassa

La chiusura consolida il Journal della giornata e ne avvia la trasmissione al PEL, che invia i corrispettivi all'AdE. Non ha corpo e risponde subito; il resto avviene in background.

POST …/fiscale/invio/chiusura
curl -X POST \
  https://pem-staging.billyssw.it/api/pem/ASVS-241232/fiscale/invio/chiusura \
  -H "Authorization: Bearer <access_token>" \
  -H "Accept: application/json"
  • 409 JN005 subito dopo un'emissione: il documento è ancora in invio al PEL, riprova dopo qualche istante.
  • GET …/fiscale/chiusure/storico mostra la giornata chiusa; inviato_il si valorizza quando il PEL l'ha ricevuta.
  • GET …/fiscale/richieste?tipo=CORRISPETTIVI elenca le trasmissioni all'AdE: con richieste/stato/{id} se ne aggiorna lo stato, con richieste/esito/{id} si scarica l'esito XML.
  • Il primo documento emesso dopo la chiusura apre la giornata successiva. Se non effettui la chiusura manualmente, il sistema chiude automaticamente cassa entro 24 ore dall'apertura; oltre le 24 ore l'emissione risponde 409 JN002.