@kreiseck/kasseneck-api 0.6.46 → 0.6.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/README.md +95 -15
  2. package/dist/cjs/client/aufrufe.d.ts +1 -1
  3. package/dist/cjs/client/aufrufe.js +1 -0
  4. package/dist/cjs/client/errors.d.ts +7 -1
  5. package/dist/cjs/client/errors.js +8 -1
  6. package/dist/cjs/client/receipts.d.ts +16 -0
  7. package/dist/cjs/client/receipts.js +10 -0
  8. package/dist/cjs/client/transport.js +5 -4
  9. package/dist/cjs/index.d.ts +1 -1
  10. package/dist/cjs/index.js +4 -2
  11. package/dist/cjs/models/cancellation.d.ts +22 -0
  12. package/dist/cjs/models/cancellation.js +31 -1
  13. package/dist/cjs/models/hobex-receipt.js +9 -2
  14. package/dist/cjs/models/index.d.ts +1 -1
  15. package/dist/cjs/models/index.js +3 -1
  16. package/dist/cjs/models/receipt.js +3 -0
  17. package/dist/cjs/models/voucher.js +18 -2
  18. package/dist/cjs/payments/hobex-hps/connect-client.d.ts +104 -0
  19. package/dist/cjs/payments/hobex-hps/connect-client.js +159 -0
  20. package/dist/cjs/payments/hobex-hps/errors.d.ts +122 -0
  21. package/dist/cjs/payments/hobex-hps/errors.js +158 -0
  22. package/dist/cjs/payments/hobex-hps/events.d.ts +22 -0
  23. package/dist/cjs/payments/hobex-hps/events.js +2 -0
  24. package/dist/cjs/payments/hobex-hps/index.d.ts +27 -0
  25. package/dist/cjs/payments/hobex-hps/index.js +66 -0
  26. package/dist/cjs/payments/hobex-hps/outcome.d.ts +31 -0
  27. package/dist/cjs/payments/hobex-hps/outcome.js +7 -0
  28. package/dist/cjs/payments/hobex-hps/payments.d.ts +149 -0
  29. package/dist/cjs/payments/hobex-hps/payments.js +550 -0
  30. package/dist/cjs/payments/hobex-hps/receipt.d.ts +28 -0
  31. package/dist/cjs/payments/hobex-hps/receipt.js +60 -0
  32. package/dist/cjs/payments/hobex-hps/transaction-id.d.ts +65 -0
  33. package/dist/cjs/payments/hobex-hps/transaction-id.js +91 -0
  34. package/dist/cjs/payments/hobex-hps/transaction-response.d.ts +163 -0
  35. package/dist/cjs/payments/hobex-hps/transaction-response.js +245 -0
  36. package/dist/cjs/payments/hobex.js +9 -6
  37. package/dist/cjs/payments/index.d.ts +26 -14
  38. package/dist/cjs/payments/index.js +59 -15
  39. package/dist/cjs/printing/index.d.ts +1 -1
  40. package/dist/cjs/printing/index.js +2 -1
  41. package/dist/cjs/printing/webusb.d.ts +37 -7
  42. package/dist/cjs/printing/webusb.js +76 -18
  43. package/dist/cjs/receipt/epos.d.ts +18 -0
  44. package/dist/cjs/receipt/epos.js +78 -6
  45. package/dist/cjs/receipt/index.d.ts +1 -1
  46. package/dist/cjs/receipt/index.js +2 -1
  47. package/dist/cjs/register/index.d.ts +1 -1
  48. package/dist/cjs/register/index.js +2 -1
  49. package/dist/cjs/register/pairing.d.ts +59 -0
  50. package/dist/cjs/register/pairing.js +51 -2
  51. package/dist/esm/client/aufrufe.d.ts +1 -1
  52. package/dist/esm/client/aufrufe.js +1 -0
  53. package/dist/esm/client/errors.d.ts +7 -1
  54. package/dist/esm/client/errors.js +8 -1
  55. package/dist/esm/client/receipts.d.ts +16 -0
  56. package/dist/esm/client/receipts.js +10 -0
  57. package/dist/esm/client/transport.js +5 -4
  58. package/dist/esm/index.d.ts +1 -1
  59. package/dist/esm/index.js +1 -1
  60. package/dist/esm/models/cancellation.d.ts +22 -0
  61. package/dist/esm/models/cancellation.js +29 -0
  62. package/dist/esm/models/hobex-receipt.js +10 -3
  63. package/dist/esm/models/index.d.ts +1 -1
  64. package/dist/esm/models/index.js +1 -1
  65. package/dist/esm/models/receipt.js +3 -0
  66. package/dist/esm/models/voucher.js +18 -2
  67. package/dist/esm/payments/hobex-hps/connect-client.d.ts +104 -0
  68. package/dist/esm/payments/hobex-hps/connect-client.js +156 -0
  69. package/dist/esm/payments/hobex-hps/errors.d.ts +122 -0
  70. package/dist/esm/payments/hobex-hps/errors.js +149 -0
  71. package/dist/esm/payments/hobex-hps/events.d.ts +22 -0
  72. package/dist/esm/payments/hobex-hps/events.js +1 -0
  73. package/dist/esm/payments/hobex-hps/index.d.ts +27 -0
  74. package/dist/esm/payments/hobex-hps/index.js +26 -0
  75. package/dist/esm/payments/hobex-hps/outcome.d.ts +31 -0
  76. package/dist/esm/payments/hobex-hps/outcome.js +4 -0
  77. package/dist/esm/payments/hobex-hps/payments.d.ts +149 -0
  78. package/dist/esm/payments/hobex-hps/payments.js +547 -0
  79. package/dist/esm/payments/hobex-hps/receipt.d.ts +28 -0
  80. package/dist/esm/payments/hobex-hps/receipt.js +57 -0
  81. package/dist/esm/payments/hobex-hps/transaction-id.d.ts +65 -0
  82. package/dist/esm/payments/hobex-hps/transaction-id.js +86 -0
  83. package/dist/esm/payments/hobex-hps/transaction-response.d.ts +163 -0
  84. package/dist/esm/payments/hobex-hps/transaction-response.js +233 -0
  85. package/dist/esm/payments/hobex.js +9 -6
  86. package/dist/esm/payments/index.d.ts +26 -14
  87. package/dist/esm/payments/index.js +26 -14
  88. package/dist/esm/printing/index.d.ts +1 -1
  89. package/dist/esm/printing/index.js +1 -1
  90. package/dist/esm/printing/webusb.d.ts +37 -7
  91. package/dist/esm/printing/webusb.js +74 -17
  92. package/dist/esm/receipt/epos.d.ts +18 -0
  93. package/dist/esm/receipt/epos.js +76 -6
  94. package/dist/esm/receipt/index.d.ts +1 -1
  95. package/dist/esm/receipt/index.js +1 -1
  96. package/dist/esm/register/index.d.ts +1 -1
  97. package/dist/esm/register/index.js +1 -1
  98. package/dist/esm/register/pairing.d.ts +59 -0
  99. package/dist/esm/register/pairing.js +50 -2
  100. package/fixtures/hobex-hps-codes.json +67 -0
  101. package/fixtures/oberflaeche.json +2 -1
  102. package/package.json +4 -2
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Erzeugung und Pruefung der HPS-Transaktionskennung.
3
+ *
4
+ * **Die Kennung steht VOR dem ersten Netzweg fest.** Kasseneck Connects
5
+ * eigene Doku sagt es woertlich: "`transactionId` MUSS die Kasse vergeben und
6
+ * sich merken" (`kasseneck-connect/lib/src/api/routes_terminal.dart`,
7
+ * `_handlePayment`). Ohne das ist ein abgerissener Vorgang unauffindbar — das
8
+ * ist der Kernfehler vom 24.08.2026.
9
+ *
10
+ * **Warum nicht `newHobexTransactionId` aus `../hobex.js`?** Diese Funktion
11
+ * erzeugt 19 Ziffern (Zeitanteil + Zufall) fuer die Hobex-CLOUD-API, die keine
12
+ * Laengengrenze dokumentiert. Das HPS-REST-Terminal dagegen erlaubt
13
+ * hoechstens **18** Ziffern (`kasseneck-connect`s eigene Pruefung,
14
+ * `_transactionId`-Regex in `routes_terminal.dart`, und `HpsClient`s
15
+ * `_maxTransactionIdLength` im Dart-Zwilling) — eine 19-stellige Kennung waere
16
+ * an dieser Schnittstelle bereits eine Formverletzung, VOR jeder Pruefung auf
17
+ * "rein numerisch". Sie taugt hier also nicht.
18
+ *
19
+ * Stattdessen **derselbe Ansatz wie `HpsClient.newTransactionId()`** im
20
+ * Dart-Zwilling: Millisekunden-Zeitstempel (13 Ziffern) plus ein 5-stelliger
21
+ * Zaehler je Millisekunde, macht genau 18 Ziffern. Der Zeitstempel beginnt
22
+ * bis zum Jahr 2286 nicht mit einer Null — das schliesst die Falle, vor der
23
+ * gewarnt wurde ("fuehrende Nullen werden am Terminal normalisiert, zwei
24
+ * Kennungen waeren sonst derselbe Vorgang"): zwei in dieser Millisekunde
25
+ * erzeugte Kennungen unterscheiden sich immer im Zaehler-Suffix, nie nur in
26
+ * einer fuehrenden Null.
27
+ */
28
+ /** Laengengrenze der Kennung laut HPS-REST-Spezifikation (siehe oben). */
29
+ export declare const MAX_TRANSACTION_ID_LENGTH = 18;
30
+ /**
31
+ * `true`, wenn [value] als HPS-Transaktionskennung taugt: nicht leer,
32
+ * hoechstens [MAX_TRANSACTION_ID_LENGTH] Zeichen, rein numerisch.
33
+ *
34
+ * Bewusst KEINE Pruefung auf eine fuehrende Null bei einer selbst
35
+ * UEBERGEBENEN Kennung — weder Connects Formregel noch der Dart-Zwilling
36
+ * verlangen das von einem Aufrufer, der eine eigene Kennung mitbringt (siehe
37
+ * `HpsClient._checkTransactionId`). Die Falle betrifft nur die ERZEUGUNG,
38
+ * siehe [newHpsTransactionId].
39
+ */
40
+ export declare function isValidHpsTransactionId(value: string): boolean;
41
+ export interface HpsTransactionIdGeneratorOptions {
42
+ /** Uhr fuer die Kennung; Vorgabe `Date.now`. Einspeisbar fuer Tests. */
43
+ now?: () => number;
44
+ }
45
+ /**
46
+ * Erzeugt eine Funktion, die bei jedem Aufruf eine neue, innerhalb dieses
47
+ * Erzeugers eindeutige Kennung liefert.
48
+ *
49
+ * Eindeutigkeit ist eine LOGISCHE Uhr, angelehnt an das Snowflake-Verfahren:
50
+ * die zuletzt vergebene Millisekunde laeuft niemals rueckwaerts. Liefert die
51
+ * Uhr keinen groesseren Wert als beim letzten Aufruf — egal ob dieselbe
52
+ * Millisekunde oder eine zurueckspringende Uhr (Zeitumstellung,
53
+ * NTP-Korrektur) — bleibt die Millisekunde stehen und nur der Zaehler steigt.
54
+ * Ist der Zaehler einer Millisekunde ausgeschoepft (100000 Kennungen),
55
+ * schaltet die Millisekunde gedanklich um eins weiter.
56
+ *
57
+ * Die Garantie gilt nur INNERHALB des einen Erzeugers (eigener, gekapselter
58
+ * Zustand) — zwei getrennte Erzeuger oder Prozesse, die in derselben
59
+ * Millisekunde eine Kennung bilden, koennen kollidieren. Fuer den Einsatz
60
+ * hier passt das: eine Kasse erzeugt Kennungen aus genau einem laufenden
61
+ * Prozess.
62
+ */
63
+ export declare function createHpsTransactionIdGenerator(options?: HpsTransactionIdGeneratorOptions): () => string;
64
+ /** Bequeme Vorgabeinstanz fuer den Alltagsgebrauch — eigener, gekapselter Zustand. */
65
+ export declare const newHpsTransactionId: () => string;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ /**
3
+ * Erzeugung und Pruefung der HPS-Transaktionskennung.
4
+ *
5
+ * **Die Kennung steht VOR dem ersten Netzweg fest.** Kasseneck Connects
6
+ * eigene Doku sagt es woertlich: "`transactionId` MUSS die Kasse vergeben und
7
+ * sich merken" (`kasseneck-connect/lib/src/api/routes_terminal.dart`,
8
+ * `_handlePayment`). Ohne das ist ein abgerissener Vorgang unauffindbar — das
9
+ * ist der Kernfehler vom 24.08.2026.
10
+ *
11
+ * **Warum nicht `newHobexTransactionId` aus `../hobex.js`?** Diese Funktion
12
+ * erzeugt 19 Ziffern (Zeitanteil + Zufall) fuer die Hobex-CLOUD-API, die keine
13
+ * Laengengrenze dokumentiert. Das HPS-REST-Terminal dagegen erlaubt
14
+ * hoechstens **18** Ziffern (`kasseneck-connect`s eigene Pruefung,
15
+ * `_transactionId`-Regex in `routes_terminal.dart`, und `HpsClient`s
16
+ * `_maxTransactionIdLength` im Dart-Zwilling) — eine 19-stellige Kennung waere
17
+ * an dieser Schnittstelle bereits eine Formverletzung, VOR jeder Pruefung auf
18
+ * "rein numerisch". Sie taugt hier also nicht.
19
+ *
20
+ * Stattdessen **derselbe Ansatz wie `HpsClient.newTransactionId()`** im
21
+ * Dart-Zwilling: Millisekunden-Zeitstempel (13 Ziffern) plus ein 5-stelliger
22
+ * Zaehler je Millisekunde, macht genau 18 Ziffern. Der Zeitstempel beginnt
23
+ * bis zum Jahr 2286 nicht mit einer Null — das schliesst die Falle, vor der
24
+ * gewarnt wurde ("fuehrende Nullen werden am Terminal normalisiert, zwei
25
+ * Kennungen waeren sonst derselbe Vorgang"): zwei in dieser Millisekunde
26
+ * erzeugte Kennungen unterscheiden sich immer im Zaehler-Suffix, nie nur in
27
+ * einer fuehrenden Null.
28
+ */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.newHpsTransactionId = exports.MAX_TRANSACTION_ID_LENGTH = void 0;
31
+ exports.isValidHpsTransactionId = isValidHpsTransactionId;
32
+ exports.createHpsTransactionIdGenerator = createHpsTransactionIdGenerator;
33
+ /** Laengengrenze der Kennung laut HPS-REST-Spezifikation (siehe oben). */
34
+ exports.MAX_TRANSACTION_ID_LENGTH = 18;
35
+ const NUMERIC_TRANSACTION_ID = /^\d+$/;
36
+ /**
37
+ * `true`, wenn [value] als HPS-Transaktionskennung taugt: nicht leer,
38
+ * hoechstens [MAX_TRANSACTION_ID_LENGTH] Zeichen, rein numerisch.
39
+ *
40
+ * Bewusst KEINE Pruefung auf eine fuehrende Null bei einer selbst
41
+ * UEBERGEBENEN Kennung — weder Connects Formregel noch der Dart-Zwilling
42
+ * verlangen das von einem Aufrufer, der eine eigene Kennung mitbringt (siehe
43
+ * `HpsClient._checkTransactionId`). Die Falle betrifft nur die ERZEUGUNG,
44
+ * siehe [newHpsTransactionId].
45
+ */
46
+ function isValidHpsTransactionId(value) {
47
+ return value.length > 0 && value.length <= exports.MAX_TRANSACTION_ID_LENGTH && NUMERIC_TRANSACTION_ID.test(value);
48
+ }
49
+ /**
50
+ * Erzeugt eine Funktion, die bei jedem Aufruf eine neue, innerhalb dieses
51
+ * Erzeugers eindeutige Kennung liefert.
52
+ *
53
+ * Eindeutigkeit ist eine LOGISCHE Uhr, angelehnt an das Snowflake-Verfahren:
54
+ * die zuletzt vergebene Millisekunde laeuft niemals rueckwaerts. Liefert die
55
+ * Uhr keinen groesseren Wert als beim letzten Aufruf — egal ob dieselbe
56
+ * Millisekunde oder eine zurueckspringende Uhr (Zeitumstellung,
57
+ * NTP-Korrektur) — bleibt die Millisekunde stehen und nur der Zaehler steigt.
58
+ * Ist der Zaehler einer Millisekunde ausgeschoepft (100000 Kennungen),
59
+ * schaltet die Millisekunde gedanklich um eins weiter.
60
+ *
61
+ * Die Garantie gilt nur INNERHALB des einen Erzeugers (eigener, gekapselter
62
+ * Zustand) — zwei getrennte Erzeuger oder Prozesse, die in derselben
63
+ * Millisekunde eine Kennung bilden, koennen kollidieren. Fuer den Einsatz
64
+ * hier passt das: eine Kasse erzeugt Kennungen aus genau einem laufenden
65
+ * Prozess.
66
+ */
67
+ function createHpsTransactionIdGenerator(options = {}) {
68
+ const now = options.now ?? Date.now;
69
+ let lastMs = null;
70
+ let counter = 0;
71
+ return function newHpsTransactionId() {
72
+ const current = Math.trunc(now());
73
+ let ms;
74
+ if (lastMs === null || current > lastMs) {
75
+ ms = current;
76
+ counter = 0;
77
+ }
78
+ else {
79
+ ms = lastMs;
80
+ counter += 1;
81
+ if (counter >= 100_000) {
82
+ ms += 1;
83
+ counter = 0;
84
+ }
85
+ }
86
+ lastMs = ms;
87
+ return `${ms}${String(counter).padStart(5, '0')}`;
88
+ };
89
+ }
90
+ /** Bequeme Vorgabeinstanz fuer den Alltagsgebrauch — eigener, gekapselter Zustand. */
91
+ exports.newHpsTransactionId = createHpsTransactionIdGenerator();
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Antwort des hobex-HPS-Terminals auf eine Zahlung oder eine Statusabfrage,
3
+ * durchgereicht von **Kasseneck Connect** (`POST /v1/terminal/payment`,
4
+ * `/status`, `/abort` — Feld `hps` im Erfolgsrumpf). Connect ordnet nichts
5
+ * ein, es reicht den Terminal-Rumpf roh durch — die Einordnung passiert hier.
6
+ *
7
+ * **Zwilling:** `kasseneck_api/lib/src/hobex_hps/transaction_response.dart`.
8
+ * Beide Seiten pinnen dieselbe Codetabelle, siehe `HPS_MEASURED_CODES` unten
9
+ * und `fixtures/hobex-hps-codes.json`.
10
+ *
11
+ * **`responseCode !== '0'` ist NICHT die Pruefung auf eine Ablehnung.** Genau
12
+ * diese Lesart hat am 24.08.2026 zur doppelten Belastung gefuehrt:
13
+ * [NO_STATEMENT_CODE] (`9027`) ist ein Code ungleich `'0'` und sagt trotzdem
14
+ * nichts aus — er steht am gemessenen Terminal gleichermassen fuer "laeuft
15
+ * gerade", "abgebrochen" und "nie gesehen". Wer ihn als Ablehnung liest,
16
+ * meldet fuer einen LAUFENDEN Vorgang "nichts belastet, Wiederholung
17
+ * gefahrlos".
18
+ *
19
+ * [isConclusive] ist die einzige Stelle, an der ein Code zu einem Ausgang
20
+ * wird — und sie ist eine ECHTE Positivliste: nur ein Code, dessen Bedeutung
21
+ * GEMESSEN und in [HPS_MEASURED_CODES] benannt ist, zaehlt. Jeder andere —
22
+ * auch ein neuer, heute noch unbekannter Code — ist eine Wissensluecke, siehe
23
+ * [isUnknownCode]. Am 27.08.2026 hat der Dart-Zwilling gemessen, warum die
24
+ * Gegenrichtung ("jeder Code ausser 9027 ist schluessig") gefaehrlich ist: ein
25
+ * bis dahin unbenannter Code ([TECHNICAL_ERROR_CODE], `9900`) war darueber
26
+ * schluessig und haette eine Zahlung, unter der tatsaechlich Geld geflossen
27
+ * sein kann, als `declined` gemeldet.
28
+ */
29
+ /** Ein Ergebniscode, dessen Bedeutung GEMESSEN und hier benannt ist. */
30
+ export interface HpsMeasuredCode {
31
+ /** Der Ergebniscode, wie ihn das Terminal im Feld `responseCode` sendet. */
32
+ readonly code: string;
33
+ /** Bedeutung, wie gemessen — deutsch, ohne Umlaute (siehe Vorbild). */
34
+ readonly meaning: string;
35
+ /**
36
+ * `true`: der Code schreibt einen Ausgang fest (Teil der Positivliste,
37
+ * siehe [isConclusive]). `false`: gemessen und benannt, aber ausdruecklich
38
+ * KEINE Aussage ueber den Vorgang (9027, 9900).
39
+ */
40
+ readonly conclusive: boolean;
41
+ }
42
+ /**
43
+ * Die gemessene Codetabelle — Vertrag mit dem Dart-Zwilling, siehe
44
+ * `fixtures/hobex-hps-codes.json`. Gemessen an einem hobex-HPS (TID 3600335,
45
+ * HPS 1.10.0, Firmware 7.3.6, 26.–28.08.2026).
46
+ *
47
+ * Reihenfolge ist die im Messprotokoll (`doc/kartenzahlung.md` im
48
+ * Dart-Zwilling) — numerisch aufsteigend zu sortieren wuerde beim Diff
49
+ * gegen die Vertragsdatei nichts gewinnen und macht Aenderungen schwerer
50
+ * nachzuverfolgen.
51
+ */
52
+ export declare const HPS_MEASURED_CODES: readonly HpsMeasuredCode[];
53
+ /** `responseCode` einer genehmigten Zahlung. */
54
+ export declare const APPROVED_CODE = "0";
55
+ /** Siehe [HPS_MEASURED_CODES]: ungueltiger Vorgang, nichts passiert. */
56
+ export declare const INVALID_TRANSACTION_CODE = "9002";
57
+ /** Siehe [HPS_MEASURED_CODES]: aufgehoben. */
58
+ export declare const TRANSACTION_CANCELED_CODE = "9011";
59
+ /** Siehe [HPS_MEASURED_CODES]: keine Aussage. */
60
+ export declare const NO_STATEMENT_CODE = "9027";
61
+ /** Siehe [HPS_MEASURED_CODES]: Kennung nicht numerisch, keine Aussage. */
62
+ export declare const TECHNICAL_ERROR_CODE = "9900";
63
+ /** Siehe [HPS_MEASURED_CODES]: abgebrochen. */
64
+ export declare const ABORTED_CODE = "100002";
65
+ /** Siehe [HPS_MEASURED_CODES]: Karte nicht aufgelegt. */
66
+ export declare const CARD_NOT_PRESENT_CODE = "100003";
67
+ /** Siehe [HPS_MEASURED_CODES]: nicht mehr abbrechbar. */
68
+ export declare const NOT_ABORTABLE_CODE = "100010";
69
+ /** Siehe [HPS_MEASURED_CODES]: Betrag abgewiesen, vor dem Kartenfluss. */
70
+ export declare const INVALID_AMOUNT_CODE = "9003";
71
+ /** Siehe [HPS_MEASURED_CODES]: Betrag ausserhalb des zulaessigen Bereichs. */
72
+ export declare const AMOUNT_OUT_OF_RANGE_CODE = "100019";
73
+ /** Siehe [HPS_MEASURED_CODES]: Terminal-Kennung unbekannt. */
74
+ export declare const INVALID_TID_CODE = "100108";
75
+ /**
76
+ * HTTP `409` ("Terminal is busy"): das Terminal serialisiert und weist eine
77
+ * zweite Anfrage ab, waehrend eine erste noch laeuft. Am 27.08.2026 gemessen:
78
+ * kommt nach 87 Millisekunden, der abgewiesene Vorgang hinterlaesst KEINE
79
+ * Spur (die Statusabfrage auf seine Kennung liefert weiterhin
80
+ * [NO_STATEMENT_CODE]).
81
+ *
82
+ * Bewusst KEIN Eintrag in [HPS_MEASURED_CODES]: es ist ein HTTP-Status, kein
83
+ * `responseCode` — er entsteht, bevor ueberhaupt ein Antwortrumpf gelesen
84
+ * wird. Siehe `errors.ts` (`HpsConnectTerminalError.isTerminalBusy`) fuer die
85
+ * getrennte Auswertung.
86
+ */
87
+ export declare const TERMINAL_BUSY_HTTP_STATUS = 409;
88
+ /** Antwort des Terminals — Zahlung, Statusabfrage oder Abbruch. */
89
+ export interface HpsTransactionResponse {
90
+ /** Kennung dieser Transaktion, wie vom Terminal bestaetigt bzw. echoed. */
91
+ readonly transactionId: string | undefined;
92
+ /** Kennung der Original-Transaktion (Gutschrift, Aufhebung). */
93
+ readonly originalTransactionId: string | undefined;
94
+ readonly tid: string | undefined;
95
+ readonly receipt: string | undefined;
96
+ readonly approvalCode: string | undefined;
97
+ readonly reference: string | undefined;
98
+ readonly transactionDate: string | undefined;
99
+ readonly cardNumber: string | undefined;
100
+ readonly cardExpiry: string | undefined;
101
+ readonly brand: string | undefined;
102
+ readonly cardIssuer: string | undefined;
103
+ readonly transactionType: string | undefined;
104
+ readonly currency: string | undefined;
105
+ readonly amount: number | undefined;
106
+ readonly tip: number | undefined;
107
+ /**
108
+ * Ergebniscode. `undefined` (nur bei einer Statusabfrage moeglich) heisst
109
+ * "laeuft noch" — siehe [isInProgress]. Auf dieser Firmware ungemessen,
110
+ * bleibt aber ebenso eine Nicht-Aussage wie [NO_STATEMENT_CODE].
111
+ *
112
+ * Ein leerer String aus dem Rumpf wird beim Einlesen zu `undefined`
113
+ * normalisiert (siehe [parseHpsTransactionResponse]): er traegt keine
114
+ * Aussage, und `!== '0'` wuerde ihn sonst faelschlich als Ablehnung lesen.
115
+ */
116
+ readonly responseCode: string | undefined;
117
+ readonly responseText: string | undefined;
118
+ /** Nur Statusabfrage (v2). Auf der gemessenen Firmware durchgehend `undefined`. */
119
+ readonly state: string | undefined;
120
+ /** Der roh decodierte Rumpf, fuer Felder ohne eigenes Modell. */
121
+ readonly raw: Record<string, unknown>;
122
+ }
123
+ /**
124
+ * Liest eine Terminal-Antwort aus dem `hps`-Feld der Connect-Huelle.
125
+ *
126
+ * Wirft, wenn [raw] keine brauchbare Form hat (kein Objekt) — das ist ein
127
+ * Formfehler der Antwort, kein Ausgang der Zahlung, und wird vom Aufrufer
128
+ * (`payments.ts`) genauso behandelt wie jeder andere unerwartete Fehler: die
129
+ * Klaerung laeuft konservativ weiter, statt ihn stillschweigend als
130
+ * "laeuft noch" zu deuten.
131
+ */
132
+ export declare function parseHpsTransactionResponse(raw: unknown): HpsTransactionResponse;
133
+ /** `true`, wenn der Vorgang genehmigt ist. */
134
+ export declare function isApproved(res: Pick<HpsTransactionResponse, 'responseCode'>): boolean;
135
+ /** `true`, wenn eine Statusabfrage meldet, der Vorgang laeuft noch (kein Code). */
136
+ export declare function isInProgress(res: Pick<HpsTransactionResponse, 'responseCode'>): boolean;
137
+ /** `true`, wenn ein Abbruch daran scheiterte, dass der Vorgang nicht mehr abbrechbar war. */
138
+ export declare function isNotAbortable(res: Pick<HpsTransactionResponse, 'responseCode'>): boolean;
139
+ /** `true`, wenn das Terminal zu dieser Kennung keine Auskunft gibt (9027). */
140
+ export declare function isNoStatement(res: Pick<HpsTransactionResponse, 'responseCode'>): boolean;
141
+ /** `true`, wenn das Terminal einen technischen Fehler meldet (9900). */
142
+ export declare function isTechnicalError(res: Pick<HpsTransactionResponse, 'responseCode'>): boolean;
143
+ /**
144
+ * `true`, wenn der Vorgang unter dieser Kennung aufgehoben wurde (9011).
145
+ *
146
+ * Vorsicht bei der Verwendung: fuer die DIREKTE Antwort auf eine Aufhebung
147
+ * bedeutet dieser Code etwas anderes als bei einer Statusabfrage auf die
148
+ * Originalzahlung -- siehe `payments.ts`, `fromCancelResponse` vs.
149
+ * `fromCancelStatus`.
150
+ */
151
+ export declare function isCanceled(res: Pick<HpsTransactionResponse, 'responseCode'>): boolean;
152
+ /**
153
+ * `true`, wenn diese Antwort ueberhaupt eine Aussage ueber den Ausgang
154
+ * traegt — ein Ergebniscode, der in [HPS_MEASURED_CODES] als `conclusive`
155
+ * gefuehrt wird. Die einzige Stelle, an der ein Code zu einem Ausgang wird.
156
+ */
157
+ export declare function isConclusive(res: Pick<HpsTransactionResponse, 'responseCode'>): boolean;
158
+ /**
159
+ * `true`, wenn ein Ergebniscode VORHANDEN ist, aber weder schluessig noch
160
+ * eine der beiden gemessenen Wissensluecken ([isNoStatement],
161
+ * [isTechnicalError]) — ein Code, den dieses Modell schlicht nicht kennt.
162
+ */
163
+ export declare function isUnknownCode(res: Pick<HpsTransactionResponse, 'responseCode'>): boolean;
@@ -0,0 +1,245 @@
1
+ "use strict";
2
+ /**
3
+ * Antwort des hobex-HPS-Terminals auf eine Zahlung oder eine Statusabfrage,
4
+ * durchgereicht von **Kasseneck Connect** (`POST /v1/terminal/payment`,
5
+ * `/status`, `/abort` — Feld `hps` im Erfolgsrumpf). Connect ordnet nichts
6
+ * ein, es reicht den Terminal-Rumpf roh durch — die Einordnung passiert hier.
7
+ *
8
+ * **Zwilling:** `kasseneck_api/lib/src/hobex_hps/transaction_response.dart`.
9
+ * Beide Seiten pinnen dieselbe Codetabelle, siehe `HPS_MEASURED_CODES` unten
10
+ * und `fixtures/hobex-hps-codes.json`.
11
+ *
12
+ * **`responseCode !== '0'` ist NICHT die Pruefung auf eine Ablehnung.** Genau
13
+ * diese Lesart hat am 24.08.2026 zur doppelten Belastung gefuehrt:
14
+ * [NO_STATEMENT_CODE] (`9027`) ist ein Code ungleich `'0'` und sagt trotzdem
15
+ * nichts aus — er steht am gemessenen Terminal gleichermassen fuer "laeuft
16
+ * gerade", "abgebrochen" und "nie gesehen". Wer ihn als Ablehnung liest,
17
+ * meldet fuer einen LAUFENDEN Vorgang "nichts belastet, Wiederholung
18
+ * gefahrlos".
19
+ *
20
+ * [isConclusive] ist die einzige Stelle, an der ein Code zu einem Ausgang
21
+ * wird — und sie ist eine ECHTE Positivliste: nur ein Code, dessen Bedeutung
22
+ * GEMESSEN und in [HPS_MEASURED_CODES] benannt ist, zaehlt. Jeder andere —
23
+ * auch ein neuer, heute noch unbekannter Code — ist eine Wissensluecke, siehe
24
+ * [isUnknownCode]. Am 27.08.2026 hat der Dart-Zwilling gemessen, warum die
25
+ * Gegenrichtung ("jeder Code ausser 9027 ist schluessig") gefaehrlich ist: ein
26
+ * bis dahin unbenannter Code ([TECHNICAL_ERROR_CODE], `9900`) war darueber
27
+ * schluessig und haette eine Zahlung, unter der tatsaechlich Geld geflossen
28
+ * sein kann, als `declined` gemeldet.
29
+ */
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.TERMINAL_BUSY_HTTP_STATUS = exports.INVALID_TID_CODE = exports.AMOUNT_OUT_OF_RANGE_CODE = exports.INVALID_AMOUNT_CODE = exports.NOT_ABORTABLE_CODE = exports.CARD_NOT_PRESENT_CODE = exports.ABORTED_CODE = exports.TECHNICAL_ERROR_CODE = exports.NO_STATEMENT_CODE = exports.TRANSACTION_CANCELED_CODE = exports.INVALID_TRANSACTION_CODE = exports.APPROVED_CODE = exports.HPS_MEASURED_CODES = void 0;
32
+ exports.parseHpsTransactionResponse = parseHpsTransactionResponse;
33
+ exports.isApproved = isApproved;
34
+ exports.isInProgress = isInProgress;
35
+ exports.isNotAbortable = isNotAbortable;
36
+ exports.isNoStatement = isNoStatement;
37
+ exports.isTechnicalError = isTechnicalError;
38
+ exports.isCanceled = isCanceled;
39
+ exports.isConclusive = isConclusive;
40
+ exports.isUnknownCode = isUnknownCode;
41
+ /**
42
+ * Die gemessene Codetabelle — Vertrag mit dem Dart-Zwilling, siehe
43
+ * `fixtures/hobex-hps-codes.json`. Gemessen an einem hobex-HPS (TID 3600335,
44
+ * HPS 1.10.0, Firmware 7.3.6, 26.–28.08.2026).
45
+ *
46
+ * Reihenfolge ist die im Messprotokoll (`doc/kartenzahlung.md` im
47
+ * Dart-Zwilling) — numerisch aufsteigend zu sortieren wuerde beim Diff
48
+ * gegen die Vertragsdatei nichts gewinnen und macht Aenderungen schwerer
49
+ * nachzuverfolgen.
50
+ */
51
+ exports.HPS_MEASURED_CODES = [
52
+ { code: '0', meaning: 'genehmigt', conclusive: true },
53
+ {
54
+ code: '9002',
55
+ meaning: 'ungueltiger Vorgang -- das Terminal hat den Vorgang selbst als '
56
+ + 'unzulaessig verworfen, bevor irgendetwas in Bewegung kam',
57
+ conclusive: true,
58
+ },
59
+ {
60
+ code: '9011',
61
+ meaning: "aufgehoben (\"Transaction Canceled\") -- der Vorgang unter dieser Kennung wurde storniert",
62
+ conclusive: true,
63
+ },
64
+ {
65
+ code: '9027',
66
+ meaning: 'keine Aussage -- steht gleichermassen fuer "nie gesehen", '
67
+ + '"laeuft gerade", "Karte nicht aufgelegt" und "abgebrochen"',
68
+ conclusive: false,
69
+ },
70
+ {
71
+ code: '9900',
72
+ meaning: '"Technical Error Database" -- gemessen im Zusammenhang mit '
73
+ + 'einer nicht rein numerischen Kennung; keine Aussage ueber den Vorgang selbst',
74
+ conclusive: false,
75
+ },
76
+ {
77
+ code: '9003',
78
+ meaning: '"Invalid Amount" -- der Betrag wird abgewiesen, BEVOR eine Karte '
79
+ + 'verlangt wird (28.08.2026: 99999,99 EUR, Antwort nach 15,7 s ohne '
80
+ + 'Kartenaufforderung); nichts belastet',
81
+ conclusive: true,
82
+ },
83
+ { code: '100002', meaning: 'abgebrochen ("Aborted")', conclusive: true },
84
+ { code: '100003', meaning: 'Karte nicht aufgelegt ("Card not present")', conclusive: true },
85
+ { code: '100010', meaning: 'nicht mehr abbrechbar -- der Vorgang ist bereits abgeschlossen', conclusive: true },
86
+ {
87
+ code: '100019',
88
+ meaning: '"Amount is not in a valid range" -- Betrag ausserhalb des '
89
+ + 'zulaessigen Bereichs, gemessen mit negativem Betrag; Abweisung vor '
90
+ + 'dem Kartenfluss, nichts belastet',
91
+ conclusive: true,
92
+ },
93
+ {
94
+ code: '100108',
95
+ meaning: '"Invalid TID" -- die Terminal-Kennung gibt es an diesem Geraet '
96
+ + 'nicht; der Vorgang wird abgewiesen, bevor etwas geschieht',
97
+ conclusive: true,
98
+ },
99
+ ];
100
+ /** `responseCode` einer genehmigten Zahlung. */
101
+ exports.APPROVED_CODE = '0';
102
+ /** Siehe [HPS_MEASURED_CODES]: ungueltiger Vorgang, nichts passiert. */
103
+ exports.INVALID_TRANSACTION_CODE = '9002';
104
+ /** Siehe [HPS_MEASURED_CODES]: aufgehoben. */
105
+ exports.TRANSACTION_CANCELED_CODE = '9011';
106
+ /** Siehe [HPS_MEASURED_CODES]: keine Aussage. */
107
+ exports.NO_STATEMENT_CODE = '9027';
108
+ /** Siehe [HPS_MEASURED_CODES]: Kennung nicht numerisch, keine Aussage. */
109
+ exports.TECHNICAL_ERROR_CODE = '9900';
110
+ /** Siehe [HPS_MEASURED_CODES]: abgebrochen. */
111
+ exports.ABORTED_CODE = '100002';
112
+ /** Siehe [HPS_MEASURED_CODES]: Karte nicht aufgelegt. */
113
+ exports.CARD_NOT_PRESENT_CODE = '100003';
114
+ /** Siehe [HPS_MEASURED_CODES]: nicht mehr abbrechbar. */
115
+ exports.NOT_ABORTABLE_CODE = '100010';
116
+ /** Siehe [HPS_MEASURED_CODES]: Betrag abgewiesen, vor dem Kartenfluss. */
117
+ exports.INVALID_AMOUNT_CODE = '9003';
118
+ /** Siehe [HPS_MEASURED_CODES]: Betrag ausserhalb des zulaessigen Bereichs. */
119
+ exports.AMOUNT_OUT_OF_RANGE_CODE = '100019';
120
+ /** Siehe [HPS_MEASURED_CODES]: Terminal-Kennung unbekannt. */
121
+ exports.INVALID_TID_CODE = '100108';
122
+ /**
123
+ * HTTP `409` ("Terminal is busy"): das Terminal serialisiert und weist eine
124
+ * zweite Anfrage ab, waehrend eine erste noch laeuft. Am 27.08.2026 gemessen:
125
+ * kommt nach 87 Millisekunden, der abgewiesene Vorgang hinterlaesst KEINE
126
+ * Spur (die Statusabfrage auf seine Kennung liefert weiterhin
127
+ * [NO_STATEMENT_CODE]).
128
+ *
129
+ * Bewusst KEIN Eintrag in [HPS_MEASURED_CODES]: es ist ein HTTP-Status, kein
130
+ * `responseCode` — er entsteht, bevor ueberhaupt ein Antwortrumpf gelesen
131
+ * wird. Siehe `errors.ts` (`HpsConnectTerminalError.isTerminalBusy`) fuer die
132
+ * getrennte Auswertung.
133
+ */
134
+ exports.TERMINAL_BUSY_HTTP_STATUS = 409;
135
+ const KNOWN_OUTCOME_CODES = new Set(exports.HPS_MEASURED_CODES.filter((c) => c.conclusive).map((c) => c.code));
136
+ /**
137
+ * Liest eine Terminal-Antwort aus dem `hps`-Feld der Connect-Huelle.
138
+ *
139
+ * Wirft, wenn [raw] keine brauchbare Form hat (kein Objekt) — das ist ein
140
+ * Formfehler der Antwort, kein Ausgang der Zahlung, und wird vom Aufrufer
141
+ * (`payments.ts`) genauso behandelt wie jeder andere unerwartete Fehler: die
142
+ * Klaerung laeuft konservativ weiter, statt ihn stillschweigend als
143
+ * "laeuft noch" zu deuten.
144
+ */
145
+ function parseHpsTransactionResponse(raw) {
146
+ if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
147
+ throw new TypeError('Terminal-Antwort ist kein JSON-Objekt');
148
+ }
149
+ const r = raw;
150
+ return {
151
+ transactionId: asString(r['transactionId']),
152
+ originalTransactionId: asString(r['originalTransactionId']),
153
+ tid: asString(r['tid']),
154
+ receipt: asString(r['receipt']),
155
+ approvalCode: asString(r['approvalCode']),
156
+ reference: asString(r['reference']),
157
+ transactionDate: asString(r['transactionDate']),
158
+ cardNumber: asString(r['cardNumber']),
159
+ cardExpiry: asString(r['cardExpiry']),
160
+ brand: asString(r['brand']),
161
+ cardIssuer: asString(r['cardIssuer']),
162
+ transactionType: asString(r['transactionType']),
163
+ currency: asString(r['currency']),
164
+ amount: asNumber(r['amount']),
165
+ tip: asNumber(r['tip']),
166
+ // responseCode kommt teils als Zahl, teils als Zeichenkette — siehe
167
+ // Zwilling. Ein leerer String traegt keine Aussage und wird wie ein
168
+ // fehlendes Feld behandelt.
169
+ responseCode: nonEmpty(stringify(r['responseCode'])),
170
+ responseText: asString(r['responseText']),
171
+ state: asString(r['state']),
172
+ raw: r,
173
+ };
174
+ }
175
+ function asString(v) {
176
+ return typeof v === 'string' ? v : undefined;
177
+ }
178
+ function asNumber(v) {
179
+ if (typeof v === 'number' && Number.isFinite(v))
180
+ return v;
181
+ if (typeof v === 'string' && v.trim() !== '') {
182
+ const n = Number(v);
183
+ return Number.isFinite(n) ? n : undefined;
184
+ }
185
+ return undefined;
186
+ }
187
+ function stringify(v) {
188
+ if (v === null || v === undefined)
189
+ return undefined;
190
+ if (typeof v === 'string')
191
+ return v;
192
+ if (typeof v === 'number')
193
+ return String(v);
194
+ return undefined;
195
+ }
196
+ function nonEmpty(v) {
197
+ return v === undefined || v === '' ? undefined : v;
198
+ }
199
+ /** `true`, wenn der Vorgang genehmigt ist. */
200
+ function isApproved(res) {
201
+ return res.responseCode === exports.APPROVED_CODE;
202
+ }
203
+ /** `true`, wenn eine Statusabfrage meldet, der Vorgang laeuft noch (kein Code). */
204
+ function isInProgress(res) {
205
+ return res.responseCode === undefined;
206
+ }
207
+ /** `true`, wenn ein Abbruch daran scheiterte, dass der Vorgang nicht mehr abbrechbar war. */
208
+ function isNotAbortable(res) {
209
+ return res.responseCode === exports.NOT_ABORTABLE_CODE;
210
+ }
211
+ /** `true`, wenn das Terminal zu dieser Kennung keine Auskunft gibt (9027). */
212
+ function isNoStatement(res) {
213
+ return res.responseCode === exports.NO_STATEMENT_CODE;
214
+ }
215
+ /** `true`, wenn das Terminal einen technischen Fehler meldet (9900). */
216
+ function isTechnicalError(res) {
217
+ return res.responseCode === exports.TECHNICAL_ERROR_CODE;
218
+ }
219
+ /**
220
+ * `true`, wenn der Vorgang unter dieser Kennung aufgehoben wurde (9011).
221
+ *
222
+ * Vorsicht bei der Verwendung: fuer die DIREKTE Antwort auf eine Aufhebung
223
+ * bedeutet dieser Code etwas anderes als bei einer Statusabfrage auf die
224
+ * Originalzahlung -- siehe `payments.ts`, `fromCancelResponse` vs.
225
+ * `fromCancelStatus`.
226
+ */
227
+ function isCanceled(res) {
228
+ return res.responseCode === exports.TRANSACTION_CANCELED_CODE;
229
+ }
230
+ /**
231
+ * `true`, wenn diese Antwort ueberhaupt eine Aussage ueber den Ausgang
232
+ * traegt — ein Ergebniscode, der in [HPS_MEASURED_CODES] als `conclusive`
233
+ * gefuehrt wird. Die einzige Stelle, an der ein Code zu einem Ausgang wird.
234
+ */
235
+ function isConclusive(res) {
236
+ return res.responseCode !== undefined && KNOWN_OUTCOME_CODES.has(res.responseCode);
237
+ }
238
+ /**
239
+ * `true`, wenn ein Ergebniscode VORHANDEN ist, aber weder schluessig noch
240
+ * eine der beiden gemessenen Wissensluecken ([isNoStatement],
241
+ * [isTechnicalError]) — ein Code, den dieses Modell schlicht nicht kennt.
242
+ */
243
+ function isUnknownCode(res) {
244
+ return res.responseCode !== undefined && !isConclusive(res) && !isNoStatement(res) && !isTechnicalError(res);
245
+ }
@@ -17,12 +17,15 @@ const money_js_1 = require("../money.js");
17
17
  * functions/payment-endpoints.js) — sie ist deshalb kein Schmuck, sondern die
18
18
  * Absicherung gegen eine doppelte Belastung.
19
19
  *
20
- * **Nur der Cloud-Weg ist hier drin, und das bleibt so.** Hobex **HPS** ist ein
21
- * physisches Terminal, mit dem die Kasse **lokal ueber TCP** spricht; **myPOS**
22
- * und **SumUp** sind **Android-SDKs**. Ein Browser hat weder rohe TCP-Sockets
23
- * noch eine Android-Laufzeit das ist keine fehlende Umsetzung und kein
24
- * Buendler-Problem, sondern eine Grenze der Umgebung. Wer diese drei Wege
25
- * braucht, braucht die Flutter-App, nicht dieses Paket.
20
+ * **Nur der Cloud-Weg ist hier drin.** Hobex **HPS** ist ein physisches
21
+ * Terminal, mit dem eine Kasse **lokal ueber TCP** spricht — dafuer hat ein
22
+ * Browser weiterhin keine rohen Sockets. Anders als hier frueher vermerkt,
23
+ * heisst das aber NICHT mehr "unerreichbar ohne Flutter": `../hobex-hps.js`
24
+ * spricht mit dem Terminal ueber **Kasseneck Connect**, einen lokalen
25
+ * Geraete-Agenten mit gewoehnlicher HTTP-Schnittstelle. **myPOS** und
26
+ * **SumUp** bleiben Android-SDKs ohne Entsprechung hier. Wer am HPS-Terminal
27
+ * eine Gutschrift oder ein Storno braucht, braucht weiterhin die Flutter-App:
28
+ * Connect exponiert dafuer (noch) keinen Endpunkt.
26
29
  *
27
30
  * **Kassen-Benutzer-Weg (`registerUserAuth`, Browser-Kasse):** Keiner der
28
31
  * beiden Endpunkte dieser Datei setzt `allowRegisterUser`; beide laufen nur
@@ -1,28 +1,39 @@
1
1
  /**
2
2
  * Unterpfad `@kreiseck/kasseneck-api/payments` — die Zahlungswege, die ein
3
3
  * Browser oder ein Node-Prozess wirklich gehen kann: **Stripe-Zahlungslinks**
4
- * (Fernzahlung per Link/QR-Code) und die **Hobex-Cloud-API** (Kartenzahlung
5
- * ueber ein bei Hobex registriertes Terminal, gesteuert ueber das Netz).
4
+ * (Fernzahlung per Link/QR-Code), die **Hobex-Cloud-API** (Kartenzahlung
5
+ * ueber ein bei Hobex registriertes Terminal, gesteuert ueber das Netz) und
6
+ * **Hobex HPS ueber Kasseneck Connect** (`./hobex-hps.js`) — ein physisches
7
+ * Terminal im Kassen-Netz, angesprochen ueber den lokalen Geraete-Agenten.
6
8
  *
7
9
  * **Was hier bewusst fehlt — und warum es auch nicht nachgeruestet wird:**
8
10
  *
9
- * - **Hobex HPS** spricht **lokal ueber TCP** mit einem angeschlossenen
10
- * Terminal (roher Socket auf eine Geraete-IP im selben Netz).
11
11
  * - **myPOS** und **SumUp** sind **Android-SDKs**; sie laufen als
12
12
  * Bibliothek in einer Android-App und reden ueber Bluetooth bzw. das
13
- * Hersteller-Geraet mit dem Terminal.
13
+ * Hersteller-Geraet mit dem Terminal. Ein Browser hat keine
14
+ * Android-Laufzeit — das ist keine Luecke in diesem Paket und auch nichts,
15
+ * was ein Buendler, ein Polyfill oder WebAssembly aufloest.
14
16
  *
15
- * Ein Browser hat weder rohe TCP-Sockets noch eine Android-Laufzeit. Das ist
16
- * keine Luecke in diesem Paket und auch nichts, was ein anderer Buendler,
17
- * ein Polyfill oder eine WebAssembly-Schicht aufloest es ist eine Grenze der
18
- * Umgebung. Diese drei Wege gibt es im Flutter-Paket `kasseneck_api`, und dort
19
- * bleiben sie.
17
+ * **Frueherer Stand, ueberholt:** hier stand einmal, Hobex HPS sei mangels
18
+ * roher TCP-Sockets im Browser unerreichbar. Das galt fuer den DIREKTEN
19
+ * Terminal-Kontakt (Zwilling: `HpsClient` in `kasseneck_api`) und gilt dafuer
20
+ * weiterhin aber **Kasseneck Connect** ist ein lokaler Geraete-Agent, der
21
+ * ueber gewoehnliches HTTP erreichbar ist und **fuer** die Kasse mit dem
22
+ * Terminal spricht. Das ist kein Widerspruch zur Umgebungsgrenze, sondern ein
23
+ * zweiter, seit `hobex-hps.js` genutzter Weg um sie herum.
24
+ *
25
+ * Wer Gutschrift oder Storno am HPS-Terminal braucht, braucht weiterhin die
26
+ * Flutter-App: Connect exponiert dafuer (noch) keinen Endpunkt, siehe
27
+ * `hobex-hps/connect-client.ts`.
20
28
  *
21
29
  * **Kassen-Benutzer-Weg (`registerUserAuth`, Browser-Kasse):** **Keiner** der
22
- * vier Zahlungs-Endpunkte setzt `allowRegisterUser`; sie laufen alle ueber
23
- * `checkRequest(req, 'user', …)` und damit nur mit `apiKeyAuth`. Dieses Paket
24
- * bildet das **nicht** nach — wer darf, entscheidet allein das Backend. Der
25
- * Hinweis steht **hier** und gilt fuer beide Dateien dieses Unterpfads.
30
+ * vier Cloud-Zahlungs-Endpunkte (Stripe, Hobex-Cloud) setzt `allowRegisterUser`;
31
+ * sie laufen alle ueber `checkRequest(req, 'user', …)` und damit nur mit
32
+ * `apiKeyAuth`. Dieses Paket bildet das **nicht** nach — wer darf, entscheidet
33
+ * allein das Backend. Der Hinweis steht **hier** und gilt fuer die beiden
34
+ * Cloud-Dateien dieses Unterpfads; `hobex-hps.js` spricht kein Kasseneck-Backend
35
+ * und kennt diese Unterscheidung nicht — dort entscheidet allein der
36
+ * Kopplungstoken von Kasseneck Connect.
26
37
  *
27
38
  * Welche **anderen** Endpunkte den Weg offen haben, steht bewusst nirgends in
28
39
  * diesem Paket: eine abgeschriebene Liste veraltet still, und sie hat hier
@@ -31,3 +42,4 @@
31
42
  export { StripeLinkMode, type StripeLinkModeKey } from '../enums/index.js';
32
43
  export { type CreateStripeLinkOptions, type StripeCaptureResult, createStripeLink, stripeCaptureIntent, } from './stripe.js';
33
44
  export { type HobexPayOptions, type HobexRefundOptions, type HobexTransactionIdOptions, hobexPay, hobexRefund, newHobexTransactionId, } from './hobex.js';
45
+ export { type CardPaymentOutcome, type HpsConnectClient, type HpsConnectClientOptions, type HpsConnectFetch, type HpsConnectFetchResponse, type HpsConnectPaymentOptions, type HpsConnectTarget, type HpsConnectTransactionOptions, type HpsMeasuredCode, type HpsPaymentEvent, type HpsPaymentEventKind, type HpsPaymentObserver, type HpsPaymentOptions, type HpsPayments, type HpsPaymentResult, type HpsPaymentsOptions, type HpsTransactionIdGeneratorOptions, type HpsTransactionResponse, ABORTED_CODE, APPROVED_CODE, CARD_NOT_PRESENT_CODE, createHpsConnectClient, createHpsPayments, createHpsTransactionIdGenerator, HPS_MEASURED_CODES, HpsClarifyTimeoutError, HpsConnectException, HpsConnectTerminalError, HpsConnectTransportError, HpsPreflightError, HpsTransactionIdError, INVALID_TRANSACTION_CODE, isApproved, isConclusive, isInProgress, isNoStatement, isNotAbortable, isTechnicalError, isUnknownCode, isValidHpsTransactionId, mayRetrySafely, MAX_TRANSACTION_ID_LENGTH, newHpsTransactionId, NOT_ABORTABLE_CODE, NO_STATEMENT_CODE, parseHpsTransactionResponse, PREFLIGHT_CONNECT_CODES, TECHNICAL_ERROR_CODE, TERMINAL_BUSY_HTTP_STATUS, TRANSACTION_CANCELED_CODE, } from './hobex-hps/index.js';