Ce démarrage rapide vous guide à travers l’authentification avec l’API SIGN DE, la création d’un TSS (système de sécurité technique) et la signature de votre première transaction. À la fin, vous disposerez d’un flux de signature fiscale fonctionnel.
Prérequis
Section intitulée « Prérequis »- Un compte fiskaly avec une organisation allemande (inscrivez-vous sur hub.fiskaly.com)
- Une clé API et un secret générés dans l’environnement de TEST
- Un outil pour effectuer des requêtes HTTP (cURL, Postman ou votre code d’application)
Votre secret API n’est affiché qu’une seule fois. Enregistrez-le immédiatement dans un endroit sûr.
S'authentifier
Utilisez votre clé API et votre secret pour obtenir un token d’accès :
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 réponse contient un
access_token(valide 24h) et unrefresh_token(valide 48h).Créer et initialiser un TSS
Créez un TSS, définissez le PIN administrateur, authentifiez-vous en tant qu’administrateur et initialisez :
# Créer le 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"}' # Changer le PIN administrateur 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"}' # S'authentifier en tant qu'administrateur 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"}' # Initialiser le 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", }; // Créer le TSS const tss = await fetch(`${BASE}/tss/${tssId}`, { method: "PUT", headers, body: JSON.stringify({ description: "Quickstart TSS" }), }).then(r => r.json()); // Changer le PIN administrateur await fetch(`${BASE}/tss/${tssId}/admin`, { method: "PATCH", headers, body: JSON.stringify({ admin_puk: tss.admin_puk, new_admin_pin: "my-secure-pin", }), }); // S'authentifier en tant qu'administrateur await fetch(`${BASE}/tss/${tssId}/admin/auth`, { method: "POST", headers, body: JSON.stringify({ admin_pin: "my-secure-pin" }), }); // Initialiser le 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}"} # Créer le TSS tss = requests.put(f"{BASE}/tss/{tss_id}", headers=headers, json={"description": "Quickstart TSS"}).json() # Changer le PIN administrateur requests.patch(f"{BASE}/tss/{tss_id}/admin", headers=headers, json={"admin_puk": tss["admin_puk"], "new_admin_pin": "my-secure-pin"}) # S'authentifier en tant qu'administrateur requests.post(f"{BASE}/tss/{tss_id}/admin/auth", headers=headers, json={"admin_pin": "my-secure-pin"}) # Initialiser le 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"; // Créer le 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(); // Parser admin_puk depuis tssBody, puis changer PIN, auth, initialiser...var tssId = Guid.NewGuid().ToString(); var BASE = "https://kassensichv-middleware.fiskaly.com/api/v2"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); // Créer le 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(); // Changer PIN admin, Auth, Initialiser suivent le même schéma...Créer 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" });Signer votre première transaction
Démarrez une transaction, puis terminez-la avec les données du reçu :
TX_ID=$(uuidgen) # Démarrer la transaction 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}'"}' # Terminer la transaction avec le reçu 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(); // Démarrer la transaction await fetch( `${BASE}/tss/${tssId}/tx/${txId}?tx_revision=1`, { method: "PUT", headers, body: JSON.stringify({ state: "ACTIVE", client_id: clientId }), } ); // Terminer avec les données du reçu 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("Transaction signée :", tx.signature);tx_id = str(uuid.uuid4()) # Démarrer la transaction requests.put(f"{BASE}/tss/{tss_id}/tx/{tx_id}?tx_revision=1", headers=headers, json={"state": "ACTIVE", "client_id": client_id}) # Terminer avec les données du reçu 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("Signé :", tx["signature"])String txId = UUID.randomUUID().toString(); // Démarrer la transaction : PUT /tss/{tssId}/tx/{txId}?tx_revision=1 // Body : {"state":"ACTIVE","client_id":"<clientId>"} // Terminer la transaction : PUT /tss/{tssId}/tx/{txId}?tx_revision=2 // Body : {"state":"FINISHED","client_id":"<clientId>","schema":{...}} // La réponse contient la signature cryptographique du TSSvar txId = Guid.NewGuid().ToString(); // Démarrer : PUT /tss/{tssId}/tx/{txId}?tx_revision=1 // Body : { state = "ACTIVE", client_id = clientId } // Terminer : PUT /tss/{tssId}/tx/{txId}?tx_revision=2 // Body : { state = "FINISHED", client_id = clientId, schema = {...} } // La réponse contient la signature cryptographique du TSSLa réponse inclut une
signaturecryptographique du TSS, lesignature_counteret toutes les données nécessaires pour un reçu conforme à KassenSichV.
Prochaines étapes
Section intitulée « Prochaines étapes »Guide d'intégration complet
Guide complet avec la configuration HUB, les collections Postman et toutes les sous-étapes
Référence API SIGN DE
Documentation complète des endpoints avec schémas et exemples
Gestion des erreurs
Meilleures pratiques pour les délais d'expiration, les nouvelles tentatives et la gestion des erreurs