@kreiseck/kasseneck-api 0.7.0 → 0.7.2

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 (122) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +87 -15
  3. package/dist/cjs/client/aufrufe.d.ts +1 -1
  4. package/dist/cjs/client/aufrufe.js +1 -0
  5. package/dist/cjs/client/errors.d.ts +8 -4
  6. package/dist/cjs/client/errors.js +12 -9
  7. package/dist/cjs/client/receipts.d.ts +22 -0
  8. package/dist/cjs/client/receipts.js +16 -0
  9. package/dist/cjs/client/transport.js +5 -4
  10. package/dist/cjs/index.d.ts +1 -1
  11. package/dist/cjs/index.js +4 -2
  12. package/dist/cjs/models/cancellation.d.ts +28 -0
  13. package/dist/cjs/models/cancellation.js +31 -1
  14. package/dist/cjs/models/hobex-receipt.js +9 -2
  15. package/dist/cjs/models/index.d.ts +1 -1
  16. package/dist/cjs/models/index.js +3 -1
  17. package/dist/cjs/models/receipt-summary.d.ts +2 -0
  18. package/dist/cjs/models/receipt-summary.js +4 -1
  19. package/dist/cjs/models/receipt.js +8 -1
  20. package/dist/cjs/models/voucher.js +18 -2
  21. package/dist/cjs/payments/hobex-hps/connect-client.d.ts +104 -0
  22. package/dist/cjs/payments/hobex-hps/connect-client.js +159 -0
  23. package/dist/cjs/payments/hobex-hps/errors.d.ts +122 -0
  24. package/dist/cjs/payments/hobex-hps/errors.js +158 -0
  25. package/dist/cjs/payments/hobex-hps/events.d.ts +22 -0
  26. package/dist/cjs/payments/hobex-hps/events.js +2 -0
  27. package/dist/cjs/payments/hobex-hps/index.d.ts +27 -0
  28. package/dist/cjs/payments/hobex-hps/index.js +67 -0
  29. package/dist/cjs/payments/hobex-hps/outcome.d.ts +46 -0
  30. package/dist/cjs/payments/hobex-hps/outcome.js +7 -0
  31. package/dist/cjs/payments/hobex-hps/payments.d.ts +149 -0
  32. package/dist/cjs/payments/hobex-hps/payments.js +573 -0
  33. package/dist/cjs/payments/hobex-hps/receipt.d.ts +28 -0
  34. package/dist/cjs/payments/hobex-hps/receipt.js +60 -0
  35. package/dist/cjs/payments/hobex-hps/transaction-id.d.ts +65 -0
  36. package/dist/cjs/payments/hobex-hps/transaction-id.js +91 -0
  37. package/dist/cjs/payments/hobex-hps/transaction-response.d.ts +175 -0
  38. package/dist/cjs/payments/hobex-hps/transaction-response.js +266 -0
  39. package/dist/cjs/payments/hobex.js +9 -6
  40. package/dist/cjs/payments/index.d.ts +26 -14
  41. package/dist/cjs/payments/index.js +59 -15
  42. package/dist/cjs/printing/index.d.ts +1 -1
  43. package/dist/cjs/printing/index.js +2 -1
  44. package/dist/cjs/printing/webusb.d.ts +37 -7
  45. package/dist/cjs/printing/webusb.js +76 -18
  46. package/dist/cjs/receipt/epos.d.ts +18 -0
  47. package/dist/cjs/receipt/epos.js +78 -6
  48. package/dist/cjs/receipt/index.d.ts +1 -1
  49. package/dist/cjs/receipt/index.js +2 -1
  50. package/dist/cjs/receipt/layout.js +19 -0
  51. package/dist/cjs/register/index.d.ts +1 -1
  52. package/dist/cjs/register/index.js +2 -1
  53. package/dist/cjs/register/pairing.d.ts +59 -0
  54. package/dist/cjs/register/pairing.js +51 -2
  55. package/dist/esm/client/aufrufe.d.ts +1 -1
  56. package/dist/esm/client/aufrufe.js +1 -0
  57. package/dist/esm/client/errors.d.ts +8 -4
  58. package/dist/esm/client/errors.js +12 -9
  59. package/dist/esm/client/receipts.d.ts +22 -0
  60. package/dist/esm/client/receipts.js +16 -0
  61. package/dist/esm/client/transport.js +5 -4
  62. package/dist/esm/index.d.ts +1 -1
  63. package/dist/esm/index.js +1 -1
  64. package/dist/esm/models/cancellation.d.ts +28 -0
  65. package/dist/esm/models/cancellation.js +29 -0
  66. package/dist/esm/models/hobex-receipt.js +10 -3
  67. package/dist/esm/models/index.d.ts +1 -1
  68. package/dist/esm/models/index.js +1 -1
  69. package/dist/esm/models/receipt-summary.d.ts +2 -0
  70. package/dist/esm/models/receipt-summary.js +4 -1
  71. package/dist/esm/models/receipt.js +8 -1
  72. package/dist/esm/models/voucher.js +18 -2
  73. package/dist/esm/payments/hobex-hps/connect-client.d.ts +104 -0
  74. package/dist/esm/payments/hobex-hps/connect-client.js +156 -0
  75. package/dist/esm/payments/hobex-hps/errors.d.ts +122 -0
  76. package/dist/esm/payments/hobex-hps/errors.js +149 -0
  77. package/dist/esm/payments/hobex-hps/events.d.ts +22 -0
  78. package/dist/esm/payments/hobex-hps/events.js +1 -0
  79. package/dist/esm/payments/hobex-hps/index.d.ts +27 -0
  80. package/dist/esm/payments/hobex-hps/index.js +26 -0
  81. package/dist/esm/payments/hobex-hps/outcome.d.ts +46 -0
  82. package/dist/esm/payments/hobex-hps/outcome.js +4 -0
  83. package/dist/esm/payments/hobex-hps/payments.d.ts +149 -0
  84. package/dist/esm/payments/hobex-hps/payments.js +570 -0
  85. package/dist/esm/payments/hobex-hps/receipt.d.ts +28 -0
  86. package/dist/esm/payments/hobex-hps/receipt.js +57 -0
  87. package/dist/esm/payments/hobex-hps/transaction-id.d.ts +65 -0
  88. package/dist/esm/payments/hobex-hps/transaction-id.js +86 -0
  89. package/dist/esm/payments/hobex-hps/transaction-response.d.ts +175 -0
  90. package/dist/esm/payments/hobex-hps/transaction-response.js +254 -0
  91. package/dist/esm/payments/hobex.js +9 -6
  92. package/dist/esm/payments/index.d.ts +26 -14
  93. package/dist/esm/payments/index.js +26 -14
  94. package/dist/esm/printing/index.d.ts +1 -1
  95. package/dist/esm/printing/index.js +1 -1
  96. package/dist/esm/printing/webusb.d.ts +37 -7
  97. package/dist/esm/printing/webusb.js +74 -17
  98. package/dist/esm/receipt/epos.d.ts +18 -0
  99. package/dist/esm/receipt/epos.js +76 -6
  100. package/dist/esm/receipt/index.d.ts +1 -1
  101. package/dist/esm/receipt/index.js +1 -1
  102. package/dist/esm/receipt/layout.js +19 -0
  103. package/dist/esm/register/index.d.ts +1 -1
  104. package/dist/esm/register/index.js +1 -1
  105. package/dist/esm/register/pairing.d.ts +59 -0
  106. package/dist/esm/register/pairing.js +50 -2
  107. package/fixtures/belege/storno-rabatt.json +3 -2
  108. package/fixtures/belege/storno-teil.json +2 -1
  109. package/fixtures/belege/storno-voll.json +2 -1
  110. package/fixtures/erwartet/storno-rabatt.grid32.txt +1 -0
  111. package/fixtures/erwartet/storno-rabatt.grid48.txt +1 -0
  112. package/fixtures/erwartet/storno-rabatt.lines.json +6 -0
  113. package/fixtures/erwartet/storno-teil.grid32.txt +1 -0
  114. package/fixtures/erwartet/storno-teil.grid48.txt +1 -0
  115. package/fixtures/erwartet/storno-teil.lines.json +6 -0
  116. package/fixtures/erwartet/storno-voll.grid32.txt +1 -0
  117. package/fixtures/erwartet/storno-voll.grid48.txt +1 -0
  118. package/fixtures/erwartet/storno-voll.lines.json +6 -0
  119. package/fixtures/hobex-hps-codes.json +83 -0
  120. package/fixtures/manifest.json +12 -12
  121. package/fixtures/oberflaeche.json +2 -1
  122. package/package.json +3 -2
@@ -76,7 +76,11 @@ function fromReceiptPayload(payload) {
76
76
  signatureSuccess: payload.signatureSuccess ?? undefined,
77
77
  customProjectId: payload.customProjectId ?? undefined,
78
78
  ...(typeof payload.tipCents === 'number' ? { tipCents: payload.tipCents } : {}),
79
- ...(payload.cancellationOf ? { cancellationOf: { receiptId: payload.cancellationOf.receiptId, fullReceiptId: payload.cancellationOf.fullReceiptId ?? null } } : {}),
79
+ ...(payload.cancellationOf ? { cancellationOf: {
80
+ receiptId: payload.cancellationOf.receiptId,
81
+ fullReceiptId: payload.cancellationOf.fullReceiptId ?? null,
82
+ ...(typeof payload.cancellationOf.timeStamp === 'string' && payload.cancellationOf.timeStamp ? { timeStamp: payload.cancellationOf.timeStamp } : {}),
83
+ } } : {}),
80
84
  ...(payload.cancellationReason ? { cancellationReason: payload.cancellationReason } : {}),
81
85
  ...((0, receipt_summary_js_1.istZeroKind)(payload.zeroKind) ? { zeroKind: payload.zeroKind } : {}),
82
86
  ...(payload.cancellations ? { cancellations: payload.cancellations.map(leseStorno) } : {}),
@@ -90,6 +94,9 @@ function leseStorno(eintrag) {
90
94
  by: eintrag.by ?? null,
91
95
  note: eintrag.note ?? null,
92
96
  items: (eintrag.items ?? []).map((p) => ({ index: Number(p.index), quantity: Number(p.quantity) })),
97
+ ...(eintrag.promoAdjustmentCents && typeof eintrag.promoAdjustmentCents === 'object'
98
+ ? { promoAdjustmentCents: Object.fromEntries(Object.entries(eintrag.promoAdjustmentCents).map(([k, v]) => [k, Number(v)])) }
99
+ : {}),
93
100
  };
94
101
  }
95
102
  /**
@@ -4,6 +4,7 @@ exports.toVoucherPayload = toVoucherPayload;
4
4
  exports.voucherIsValid = voucherIsValid;
5
5
  exports.fromVoucherPayload = fromVoucherPayload;
6
6
  const index_js_1 = require("../enums/index.js");
7
+ const money_js_1 = require("../money.js");
7
8
  const enum_payload_js_1 = require("./enum-payload.js");
8
9
  function toVoucherPayload(voucher) {
9
10
  return {
@@ -35,16 +36,31 @@ function voucherIsValid(voucher) {
35
36
  if (voucher.type === index_js_1.VoucherType.promo && voucher.valueCents == null) {
36
37
  return false;
37
38
  }
38
- if (voucher.valueCents != null && voucher.valueCents <= 0) {
39
+ // `!Number.isFinite` VOR den Vergleich, nicht dahinter: `NaN <= 0` und
40
+ // `Infinity <= 0` sind beide `false`, ein Vergleich mit einem
41
+ // nicht-endlichen Wert ist also IMMER falsch und liesse ihn hier
42
+ // durchrutschen. Gemessen (28.08.2026): ein Gutschein mit `valueCents: NaN`
43
+ // (aus einem kaputten `value` in der Nutzlast, siehe [fromVoucherPayload])
44
+ // oder `valueCents: Infinity` galt bis zu dieser Fassung als GUELTIG und
45
+ // waere still in die Belegsummen gewandert. Diese Pruefung greift
46
+ // unabhaengig davon, ob `valueCents` ueber [fromVoucherPayload] oder direkt
47
+ // gesetzt wurde -- die gehaertete Umrechnung dort allein reicht nicht.
48
+ if (voucher.valueCents != null && (!Number.isFinite(voucher.valueCents) || voucher.valueCents <= 0)) {
39
49
  return false;
40
50
  }
41
51
  return true;
42
52
  }
43
53
  function fromVoucherPayload(payload) {
54
+ // Euro->Cent ueber die eine gehaertete Stelle im Paket ([euroToCents],
55
+ // money.ts) statt einer eigenen `Math.round(payload.value * 100)` --
56
+ // [euroToCents] prueft `Number.isFinite` und liefert fuer einen
57
+ // nicht-numerischen oder nicht-endlichen Wert `0` statt eines lautlosen
58
+ // `NaN`. Siehe auch [voucherIsValid]: `0` faellt dort ueber die
59
+ // "<= 0"-Pruefung, ein `NaN` waere durchgerutscht.
44
60
  const valueCents = payload.valueCents != null
45
61
  ? payload.valueCents
46
62
  : payload.value != null
47
- ? Math.round(payload.value * 100)
63
+ ? (0, money_js_1.euroToCents)(payload.value)
48
64
  : undefined;
49
65
  return {
50
66
  name: payload.name ?? undefined,
@@ -0,0 +1,104 @@
1
+ import { type HpsTransactionResponse } from './transaction-response.js';
2
+ /**
3
+ * Client fuer die Terminal-Endpunkte von **Kasseneck Connect** — dem lokalen
4
+ * Geraete-Agenten, der ueber HTTP erreichbar ist und mit dem hobex-HPS
5
+ * spricht (`kasseneck-connect/lib/src/api/routes_terminal.dart`). Connect
6
+ * reicht die Antwort des Terminals ROH durch und ordnet nichts ein; die
7
+ * Einordnung passiert in `transaction-response.ts` und `payments.ts`.
8
+ *
9
+ * **Kein direkter Terminal-Kontakt.** Ein Browser hat keine rohen
10
+ * TCP-Sockets — das ist der Unterschied zum Dart-Zwilling `HpsClient`, der
11
+ * das HPS-Terminal direkt anspricht. Dieser Client spricht ausschliesslich
12
+ * mit Connect, niemals mit dem Terminal selbst.
13
+ *
14
+ * **`payment`/`status`/`abort`/`refund`/`cancel`.** Seit
15
+ * `kasseneck-connect` Commit `1c8a003` traegt Connect auch die Gutschrift
16
+ * (`POST /v1/terminal/refund`) und die Aufhebung (`POST /v1/terminal/cancel`)
17
+ * — beide erben denselben Fehlerpfad wie `payment` (`error.detail.terminalHttpStatus`,
18
+ * siehe `HpsConnectTerminalError.isTerminalBusy`).
19
+ */
20
+ /** Adresse des Ziel-Terminals — bei jedem Aufruf mitgegeben, Connect selbst ist zustandslos. */
21
+ export interface HpsConnectTarget {
22
+ /** IP oder Hostname des Terminals im Kassen-Netz. */
23
+ host: string;
24
+ /** Vorgabe: `8080` (hobex-HPS-Standardport), siehe Connect. */
25
+ port?: number;
26
+ /** Terminal-ID, wie am Geraet angezeigt (fuehrende Nullen werden toleriert). */
27
+ tid: string;
28
+ }
29
+ export interface HpsConnectPaymentOptions extends HpsConnectTarget {
30
+ /** Kennung dieser Zahlung — MUSS vor diesem Aufruf feststehen, siehe `transaction-id.ts`. */
31
+ transactionId: string;
32
+ /** Zu belastender Betrag in **Cent** (ohne Trinkgeld). */
33
+ amountCents: number;
34
+ /** Trinkgeld in **Cent**; das Terminal belastet Betrag + Trinkgeld in einem. */
35
+ tipCents?: number;
36
+ reference?: string;
37
+ currency?: string;
38
+ language?: string;
39
+ }
40
+ export interface HpsConnectTransactionOptions extends HpsConnectTarget {
41
+ transactionId: string;
42
+ }
43
+ export interface HpsConnectRefundOptions extends HpsConnectTarget {
44
+ /** Kennung der Gutschrift SELBST — eine NEUE, nicht die der erstatteten Zahlung. */
45
+ transactionId: string;
46
+ /** Kennung der erstatteten Zahlung. Verlangt Connect zwingend, siehe `_handleRefund`. */
47
+ originalTransactionId: string;
48
+ /** Zu erstattender Betrag in **Cent**. */
49
+ amountCents: number;
50
+ reference?: string;
51
+ currency?: string;
52
+ language?: string;
53
+ }
54
+ export interface HpsConnectCancelOptions extends HpsConnectTarget {
55
+ /** Kennung der URSPRUENGLICHEN Zahlung — keine neue. */
56
+ transactionId: string;
57
+ /** Pflicht: das Terminal weist einen Void ohne Betrag mit `400 Missing amount` ab. */
58
+ amountCents: number;
59
+ currency?: string;
60
+ language?: string;
61
+ }
62
+ /** Austauschbare `fetch`-Umsetzung, minimal genug fuer eine Attrappe im Test. */
63
+ export interface HpsConnectFetchResponse {
64
+ status: number;
65
+ text(): Promise<string>;
66
+ }
67
+ export type HpsConnectFetch = (url: string, init: {
68
+ method: string;
69
+ headers: Record<string, string>;
70
+ body: string;
71
+ signal: AbortSignal;
72
+ }) => Promise<HpsConnectFetchResponse>;
73
+ export interface HpsConnectClientOptions {
74
+ /** Basisadresse des Agenten. Vorgabe `http://127.0.0.1:27182` (README `kasseneck-connect`). */
75
+ baseUrl?: string;
76
+ /** Kopplungstoken, geht als `Authorization: Bearer <token>` mit. */
77
+ token: string;
78
+ /**
79
+ * Zeitlimit fuer `status`/`abort`/`diagnosis` in ms. Vorgabe 30 s — deutlich
80
+ * ueber Connects eigenem `hpsKurzTimeout` (15 s), damit dieser Client nicht
81
+ * VOR Connect selbst aufgibt und dessen Fehlermeldung verschluckt.
82
+ */
83
+ shortTimeoutMs?: number;
84
+ /**
85
+ * Zeitlimit fuer `payment` in ms. Vorgabe 4,5 Minuten — ueber Connects
86
+ * eigenem `hpsZahlungTimeout` (4 Minuten): eine Zahlung blockiert, bis der
87
+ * Karteninhaber fertig ist, das darf nicht vorzeitig aufgegeben werden.
88
+ */
89
+ paymentTimeoutMs?: number;
90
+ /** Eigene `fetch`-Umsetzung (Tests). Vorgabe: globales `fetch`. */
91
+ fetch?: HpsConnectFetch;
92
+ }
93
+ export interface HpsConnectClient {
94
+ payment(options: HpsConnectPaymentOptions): Promise<HpsTransactionResponse>;
95
+ status(options: HpsConnectTransactionOptions): Promise<HpsTransactionResponse>;
96
+ abort(options: HpsConnectTransactionOptions): Promise<HpsTransactionResponse>;
97
+ /** Gutschrift — ein Kartenfluss wie [payment], deshalb dieselbe lange Frist. */
98
+ refund(options: HpsConnectRefundOptions): Promise<HpsTransactionResponse>;
99
+ /** Aufhebung (Storno/Void) — kurzer Aufruf, keine Karteninteraktion. */
100
+ cancel(options: HpsConnectCancelOptions): Promise<HpsTransactionResponse>;
101
+ /** Erreichbarkeits-/Firmware-Check, folgenlos. Rohe Nutzlast, Connect ordnet nichts ein. */
102
+ diagnosis(options: HpsConnectTarget): Promise<Record<string, unknown>>;
103
+ }
104
+ export declare function createHpsConnectClient(options: HpsConnectClientOptions): HpsConnectClient;
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createHpsConnectClient = createHpsConnectClient;
4
+ const errors_js_1 = require("./errors.js");
5
+ const transaction_id_js_1 = require("./transaction-id.js");
6
+ const transaction_response_js_1 = require("./transaction-response.js");
7
+ const DEFAULT_BASE_URL = 'http://127.0.0.1:27182';
8
+ const DEFAULT_SHORT_TIMEOUT_MS = 30_000;
9
+ const DEFAULT_PAYMENT_TIMEOUT_MS = 4 * 60_000 + 30_000;
10
+ function createHpsConnectClient(options) {
11
+ const baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, '');
12
+ const token = options.token;
13
+ const shortTimeoutMs = options.shortTimeoutMs ?? DEFAULT_SHORT_TIMEOUT_MS;
14
+ const paymentTimeoutMs = options.paymentTimeoutMs ?? DEFAULT_PAYMENT_TIMEOUT_MS;
15
+ const holen = options.fetch ?? globalHpsConnectFetch();
16
+ async function rufen(path, body, timeoutMs) {
17
+ const abbruch = new AbortController();
18
+ const wecker = setTimeout(() => abbruch.abort(), timeoutMs);
19
+ let antwort;
20
+ let text;
21
+ try {
22
+ try {
23
+ antwort = await holen(`${baseUrl}${path}`, {
24
+ method: 'POST',
25
+ headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
26
+ body: JSON.stringify(body),
27
+ signal: abbruch.signal,
28
+ });
29
+ text = await antwort.text();
30
+ }
31
+ catch (ursache) {
32
+ // Connect selbst nicht erreichbar (Agent nicht gestartet, falscher
33
+ // Port, Zeitueberschreitung dieses Aufrufs). Kein Terminal-Kontakt
34
+ // versucht -- das entscheidet payments.ts aber nicht hier, sondern
35
+ // ueber die Fehlerart: [HpsConnectTransportError] wird dort wie jeder
36
+ // andere Transportfehler behandelt (klaeren, niemals `declined`).
37
+ const grund = abbruch.signal.aborted ? `Zeitueberschreitung nach ${timeoutMs} ms` : String(ursache);
38
+ throw new errors_js_1.HpsConnectTransportError(`Kasseneck Connect nicht erreichbar (${baseUrl}): ${grund}`);
39
+ }
40
+ }
41
+ finally {
42
+ clearTimeout(wecker);
43
+ }
44
+ let huelle;
45
+ try {
46
+ huelle = text.trim() === '' ? null : JSON.parse(text);
47
+ }
48
+ catch {
49
+ throw new errors_js_1.HpsConnectTransportError(`Antwort von Kasseneck Connect ist kein JSON (HTTP ${antwort.status})`);
50
+ }
51
+ if (huelle === null || typeof huelle !== 'object' || !('ok' in huelle)) {
52
+ throw new errors_js_1.HpsConnectTransportError(`Antwort von Kasseneck Connect ohne "ok"-Feld (HTTP ${antwort.status})`);
53
+ }
54
+ const h = huelle;
55
+ if (h.ok === true) {
56
+ return h;
57
+ }
58
+ const code = typeof h.error?.code === 'string' ? h.error.code : undefined;
59
+ const message = typeof h.error?.message === 'string' && h.error.message.trim() !== ''
60
+ ? h.error.message
61
+ : `Kasseneck Connect meldet einen Fehler (HTTP ${antwort.status})`;
62
+ if (code !== undefined && errors_js_1.PREFLIGHT_CONNECT_CODES.has(code)) {
63
+ // Siehe errors.ts: diese Codes entstehen laut `kasseneck-connect`
64
+ // ausnahmslos VOR jedem Terminal-Kontakt -- beweisbar nichts gesendet.
65
+ throw new errors_js_1.HpsPreflightError(message, code);
66
+ }
67
+ // terminal_error / timeout / terminal_offline -- oder ein Code, den
68
+ // dieses Paket nicht kennt. Bewusst dieselbe Klasse fuer beide: ein
69
+ // unbekannter Code ist keine bewiesene Nicht-Aussendung, siehe
70
+ // PREFLIGHT_CONNECT_CODES.
71
+ //
72
+ // `error.detail.terminalHttpStatus` reist seit `kasseneck-connect`
73
+ // Commit `0fb6f66` mit, wenn das TERMINAL selbst einen HTTP-Status
74
+ // genannt hat (nie bei einem Transportfehler -- der erfindet keinen
75
+ // Status). Siehe errors.ts, `HpsConnectTerminalError.isTerminalBusy`.
76
+ const detail = h.error?.detail;
77
+ const terminalHttpStatus = typeof detail?.terminalHttpStatus === 'number' ? detail.terminalHttpStatus : undefined;
78
+ throw new errors_js_1.HpsConnectTerminalError(code ?? 'unbekannt', message, terminalHttpStatus);
79
+ }
80
+ function checkedTransactionId(value) {
81
+ if (!(0, transaction_id_js_1.isValidHpsTransactionId)(value)) {
82
+ throw new errors_js_1.HpsTransactionIdError(value);
83
+ }
84
+ return value;
85
+ }
86
+ function target(t) {
87
+ return { host: t.host, port: t.port, tid: t.tid };
88
+ }
89
+ return {
90
+ async payment(o) {
91
+ const transactionId = checkedTransactionId(o.transactionId);
92
+ const antwort = await rufen('/v1/terminal/payment', {
93
+ ...target(o),
94
+ transactionId,
95
+ amountCents: o.amountCents,
96
+ tipCents: o.tipCents,
97
+ reference: o.reference,
98
+ currency: o.currency,
99
+ language: o.language,
100
+ }, paymentTimeoutMs);
101
+ return (0, transaction_response_js_1.parseHpsTransactionResponse)(antwort['hps']);
102
+ },
103
+ async status(o) {
104
+ const transactionId = checkedTransactionId(o.transactionId);
105
+ const antwort = await rufen('/v1/terminal/status', { ...target(o), transactionId }, shortTimeoutMs);
106
+ return (0, transaction_response_js_1.parseHpsTransactionResponse)(antwort['hps']);
107
+ },
108
+ async abort(o) {
109
+ const transactionId = checkedTransactionId(o.transactionId);
110
+ const antwort = await rufen('/v1/terminal/abort', { ...target(o), transactionId }, shortTimeoutMs);
111
+ return (0, transaction_response_js_1.parseHpsTransactionResponse)(antwort['hps']);
112
+ },
113
+ async refund(o) {
114
+ // Beide Kennungen gehen ans Terminal -- beide muessen die
115
+ // Ziffernpruefung bestehen, sonst ist der Vorgang spaeter dauerhaft
116
+ // unauffindbar (siehe HpsClient._checkTransactionId im Dart-Zwilling).
117
+ const transactionId = checkedTransactionId(o.transactionId);
118
+ const originalTransactionId = checkedTransactionId(o.originalTransactionId);
119
+ const antwort = await rufen('/v1/terminal/refund', {
120
+ ...target(o),
121
+ transactionId,
122
+ originalTransactionId,
123
+ amountCents: o.amountCents,
124
+ reference: o.reference,
125
+ currency: o.currency,
126
+ language: o.language,
127
+ },
128
+ // Gutschrift ist ein Kartenfluss wie die Zahlung -- dieselbe lange Frist.
129
+ paymentTimeoutMs);
130
+ return (0, transaction_response_js_1.parseHpsTransactionResponse)(antwort['hps']);
131
+ },
132
+ async cancel(o) {
133
+ // Hier ist [transactionId] die der URSPRUENGLICHEN Zahlung -- die
134
+ // Ziffernpruefung gilt trotzdem unveraendert, sonst liefe die
135
+ // anschliessende Statusabfrage darauf ins Leere.
136
+ const transactionId = checkedTransactionId(o.transactionId);
137
+ const antwort = await rufen('/v1/terminal/cancel', {
138
+ ...target(o),
139
+ transactionId,
140
+ amountCents: o.amountCents,
141
+ currency: o.currency,
142
+ language: o.language,
143
+ }, shortTimeoutMs);
144
+ return (0, transaction_response_js_1.parseHpsTransactionResponse)(antwort['hps']);
145
+ },
146
+ async diagnosis(o) {
147
+ const antwort = await rufen('/v1/terminal/diagnosis', target(o), shortTimeoutMs);
148
+ const hps = antwort['hps'];
149
+ return hps !== null && typeof hps === 'object' && !Array.isArray(hps) ? hps : {};
150
+ },
151
+ };
152
+ }
153
+ function globalHpsConnectFetch() {
154
+ const umgebung = globalThis;
155
+ if (typeof umgebung.fetch !== 'function') {
156
+ throw new Error('createHpsConnectClient: kein globales fetch vorhanden -- Node >= 20.18 verwenden oder eine fetch-Umsetzung uebergeben');
157
+ }
158
+ return (url, init) => umgebung.fetch(url, init);
159
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Fehlerarten auf dem Weg ueber **Kasseneck Connect** zum hobex-HPS-Terminal.
3
+ *
4
+ * Drei Arten, bewusst getrennt, weil `payments.ts` auf jede anders reagiert —
5
+ * das ist die wichtigste Unterscheidung in diesem ganzen Vorhaben:
6
+ *
7
+ * - [HpsPreflightError] — es ist NACHWEISLICH nichts gesendet worden. Entweder
8
+ * die Kennung selbst war unbrauchbar (siehe `connect-client.ts`), oder
9
+ * Connect hat die Anfrage VOR dem Terminal-Kontakt abgelehnt (falscher
10
+ * Host, keine Kopplung, ...). Wird von `payments.ts` unveraendert
11
+ * weitergeworfen, niemals in einen Ausgang uebersetzt — Zwilling von
12
+ * Dart's `ArgumentError`-Sonderfall in `HpsPayments.pay()`.
13
+ * - [HpsConnectTerminalError] — die Anfrage GING RAUS (oder der Versuch dazu
14
+ * scheiterte am Transport), aber es kam keine schluessige Antwort. Das
15
+ * umfasst ausdruecklich auch [isTerminalBusy]: HTTP `409` ist die einzige
16
+ * dieser Lagen, die als [isTerminalBusy] eine POSITIVE Aussage traegt,
17
+ * siehe dort.
18
+ * - [HpsConnectTransportError] — Connect selbst war nicht erreichbar oder
19
+ * antwortete nicht in der erwarteten Form (kein JSON, keine Huelle).
20
+ *
21
+ * Beide letzteren werden von `payments.ts` in die Klaerung (Abbruch + Polling)
22
+ * geschickt, NIE in `declined` uebersetzt — mit der einen, gemessenen
23
+ * Ausnahme [isTerminalBusy].
24
+ */
25
+ export declare abstract class HpsConnectException extends Error {
26
+ }
27
+ /**
28
+ * Nichts ist gesendet worden. `reason` ist deutscher Klartext, `connectCode`
29
+ * gesetzt, wenn die Ablehnung von Connect kam (statt von der lokalen
30
+ * Kennungspruefung).
31
+ */
32
+ export declare class HpsPreflightError extends HpsConnectException {
33
+ readonly name: string;
34
+ readonly connectCode: string | undefined;
35
+ constructor(reason: string, connectCode?: string);
36
+ }
37
+ /**
38
+ * Die Transaktionskennung ist unbrauchbar (nicht rein numerisch, leer, oder
39
+ * laenger als 18 Stellen) — geprueft BEVOR irgendetwas an Connect geht, wie
40
+ * bei `HpsClient._checkTransactionId` im Dart-Zwilling.
41
+ *
42
+ * Eigene Klasse (statt nur [HpsPreflightError]) macht die Unterscheidung
43
+ * `instanceof`-pruefbar, ohne sich auf einen Text zu verlassen.
44
+ */
45
+ export declare class HpsTransactionIdError extends HpsPreflightError {
46
+ readonly name = "HpsTransactionIdError";
47
+ readonly value: string;
48
+ constructor(value: string);
49
+ }
50
+ /**
51
+ * Bekannte Connect-Fehlercodes, die VOR jedem Terminal-Kontakt entstehen (aus
52
+ * `kasseneck-connect/lib/src/api/{auth,responses,routes_terminal}.dart`):
53
+ * Middleware (Herkunft, Token, Pfad, Rumpfgroesse) oder die Feldpruefung in
54
+ * `_ziel`/`_handlePayment`/`_mitTransaktion` laufen alle, BEVOR die Bruecke
55
+ * `HpsBridge` das Terminal ueberhaupt anspricht.
56
+ *
57
+ * Bewusst eine Positivliste: nur ein hier benannter Code gilt als "beweisbar
58
+ * nichts gesendet". Ein Code, den diese Liste nicht kennt, wird in
59
+ * `connect-client.ts` NICHT als [HpsPreflightError] gelesen, sondern als
60
+ * [HpsConnectTerminalError] — die sichere Richtung, falls Connect einmal um
61
+ * einen Fehlercode erweitert wird, der doch am Terminal entsteht.
62
+ */
63
+ export declare const PREFLIGHT_CONNECT_CODES: ReadonlySet<string>;
64
+ /**
65
+ * Die Anfrage ging (oder der Versuch dazu) in Richtung Terminal, aber es kam
66
+ * keine schluessige Antwort — Connect meldete `terminal_error`, `timeout`
67
+ * oder `terminal_offline` (`kasseneck-connect/lib/src/terminal/hps.dart`),
68
+ * oder einen Fehlercode, den dieses Paket nicht kennt.
69
+ */
70
+ export declare class HpsConnectTerminalError extends HpsConnectException {
71
+ readonly name = "HpsConnectTerminalError";
72
+ /** Fehlercode von Connect, z. B. `terminal_error`, `timeout`, `terminal_offline`. */
73
+ readonly connectCode: string;
74
+ /**
75
+ * Der rohe HTTP-Status des Terminals, wenn Connect einen genannt hat
76
+ * (`error.detail.terminalHttpStatus`, seit `kasseneck-connect` Commit
77
+ * `0fb6f66`, "fix(terminal): den rohen HTTP-Status des Terminals mitgeben").
78
+ * `undefined` bei einem Transportfehler (Connect erfindet dort keinen) oder
79
+ * bei einer aelteren Connect-Fassung, die das Feld noch nicht sendet.
80
+ */
81
+ readonly terminalHttpStatus: number | undefined;
82
+ constructor(connectCode: string, message: string, terminalHttpStatus?: number);
83
+ /**
84
+ * `true`, wenn dies der gemessene "Terminal beschaeftigt"-Fall ist: das
85
+ * Terminal hat mit HTTP `409` geantwortet.
86
+ *
87
+ * Liest bevorzugt [terminalHttpStatus] — das strukturierte Feld, das
88
+ * Connect seit `0fb6f66` mitgibt. Nur wenn das Feld fehlt (aeltere
89
+ * Connect-Fassung im Feld, die es noch nicht kennt), faellt die Pruefung
90
+ * auf den Meldungstext zurueck (`_call` in
91
+ * `kasseneck-connect/lib/src/terminal/hps.dart` schrieb schon vor `0fb6f66`
92
+ * wortgleich `'Terminal meldet (HTTP ${response.statusCode}): ...'`).
93
+ *
94
+ * **Der Rueckfall ist eine Uebergangsloesung, kein Dauerzustand.** Sobald
95
+ * jede Kasse im Feld gegen einen Connect-Agenten mit `terminalHttpStatus`
96
+ * spricht, kann der Textabgleich entfallen — bis dahin bleibt er die
97
+ * einzige Absicherung fuer eine Installation, die noch nicht aktualisiert
98
+ * hat. Bricht auch das Textmuster (Formulierungsaenderung in Connect),
99
+ * faellt diese Erkennung auf `false` zurueck — die sichere Richtung: aus
100
+ * einem `409` wuerde dann `unresolved` statt des beweisbaren `declined`,
101
+ * niemals umgekehrt.
102
+ */
103
+ get isTerminalBusy(): boolean;
104
+ }
105
+ /**
106
+ * Connect selbst war nicht erreichbar, oder die Antwort hatte nicht die
107
+ * erwartete Form (kein JSON, keine `{ok, ...}`-Huelle, unerwarteter
108
+ * HTTP-Status ohne diese Huelle).
109
+ */
110
+ export declare class HpsConnectTransportError extends HpsConnectException {
111
+ readonly name = "HpsConnectTransportError";
112
+ constructor(message: string);
113
+ }
114
+ /**
115
+ * Das Klaerbudget ist aufgebraucht, WAEHREND ein einzelner Abruf (Abbruch
116
+ * oder Statusabfrage) noch lief. Wird in `payments.ts` wie jeder andere
117
+ * Transportfehler behandelt — siehe `withinBudget`.
118
+ */
119
+ export declare class HpsClarifyTimeoutError extends HpsConnectException {
120
+ readonly name = "HpsClarifyTimeoutError";
121
+ constructor(budgetMs: number);
122
+ }
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HpsClarifyTimeoutError = exports.HpsConnectTransportError = exports.HpsConnectTerminalError = exports.PREFLIGHT_CONNECT_CODES = exports.HpsTransactionIdError = exports.HpsPreflightError = exports.HpsConnectException = void 0;
4
+ const transaction_response_js_1 = require("./transaction-response.js");
5
+ /**
6
+ * Fehlerarten auf dem Weg ueber **Kasseneck Connect** zum hobex-HPS-Terminal.
7
+ *
8
+ * Drei Arten, bewusst getrennt, weil `payments.ts` auf jede anders reagiert —
9
+ * das ist die wichtigste Unterscheidung in diesem ganzen Vorhaben:
10
+ *
11
+ * - [HpsPreflightError] — es ist NACHWEISLICH nichts gesendet worden. Entweder
12
+ * die Kennung selbst war unbrauchbar (siehe `connect-client.ts`), oder
13
+ * Connect hat die Anfrage VOR dem Terminal-Kontakt abgelehnt (falscher
14
+ * Host, keine Kopplung, ...). Wird von `payments.ts` unveraendert
15
+ * weitergeworfen, niemals in einen Ausgang uebersetzt — Zwilling von
16
+ * Dart's `ArgumentError`-Sonderfall in `HpsPayments.pay()`.
17
+ * - [HpsConnectTerminalError] — die Anfrage GING RAUS (oder der Versuch dazu
18
+ * scheiterte am Transport), aber es kam keine schluessige Antwort. Das
19
+ * umfasst ausdruecklich auch [isTerminalBusy]: HTTP `409` ist die einzige
20
+ * dieser Lagen, die als [isTerminalBusy] eine POSITIVE Aussage traegt,
21
+ * siehe dort.
22
+ * - [HpsConnectTransportError] — Connect selbst war nicht erreichbar oder
23
+ * antwortete nicht in der erwarteten Form (kein JSON, keine Huelle).
24
+ *
25
+ * Beide letzteren werden von `payments.ts` in die Klaerung (Abbruch + Polling)
26
+ * geschickt, NIE in `declined` uebersetzt — mit der einen, gemessenen
27
+ * Ausnahme [isTerminalBusy].
28
+ */
29
+ class HpsConnectException extends Error {
30
+ }
31
+ exports.HpsConnectException = HpsConnectException;
32
+ /**
33
+ * Nichts ist gesendet worden. `reason` ist deutscher Klartext, `connectCode`
34
+ * gesetzt, wenn die Ablehnung von Connect kam (statt von der lokalen
35
+ * Kennungspruefung).
36
+ */
37
+ class HpsPreflightError extends HpsConnectException {
38
+ name = 'HpsPreflightError';
39
+ connectCode;
40
+ constructor(reason, connectCode) {
41
+ super(reason);
42
+ this.connectCode = connectCode;
43
+ }
44
+ }
45
+ exports.HpsPreflightError = HpsPreflightError;
46
+ /**
47
+ * Die Transaktionskennung ist unbrauchbar (nicht rein numerisch, leer, oder
48
+ * laenger als 18 Stellen) — geprueft BEVOR irgendetwas an Connect geht, wie
49
+ * bei `HpsClient._checkTransactionId` im Dart-Zwilling.
50
+ *
51
+ * Eigene Klasse (statt nur [HpsPreflightError]) macht die Unterscheidung
52
+ * `instanceof`-pruefbar, ohne sich auf einen Text zu verlassen.
53
+ */
54
+ class HpsTransactionIdError extends HpsPreflightError {
55
+ name = 'HpsTransactionIdError';
56
+ value;
57
+ constructor(value) {
58
+ super(`Transaktionskennung "${value}" ist unbrauchbar -- HPS erlaubt 1 bis 18 `
59
+ + 'Ziffern, rein numerisch');
60
+ this.value = value;
61
+ }
62
+ }
63
+ exports.HpsTransactionIdError = HpsTransactionIdError;
64
+ /**
65
+ * Bekannte Connect-Fehlercodes, die VOR jedem Terminal-Kontakt entstehen (aus
66
+ * `kasseneck-connect/lib/src/api/{auth,responses,routes_terminal}.dart`):
67
+ * Middleware (Herkunft, Token, Pfad, Rumpfgroesse) oder die Feldpruefung in
68
+ * `_ziel`/`_handlePayment`/`_mitTransaktion` laufen alle, BEVOR die Bruecke
69
+ * `HpsBridge` das Terminal ueberhaupt anspricht.
70
+ *
71
+ * Bewusst eine Positivliste: nur ein hier benannter Code gilt als "beweisbar
72
+ * nichts gesendet". Ein Code, den diese Liste nicht kennt, wird in
73
+ * `connect-client.ts` NICHT als [HpsPreflightError] gelesen, sondern als
74
+ * [HpsConnectTerminalError] — die sichere Richtung, falls Connect einmal um
75
+ * einen Fehlercode erweitert wird, der doch am Terminal entsteht.
76
+ */
77
+ exports.PREFLIGHT_CONNECT_CODES = new Set([
78
+ 'bad_request',
79
+ 'unauthorized',
80
+ 'origin_forbidden',
81
+ 'not_found',
82
+ 'body_too_large',
83
+ ]);
84
+ /**
85
+ * Die Anfrage ging (oder der Versuch dazu) in Richtung Terminal, aber es kam
86
+ * keine schluessige Antwort — Connect meldete `terminal_error`, `timeout`
87
+ * oder `terminal_offline` (`kasseneck-connect/lib/src/terminal/hps.dart`),
88
+ * oder einen Fehlercode, den dieses Paket nicht kennt.
89
+ */
90
+ class HpsConnectTerminalError extends HpsConnectException {
91
+ name = 'HpsConnectTerminalError';
92
+ /** Fehlercode von Connect, z. B. `terminal_error`, `timeout`, `terminal_offline`. */
93
+ connectCode;
94
+ /**
95
+ * Der rohe HTTP-Status des Terminals, wenn Connect einen genannt hat
96
+ * (`error.detail.terminalHttpStatus`, seit `kasseneck-connect` Commit
97
+ * `0fb6f66`, "fix(terminal): den rohen HTTP-Status des Terminals mitgeben").
98
+ * `undefined` bei einem Transportfehler (Connect erfindet dort keinen) oder
99
+ * bei einer aelteren Connect-Fassung, die das Feld noch nicht sendet.
100
+ */
101
+ terminalHttpStatus;
102
+ constructor(connectCode, message, terminalHttpStatus) {
103
+ super(message);
104
+ this.connectCode = connectCode;
105
+ this.terminalHttpStatus = terminalHttpStatus;
106
+ }
107
+ /**
108
+ * `true`, wenn dies der gemessene "Terminal beschaeftigt"-Fall ist: das
109
+ * Terminal hat mit HTTP `409` geantwortet.
110
+ *
111
+ * Liest bevorzugt [terminalHttpStatus] — das strukturierte Feld, das
112
+ * Connect seit `0fb6f66` mitgibt. Nur wenn das Feld fehlt (aeltere
113
+ * Connect-Fassung im Feld, die es noch nicht kennt), faellt die Pruefung
114
+ * auf den Meldungstext zurueck (`_call` in
115
+ * `kasseneck-connect/lib/src/terminal/hps.dart` schrieb schon vor `0fb6f66`
116
+ * wortgleich `'Terminal meldet (HTTP ${response.statusCode}): ...'`).
117
+ *
118
+ * **Der Rueckfall ist eine Uebergangsloesung, kein Dauerzustand.** Sobald
119
+ * jede Kasse im Feld gegen einen Connect-Agenten mit `terminalHttpStatus`
120
+ * spricht, kann der Textabgleich entfallen — bis dahin bleibt er die
121
+ * einzige Absicherung fuer eine Installation, die noch nicht aktualisiert
122
+ * hat. Bricht auch das Textmuster (Formulierungsaenderung in Connect),
123
+ * faellt diese Erkennung auf `false` zurueck — die sichere Richtung: aus
124
+ * einem `409` wuerde dann `unresolved` statt des beweisbaren `declined`,
125
+ * niemals umgekehrt.
126
+ */
127
+ get isTerminalBusy() {
128
+ if (this.terminalHttpStatus !== undefined) {
129
+ return this.terminalHttpStatus === transaction_response_js_1.TERMINAL_BUSY_HTTP_STATUS;
130
+ }
131
+ return this.connectCode === 'terminal_error' && new RegExp(`\\(HTTP ${transaction_response_js_1.TERMINAL_BUSY_HTTP_STATUS}\\)`).test(this.message);
132
+ }
133
+ }
134
+ exports.HpsConnectTerminalError = HpsConnectTerminalError;
135
+ /**
136
+ * Connect selbst war nicht erreichbar, oder die Antwort hatte nicht die
137
+ * erwartete Form (kein JSON, keine `{ok, ...}`-Huelle, unerwarteter
138
+ * HTTP-Status ohne diese Huelle).
139
+ */
140
+ class HpsConnectTransportError extends HpsConnectException {
141
+ name = 'HpsConnectTransportError';
142
+ constructor(message) {
143
+ super(message);
144
+ }
145
+ }
146
+ exports.HpsConnectTransportError = HpsConnectTransportError;
147
+ /**
148
+ * Das Klaerbudget ist aufgebraucht, WAEHREND ein einzelner Abruf (Abbruch
149
+ * oder Statusabfrage) noch lief. Wird in `payments.ts` wie jeder andere
150
+ * Transportfehler behandelt — siehe `withinBudget`.
151
+ */
152
+ class HpsClarifyTimeoutError extends HpsConnectException {
153
+ name = 'HpsClarifyTimeoutError';
154
+ constructor(budgetMs) {
155
+ super(`Klaerbudget ueberschritten (${budgetMs} ms)`);
156
+ }
157
+ }
158
+ exports.HpsClarifyTimeoutError = HpsClarifyTimeoutError;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Ereignisse der Klaerung — Zwilling von `HpsEventKind`/`HpsObserver`
3
+ * (`kasseneck_api/lib/src/hobex_hps/observer.dart`), hier nur fuer die
4
+ * Klaerungsphase in `payments.ts` (kein eigenes Ereignis je HTTP-Aufruf an
5
+ * Connect — die stehen bereits, mit Begruendung, in `HpsPaymentResult.steps`).
6
+ */
7
+ export type HpsPaymentEventKind =
8
+ /** Der Ausgang ist nach der direkten Antwort offen, die Klaerung laeuft. */
9
+ 'resolving'
10
+ /** Der Ausgang steht fest. */
11
+ | 'resolved'
12
+ /** Ein Fehler beim Auswerten der Antwort, der KEIN erwarteter Connect-Fehler ist. */
13
+ | 'unexpectedError';
14
+ /** Ein Ereignis der Klaerung. Bewusst schlank und ohne Kartendaten. */
15
+ export interface HpsPaymentEvent {
16
+ readonly kind: HpsPaymentEventKind;
17
+ readonly message: string;
18
+ readonly transactionId: string;
19
+ readonly error?: unknown;
20
+ }
21
+ /** Empfaenger der Ereignisse — die App legt ihn typischerweise auf ihr Protokoll. */
22
+ export type HpsPaymentObserver = (event: HpsPaymentEvent) => void;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Hobex-**HPS**-Kartenzahlung ueber **Kasseneck Connect** — den lokalen
3
+ * Geraete-Agenten, der ueber HTTP erreichbar ist und mit dem physischen
4
+ * Terminal spricht. Siehe `payments.ts` fuer den Klaerweg (Doku dort ist der
5
+ * Maszstab) und `connect-client.ts` fuer die Abgrenzung zum Dart-Zwilling
6
+ * `HpsClient` (der das Terminal DIREKT anspricht, ohne Connect).
7
+ *
8
+ * `pay`/`refund`/`cancel` — seit `kasseneck-connect` Commit `1c8a003` traegt
9
+ * Connect auch Gutschrift und Aufhebung, die Luecke aus einer frueheren
10
+ * Fassung dieses Moduls ist geschlossen.
11
+ *
12
+ * **Verbleibt: keine Adress-/Port-Ermittlung fuer Connect.** Der Agent kann
13
+ * auf `127.0.0.1:27182` bis `27189` laufen (belegter Port faellt auf den
14
+ * naechsten zurueck, siehe `kasseneck-connect`s README). Dieses Modul nimmt
15
+ * eine FESTE `baseUrl` entgegen (`HpsConnectClientOptions.baseUrl`, Vorgabe
16
+ * `27182`) und probiert die Portreihe nicht selbst durch — das Aufloesen der
17
+ * tatsaechlichen Adresse (z. B. ueber `GET /v1/status` je Port) bleibt Sache
18
+ * des Aufrufers.
19
+ */
20
+ export { type HpsConnectCancelOptions, type HpsConnectClient, type HpsConnectClientOptions, type HpsConnectFetch, type HpsConnectFetchResponse, type HpsConnectPaymentOptions, type HpsConnectRefundOptions, type HpsConnectTarget, type HpsConnectTransactionOptions, createHpsConnectClient, } from './connect-client.js';
21
+ export { HpsClarifyTimeoutError, HpsConnectException, HpsConnectTerminalError, HpsConnectTransportError, HpsPreflightError, HpsTransactionIdError, PREFLIGHT_CONNECT_CODES, } from './errors.js';
22
+ export { type HpsPaymentEvent, type HpsPaymentEventKind, type HpsPaymentObserver, } from './events.js';
23
+ export { type CardPaymentOutcome, type HpsPaymentResult, mayRetrySafely, } from './outcome.js';
24
+ export { type HpsCancelOptions, type HpsPaymentOptions, type HpsPayments, type HpsPaymentsOptions, type HpsRefundOptions, createHpsPayments, } from './payments.js';
25
+ export { MAX_TRANSACTION_ID_LENGTH, createHpsTransactionIdGenerator, isValidHpsTransactionId, newHpsTransactionId, type HpsTransactionIdGeneratorOptions, } from './transaction-id.js';
26
+ export { ABORTED_CODE, APPROVED_CODE, CARD_NOT_PRESENT_CODE, HPS_MEASURED_CODES, INVALID_TRANSACTION_CODE, NOT_ABORTABLE_CODE, INVALID_AMOUNT_CODE, AMOUNT_OUT_OF_RANGE_CODE, INVALID_TID_CODE, WRONG_PIN_CODE, NO_STATEMENT_CODE, TECHNICAL_ERROR_CODE, TERMINAL_BUSY_HTTP_STATUS, TRANSACTION_CANCELED_CODE, isApproved, isCanceled, isConclusive, isInProgress, isNoStatement, isNotAbortable, isTechnicalError, isUnknownCode, parseHpsTransactionResponse, type HpsMeasuredCode, type HpsTransactionResponse, } from './transaction-response.js';
27
+ export { hobexReceiptFromHps } from './receipt.js';