Avvio rapido Germania
Questa guida rapida ti accompagna nell’autenticazione con l’API SIGN DE, nella creazione di una TSS (Technische Sicherheitseinrichtung) e nella firma della tua prima transazione. Al termine avrai un flusso di firma fiscale funzionante.
Prerequisiti
Sezione intitolata “Prerequisiti”- Un account fiskaly con un’organizzazione tedesca (registrati su hub.fiskaly.com)
- Una chiave API e un segreto generati nell’ambiente di TEST
- Uno strumento per effettuare richieste HTTP (cURL, Postman o il codice della tua applicazione)
Il tuo segreto API viene mostrato una sola volta. Salvalo immediatamente in un luogo sicuro.
Passaggi
Sezione intitolata “Passaggi”Autenticarsi
Usa la tua chiave API e il segreto per ottenere un token di accesso:
curl -X POST https://kassensichv-middleware.fiskaly.com/api/v2/auth \ -H "Content-Type: application/json" \ -d '{ "api_key": "YOUR_API_KEY", "api_secret": "YOUR_API_SECRET" }'const response = await fetch( "https://kassensichv-middleware.fiskaly.com/api/v2/auth", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ api_key: "YOUR_API_KEY", api_secret: "YOUR_API_SECRET", }), } ); const { access_token } = await response.json();import requests response = requests.post( "https://kassensichv-middleware.fiskaly.com/api/v2/auth", json={ "api_key": "YOUR_API_KEY", "api_secret": "YOUR_API_SECRET", }, ) access_token = response.json()["access_token"]HttpClient client = HttpClient.newHttpClient(); String body = """ {"api_key":"YOUR_API_KEY","api_secret":"YOUR_API_SECRET"} """; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://kassensichv-middleware.fiskaly.com/api/v2/auth")) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(body)) .build(); HttpResponse<String> response = client.send( request, HttpResponse.BodyHandlers.ofString()); // Parse response.body() for access_tokenusing var client = new HttpClient(); var payload = new { api_key = "YOUR_API_KEY", api_secret = "YOUR_API_SECRET" }; var response = await client.PostAsJsonAsync( "https://kassensichv-middleware.fiskaly.com/api/v2/auth", payload); var result = await response.Content .ReadFromJsonAsync<JsonElement>(); var accessToken = result .GetProperty("access_token").GetString();La risposta contiene un
access_token(valido 24h) e unrefresh_token(valido 48h).Creare e inizializzare una TSS
Crea una TSS, imposta il PIN amministratore, autenticati come amministratore e inizializza:
# Creare TSS TSS_ID=$(uuidgen) curl -X PUT "https://kassensichv-middleware.fiskaly.com/api/v2/tss/${TSS_ID}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"description": "Quickstart TSS"}' # Cambiare PIN amministratore curl -X PATCH "https://kassensichv-middleware.fiskaly.com/api/v2/tss/${TSS_ID}/admin" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"admin_puk": "ADMIN_PUK_FROM_RESPONSE", "new_admin_pin": "my-secure-pin"}' # Autenticarsi come amministratore curl -X POST "https://kassensichv-middleware.fiskaly.com/api/v2/tss/${TSS_ID}/admin/auth" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"admin_pin": "my-secure-pin"}' # Inizializzare TSS curl -X PATCH "https://kassensichv-middleware.fiskaly.com/api/v2/tss/${TSS_ID}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"state": "INITIALIZED"}'const tssId = crypto.randomUUID(); const BASE = "https://kassensichv-middleware.fiskaly.com/api/v2"; const headers = { "Authorization": `Bearer ${accessToken}`, "Content-Type": "application/json", }; // Creare TSS const tss = await fetch(`${BASE}/tss/${tssId}`, { method: "PUT", headers, body: JSON.stringify({ description: "Quickstart TSS" }), }).then(r => r.json()); // Cambiare PIN amministratore await fetch(`${BASE}/tss/${tssId}/admin`, { method: "PATCH", headers, body: JSON.stringify({ admin_puk: tss.admin_puk, new_admin_pin: "my-secure-pin", }), }); // Autenticarsi come amministratore await fetch(`${BASE}/tss/${tssId}/admin/auth`, { method: "POST", headers, body: JSON.stringify({ admin_pin: "my-secure-pin" }), }); // Inizializzare TSS await fetch(`${BASE}/tss/${tssId}`, { method: "PATCH", headers, body: JSON.stringify({ state: "INITIALIZED" }), });import uuid, requests tss_id = str(uuid.uuid4()) BASE = "https://kassensichv-middleware.fiskaly.com/api/v2" headers = {"Authorization": f"Bearer {access_token}"} # Creare TSS tss = requests.put(f"{BASE}/tss/{tss_id}", headers=headers, json={"description": "Quickstart TSS"}).json() # Cambiare PIN amministratore requests.patch(f"{BASE}/tss/{tss_id}/admin", headers=headers, json={"admin_puk": tss["admin_puk"], "new_admin_pin": "my-secure-pin"}) # Autenticarsi come amministratore requests.post(f"{BASE}/tss/{tss_id}/admin/auth", headers=headers, json={"admin_pin": "my-secure-pin"}) # Inizializzare TSS requests.patch(f"{BASE}/tss/{tss_id}", headers=headers, json={"state": "INITIALIZED"})String tssId = UUID.randomUUID().toString(); String BASE = "https://kassensichv-middleware.fiskaly.com/api/v2"; // Creare TSS HttpRequest createTss = HttpRequest.newBuilder() .uri(URI.create(BASE + "/tss/" + tssId)) .header("Authorization", "Bearer " + accessToken) .header("Content-Type", "application/json") .PUT(HttpRequest.BodyPublishers.ofString( "{\"description\":\"Quickstart TSS\"}")) .build(); String tssBody = client.send(createTss, HttpResponse.BodyHandlers.ofString()).body(); // Parse admin_puk from tssBody, then change PIN, auth, initialize...var tssId = Guid.NewGuid().ToString(); var BASE = "https://kassensichv-middleware.fiskaly.com/api/v2"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); // Creare TSS var tss = await client.PutAsJsonAsync( $"{BASE}/tss/{tssId}", new { description = "Quickstart TSS" }); var tssData = await tss.Content.ReadFromJsonAsync<JsonElement>(); var adminPuk = tssData.GetProperty("admin_puk").GetString(); // Cambiare PIN amministratore, Auth, Inizializzare seguono lo stesso schema...Creare un Client
CLIENT_ID=$(uuidgen) curl -X PUT "https://kassensichv-middleware.fiskaly.com/api/v2/tss/${TSS_ID}/client/${CLIENT_ID}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"serial_number": "POS-001"}'const clientId = crypto.randomUUID(); const clientResp = await fetch( `${BASE}/tss/${tssId}/client/${clientId}`, { method: "PUT", headers, body: JSON.stringify({ serial_number: "POS-001" }), } );client_id = str(uuid.uuid4()) requests.put(f"{BASE}/tss/{tss_id}/client/{client_id}", headers=headers, json={"serial_number": "POS-001"})String clientId = UUID.randomUUID().toString(); HttpRequest createClient = HttpRequest.newBuilder() .uri(URI.create(BASE + "/tss/" + tssId + "/client/" + clientId)) .header("Authorization", "Bearer " + accessToken) .header("Content-Type", "application/json") .PUT(HttpRequest.BodyPublishers.ofString( "{\"serial_number\":\"POS-001\"}")) .build(); client.send(createClient, HttpResponse.BodyHandlers.ofString());var clientId = Guid.NewGuid().ToString(); await client.PutAsJsonAsync( $"{BASE}/tss/{tssId}/client/{clientId}", new { serial_number = "POS-001" });Firmare la prima transazione
Avvia una transazione, poi completala con i dati della ricevuta:
TX_ID=$(uuidgen) # Avviare la transazione curl -X PUT "https://kassensichv-middleware.fiskaly.com/api/v2/tss/${TSS_ID}/tx/${TX_ID}?tx_revision=1" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"state": "ACTIVE", "client_id": "'${CLIENT_ID}'"}' # Completare la transazione con ricevuta curl -X PUT "https://kassensichv-middleware.fiskaly.com/api/v2/tss/${TSS_ID}/tx/${TX_ID}?tx_revision=2" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "state": "FINISHED", "client_id": "'${CLIENT_ID}'", "schema": { "standard_v1": { "receipt": { "receipt_type": "RECEIPT", "amounts_per_vat_rate": [{"vat_rate": "NORMAL", "amount": "10.00"}], "amounts_per_payment_type": [{"payment_type": "CASH", "amount": "10.00"}] } } } }'const txId = crypto.randomUUID(); // Avviare la transazione await fetch( `${BASE}/tss/${tssId}/tx/${txId}?tx_revision=1`, { method: "PUT", headers, body: JSON.stringify({ state: "ACTIVE", client_id: clientId }), } ); // Completare con i dati della ricevuta const tx = await fetch( `${BASE}/tss/${tssId}/tx/${txId}?tx_revision=2`, { method: "PUT", headers, body: JSON.stringify({ state: "FINISHED", client_id: clientId, schema: { standard_v1: { receipt: { receipt_type: "RECEIPT", amounts_per_vat_rate: [ { vat_rate: "NORMAL", amount: "10.00" }, ], amounts_per_payment_type: [ { payment_type: "CASH", amount: "10.00" }, ], }, }, }, }), } ).then(r => r.json()); console.log("Transazione firmata:", tx.signature);tx_id = str(uuid.uuid4()) # Avviare la transazione requests.put(f"{BASE}/tss/{tss_id}/tx/{tx_id}?tx_revision=1", headers=headers, json={"state": "ACTIVE", "client_id": client_id}) # Completare con i dati della ricevuta tx = requests.put(f"{BASE}/tss/{tss_id}/tx/{tx_id}?tx_revision=2", headers=headers, json={ "state": "FINISHED", "client_id": client_id, "schema": { "standard_v1": { "receipt": { "receipt_type": "RECEIPT", "amounts_per_vat_rate": [ {"vat_rate": "NORMAL", "amount": "10.00"} ], "amounts_per_payment_type": [ {"payment_type": "CASH", "amount": "10.00"} ], } } }, }).json() print("Firmato:", tx["signature"])String txId = UUID.randomUUID().toString(); // Avviare transazione: PUT /tss/{tssId}/tx/{txId}?tx_revision=1 // Body: {"state":"ACTIVE","client_id":"<clientId>"} // Completare transazione: PUT /tss/{tssId}/tx/{txId}?tx_revision=2 // Body: {"state":"FINISHED","client_id":"<clientId>","schema":{...}} // La risposta contiene la firma crittografica della TSSvar txId = Guid.NewGuid().ToString(); // Avviare: PUT /tss/{tssId}/tx/{txId}?tx_revision=1 // Body: { state = "ACTIVE", client_id = clientId } // Completare: PUT /tss/{tssId}/tx/{txId}?tx_revision=2 // Body: { state = "FINISHED", client_id = clientId, schema = {...} } // La risposta contiene la firma crittografica della TSSLa risposta include una
signaturecrittografica della TSS, ilsignature_countere tutti i dati necessari per una ricevuta conforme a KassenSichV.
Prossimi passi
Sezione intitolata “Prossimi passi”Was this page helpful?