Hai crediti che aspetti di incassare e fatture che devi ancora pagare. Nexyzen, la piattaforma di Camera di Compensazione, cerca catene di debiti reciproci tra imprese e le chiude per compensazione, senza bonifici. Tu cedi un credito che vanti verso un tuo debitore, ricevi in cambio un credito equivalente da un altro partecipante, e il tuo debito si estingue. Nessun denaro si muove.
Questa guida spiega come collegare il tuo gestionale alla piattaforma via API: inviare le fatture, leggere le compensazioni che il motore propone, accettarle e recuperare l’atto di cessione del credito. Gli esempi sono in Java, PHP, C# e Python.
La documentazione interattiva, con cui provare le chiamate dal browser, è su cameracompensazione.github.io/cc_webservice.
Come è fatta l’API
C’è un solo indirizzo:
POST https://webapp.cameracompensazione.it/webservices/Content-Type: application/json
Ogni richiesta è un oggetto JSON con un campo op che dice quale operazione vuoi, il token di sessione jwt e un oggetto dati con i parametri:
{ "op": "nome_operazione", "jwt": "…", "dati": { } }
Le operazioni disponibili:
op | Cosa fa |
|---|---|
gjwt | apre la sessione e restituisce il token JWT |
cjwt | verifica che un JWT sia ancora valido |
ins_manuale | invia una fattura inserendone i dati a mano |
ins_dati | invia una fattura elettronica (XML, P7M o PDF) |
get_compensazioni | legge le compensazioni proposte per una P.IVA |
accetta_compensazione | accetta una compensazione |
get_lettere_cessione | recupera gli atti di cessione del credito |
Le risposte hanno sempre un campo result. Quando qualcosa va storto, result vale errore e message spiega il motivo. I codici HTTP seguono la convenzione usuale: 400 richiesta malformata, 401 non autorizzato, 422 dati non elaborabili, 503 servizio momentaneamente occupato.
Il ciclo di vita di una compensazione
Prima di scrivere codice, tieni presente il flusso, perché una parte non è istantanea.
- Invii le fatture. Carichi crediti e debiti della tua azienda.
- Il motore elabora. Periodicamente, il motore di clearing proprietario cerca nei dati i cicli di debiti reciproci che si possono chiudere. Non gira a ogni chiamata: le compensazioni compaiono dopo l’elaborazione successiva. Durante l’elaborazione il webservice risponde
503; riprovi più tardi. - Leggi le proposte. Con
get_compensazionivedi le compensazioni in attesa della tua accettazione. - Accetti. Con
accetta_compensazioneconfermi. Quando tutti i partecipanti del ciclo hanno accettato, il ciclo si perfeziona. - Ricevi l’atto. Con
get_lettere_cessionerecuperi l’atto di cessione del credito, che formalizza l’operazione.
Autenticazione
Per ottenere le credenziali (un cod_affiliato e un token) scrivi a commerciale@cameracompensazione.it. Sono le credenziali dell’integrazione, non di una singola azienda.
La sessione si apre con gjwt. Ricevi un JWT valido un’ora, da mettere nel campo jwt di ogni chiamata successiva.
{
"op": "gjwt",
"criptato": false,
"dati": { "cod_affiliato": "il_tuo_codice", "token": "il_tuo_token" }
}
Risposta:
{ "result": "Successful login", "jwt": "eyJ0eXAiOiJKV1Q…", "expireAt": 1788779798 }
token_azienda: l’autorizzazione sulla singola P.IVA
Le operazioni che leggono o modificano le compensazioni di un’azienda (get_compensazioni, accetta_compensazione, get_lettere_cessione) richiedono una prova che tu agisca per conto di quella P.IVA. La prova è il token_azienda, che il webservice ti restituisce la prima volta che invii una fattura per quell’azienda. Conservalo: lo passi nelle chiamate successive.
In alternativa leghi il JWT a una singola P.IVA fin dalla connessione, aggiungendo partita_iva e token_azienda ai dati di gjwt. Il JWT che ottieni vale solo per quell’azienda, e non devi più ripetere il token_azienda a ogni chiamata.
Inviare le fatture
Con ins_manuale invii una fattura passandone i campi. tipo_fattura vale v per una vendita (un tuo credito) o a per un acquisto (un tuo debito). Se ometti importo_residuo, o lo metti a zero, vale l’intero importo.
{
"op": "ins_manuale",
"jwt": "…",
"dati": {
"tipo_fattura": "v",
"partita_iva_creditore": "IT01234567897",
"partita_iva_debitore": "IT09876543210",
"data_fattura": "2026-09-01",
"numero_fattura": "2026/145",
"importo_totale": "1200.00"
}
}
Risposta:
{ "result": "ok", "inserted": [845], "token_azienda": "d4b8d6b5ebbf8923108f857e2849e874" }
Quel token_azienda è la chiave d’accesso alle compensazioni del proponente. Salvalo.
Se hai già la fattura elettronica, usa ins_dati: passi il file in base64 nel campo documento_base64 e il webservice ne estrae i dati. Accetta XML e P7M (che legge direttamente) e PDF (che mette in coda per la verifica manuale).
Leggere le compensazioni proposte
get_compensazioni restituisce le compensazioni in cui la tua azienda è cedente e che aspettano la tua accettazione.
{
"op": "get_compensazioni",
"jwt": "…",
"dati": { "partita_iva": "IT01234567897", "token_azienda": "d4b8d6b5…", "lingua": "it" }
}
Ogni elemento della risposta descrive l’operazione per intero: quale credito cedi e verso chi, quale tuo debito si compensa, a chi va il credito ceduto e da chi ricevi la contropartita. C’è anche il token monouso che ti serve per accettare, e anagrafica_mancante, l’elenco dei campi anagrafici che devi completare prima di poter accettare (di norma i dati del legale rappresentante, necessari all’atto di cessione).
{
"result": "ok",
"compensazioni": [{
"id_compensazione": 92,
"id_ciclo": 2927,
"importo": 1000,
"token": "JqCSY_ycKSvQdohe9yJgJYyuX0dbbAO4",
"anagrafica_mancante": ["nome_legale_rappresentante", "cognome_legale_rappresentante"],
"credito_verso": { "partita_iva": "IT099…", "ragione_sociale": "Beta S.p.A." },
"debito_verso": { "partita_iva": "IT033…", "ragione_sociale": "Gamma S.r.l." },
"credito_ceduto_a": { "partita_iva": "IT055…", "ragione_sociale": "Delta S.n.c." },
"credito_ricevuto_da": { "partita_iva": "IT077…", "ragione_sociale": "Epsilon S.r.l." },
"base_legale": "compensazione volontaria ex art. 1252 c.c."
}]
}
Accettare una compensazione
Qui sta la parte che richiede attenzione. Accettare non è un clic: cedi un credito a un terzo, e la legge chiede che tu dichiari e garantisca alcune cose su quel credito. L’API le pretende come le pretende il modulo web pubblico. Passi un oggetto dichiarazioni con undici conferme, tutte a true. Se ne manca una, la risposta è 422 e l’accettazione non passa.
Le undici conferme:
| Campo | Che cosa dichiari |
|---|---|
riconoscimento_credito | vanti il credito verso il tuo debitore |
riconoscimento_debito | hai il debito che viene compensato |
cessione_credito | cedi il credito al cessionario |
ricezione_credito | accetti il credito ricevuto in cambio |
dich_esistenza | il credito esiste, è certo, valido ed esigibile |
dich_titolarita | il credito è tuo e non è vincolato a favore di terzi |
dich_non_pagato | il credito non è stato pagato o estinto |
dich_non_contestato | il credito non è contestato né in causa |
dich_no_procedure | non sei in procedura concorsuale né insolvente |
dich_no_incedibilita | la cessione non viola divieti o vincoli |
dich_pro_soluto | prendi atto delle condizioni (cessione pro soluto) |
Se get_compensazioni ti ha restituito anagrafica_mancante non vuoto, aggiungi anche l’oggetto anagrafica con i campi mancanti. Le date vanno in formato AAAA-MM-GG.
{
"op": "accetta_compensazione",
"jwt": "…",
"dati": {
"token": "JqCSY_ycKSvQdohe9yJgJYyuX0dbbAO4",
"token_azienda": "d4b8d6b5…",
"anagrafica": {
"nome_legale_rappresentante": "Anna",
"cognome_legale_rappresentante": "Rossi",
"cf_legale_rappresentante": "RSSNNA80A41F158X",
"qualita_legale_rappresentante": "Amministratore Unico",
"luogo_nascita_legale_rappresentante": "Messina",
"data_nascita_legale_rappresentante": "1980-01-01"
},
"dichiarazioni": {
"riconoscimento_credito": true, "riconoscimento_debito": true,
"cessione_credito": true, "ricezione_credito": true,
"dich_esistenza": true, "dich_titolarita": true, "dich_non_pagato": true,
"dich_non_contestato": true, "dich_no_procedure": true,
"dich_no_incedibilita": true, "dich_pro_soluto": true
}
}
}
Risposta:
{ "result": "ok", "accepted": true, "id_compensazione": 92, "id_ciclo": 2927, "ciclo_completo": false }
ciclo_completo diventa true quando la tua accettazione è l’ultima che mancava: da quel momento il ciclo si perfeziona e gli atti partono.
Recuperare l’atto di cessione
Perfezionato il ciclo, get_lettere_cessione restituisce l’atto di cessione del credito per la tua azienda, già compilato e pronto in HTML. È lo stesso documento che la piattaforma notifica via PEC al debitore ceduto.
{
"op": "get_lettere_cessione",
"jwt": "…",
"dati": { "partita_iva": "IT01234567897", "token_azienda": "d4b8d6b5…", "tutte": false }
}
Con tutte: false ricevi solo gli atti nuovi e li marchi come consegnati; con tutte: true rileggi anche quelli già ritirati.
Stati ed errori da gestire
Tre casi meritano codice apposta:
503durante l’elaborazione. Mentre il motore cerca i cicli, il webservice rifiuta le nuove richieste. Riprova dopo qualche minuto invece di considerarlo un errore.401sultoken_azienda. Se leggi o accetti compensazioni senza iltoken_aziendagiusto (o senza un JWT legato alla P.IVA), ottieni401. Verifica di aver salvato il token restituito al primo invio fattura.422sulle dichiarazioni o sull’anagrafica. Manca una conferma o un campo obbligatorio. Ilmessageelenca cosa manca.
Scenari reali
Il gestionale che invia le fatture da solo. Un ERP come Odoo o SAP, a fine giornata, prende le fatture emesse e ricevute e le manda con ins_manuale o ins_dati. Alla prossima elaborazione, un job legge con get_compensazioni le proposte e le mostra all’amministrazione, che accetta con un clic. L’integrazione conserva un token_azienda per ogni azienda gestita.
La banca che mostra la liquidità nascosta. Una fintech o una banca d’impresa (Qonto integra la piattaforma con questa logica) legge le fatture non pagate del cliente, le invia, e quando compare una compensazione la propone dentro l’home banking come modo per liberare capitale circolante senza chiedere credito. L’atto di cessione recuperato con get_lettere_cessione diventa l’allegato dell’operazione.
Il portale pubblico. Un frontend che gira nel browser dell’utente non può custodire le credenziali dell’integrazione. Per questo gjwt accetta anche un payload cifrato (criptato: true), con cui il frontend ottiene un JWT a vita breve senza esporre il token. Lo usa il sito pubblico di Nexyzen.
Esempi completi
Ogni esempio fa lo stesso giro: apre la sessione, invia una fattura di vendita, legge le compensazioni e ne accetta una con le dichiarazioni. Cambia solo il linguaggio.
Java
import java.net.URI;
import java.net.http.*;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
public class NexyzenClient {
static final String URL = "https://webapp.cameracompensazione.it/webservices/";
static final HttpClient http = HttpClient.newHttpClient();
static final ObjectMapper json = new ObjectMapper();
static JsonNode call(Map<String,Object> body) throws Exception {
HttpRequest req = HttpRequest.newBuilder(URI.create(URL))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json.writeValueAsString(body)))
.build();
return json.readTree(http.send(req, HttpResponse.BodyHandlers.ofString()).body());
}
static Map<String,Boolean> dichiarazioni() {
String[] campi = {"riconoscimento_credito","riconoscimento_debito","cessione_credito",
"ricezione_credito","dich_esistenza","dich_titolarita","dich_non_pagato",
"dich_non_contestato","dich_no_procedure","dich_no_incedibilita","dich_pro_soluto"};
var d = new java.util.HashMap<String,Boolean>();
for (String c : campi) d.put(c, true);
return d;
}
public static void main(String[] args) throws Exception {
// 1. connessione
JsonNode login = call(Map.of("op","gjwt","criptato",false,
"dati", Map.of("cod_affiliato","IL_TUO_CODICE","token","IL_TUO_TOKEN")));
String jwt = login.get("jwt").asText();
// 2. invio di una fattura di vendita
JsonNode ins = call(Map.of("op","ins_manuale","jwt",jwt,
"dati", Map.of("tipo_fattura","v",
"partita_iva_creditore","IT01234567897",
"partita_iva_debitore","IT09876543210",
"data_fattura","2026-09-01","numero_fattura","2026/145",
"importo_totale","1200.00")));
String tokenAzienda = ins.get("token_azienda").asText();
// 3. lettura delle compensazioni proposte
JsonNode comp = call(Map.of("op","get_compensazioni","jwt",jwt,
"dati", Map.of("partita_iva","IT01234567897","token_azienda",tokenAzienda)));
if (!comp.has("compensazioni") || comp.get("compensazioni").isEmpty()) {
System.out.println("Nessuna compensazione: riprova dopo l'elaborazione.");
return;
}
// 4. accettazione della prima
String token = comp.get("compensazioni").get(0).get("token").asText();
JsonNode ok = call(Map.of("op","accetta_compensazione","jwt",jwt,
"dati", Map.of("token",token,"token_azienda",tokenAzienda,
"dichiarazioni", dichiarazioni())));
System.out.println("accettata: " + ok.get("accepted") + ", ciclo completo: " + ok.get("ciclo_completo"));
}
}
PHP
<?php
const URL = 'https://webapp.cameracompensazione.it/webservices/';
function call(array $body): array {
$ch = curl_init(URL);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($body),
]);
$resp = curl_exec($ch);
curl_close($ch);
return json_decode($resp, true);
}
function dichiarazioni(): array {
$campi = ['riconoscimento_credito','riconoscimento_debito','cessione_credito',
'ricezione_credito','dich_esistenza','dich_titolarita','dich_non_pagato',
'dich_non_contestato','dich_no_procedure','dich_no_incedibilita','dich_pro_soluto'];
return array_fill_keys($campi, true);
}
// 1. connessione
$login = call(['op'=>'gjwt','criptato'=>false,
'dati'=>['cod_affiliato'=>'IL_TUO_CODICE','token'=>'IL_TUO_TOKEN']]);
$jwt = $login['jwt'];
// 2. invio di una fattura di vendita
$ins = call(['op'=>'ins_manuale','jwt'=>$jwt,'dati'=>[
'tipo_fattura'=>'v',
'partita_iva_creditore'=>'IT01234567897',
'partita_iva_debitore'=>'IT09876543210',
'data_fattura'=>'2026-09-01','numero_fattura'=>'2026/145',
'importo_totale'=>'1200.00']]);
$tokenAzienda = $ins['token_azienda'];
// 3. lettura delle compensazioni proposte
$comp = call(['op'=>'get_compensazioni','jwt'=>$jwt,
'dati'=>['partita_iva'=>'IT01234567897','token_azienda'=>$tokenAzienda]]);
if (empty($comp['compensazioni'])) {
echo "Nessuna compensazione: riprova dopo l'elaborazione.\n";
exit;
}
// 4. accettazione della prima
$token = $comp['compensazioni'][0]['token'];
$ok = call(['op'=>'accetta_compensazione','jwt'=>$jwt,'dati'=>[
'token'=>$token,'token_azienda'=>$tokenAzienda,'dichiarazioni'=>dichiarazioni()]]);
echo "accettata: {$ok['accepted']}, ciclo completo: {$ok['ciclo_completo']}\n";
C#
using System.Net.Http;
using System.Text;
using System.Text.Json;
class NexyzenClient
{
const string Url = "https://webapp.cameracompensazione.it/webservices/";
static readonly HttpClient Http = new();
static async Task<JsonElement> Call(object body)
{
var content = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json");
var resp = await Http.PostAsync(Url, content);
var text = await resp.Content.ReadAsStringAsync();
return JsonDocument.Parse(text).RootElement;
}
static Dictionary<string, bool> Dichiarazioni()
{
string[] campi = { "riconoscimento_credito","riconoscimento_debito","cessione_credito",
"ricezione_credito","dich_esistenza","dich_titolarita","dich_non_pagato",
"dich_non_contestato","dich_no_procedure","dich_no_incedibilita","dich_pro_soluto" };
return campi.ToDictionary(c => c, _ => true);
}
static async Task Main()
{
// 1. connessione
var login = await Call(new { op = "gjwt", criptato = false,
dati = new { cod_affiliato = "IL_TUO_CODICE", token = "IL_TUO_TOKEN" } });
string jwt = login.GetProperty("jwt").GetString()!;
// 2. invio di una fattura di vendita
var ins = await Call(new { op = "ins_manuale", jwt, dati = new {
tipo_fattura = "v",
partita_iva_creditore = "IT01234567897",
partita_iva_debitore = "IT09876543210",
data_fattura = "2026-09-01", numero_fattura = "2026/145",
importo_totale = "1200.00" } });
string tokenAzienda = ins.GetProperty("token_azienda").GetString()!;
// 3. lettura delle compensazioni proposte
var comp = await Call(new { op = "get_compensazioni", jwt,
dati = new { partita_iva = "IT01234567897", token_azienda = tokenAzienda } });
var lista = comp.GetProperty("compensazioni");
if (lista.GetArrayLength() == 0)
{
Console.WriteLine("Nessuna compensazione: riprova dopo l'elaborazione.");
return;
}
// 4. accettazione della prima
string token = lista[0].GetProperty("token").GetString()!;
var ok = await Call(new { op = "accetta_compensazione", jwt, dati = new {
token, token_azienda = tokenAzienda, dichiarazioni = Dichiarazioni() } });
Console.WriteLine($"accettata: {ok.GetProperty("accepted")}, ciclo completo: {ok.GetProperty("ciclo_completo")}");
}
}
Python
import requests
URL = "https://webapp.cameracompensazione.it/webservices/"
def call(body: dict) -> dict:
return requests.post(URL, json=body, timeout=30).json()
def dichiarazioni() -> dict:
campi = ["riconoscimento_credito", "riconoscimento_debito", "cessione_credito",
"ricezione_credito", "dich_esistenza", "dich_titolarita", "dich_non_pagato",
"dich_non_contestato", "dich_no_procedure", "dich_no_incedibilita", "dich_pro_soluto"]
return {c: True for c in campi}
# 1. connessione
login = call({"op": "gjwt", "criptato": False,
"dati": {"cod_affiliato": "IL_TUO_CODICE", "token": "IL_TUO_TOKEN"}})
jwt = login["jwt"]
# 2. invio di una fattura di vendita
ins = call({"op": "ins_manuale", "jwt": jwt, "dati": {
"tipo_fattura": "v",
"partita_iva_creditore": "IT01234567897",
"partita_iva_debitore": "IT09876543210",
"data_fattura": "2026-09-01", "numero_fattura": "2026/145",
"importo_totale": "1200.00"}})
token_azienda = ins["token_azienda"]
# 3. lettura delle compensazioni proposte
comp = call({"op": "get_compensazioni", "jwt": jwt,
"dati": {"partita_iva": "IT01234567897", "token_azienda": token_azienda}})
if not comp.get("compensazioni"):
print("Nessuna compensazione: riprova dopo l'elaborazione.")
raise SystemExit
# 4. accettazione della prima
token = comp["compensazioni"][0]["token"]
ok = call({"op": "accetta_compensazione", "jwt": jwt, "dati": {
"token": token, "token_azienda": token_azienda, "dichiarazioni": dichiarazioni()}})
print("accettata:", ok["accepted"], "- ciclo completo:", ok["ciclo_completo"])
Da qui in poi
Con questi quattro passi copri l’integrazione completa. Prova prima le chiamate dalla documentazione interattiva, poi chiedi le credenziali a commerciale@cameracompensazione.it. Un consiglio pratico: gestisci il 503 con qualche tentativo distanziato, e salva il token_azienda di ogni azienda che segui, perché è la chiave di tutto ciò che riguarda le sue compensazioni.