@kreiseck/kasseneck-api 0.6.45 → 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.
- package/README.md +95 -15
- package/dist/cjs/client/aufrufe.d.ts +1 -1
- package/dist/cjs/client/aufrufe.js +2 -0
- package/dist/cjs/client/errors.d.ts +7 -1
- package/dist/cjs/client/errors.js +8 -1
- package/dist/cjs/client/receipts.d.ts +16 -0
- package/dist/cjs/client/receipts.js +10 -0
- package/dist/cjs/client/transport.js +5 -4
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +4 -2
- package/dist/cjs/kasse/index.d.ts +1 -0
- package/dist/cjs/kasse/index.js +3 -0
- package/dist/cjs/kasse/trinkgeld.d.ts +10 -0
- package/dist/cjs/kasse/trinkgeld.js +27 -0
- package/dist/cjs/models/cancellation.d.ts +22 -0
- package/dist/cjs/models/cancellation.js +31 -1
- package/dist/cjs/models/hobex-receipt.js +9 -2
- package/dist/cjs/models/index.d.ts +1 -1
- package/dist/cjs/models/index.js +3 -1
- package/dist/cjs/models/receipt.js +3 -0
- package/dist/cjs/models/voucher.js +18 -2
- package/dist/cjs/payments/hobex-hps/connect-client.d.ts +104 -0
- package/dist/cjs/payments/hobex-hps/connect-client.js +159 -0
- package/dist/cjs/payments/hobex-hps/errors.d.ts +122 -0
- package/dist/cjs/payments/hobex-hps/errors.js +158 -0
- package/dist/cjs/payments/hobex-hps/events.d.ts +22 -0
- package/dist/cjs/payments/hobex-hps/events.js +2 -0
- package/dist/cjs/payments/hobex-hps/index.d.ts +27 -0
- package/dist/cjs/payments/hobex-hps/index.js +66 -0
- package/dist/cjs/payments/hobex-hps/outcome.d.ts +31 -0
- package/dist/cjs/payments/hobex-hps/outcome.js +7 -0
- package/dist/cjs/payments/hobex-hps/payments.d.ts +149 -0
- package/dist/cjs/payments/hobex-hps/payments.js +550 -0
- package/dist/cjs/payments/hobex-hps/receipt.d.ts +28 -0
- package/dist/cjs/payments/hobex-hps/receipt.js +60 -0
- package/dist/cjs/payments/hobex-hps/transaction-id.d.ts +65 -0
- package/dist/cjs/payments/hobex-hps/transaction-id.js +91 -0
- package/dist/cjs/payments/hobex-hps/transaction-response.d.ts +163 -0
- package/dist/cjs/payments/hobex-hps/transaction-response.js +245 -0
- package/dist/cjs/payments/hobex.js +9 -6
- package/dist/cjs/payments/index.d.ts +26 -14
- package/dist/cjs/payments/index.js +59 -15
- package/dist/cjs/printing/index.d.ts +1 -1
- package/dist/cjs/printing/index.js +2 -1
- package/dist/cjs/printing/webusb.d.ts +37 -7
- package/dist/cjs/printing/webusb.js +76 -18
- package/dist/cjs/receipt/epos.d.ts +18 -0
- package/dist/cjs/receipt/epos.js +78 -6
- package/dist/cjs/receipt/index.d.ts +1 -1
- package/dist/cjs/receipt/index.js +2 -1
- package/dist/cjs/register/index.d.ts +1 -1
- package/dist/cjs/register/index.js +2 -1
- package/dist/cjs/register/pairing.d.ts +67 -1
- package/dist/cjs/register/pairing.js +59 -3
- package/dist/esm/client/aufrufe.d.ts +1 -1
- package/dist/esm/client/aufrufe.js +2 -0
- package/dist/esm/client/errors.d.ts +7 -1
- package/dist/esm/client/errors.js +8 -1
- package/dist/esm/client/receipts.d.ts +16 -0
- package/dist/esm/client/receipts.js +10 -0
- package/dist/esm/client/transport.js +5 -4
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/kasse/index.d.ts +1 -0
- package/dist/esm/kasse/index.js +1 -0
- package/dist/esm/kasse/trinkgeld.d.ts +10 -0
- package/dist/esm/kasse/trinkgeld.js +24 -0
- package/dist/esm/models/cancellation.d.ts +22 -0
- package/dist/esm/models/cancellation.js +29 -0
- package/dist/esm/models/hobex-receipt.js +10 -3
- package/dist/esm/models/index.d.ts +1 -1
- package/dist/esm/models/index.js +1 -1
- package/dist/esm/models/receipt.js +3 -0
- package/dist/esm/models/voucher.js +18 -2
- package/dist/esm/payments/hobex-hps/connect-client.d.ts +104 -0
- package/dist/esm/payments/hobex-hps/connect-client.js +156 -0
- package/dist/esm/payments/hobex-hps/errors.d.ts +122 -0
- package/dist/esm/payments/hobex-hps/errors.js +149 -0
- package/dist/esm/payments/hobex-hps/events.d.ts +22 -0
- package/dist/esm/payments/hobex-hps/events.js +1 -0
- package/dist/esm/payments/hobex-hps/index.d.ts +27 -0
- package/dist/esm/payments/hobex-hps/index.js +26 -0
- package/dist/esm/payments/hobex-hps/outcome.d.ts +31 -0
- package/dist/esm/payments/hobex-hps/outcome.js +4 -0
- package/dist/esm/payments/hobex-hps/payments.d.ts +149 -0
- package/dist/esm/payments/hobex-hps/payments.js +547 -0
- package/dist/esm/payments/hobex-hps/receipt.d.ts +28 -0
- package/dist/esm/payments/hobex-hps/receipt.js +57 -0
- package/dist/esm/payments/hobex-hps/transaction-id.d.ts +65 -0
- package/dist/esm/payments/hobex-hps/transaction-id.js +86 -0
- package/dist/esm/payments/hobex-hps/transaction-response.d.ts +163 -0
- package/dist/esm/payments/hobex-hps/transaction-response.js +233 -0
- package/dist/esm/payments/hobex.js +9 -6
- package/dist/esm/payments/index.d.ts +26 -14
- package/dist/esm/payments/index.js +26 -14
- package/dist/esm/printing/index.d.ts +1 -1
- package/dist/esm/printing/index.js +1 -1
- package/dist/esm/printing/webusb.d.ts +37 -7
- package/dist/esm/printing/webusb.js +74 -17
- package/dist/esm/receipt/epos.d.ts +18 -0
- package/dist/esm/receipt/epos.js +76 -6
- package/dist/esm/receipt/index.d.ts +1 -1
- package/dist/esm/receipt/index.js +1 -1
- package/dist/esm/register/index.d.ts +1 -1
- package/dist/esm/register/index.js +1 -1
- package/dist/esm/register/pairing.d.ts +67 -1
- package/dist/esm/register/pairing.js +58 -3
- package/fixtures/hobex-hps-codes.json +67 -0
- package/fixtures/oberflaeche.json +3 -1
- package/package.json +4 -2
|
@@ -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,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, 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';
|