@kreiseck/kasseneck-api 0.7.1 → 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.
- package/CHANGELOG.md +32 -0
- package/dist/cjs/payments/hobex-hps/index.d.ts +1 -1
- package/dist/cjs/payments/hobex-hps/index.js +2 -1
- package/dist/cjs/payments/hobex-hps/outcome.d.ts +16 -1
- package/dist/cjs/payments/hobex-hps/payments.js +34 -11
- package/dist/cjs/payments/hobex-hps/transaction-response.d.ts +12 -0
- package/dist/cjs/payments/hobex-hps/transaction-response.js +22 -1
- package/dist/esm/payments/hobex-hps/index.d.ts +1 -1
- package/dist/esm/payments/hobex-hps/index.js +1 -1
- package/dist/esm/payments/hobex-hps/outcome.d.ts +16 -1
- package/dist/esm/payments/hobex-hps/payments.js +34 -11
- package/dist/esm/payments/hobex-hps/transaction-response.d.ts +12 -0
- package/dist/esm/payments/hobex-hps/transaction-response.js +21 -0
- package/fixtures/hobex-hps-codes.json +17 -1
- package/fixtures/oberflaeche.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,38 @@ Was vor 0.7.0 geschah, steht in der Commit-Historie (`git log`); ab hier wird
|
|
|
4
4
|
es hier geführt. Ein Eintrag nennt die Änderung **und ihren Grund** —
|
|
5
5
|
nur der Grund überlebt den nächsten Umbau.
|
|
6
6
|
|
|
7
|
+
## 0.7.2
|
|
8
|
+
|
|
9
|
+
### `55` („PIN falsch") ist eine gemessene Host-Ablehnung → `declined`
|
|
10
|
+
|
|
11
|
+
**Anlass:** Vorfall vom 02.09.2026 am Produktivterminal 3556988 (HPS 1.11.4,
|
|
12
|
+
Firmware 2.3.9), vom Dart-Zwilling `kasseneck_api` 6.4.0 übernommen — die
|
|
13
|
+
erste echte Host-Ablehnung, die je beobachtet wurde. Die Zahlung antwortete
|
|
14
|
+
direkt mit `55`, die Statusabfrage danach elfmal in Folge ebenfalls. Als
|
|
15
|
+
Wissenslücke kostete der Code 90 s Klärung ins Budget, `unresolved`, einen
|
|
16
|
+
stehenden Merker und eine Rückfrage an den Bediener — für eine falsch
|
|
17
|
+
getippte PIN.
|
|
18
|
+
|
|
19
|
+
- Neu: `WRONG_PIN_CODE`, in `HPS_MEASURED_CODES` als schlüssig geführt.
|
|
20
|
+
- Bewusst **keine** Familienregel für zweistellige Host-Codes: ISO 8583 führt
|
|
21
|
+
dort auch Genehmigungen (`08`, `10`, `11`, `85`). Die Zwei-`9027`-Regel
|
|
22
|
+
greift bei Host-Codes nicht (der Status antwortet mit dem Code selbst);
|
|
23
|
+
ungemessene Host-Codes enden weiterhin bei `unresolved`.
|
|
24
|
+
- `fixtures/hobex-hps-codes.json` neu erzeugt; die Vertragsdatei nennt jetzt
|
|
25
|
+
unter `ergaenztAn`, welcher Code von welchem Gerät stammt.
|
|
26
|
+
|
|
27
|
+
### Neu: `HpsPaymentResult.lastResponse` und Terminal-Klartext im Nachweis
|
|
28
|
+
|
|
29
|
+
Am 02.09.2026 sah der Bediener bei einer Antwort `55` „PIN falsch" nur
|
|
30
|
+
„Ausgang unklar", musste raten und buchte die abgelehnte Zahlung als bezahlt;
|
|
31
|
+
75 EUR Umsatz waren weg. Der Klartext hätte die Entscheidung getragen.
|
|
32
|
+
|
|
33
|
+
- `lastResponse`: die letzte Terminal-Antwort bei `unresolved`, auch wenn sie
|
|
34
|
+
nichts entschied — Material für Anzeige und Katalog, nie ein Beleg.
|
|
35
|
+
`response` bleibt bei `unresolved` weiterhin ungesetzt.
|
|
36
|
+
- Der Nachweis nennt bei einem unbekannten Code den Klartext des Terminals:
|
|
37
|
+
`Terminal nennt einen unbekannten Code (55) "PIN falsch"`.
|
|
38
|
+
|
|
7
39
|
## 0.7.0
|
|
8
40
|
|
|
9
41
|
### Neu: Unterpfad `./partner` — die Partner-API
|
|
@@ -23,5 +23,5 @@ export { type HpsPaymentEvent, type HpsPaymentEventKind, type HpsPaymentObserver
|
|
|
23
23
|
export { type CardPaymentOutcome, type HpsPaymentResult, mayRetrySafely, } from './outcome.js';
|
|
24
24
|
export { type HpsCancelOptions, type HpsPaymentOptions, type HpsPayments, type HpsPaymentsOptions, type HpsRefundOptions, createHpsPayments, } from './payments.js';
|
|
25
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';
|
|
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
27
|
export { hobexReceiptFromHps } from './receipt.js';
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* des Aufrufers.
|
|
20
20
|
*/
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.hobexReceiptFromHps = exports.parseHpsTransactionResponse = exports.isUnknownCode = exports.isTechnicalError = exports.isNotAbortable = exports.isNoStatement = exports.isInProgress = exports.isConclusive = exports.isCanceled = exports.isApproved = exports.TRANSACTION_CANCELED_CODE = exports.TERMINAL_BUSY_HTTP_STATUS = exports.TECHNICAL_ERROR_CODE = exports.NO_STATEMENT_CODE = exports.INVALID_TID_CODE = exports.AMOUNT_OUT_OF_RANGE_CODE = exports.INVALID_AMOUNT_CODE = exports.NOT_ABORTABLE_CODE = exports.INVALID_TRANSACTION_CODE = exports.HPS_MEASURED_CODES = exports.CARD_NOT_PRESENT_CODE = exports.APPROVED_CODE = exports.ABORTED_CODE = exports.newHpsTransactionId = exports.isValidHpsTransactionId = exports.createHpsTransactionIdGenerator = exports.MAX_TRANSACTION_ID_LENGTH = exports.createHpsPayments = exports.mayRetrySafely = exports.PREFLIGHT_CONNECT_CODES = exports.HpsTransactionIdError = exports.HpsPreflightError = exports.HpsConnectTransportError = exports.HpsConnectTerminalError = exports.HpsConnectException = exports.HpsClarifyTimeoutError = exports.createHpsConnectClient = void 0;
|
|
22
|
+
exports.hobexReceiptFromHps = exports.parseHpsTransactionResponse = exports.isUnknownCode = exports.isTechnicalError = exports.isNotAbortable = exports.isNoStatement = exports.isInProgress = exports.isConclusive = exports.isCanceled = exports.isApproved = exports.TRANSACTION_CANCELED_CODE = exports.TERMINAL_BUSY_HTTP_STATUS = exports.TECHNICAL_ERROR_CODE = exports.NO_STATEMENT_CODE = exports.WRONG_PIN_CODE = exports.INVALID_TID_CODE = exports.AMOUNT_OUT_OF_RANGE_CODE = exports.INVALID_AMOUNT_CODE = exports.NOT_ABORTABLE_CODE = exports.INVALID_TRANSACTION_CODE = exports.HPS_MEASURED_CODES = exports.CARD_NOT_PRESENT_CODE = exports.APPROVED_CODE = exports.ABORTED_CODE = exports.newHpsTransactionId = exports.isValidHpsTransactionId = exports.createHpsTransactionIdGenerator = exports.MAX_TRANSACTION_ID_LENGTH = exports.createHpsPayments = exports.mayRetrySafely = exports.PREFLIGHT_CONNECT_CODES = exports.HpsTransactionIdError = exports.HpsPreflightError = exports.HpsConnectTransportError = exports.HpsConnectTerminalError = exports.HpsConnectException = exports.HpsClarifyTimeoutError = exports.createHpsConnectClient = void 0;
|
|
23
23
|
var connect_client_js_1 = require("./connect-client.js");
|
|
24
24
|
Object.defineProperty(exports, "createHpsConnectClient", { enumerable: true, get: function () { return connect_client_js_1.createHpsConnectClient; } });
|
|
25
25
|
var errors_js_1 = require("./errors.js");
|
|
@@ -49,6 +49,7 @@ Object.defineProperty(exports, "NOT_ABORTABLE_CODE", { enumerable: true, get: fu
|
|
|
49
49
|
Object.defineProperty(exports, "INVALID_AMOUNT_CODE", { enumerable: true, get: function () { return transaction_response_js_1.INVALID_AMOUNT_CODE; } });
|
|
50
50
|
Object.defineProperty(exports, "AMOUNT_OUT_OF_RANGE_CODE", { enumerable: true, get: function () { return transaction_response_js_1.AMOUNT_OUT_OF_RANGE_CODE; } });
|
|
51
51
|
Object.defineProperty(exports, "INVALID_TID_CODE", { enumerable: true, get: function () { return transaction_response_js_1.INVALID_TID_CODE; } });
|
|
52
|
+
Object.defineProperty(exports, "WRONG_PIN_CODE", { enumerable: true, get: function () { return transaction_response_js_1.WRONG_PIN_CODE; } });
|
|
52
53
|
Object.defineProperty(exports, "NO_STATEMENT_CODE", { enumerable: true, get: function () { return transaction_response_js_1.NO_STATEMENT_CODE; } });
|
|
53
54
|
Object.defineProperty(exports, "TECHNICAL_ERROR_CODE", { enumerable: true, get: function () { return transaction_response_js_1.TECHNICAL_ERROR_CODE; } });
|
|
54
55
|
Object.defineProperty(exports, "TERMINAL_BUSY_HTTP_STATUS", { enumerable: true, get: function () { return transaction_response_js_1.TERMINAL_BUSY_HTTP_STATUS; } });
|
|
@@ -18,8 +18,23 @@ export type CardPaymentOutcome = 'approved' | 'declined' | 'unresolved';
|
|
|
18
18
|
export interface HpsPaymentResult {
|
|
19
19
|
readonly outcome: CardPaymentOutcome;
|
|
20
20
|
readonly transactionId: string;
|
|
21
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Die Antwort des Terminals, die den Ausgang FESTGESCHRIEBEN hat -- nur
|
|
23
|
+
* bei `approved` und `declined`. Bei `unresolved` fehlt sie: eine
|
|
24
|
+
* Nicht-Aussage darf nicht als Beleg mitgegeben werden. Was das Terminal
|
|
25
|
+
* zuletzt gesagt hat, steht dann in [lastResponse].
|
|
26
|
+
*/
|
|
22
27
|
readonly response?: HpsTransactionResponse;
|
|
28
|
+
/**
|
|
29
|
+
* Die letzte Antwort des Terminals bei `unresolved`, sofern ueberhaupt
|
|
30
|
+
* eine ankam -- auch wenn sie nichts entschied (9027, 9900, ein
|
|
31
|
+
* unbekannter Code). NIE ein Beleg, sondern Material fuer Anzeige und
|
|
32
|
+
* Katalog: am 02.09.2026 sah der Bediener bei einer Antwort `55`
|
|
33
|
+
* "PIN falsch" nur "Ausgang unklar", musste raten und buchte eine
|
|
34
|
+
* abgelehnte Zahlung als bezahlt. Der Klartext des Terminals haette die
|
|
35
|
+
* Entscheidung getragen. Bei schluessigem Ausgang nicht gesetzt.
|
|
36
|
+
*/
|
|
37
|
+
readonly lastResponse?: HpsTransactionResponse;
|
|
23
38
|
/**
|
|
24
39
|
* Verlauf der Klaerung, in Reihenfolge — der Nachweis, der im
|
|
25
40
|
* Belastungsstreit gelesen wird. Behauptet nie eine Ursache, die nicht
|
|
@@ -70,7 +70,7 @@ function createHpsPayments(client, target, options = {}) {
|
|
|
70
70
|
return `Antwort mit technischem Fehler (${transaction_response_js_1.TECHNICAL_ERROR_CODE}) -- keine Aussage ueber den Vorgang, Ausgang wird geklaert`;
|
|
71
71
|
}
|
|
72
72
|
if ((0, transaction_response_js_1.isUnknownCode)(res)) {
|
|
73
|
-
return `Terminal nennt einen unbekannten Code (${res.responseCode}) -- Ausgang wird geklaert`;
|
|
73
|
+
return `Terminal nennt einen unbekannten Code (${res.responseCode})${klartext(res)} -- Ausgang wird geklaert`;
|
|
74
74
|
}
|
|
75
75
|
return `Antwort ohne Aussage (${res.responseCode}) -- Ausgang wird geklaert`;
|
|
76
76
|
}
|
|
@@ -83,10 +83,21 @@ function createHpsPayments(client, target, options = {}) {
|
|
|
83
83
|
return `Status: technischer Fehler (${transaction_response_js_1.TECHNICAL_ERROR_CODE}) -- keine Aussage ueber den Vorgang`;
|
|
84
84
|
}
|
|
85
85
|
if ((0, transaction_response_js_1.isUnknownCode)(status)) {
|
|
86
|
-
return `Status: unbekannter Code (${status.responseCode}) -- keine Aussage`;
|
|
86
|
+
return `Status: unbekannter Code (${status.responseCode})${klartext(status)} -- keine Aussage`;
|
|
87
87
|
}
|
|
88
88
|
return null;
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Der Klartext des Terminals zu einem UNBEKANNTEN Code, als Zusatz fuer den
|
|
92
|
+
* Nachweis -- oder leer, wenn keiner mitkam. Nur hier, nicht bei den
|
|
93
|
+
* gemessenen Codes: deren Bedeutung ist benannt. Bei einem unbekannten Code
|
|
94
|
+
* ist er dagegen das Einzige, was ein Mensch lesen kann -- "PIN falsch"
|
|
95
|
+
* neben `55` haette am 02.09.2026 gereicht, um nicht "bezahlt" zu buchen.
|
|
96
|
+
*/
|
|
97
|
+
function klartext(res) {
|
|
98
|
+
const text = res.responseText?.trim();
|
|
99
|
+
return text ? ` "${text}"` : '';
|
|
100
|
+
}
|
|
90
101
|
/** Ordnet eine Terminal-Antwort ein. `null`, wenn sie nichts entscheidet. */
|
|
91
102
|
function fromResponse(res, id, steps) {
|
|
92
103
|
if (!(0, transaction_response_js_1.isConclusive)(res))
|
|
@@ -188,9 +199,19 @@ function createHpsPayments(client, target, options = {}) {
|
|
|
188
199
|
}
|
|
189
200
|
return null;
|
|
190
201
|
}
|
|
191
|
-
|
|
202
|
+
/**
|
|
203
|
+
* [letzteAntwort] ist die letzte Antwort, die das Terminal in dieser
|
|
204
|
+
* Klaerung gab -- als `lastResponse` fuer Anzeige und Katalog,
|
|
205
|
+
* ausdruecklich NICHT als `response`.
|
|
206
|
+
*/
|
|
207
|
+
function open(id, steps, letzteAntwort) {
|
|
192
208
|
emit('resolved', steps[steps.length - 1], id);
|
|
193
|
-
return {
|
|
209
|
+
return {
|
|
210
|
+
outcome: 'unresolved',
|
|
211
|
+
transactionId: id,
|
|
212
|
+
...(letzteAntwort ? { lastResponse: letzteAntwort } : {}),
|
|
213
|
+
steps: [...steps],
|
|
214
|
+
};
|
|
194
215
|
}
|
|
195
216
|
/**
|
|
196
217
|
* Fuehrt [call] aus, aber hoechstens so lange, wie vom [resolveBudgetMs]
|
|
@@ -263,7 +284,7 @@ function createHpsPayments(client, target, options = {}) {
|
|
|
263
284
|
* [NO_STATEMENT_CODE] (`9027`) beim Pollen einen Aussagewert, den es sonst
|
|
264
285
|
* nicht hat. Siehe [ausGeschlossenerAntwort].
|
|
265
286
|
*/
|
|
266
|
-
async function resolve(id, steps, antwortMitCode = false) {
|
|
287
|
+
async function resolve(id, steps, antwortMitCode = false, letzteAntwort) {
|
|
267
288
|
emit('resolving', 'Ausgang offen, Klaerung laeuft', id);
|
|
268
289
|
const start = now();
|
|
269
290
|
const elapsedMs = () => now() - start;
|
|
@@ -284,6 +305,7 @@ function createHpsPayments(client, target, options = {}) {
|
|
|
284
305
|
try {
|
|
285
306
|
status = await withinBudget(elapsedMs, () => client.status({ ...target, transactionId: id }));
|
|
286
307
|
transportFailures = 0;
|
|
308
|
+
letzteAntwort = status;
|
|
287
309
|
}
|
|
288
310
|
catch (e) {
|
|
289
311
|
transportFailures += 1;
|
|
@@ -312,7 +334,7 @@ function createHpsPayments(client, target, options = {}) {
|
|
|
312
334
|
wait = nextWait(wait);
|
|
313
335
|
}
|
|
314
336
|
steps.push('Ausgang bleibt offen');
|
|
315
|
-
return open(id, steps);
|
|
337
|
+
return open(id, steps, letzteAntwort);
|
|
316
338
|
}
|
|
317
339
|
/**
|
|
318
340
|
* Liest `9027` beim Pollen als "nicht genehmigt" -- aber NUR, wenn das
|
|
@@ -372,7 +394,7 @@ function createHpsPayments(client, target, options = {}) {
|
|
|
372
394
|
* Budget, Backoff und Transportfehler-Deckelung sind unveraendert aus
|
|
373
395
|
* [resolve] uebernommen.
|
|
374
396
|
*/
|
|
375
|
-
async function resolveCancel(id, steps) {
|
|
397
|
+
async function resolveCancel(id, steps, letzteAntwort) {
|
|
376
398
|
emit('resolving', 'Ausgang offen, Klaerung laeuft', id);
|
|
377
399
|
const start = now();
|
|
378
400
|
const elapsedMs = () => now() - start;
|
|
@@ -393,6 +415,7 @@ function createHpsPayments(client, target, options = {}) {
|
|
|
393
415
|
status = await withinBudget(elapsedMs, () => client.status({ ...target, transactionId: id }));
|
|
394
416
|
transportFailures = 0;
|
|
395
417
|
answeredQueries += 1;
|
|
418
|
+
letzteAntwort = status;
|
|
396
419
|
}
|
|
397
420
|
catch (e) {
|
|
398
421
|
transportFailures += 1;
|
|
@@ -416,7 +439,7 @@ function createHpsPayments(client, target, options = {}) {
|
|
|
416
439
|
wait = nextWait(wait);
|
|
417
440
|
}
|
|
418
441
|
steps.push('Ausgang bleibt offen');
|
|
419
|
-
return open(id, steps);
|
|
442
|
+
return open(id, steps, letzteAntwort);
|
|
420
443
|
}
|
|
421
444
|
async function pay(paymentOptions) {
|
|
422
445
|
const id = paymentOptions.transactionId ?? (0, transaction_id_js_1.newHpsTransactionId)();
|
|
@@ -455,7 +478,7 @@ function createHpsPayments(client, target, options = {}) {
|
|
|
455
478
|
return settled;
|
|
456
479
|
steps.push(offeneAntwort(res));
|
|
457
480
|
}
|
|
458
|
-
return resolve(id, steps, res?.responseCode !== undefined);
|
|
481
|
+
return resolve(id, steps, res?.responseCode !== undefined, res);
|
|
459
482
|
}
|
|
460
483
|
/**
|
|
461
484
|
* Gutschrift mit geklaertem Ausgang -- EXAKT derselbe Klaerweg wie [pay]
|
|
@@ -499,7 +522,7 @@ function createHpsPayments(client, target, options = {}) {
|
|
|
499
522
|
// Dieselbe Klaerfunktion wie [pay]: die Kennung ist die des NEUEN
|
|
500
523
|
// Vorgangs, eine Statusabfrage darauf liefert also genau dessen Ausgang,
|
|
501
524
|
// und der Abbruch ist derselbe Diskriminator wie bei einer Zahlung.
|
|
502
|
-
return resolve(id, steps, res?.responseCode !== undefined);
|
|
525
|
+
return resolve(id, steps, res?.responseCode !== undefined, res);
|
|
503
526
|
}
|
|
504
527
|
/**
|
|
505
528
|
* Aufhebung (Storno/Void) einer bestehenden Zahlung mit geklaertem Ausgang.
|
|
@@ -544,7 +567,7 @@ function createHpsPayments(client, target, options = {}) {
|
|
|
544
567
|
if (!(0, transaction_response_js_1.isCanceled)(res))
|
|
545
568
|
steps.push(offeneAntwort(res));
|
|
546
569
|
}
|
|
547
|
-
return resolveCancel(id, steps);
|
|
570
|
+
return resolveCancel(id, steps, res);
|
|
548
571
|
}
|
|
549
572
|
return { pay, refund, cancel };
|
|
550
573
|
}
|
|
@@ -72,6 +72,18 @@ export declare const INVALID_AMOUNT_CODE = "9003";
|
|
|
72
72
|
export declare const AMOUNT_OUT_OF_RANGE_CODE = "100019";
|
|
73
73
|
/** Siehe [HPS_MEASURED_CODES]: Terminal-Kennung unbekannt. */
|
|
74
74
|
export declare const INVALID_TID_CODE = "100108";
|
|
75
|
+
/**
|
|
76
|
+
* Siehe [HPS_MEASURED_CODES]: Host-Ablehnung, falsche PIN -- nichts belastet.
|
|
77
|
+
*
|
|
78
|
+
* Zweistellig, weil ein Antwortcode des HOSTS (ISO 8583, 55 = "Incorrect
|
|
79
|
+
* PIN"), kein `9xxx`-Terminalcode und kein `100xxx`-Code der HPS-Anwendung.
|
|
80
|
+
* Daraus folgt KEINE Regel fuer andere zweistellige Codes: in derselben
|
|
81
|
+
* Familie stehen Genehmigungen (`08`, `10`, `11`, `85`). Jeder andere
|
|
82
|
+
* Host-Code bleibt eine Wissensluecke, bis er gemessen ist -- und die
|
|
83
|
+
* Zwei-9027-Regel in `payments.ts` faengt ihn nicht, weil die Statusabfrage
|
|
84
|
+
* dann nicht 9027 antwortet, sondern mit dem Code selbst.
|
|
85
|
+
*/
|
|
86
|
+
export declare const WRONG_PIN_CODE = "55";
|
|
75
87
|
/**
|
|
76
88
|
* HTTP `409` ("Terminal is busy"): das Terminal serialisiert und weist eine
|
|
77
89
|
* zweite Anfrage ab, waehrend eine erste noch laeuft. Am 27.08.2026 gemessen:
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
* sein kann, als `declined` gemeldet.
|
|
29
29
|
*/
|
|
30
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;
|
|
31
|
+
exports.TERMINAL_BUSY_HTTP_STATUS = exports.WRONG_PIN_CODE = 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
32
|
exports.parseHpsTransactionResponse = parseHpsTransactionResponse;
|
|
33
33
|
exports.isApproved = isApproved;
|
|
34
34
|
exports.isInProgress = isInProgress;
|
|
@@ -96,6 +96,15 @@ exports.HPS_MEASURED_CODES = [
|
|
|
96
96
|
+ 'nicht; der Vorgang wird abgewiesen, bevor etwas geschieht',
|
|
97
97
|
conclusive: true,
|
|
98
98
|
},
|
|
99
|
+
{
|
|
100
|
+
code: '55',
|
|
101
|
+
meaning: '"PIN falsch" -- Host-Ablehnung wegen falscher PIN, die erste '
|
|
102
|
+
+ 'gemessene Host-Ablehnung ueberhaupt (02.09.2026 im Betrieb, TID '
|
|
103
|
+
+ '3556988, HPS 1.11.4, Firmware 2.3.9): die Zahlung antwortete direkt '
|
|
104
|
+
+ 'damit, die Statusabfrage danach elfmal in Folge ebenso -- eine '
|
|
105
|
+
+ 'Host-Ablehnung bleibt am Terminal abrufbar; nichts belastet',
|
|
106
|
+
conclusive: true,
|
|
107
|
+
},
|
|
99
108
|
];
|
|
100
109
|
/** `responseCode` einer genehmigten Zahlung. */
|
|
101
110
|
exports.APPROVED_CODE = '0';
|
|
@@ -119,6 +128,18 @@ exports.INVALID_AMOUNT_CODE = '9003';
|
|
|
119
128
|
exports.AMOUNT_OUT_OF_RANGE_CODE = '100019';
|
|
120
129
|
/** Siehe [HPS_MEASURED_CODES]: Terminal-Kennung unbekannt. */
|
|
121
130
|
exports.INVALID_TID_CODE = '100108';
|
|
131
|
+
/**
|
|
132
|
+
* Siehe [HPS_MEASURED_CODES]: Host-Ablehnung, falsche PIN -- nichts belastet.
|
|
133
|
+
*
|
|
134
|
+
* Zweistellig, weil ein Antwortcode des HOSTS (ISO 8583, 55 = "Incorrect
|
|
135
|
+
* PIN"), kein `9xxx`-Terminalcode und kein `100xxx`-Code der HPS-Anwendung.
|
|
136
|
+
* Daraus folgt KEINE Regel fuer andere zweistellige Codes: in derselben
|
|
137
|
+
* Familie stehen Genehmigungen (`08`, `10`, `11`, `85`). Jeder andere
|
|
138
|
+
* Host-Code bleibt eine Wissensluecke, bis er gemessen ist -- und die
|
|
139
|
+
* Zwei-9027-Regel in `payments.ts` faengt ihn nicht, weil die Statusabfrage
|
|
140
|
+
* dann nicht 9027 antwortet, sondern mit dem Code selbst.
|
|
141
|
+
*/
|
|
142
|
+
exports.WRONG_PIN_CODE = '55';
|
|
122
143
|
/**
|
|
123
144
|
* HTTP `409` ("Terminal is busy"): das Terminal serialisiert und weist eine
|
|
124
145
|
* zweite Anfrage ab, waehrend eine erste noch laeuft. Am 27.08.2026 gemessen:
|
|
@@ -23,5 +23,5 @@ export { type HpsPaymentEvent, type HpsPaymentEventKind, type HpsPaymentObserver
|
|
|
23
23
|
export { type CardPaymentOutcome, type HpsPaymentResult, mayRetrySafely, } from './outcome.js';
|
|
24
24
|
export { type HpsCancelOptions, type HpsPaymentOptions, type HpsPayments, type HpsPaymentsOptions, type HpsRefundOptions, createHpsPayments, } from './payments.js';
|
|
25
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';
|
|
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
27
|
export { hobexReceiptFromHps } from './receipt.js';
|
|
@@ -22,5 +22,5 @@ export { HpsClarifyTimeoutError, HpsConnectException, HpsConnectTerminalError, H
|
|
|
22
22
|
export { mayRetrySafely, } from './outcome.js';
|
|
23
23
|
export { createHpsPayments, } from './payments.js';
|
|
24
24
|
export { MAX_TRANSACTION_ID_LENGTH, createHpsTransactionIdGenerator, isValidHpsTransactionId, newHpsTransactionId, } from './transaction-id.js';
|
|
25
|
-
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, } from './transaction-response.js';
|
|
25
|
+
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, } from './transaction-response.js';
|
|
26
26
|
export { hobexReceiptFromHps } from './receipt.js';
|
|
@@ -18,8 +18,23 @@ export type CardPaymentOutcome = 'approved' | 'declined' | 'unresolved';
|
|
|
18
18
|
export interface HpsPaymentResult {
|
|
19
19
|
readonly outcome: CardPaymentOutcome;
|
|
20
20
|
readonly transactionId: string;
|
|
21
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Die Antwort des Terminals, die den Ausgang FESTGESCHRIEBEN hat -- nur
|
|
23
|
+
* bei `approved` und `declined`. Bei `unresolved` fehlt sie: eine
|
|
24
|
+
* Nicht-Aussage darf nicht als Beleg mitgegeben werden. Was das Terminal
|
|
25
|
+
* zuletzt gesagt hat, steht dann in [lastResponse].
|
|
26
|
+
*/
|
|
22
27
|
readonly response?: HpsTransactionResponse;
|
|
28
|
+
/**
|
|
29
|
+
* Die letzte Antwort des Terminals bei `unresolved`, sofern ueberhaupt
|
|
30
|
+
* eine ankam -- auch wenn sie nichts entschied (9027, 9900, ein
|
|
31
|
+
* unbekannter Code). NIE ein Beleg, sondern Material fuer Anzeige und
|
|
32
|
+
* Katalog: am 02.09.2026 sah der Bediener bei einer Antwort `55`
|
|
33
|
+
* "PIN falsch" nur "Ausgang unklar", musste raten und buchte eine
|
|
34
|
+
* abgelehnte Zahlung als bezahlt. Der Klartext des Terminals haette die
|
|
35
|
+
* Entscheidung getragen. Bei schluessigem Ausgang nicht gesetzt.
|
|
36
|
+
*/
|
|
37
|
+
readonly lastResponse?: HpsTransactionResponse;
|
|
23
38
|
/**
|
|
24
39
|
* Verlauf der Klaerung, in Reihenfolge — der Nachweis, der im
|
|
25
40
|
* Belastungsstreit gelesen wird. Behauptet nie eine Ursache, die nicht
|
|
@@ -67,7 +67,7 @@ export function createHpsPayments(client, target, options = {}) {
|
|
|
67
67
|
return `Antwort mit technischem Fehler (${TECHNICAL_ERROR_CODE}) -- keine Aussage ueber den Vorgang, Ausgang wird geklaert`;
|
|
68
68
|
}
|
|
69
69
|
if (isUnknownCode(res)) {
|
|
70
|
-
return `Terminal nennt einen unbekannten Code (${res.responseCode}) -- Ausgang wird geklaert`;
|
|
70
|
+
return `Terminal nennt einen unbekannten Code (${res.responseCode})${klartext(res)} -- Ausgang wird geklaert`;
|
|
71
71
|
}
|
|
72
72
|
return `Antwort ohne Aussage (${res.responseCode}) -- Ausgang wird geklaert`;
|
|
73
73
|
}
|
|
@@ -80,10 +80,21 @@ export function createHpsPayments(client, target, options = {}) {
|
|
|
80
80
|
return `Status: technischer Fehler (${TECHNICAL_ERROR_CODE}) -- keine Aussage ueber den Vorgang`;
|
|
81
81
|
}
|
|
82
82
|
if (isUnknownCode(status)) {
|
|
83
|
-
return `Status: unbekannter Code (${status.responseCode}) -- keine Aussage`;
|
|
83
|
+
return `Status: unbekannter Code (${status.responseCode})${klartext(status)} -- keine Aussage`;
|
|
84
84
|
}
|
|
85
85
|
return null;
|
|
86
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Der Klartext des Terminals zu einem UNBEKANNTEN Code, als Zusatz fuer den
|
|
89
|
+
* Nachweis -- oder leer, wenn keiner mitkam. Nur hier, nicht bei den
|
|
90
|
+
* gemessenen Codes: deren Bedeutung ist benannt. Bei einem unbekannten Code
|
|
91
|
+
* ist er dagegen das Einzige, was ein Mensch lesen kann -- "PIN falsch"
|
|
92
|
+
* neben `55` haette am 02.09.2026 gereicht, um nicht "bezahlt" zu buchen.
|
|
93
|
+
*/
|
|
94
|
+
function klartext(res) {
|
|
95
|
+
const text = res.responseText?.trim();
|
|
96
|
+
return text ? ` "${text}"` : '';
|
|
97
|
+
}
|
|
87
98
|
/** Ordnet eine Terminal-Antwort ein. `null`, wenn sie nichts entscheidet. */
|
|
88
99
|
function fromResponse(res, id, steps) {
|
|
89
100
|
if (!isConclusive(res))
|
|
@@ -185,9 +196,19 @@ export function createHpsPayments(client, target, options = {}) {
|
|
|
185
196
|
}
|
|
186
197
|
return null;
|
|
187
198
|
}
|
|
188
|
-
|
|
199
|
+
/**
|
|
200
|
+
* [letzteAntwort] ist die letzte Antwort, die das Terminal in dieser
|
|
201
|
+
* Klaerung gab -- als `lastResponse` fuer Anzeige und Katalog,
|
|
202
|
+
* ausdruecklich NICHT als `response`.
|
|
203
|
+
*/
|
|
204
|
+
function open(id, steps, letzteAntwort) {
|
|
189
205
|
emit('resolved', steps[steps.length - 1], id);
|
|
190
|
-
return {
|
|
206
|
+
return {
|
|
207
|
+
outcome: 'unresolved',
|
|
208
|
+
transactionId: id,
|
|
209
|
+
...(letzteAntwort ? { lastResponse: letzteAntwort } : {}),
|
|
210
|
+
steps: [...steps],
|
|
211
|
+
};
|
|
191
212
|
}
|
|
192
213
|
/**
|
|
193
214
|
* Fuehrt [call] aus, aber hoechstens so lange, wie vom [resolveBudgetMs]
|
|
@@ -260,7 +281,7 @@ export function createHpsPayments(client, target, options = {}) {
|
|
|
260
281
|
* [NO_STATEMENT_CODE] (`9027`) beim Pollen einen Aussagewert, den es sonst
|
|
261
282
|
* nicht hat. Siehe [ausGeschlossenerAntwort].
|
|
262
283
|
*/
|
|
263
|
-
async function resolve(id, steps, antwortMitCode = false) {
|
|
284
|
+
async function resolve(id, steps, antwortMitCode = false, letzteAntwort) {
|
|
264
285
|
emit('resolving', 'Ausgang offen, Klaerung laeuft', id);
|
|
265
286
|
const start = now();
|
|
266
287
|
const elapsedMs = () => now() - start;
|
|
@@ -281,6 +302,7 @@ export function createHpsPayments(client, target, options = {}) {
|
|
|
281
302
|
try {
|
|
282
303
|
status = await withinBudget(elapsedMs, () => client.status({ ...target, transactionId: id }));
|
|
283
304
|
transportFailures = 0;
|
|
305
|
+
letzteAntwort = status;
|
|
284
306
|
}
|
|
285
307
|
catch (e) {
|
|
286
308
|
transportFailures += 1;
|
|
@@ -309,7 +331,7 @@ export function createHpsPayments(client, target, options = {}) {
|
|
|
309
331
|
wait = nextWait(wait);
|
|
310
332
|
}
|
|
311
333
|
steps.push('Ausgang bleibt offen');
|
|
312
|
-
return open(id, steps);
|
|
334
|
+
return open(id, steps, letzteAntwort);
|
|
313
335
|
}
|
|
314
336
|
/**
|
|
315
337
|
* Liest `9027` beim Pollen als "nicht genehmigt" -- aber NUR, wenn das
|
|
@@ -369,7 +391,7 @@ export function createHpsPayments(client, target, options = {}) {
|
|
|
369
391
|
* Budget, Backoff und Transportfehler-Deckelung sind unveraendert aus
|
|
370
392
|
* [resolve] uebernommen.
|
|
371
393
|
*/
|
|
372
|
-
async function resolveCancel(id, steps) {
|
|
394
|
+
async function resolveCancel(id, steps, letzteAntwort) {
|
|
373
395
|
emit('resolving', 'Ausgang offen, Klaerung laeuft', id);
|
|
374
396
|
const start = now();
|
|
375
397
|
const elapsedMs = () => now() - start;
|
|
@@ -390,6 +412,7 @@ export function createHpsPayments(client, target, options = {}) {
|
|
|
390
412
|
status = await withinBudget(elapsedMs, () => client.status({ ...target, transactionId: id }));
|
|
391
413
|
transportFailures = 0;
|
|
392
414
|
answeredQueries += 1;
|
|
415
|
+
letzteAntwort = status;
|
|
393
416
|
}
|
|
394
417
|
catch (e) {
|
|
395
418
|
transportFailures += 1;
|
|
@@ -413,7 +436,7 @@ export function createHpsPayments(client, target, options = {}) {
|
|
|
413
436
|
wait = nextWait(wait);
|
|
414
437
|
}
|
|
415
438
|
steps.push('Ausgang bleibt offen');
|
|
416
|
-
return open(id, steps);
|
|
439
|
+
return open(id, steps, letzteAntwort);
|
|
417
440
|
}
|
|
418
441
|
async function pay(paymentOptions) {
|
|
419
442
|
const id = paymentOptions.transactionId ?? newHpsTransactionId();
|
|
@@ -452,7 +475,7 @@ export function createHpsPayments(client, target, options = {}) {
|
|
|
452
475
|
return settled;
|
|
453
476
|
steps.push(offeneAntwort(res));
|
|
454
477
|
}
|
|
455
|
-
return resolve(id, steps, res?.responseCode !== undefined);
|
|
478
|
+
return resolve(id, steps, res?.responseCode !== undefined, res);
|
|
456
479
|
}
|
|
457
480
|
/**
|
|
458
481
|
* Gutschrift mit geklaertem Ausgang -- EXAKT derselbe Klaerweg wie [pay]
|
|
@@ -496,7 +519,7 @@ export function createHpsPayments(client, target, options = {}) {
|
|
|
496
519
|
// Dieselbe Klaerfunktion wie [pay]: die Kennung ist die des NEUEN
|
|
497
520
|
// Vorgangs, eine Statusabfrage darauf liefert also genau dessen Ausgang,
|
|
498
521
|
// und der Abbruch ist derselbe Diskriminator wie bei einer Zahlung.
|
|
499
|
-
return resolve(id, steps, res?.responseCode !== undefined);
|
|
522
|
+
return resolve(id, steps, res?.responseCode !== undefined, res);
|
|
500
523
|
}
|
|
501
524
|
/**
|
|
502
525
|
* Aufhebung (Storno/Void) einer bestehenden Zahlung mit geklaertem Ausgang.
|
|
@@ -541,7 +564,7 @@ export function createHpsPayments(client, target, options = {}) {
|
|
|
541
564
|
if (!isCanceled(res))
|
|
542
565
|
steps.push(offeneAntwort(res));
|
|
543
566
|
}
|
|
544
|
-
return resolveCancel(id, steps);
|
|
567
|
+
return resolveCancel(id, steps, res);
|
|
545
568
|
}
|
|
546
569
|
return { pay, refund, cancel };
|
|
547
570
|
}
|
|
@@ -72,6 +72,18 @@ export declare const INVALID_AMOUNT_CODE = "9003";
|
|
|
72
72
|
export declare const AMOUNT_OUT_OF_RANGE_CODE = "100019";
|
|
73
73
|
/** Siehe [HPS_MEASURED_CODES]: Terminal-Kennung unbekannt. */
|
|
74
74
|
export declare const INVALID_TID_CODE = "100108";
|
|
75
|
+
/**
|
|
76
|
+
* Siehe [HPS_MEASURED_CODES]: Host-Ablehnung, falsche PIN -- nichts belastet.
|
|
77
|
+
*
|
|
78
|
+
* Zweistellig, weil ein Antwortcode des HOSTS (ISO 8583, 55 = "Incorrect
|
|
79
|
+
* PIN"), kein `9xxx`-Terminalcode und kein `100xxx`-Code der HPS-Anwendung.
|
|
80
|
+
* Daraus folgt KEINE Regel fuer andere zweistellige Codes: in derselben
|
|
81
|
+
* Familie stehen Genehmigungen (`08`, `10`, `11`, `85`). Jeder andere
|
|
82
|
+
* Host-Code bleibt eine Wissensluecke, bis er gemessen ist -- und die
|
|
83
|
+
* Zwei-9027-Regel in `payments.ts` faengt ihn nicht, weil die Statusabfrage
|
|
84
|
+
* dann nicht 9027 antwortet, sondern mit dem Code selbst.
|
|
85
|
+
*/
|
|
86
|
+
export declare const WRONG_PIN_CODE = "55";
|
|
75
87
|
/**
|
|
76
88
|
* HTTP `409` ("Terminal is busy"): das Terminal serialisiert und weist eine
|
|
77
89
|
* zweite Anfrage ab, waehrend eine erste noch laeuft. Am 27.08.2026 gemessen:
|
|
@@ -84,6 +84,15 @@ export const HPS_MEASURED_CODES = [
|
|
|
84
84
|
+ 'nicht; der Vorgang wird abgewiesen, bevor etwas geschieht',
|
|
85
85
|
conclusive: true,
|
|
86
86
|
},
|
|
87
|
+
{
|
|
88
|
+
code: '55',
|
|
89
|
+
meaning: '"PIN falsch" -- Host-Ablehnung wegen falscher PIN, die erste '
|
|
90
|
+
+ 'gemessene Host-Ablehnung ueberhaupt (02.09.2026 im Betrieb, TID '
|
|
91
|
+
+ '3556988, HPS 1.11.4, Firmware 2.3.9): die Zahlung antwortete direkt '
|
|
92
|
+
+ 'damit, die Statusabfrage danach elfmal in Folge ebenso -- eine '
|
|
93
|
+
+ 'Host-Ablehnung bleibt am Terminal abrufbar; nichts belastet',
|
|
94
|
+
conclusive: true,
|
|
95
|
+
},
|
|
87
96
|
];
|
|
88
97
|
/** `responseCode` einer genehmigten Zahlung. */
|
|
89
98
|
export const APPROVED_CODE = '0';
|
|
@@ -107,6 +116,18 @@ export const INVALID_AMOUNT_CODE = '9003';
|
|
|
107
116
|
export const AMOUNT_OUT_OF_RANGE_CODE = '100019';
|
|
108
117
|
/** Siehe [HPS_MEASURED_CODES]: Terminal-Kennung unbekannt. */
|
|
109
118
|
export const INVALID_TID_CODE = '100108';
|
|
119
|
+
/**
|
|
120
|
+
* Siehe [HPS_MEASURED_CODES]: Host-Ablehnung, falsche PIN -- nichts belastet.
|
|
121
|
+
*
|
|
122
|
+
* Zweistellig, weil ein Antwortcode des HOSTS (ISO 8583, 55 = "Incorrect
|
|
123
|
+
* PIN"), kein `9xxx`-Terminalcode und kein `100xxx`-Code der HPS-Anwendung.
|
|
124
|
+
* Daraus folgt KEINE Regel fuer andere zweistellige Codes: in derselben
|
|
125
|
+
* Familie stehen Genehmigungen (`08`, `10`, `11`, `85`). Jeder andere
|
|
126
|
+
* Host-Code bleibt eine Wissensluecke, bis er gemessen ist -- und die
|
|
127
|
+
* Zwei-9027-Regel in `payments.ts` faengt ihn nicht, weil die Statusabfrage
|
|
128
|
+
* dann nicht 9027 antwortet, sondern mit dem Code selbst.
|
|
129
|
+
*/
|
|
130
|
+
export const WRONG_PIN_CODE = '55';
|
|
110
131
|
/**
|
|
111
132
|
* HTTP `409` ("Terminal is busy"): das Terminal serialisiert und weist eine
|
|
112
133
|
* zweite Anfrage ab, waehrend eine erste noch laeuft. Am 27.08.2026 gemessen:
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.7.
|
|
2
|
+
"version": "0.7.2",
|
|
3
3
|
"gemessenAn": {
|
|
4
4
|
"tid": "3600335",
|
|
5
5
|
"hpsVersion": "1.10.0",
|
|
6
6
|
"firmware": "7.3.6",
|
|
7
7
|
"zeitraum": "26.-28.08.2026"
|
|
8
8
|
},
|
|
9
|
+
"ergaenztAn": [
|
|
10
|
+
{
|
|
11
|
+
"tid": "3556988",
|
|
12
|
+
"hpsVersion": "1.11.4",
|
|
13
|
+
"firmware": "2.3.9",
|
|
14
|
+
"zeitraum": "02.09.2026",
|
|
15
|
+
"codes": [
|
|
16
|
+
"55"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
],
|
|
9
20
|
"codes": [
|
|
10
21
|
{
|
|
11
22
|
"code": "0",
|
|
@@ -61,6 +72,11 @@
|
|
|
61
72
|
"code": "100108",
|
|
62
73
|
"meaning": "\"Invalid TID\" -- die Terminal-Kennung gibt es an diesem Geraet nicht; der Vorgang wird abgewiesen, bevor etwas geschieht",
|
|
63
74
|
"conclusive": true
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"code": "55",
|
|
78
|
+
"meaning": "\"PIN falsch\" -- Host-Ablehnung wegen falscher PIN, die erste gemessene Host-Ablehnung ueberhaupt (02.09.2026 im Betrieb, TID 3556988, HPS 1.11.4, Firmware 2.3.9): die Zahlung antwortete direkt damit, die Statusabfrage danach elfmal in Folge ebenso -- eine Host-Ablehnung bleibt am Terminal abrufbar; nichts belastet",
|
|
79
|
+
"conclusive": true
|
|
64
80
|
}
|
|
65
81
|
],
|
|
66
82
|
"terminalBusyHttpStatus": 409
|