diff --git a/office-alexander-logistics-app/pom.xml b/office-alexander-logistics-app/pom.xml
index c3fe427..83af5bb 100644
--- a/office-alexander-logistics-app/pom.xml
+++ b/office-alexander-logistics-app/pom.xml
@@ -398,12 +398,14 @@
+
- org.keycloak
- keycloak-authz-client
- 26.0.4
+ io.alapierre.ksef-sdk
+ ksef-client
+ 2.1.8
test
+
\ No newline at end of file
diff --git a/office-alexander-logistics-app/src/test/java/com/alexanderlogistics/ksef/Params.java b/office-alexander-logistics-app/src/test/java/com/alexanderlogistics/ksef/Params.java
new file mode 100644
index 0000000..37bdf5b
--- /dev/null
+++ b/office-alexander-logistics-app/src/test/java/com/alexanderlogistics/ksef/Params.java
@@ -0,0 +1,13 @@
+package com.alexanderlogistics.ksef;
+
+public class Params {
+ public static final String TOKEN = "20251113-EC-2751AC3000-5C5466924B-62|nip-9552521552|fc0c95d020dc45d4af491fb0aa755f3f3f674b33ecbf4250a88ea6e36fa8340b";
+ public static final String TOKENx = "20251113-EC-2751AC3000-5C5466924B-62.nip-9552521552.fc0c95d020dc45d4af491fb0aa755f3f3f674b33ecbf4250a88ea6e36fa8340b";
+ public static final String NIP = "9552521552";
+
+ public static String getEncodedToken() {
+ String result = java.util.Base64.getEncoder().encodeToString(Params.TOKEN.getBytes());
+
+ return result;
+ }
+}
diff --git a/office-alexander-logistics-app/src/test/java/com/alexanderlogistics/ksef/TestKSeF.java b/office-alexander-logistics-app/src/test/java/com/alexanderlogistics/ksef/TestKSeF.java
new file mode 100644
index 0000000..56a5a6c
--- /dev/null
+++ b/office-alexander-logistics-app/src/test/java/com/alexanderlogistics/ksef/TestKSeF.java
@@ -0,0 +1,124 @@
+package com.alexanderlogistics.ksef;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.util.logging.Logger;
+
+import org.imixs.workflow.exceptions.ModelException;
+import org.imixs.workflow.exceptions.PluginException;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * Test cases KSeF Interface
+ *
+ *
+ * @author rsoika
+ */
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+public class TestKSeF {
+
+ final static String ENCODING = "UTF-8";
+
+ private static Logger logger = Logger.getLogger(TestKSeF.class.getName());
+
+ // Configuration - replace with your actual values
+ private static final String KSEF_TEST_URL = "https://ksef-test.mf.gov.pl/api/v2";
+ // https://ksef-test.mf.gov.pl/api/v2/auth/challenge
+
+ private static HttpClient httpClient;
+ private static String challenge; // Static variable to share between tests
+
+ private final ObjectMapper objectMapper = new ObjectMapper();
+
+ @BeforeAll
+ public static void setupClass() {
+ logger.info("=== KSeF 2.0 Client Test ===");
+ logger.info("KSeF URL: " + KSEF_TEST_URL);
+ logger.info("NIP: " + Params.NIP);
+
+ httpClient = HttpClient.newBuilder()
+ .version(HttpClient.Version.HTTP_2)
+ .build();
+ }
+
+ @BeforeEach
+ public void setup() throws PluginException, ModelException {
+ logger.info("setup test environment ...");
+ }
+
+ @Test
+ @Order(1)
+ @DisplayName("Einfacher Challenge test 2.0 API")
+ public void testChallenge() throws Exception {
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(URI.create(KSEF_TEST_URL + "/auth/challenge")) // nur Endpoint checken
+ .header("Accept", "application/json")
+ .POST(HttpRequest.BodyPublishers.noBody()) //
+ .build();
+
+ HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+
+ System.out.println("Status: " + response.statusCode());
+ System.out.println("Response: " + response.body());
+
+ // Prüfen, dass wir eine API-Antwort bekommen, kein HTML
+ assertTrue(response.statusCode() < 500, "API sollte antworten, Status < 500");
+ assertFalse(response.body().contains(""), "Response sollte keine HTML-Seite sein");
+
+ // Challenge aus Response extrahieren und speichern
+ if (response.statusCode() == 200) {
+ JsonNode jsonNode = objectMapper.readTree(response.body());
+ challenge = jsonNode.get("challenge").asText();
+ logger.info("Extracted challenge: " + challenge);
+ }
+ }
+
+ @Test
+ @Order(2)
+ @DisplayName("KSeF Token Request")
+ public void testKsefToken() throws Exception {
+ // JSON Payload erstellen
+
+ String jsonPayload = String.format(
+ "{" +
+ "\"challenge\": \"%s\"," +
+ "\"contextIdentifier\": {" +
+ " \"type\": \"Nip\"," +
+ " \"value\": \"%s\"" +
+ "}," +
+ "\"encryptedToken\": \"%s\"" +
+ "}",
+ challenge, Params.NIP, Params.getEncodedToken());
+
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(URI.create(KSEF_TEST_URL + "/auth/ksef-token"))
+ .header("Accept", "application/json")
+ .header("Content-Type", "application/json")
+ .POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
+ .build();
+
+ HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+
+ System.out.println("Status: " + response.statusCode());
+ System.out.println("Response: " + response.body());
+
+ // Prüfen, dass wir eine API-Antwort bekommen
+ assertTrue(response.statusCode() < 500, "API sollte antworten, Status < 500");
+ assertFalse(response.body().contains(""), "Response sollte keine HTML-Seite sein");
+ }
+
+}