@kreiseck/kasseneck-api 0.12.0 → 0.13.1

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 (52) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +26 -0
  3. package/dist/cjs/client/api.d.ts +3 -1
  4. package/dist/cjs/client/api.js +1 -0
  5. package/dist/cjs/client/aufrufe.d.ts +1 -1
  6. package/dist/cjs/client/aufrufe.js +1 -0
  7. package/dist/cjs/client/index.d.ts +1 -1
  8. package/dist/cjs/client/index.js +2 -1
  9. package/dist/cjs/client/receipts.d.ts +57 -0
  10. package/dist/cjs/client/receipts.js +49 -0
  11. package/dist/cjs/index.d.ts +2 -2
  12. package/dist/cjs/index.js +5 -2
  13. package/dist/cjs/models/index.d.ts +1 -0
  14. package/dist/cjs/models/index.js +4 -1
  15. package/dist/cjs/models/receipt-email.d.ts +22 -0
  16. package/dist/cjs/models/receipt-email.js +32 -0
  17. package/dist/cjs/payments/hobex-hps/errors.d.ts +11 -0
  18. package/dist/cjs/payments/hobex-hps/errors.js +16 -0
  19. package/dist/cjs/payments/hobex-hps/index.d.ts +1 -1
  20. package/dist/cjs/payments/hobex-hps/index.js +2 -1
  21. package/dist/cjs/payments/hobex-hps/payments.js +6 -1
  22. package/dist/cjs/payments/hobex-hps/transaction-response.d.ts +12 -0
  23. package/dist/cjs/payments/hobex-hps/transaction-response.js +13 -1
  24. package/dist/cjs/payments/index.d.ts +1 -1
  25. package/dist/cjs/payments/index.js +2 -1
  26. package/dist/esm/client/api.d.ts +3 -1
  27. package/dist/esm/client/api.js +2 -1
  28. package/dist/esm/client/aufrufe.d.ts +1 -1
  29. package/dist/esm/client/aufrufe.js +1 -0
  30. package/dist/esm/client/index.d.ts +1 -1
  31. package/dist/esm/client/index.js +1 -1
  32. package/dist/esm/client/receipts.d.ts +57 -0
  33. package/dist/esm/client/receipts.js +48 -0
  34. package/dist/esm/index.d.ts +2 -2
  35. package/dist/esm/index.js +2 -2
  36. package/dist/esm/models/index.d.ts +1 -0
  37. package/dist/esm/models/index.js +1 -0
  38. package/dist/esm/models/receipt-email.d.ts +22 -0
  39. package/dist/esm/models/receipt-email.js +28 -0
  40. package/dist/esm/payments/hobex-hps/errors.d.ts +11 -0
  41. package/dist/esm/payments/hobex-hps/errors.js +17 -1
  42. package/dist/esm/payments/hobex-hps/index.d.ts +1 -1
  43. package/dist/esm/payments/hobex-hps/index.js +1 -1
  44. package/dist/esm/payments/hobex-hps/payments.js +6 -1
  45. package/dist/esm/payments/hobex-hps/transaction-response.d.ts +12 -0
  46. package/dist/esm/payments/hobex-hps/transaction-response.js +12 -0
  47. package/dist/esm/payments/index.d.ts +1 -1
  48. package/dist/esm/payments/index.js +1 -1
  49. package/fixtures/hobex-hps-codes.json +1 -1
  50. package/fixtures/kasse-texte.json +1 -1
  51. package/fixtures/oberflaeche.json +2 -1
  52. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,59 @@ 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.13.1
8
+
9
+ ### Der 404 beim Abbruch wird benannt, nicht als Abriss gefuehrt
10
+
11
+ **Anlass:** Am Produktivterminal (TID 3556988, Firmware 2.3.9) antwortet der
12
+ Abbruch mit HTTP 404, am Testgeraet nie. Bisher war das im Nachweis nicht von
13
+ einem Leitungsabriss zu unterscheiden -- und `steps` ist der Text, der im
14
+ Belastungsstreit gelesen wird. Zwilling: kasseneck_api 6.12.1.
15
+
16
+ - **`NOT_FOUND_HTTP_STATUS`** und **`HpsConnectTerminalError.isNotFound`**
17
+ (wie `isTerminalBusy`: liest bevorzugt `terminalHttpStatus`).
18
+ - Der Abbruch schreibt beide Lesarten hin, ohne eine zu behaupten: das
19
+ Terminal kennt entweder den Vorgang nicht oder den Endpunkt nicht. Welche
20
+ zutrifft, ist ungemessen (bei hobex angefragt).
21
+ - **Verhalten unveraendert:** weiter klaeren, nie ein Ausgang.
22
+
23
+ ## 0.13.0
24
+
25
+ ### Beleg per E-Mail an den Gast (`sendReceiptEmail`)
26
+
27
+ **Anlass:** Der Endpunkt ist im Backend live (keck#361), beide Kassen haben den
28
+ Weg gebaut — hinter einer Schnittstelle, hinter der nichts stand, weil kein
29
+ Paket den Aufruf kannte. Verschickt wird ein **Link auf die öffentliche
30
+ Belegseite**, kein PDF im Anhang: die Belegseite führt dasselbe Zeilenmodell
31
+ wie Bildschirm und Bon, ein mitgeschicktes PDF wäre dieselbe Sache ein zweites
32
+ Mal, nur unveränderlich veraltet. Der Beleg selbst bleibt unberührt (BAO §131 /
33
+ RKSV); das Versandprotokoll führt das Backend neben ihm.
34
+
35
+ - **`sendReceiptEmail({ fullReceiptId, to, sprache? })`** — auch auf der
36
+ Fassade `createKasseneckApi`. Antwort: `{ to, at, via }` — Adresse in der
37
+ protokollierten Form, Zeitpunkt als ISO mit Wiener Zonenoffset, Versandweg
38
+ (`eigen`, `plattform`, `plattform-fallback`; fehlt er, ist `via` `null` und
39
+ nicht etwa ein Fehler — er sagt etwas über den Weg, nichts über den Erfolg).
40
+ - **Kein `cashregisterId` in den Optionen.** Die Kasse kommt aus der Anmeldung:
41
+ beim Gerät über die Kopfzeile `cashregister-token`, beim Kassen-Benutzer über
42
+ den Parameter, den `registerUserAuth` ohnehin setzt. Eine dritte Stelle wäre
43
+ nur eine Gelegenheit, eine andere Kasse zu behaupten als die, an der man
44
+ angemeldet ist — und das Backend nimmt den Belegpfad aus der angemeldeten.
45
+ - **`RECEIPT_EMAIL_ERROR_CODES`**, Typ `ReceiptEmailErrorCode` und der Wächter
46
+ `isReceiptEmailErrorCode`: `adresse_ungueltig`, `beleg_nicht_gefunden`
47
+ (auch für einen Beleg einer fremden Kasse — das Backend gibt darüber bewusst
48
+ keine Auskunft), `zu_oft` (5 Mails je Beleg in 24 Stunden, 30 je Kasse und
49
+ Stunde) und `versand_fehlgeschlagen`. Die Codes kommen unverändert als
50
+ `KasseneckApiError.code` heraus; das Paket legt keine eigenen an. **Am Code
51
+ entscheiden, nie am deutschen Text.**
52
+ - Die Adresse prüft das Paket **nicht** selbst — nur leer/fehlend wird vor dem
53
+ Senden abgewiesen (`fullReceiptId`, `to`; beides getrimmt, weil es von Hand
54
+ ins Feld kommt). Eine zweite, eigene Adressregel könnte strenger sein als die
55
+ des Backends und eine gültige Adresse abweisen, ohne dass es auffällt.
56
+ - `sendReceiptEmail` steht in `AUFRUFE` und damit in
57
+ `fixtures/oberflaeche.json` — der Zwilling `kasseneck_api` (Dart) prüft
58
+ dagegen.
59
+
7
60
  ## 0.12.0
8
61
 
9
62
  ### Storno mit Kartendaten der Erstattung
package/README.md CHANGED
@@ -211,6 +211,32 @@ Grund: „STORNOBELEG / Stornobuchung zu Beleg KASSE1-ID-42 / vom 11.08.2026,
211
211
  09:02 Uhr / Grund: Fehleingabe". Das Datum kommt aus `cancellationOf.timeStamp`
212
212
  (Backend seit 2026-09-04); Altbelege ohne bleiben ohne die Zeile.
213
213
 
214
+ ## Beleg per E-Mail an den Gast
215
+
216
+ ```ts
217
+ const bestaetigung = await api.sendReceiptEmail({
218
+ fullReceiptId: beleg.fullReceiptId, // oder api.generateFullReceiptId(receiptId)
219
+ to: 'gast@example.at',
220
+ sprache: 'de', // optional; heute wertet das Backend nur 'de' aus
221
+ });
222
+ bestaetigung.to; // Adresse, wie das Backend sie protokolliert hat
223
+ bestaetigung.at; // Zeitpunkt, ISO mit Wiener Zonenoffset
224
+ bestaetigung.via; // 'eigen' | 'plattform' | 'plattform-fallback' | null
225
+ ```
226
+
227
+ Verschickt wird ein **Link auf die öffentliche Belegseite**, kein PDF im
228
+ Anhang: die Belegseite führt dasselbe Zeilenmodell wie Bildschirm und Bon und
229
+ liefert dort auf Wunsch ein PDF. Der Beleg selbst bleibt unberührt (BAO §131 /
230
+ RKSV) — das Versandprotokoll führt das Backend neben ihm.
231
+
232
+ Die Kasse kommt aus der Anmeldung (Kopfzeile `cashregister-token` bzw. der
233
+ Parameter, den `registerUserAuth` setzt), nicht aus den Optionen; ein Beleg
234
+ einer anderen Kasse ist deshalb dieselbe Auskunft wie ein Beleg, den es nicht
235
+ gibt. Auch hier gilt: **am Code entscheiden, nicht am Text.** Die Codes stehen
236
+ in `RECEIPT_EMAIL_ERROR_CODES` (`isReceiptEmailErrorCode`):
237
+ `adresse_ungueltig`, `beleg_nicht_gefunden`, `zu_oft` (5 Mails je Beleg in 24
238
+ Stunden, 30 je Kasse und Stunde) und `versand_fehlgeschlagen`.
239
+
214
240
  ## Partner-API (`./partner`)
215
241
 
216
242
  Für Softwarehäuser, die Kasseneck in ihr eigenes Produkt einbauen: Betriebe
@@ -3,7 +3,7 @@ import { type CreateStripeLinkOptions, type StripeCaptureResult } from '../payme
3
3
  import { type HobexPayOptions, type HobexRefundOptions } from '../payments/hobex.js';
4
4
  import { type TransportOptions } from './transport.js';
5
5
  import { type CashboxStatus, type SignatureStatus } from './status.js';
6
- import { type ListMyReceiptsOptions, type ReceiptList, type ReceiptWithCompany, type SellReceiptOptions, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions } from './receipts.js';
6
+ import { type SendReceiptEmailOptions, type SendReceiptEmailResult, type ListMyReceiptsOptions, type ReceiptList, type ReceiptWithCompany, type SellReceiptOptions, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions } from './receipts.js';
7
7
  /**
8
8
  * Schlichte Factory ueber den Endpunkt-Funktionen: bindet einen Transport
9
9
  * einmal und liefert die Aufrufe ohne den wiederkehrenden ersten Parameter.
@@ -47,6 +47,8 @@ export interface KasseneckApi {
47
47
  generateFullReceiptId(receiptId: string): Promise<string>;
48
48
  /** Berichtsmonat des ersten Belegs (nicht fuer den Kassen-Benutzer-Weg). */
49
49
  getFirstReceiptDate(): Promise<ReportMonth>;
50
+ /** Beleg als Link auf die oeffentliche Belegseite per E-Mail schicken. */
51
+ sendReceiptEmail(options: SendReceiptEmailOptions): Promise<SendReceiptEmailResult>;
50
52
  /** Belegliste einer Kasse samt Kennzahlen (nur mit ID-Token, siehe receipts.ts). */
51
53
  listMyReceipts(options: ListMyReceiptsOptions): Promise<ReceiptList>;
52
54
  /** Kassen des angemeldeten Benutzers (nur mit ID-Token, siehe cashregisters.ts). */
@@ -25,6 +25,7 @@ function createKasseneckApi(options) {
25
25
  generateFullReceiptId: (receiptId) => (0, receipts_js_1.generateFullReceiptId)(rufen, receiptId),
26
26
  getFirstReceiptDate: () => (0, receipts_js_1.getFirstReceiptDate)(rufen),
27
27
  listMyReceipts: (o) => (0, receipts_js_1.listMyReceipts)(rufen, o),
28
+ sendReceiptEmail: (o) => (0, receipts_js_1.sendReceiptEmail)(rufen, o),
28
29
  listMyCashregisters: () => (0, cashregisters_js_1.listMyCashregisters)(rufen),
29
30
  downloadDailyReport: (date) => (0, reports_js_1.downloadDailyReport)(rufenBinaer, date),
30
31
  downloadMonthlyReport: (reportMonth) => (0, reports_js_1.downloadMonthlyReport)(rufenBinaer, reportMonth),
@@ -13,7 +13,7 @@
13
13
  * umhuellt, muss ihn weiterhin absetzen koennen.
14
14
  */
15
15
  import type { TransportBodyFields } from './transport.js';
16
- export declare const AUFRUFE: readonly ["activateCashregister", "cancelReceipt", "createCustomerCashregister", "createPartnerCustomer", "checkPartnerCustomerEmail", "createPartnerWebhook", "createPaymentLinkStripe", "createPrintJob", "createReceipt", "deletePartnerWebhook", "downloadDailyReport", "downloadReport", "endRegisterSession", "financeWebService", "generateFullReceiptId", "getCustomerCredentials", "getCustomerSignatureStatus", "getFirstReceiptDate", "getKasseSettings", "getPartnerCustomer", "getPartnerInfo", "getPrintJob", "getReceipt", "hobexPayApi", "hobexRefundApi", "listCustomerCashregisters", "listMyArticleGroups", "listMyArticles", "listMyCashregisters", "listMyPrinters", "listMyReceipts", "listMyTipRecipients", "listPartnerCustomers", "listPartnerWebhookDeliveries", "listPartnerWebhooks", "listRegisterUsersForDevice", "listRegisterSessionsForDevice", "pairRegisterDevice", "registerPinLogin", "registerUserLogin", "renewRegisterSession", "requestCustomerSignature", "sendPartnerCustomerFonLink", "sendPartnerWebhookTest", "setMyKasseSettings", "setMyRegisterDeviceSettings", "stripeCaptureIntent", "unpairRegisterDevice", "rotatePartnerWebhookSecret", "updatePartnerWebhook"];
16
+ export declare const AUFRUFE: readonly ["activateCashregister", "cancelReceipt", "createCustomerCashregister", "createPartnerCustomer", "checkPartnerCustomerEmail", "createPartnerWebhook", "createPaymentLinkStripe", "createPrintJob", "createReceipt", "deletePartnerWebhook", "downloadDailyReport", "downloadReport", "endRegisterSession", "financeWebService", "generateFullReceiptId", "getCustomerCredentials", "getCustomerSignatureStatus", "getFirstReceiptDate", "getKasseSettings", "getPartnerCustomer", "getPartnerInfo", "getPrintJob", "getReceipt", "hobexPayApi", "hobexRefundApi", "listCustomerCashregisters", "listMyArticleGroups", "listMyArticles", "listMyCashregisters", "listMyPrinters", "listMyReceipts", "listMyTipRecipients", "listPartnerCustomers", "listPartnerWebhookDeliveries", "listPartnerWebhooks", "listRegisterUsersForDevice", "listRegisterSessionsForDevice", "pairRegisterDevice", "registerPinLogin", "registerUserLogin", "renewRegisterSession", "requestCustomerSignature", "sendPartnerCustomerFonLink", "sendPartnerWebhookTest", "sendReceiptEmail", "setMyKasseSettings", "setMyRegisterDeviceSettings", "stripeCaptureIntent", "unpairRegisterDevice", "rotatePartnerWebhookSecret", "updatePartnerWebhook"];
17
17
  export type Aufruf = typeof AUFRUFE[number];
18
18
  /** Wie [KasseneckTransport], nur mit bekanntem Aufrufnamen. Nicht exportiert nach aussen. */
19
19
  export type InternerTransport = <T = unknown>(functionName: Aufruf, params?: Record<string, unknown>, extraBodyFields?: TransportBodyFields, secretParams?: readonly string[]) => Promise<T>;
@@ -46,6 +46,7 @@ exports.AUFRUFE = [
46
46
  'requestCustomerSignature',
47
47
  'sendPartnerCustomerFonLink',
48
48
  'sendPartnerWebhookTest',
49
+ 'sendReceiptEmail',
49
50
  'setMyKasseSettings',
50
51
  'setMyRegisterDeviceSettings',
51
52
  'stripeCaptureIntent',
@@ -2,7 +2,7 @@ export { type AuthCredentials, type KasseneckAuth, type ApiKeyAuthOptions, type
2
2
  export { DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type HttpResponseLike, type HttpRequestInit, type FetchLike, type TransportOptions, type TransportBodyFields, type KasseneckTransport, type KasseneckBinaryTransport, createTransport, createBinaryTransport, } from './transport.js';
3
3
  export { AUFRUFE, type Aufruf, } from './aufrufe.js';
4
4
  export { KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, type ValidationScope, type KasseneckError, type HttpFailureReason, type CauseDigest, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, } from './errors.js';
5
- export { type ReceiptCommonOptions, type SellReceiptOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, type CancelReceiptResult, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, checkVoucherCombinationError, } from './receipts.js';
5
+ export { type ReceiptCommonOptions, type SellReceiptOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, type CancelReceiptResult, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, checkVoucherCombinationError, type SendReceiptEmailOptions, type SendReceiptEmailResult, sendReceiptEmail, } from './receipts.js';
6
6
  export { listMyCashregisters } from './cashregisters.js';
7
7
  export { downloadDailyReport, downloadMonthlyReport } from './reports.js';
8
8
  export { type CashboxStatus, type SignatureStatus, getCashboxStatus, getSignatureStatus, } from './status.js';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createKasseneckApi = exports.getSignatureStatus = exports.getCashboxStatus = exports.downloadMonthlyReport = exports.downloadDailyReport = exports.listMyCashregisters = exports.checkVoucherCombinationError = exports.listMyReceipts = exports.getFirstReceiptDate = exports.generateFullReceiptId = exports.getReceiptWithCompany = exports.getReceipt = exports.zeroReceipt = exports.createCancelReceipt = exports.cancelReceipt = exports.sellReceiptWithCompany = exports.sellReceipt = exports.isKasseneckValidationError = exports.isKasseneckNetworkError = exports.isKasseneckHttpError = exports.isKasseneckAuthError = exports.isKasseneckApiError = exports.KasseneckValidationError = exports.KasseneckNetworkError = exports.KasseneckHttpError = exports.KasseneckAuthError = exports.KasseneckApiError = exports.AUFRUFE = exports.createBinaryTransport = exports.createTransport = exports.DEFAULT_TIMEOUT_MS = exports.DEFAULT_BASE_URL = exports.registerUserAuth = exports.apiKeyAuth = void 0;
3
+ exports.createKasseneckApi = exports.getSignatureStatus = exports.getCashboxStatus = exports.downloadMonthlyReport = exports.downloadDailyReport = exports.listMyCashregisters = exports.sendReceiptEmail = exports.checkVoucherCombinationError = exports.listMyReceipts = exports.getFirstReceiptDate = exports.generateFullReceiptId = exports.getReceiptWithCompany = exports.getReceipt = exports.zeroReceipt = exports.createCancelReceipt = exports.cancelReceipt = exports.sellReceiptWithCompany = exports.sellReceipt = exports.isKasseneckValidationError = exports.isKasseneckNetworkError = exports.isKasseneckHttpError = exports.isKasseneckAuthError = exports.isKasseneckApiError = exports.KasseneckValidationError = exports.KasseneckNetworkError = exports.KasseneckHttpError = exports.KasseneckAuthError = exports.KasseneckApiError = exports.AUFRUFE = exports.createBinaryTransport = exports.createTransport = exports.DEFAULT_TIMEOUT_MS = exports.DEFAULT_BASE_URL = exports.registerUserAuth = exports.apiKeyAuth = void 0;
4
4
  var auth_js_1 = require("./auth.js");
5
5
  Object.defineProperty(exports, "apiKeyAuth", { enumerable: true, get: function () { return auth_js_1.apiKeyAuth; } });
6
6
  Object.defineProperty(exports, "registerUserAuth", { enumerable: true, get: function () { return auth_js_1.registerUserAuth; } });
@@ -34,6 +34,7 @@ Object.defineProperty(exports, "generateFullReceiptId", { enumerable: true, get:
34
34
  Object.defineProperty(exports, "getFirstReceiptDate", { enumerable: true, get: function () { return receipts_js_1.getFirstReceiptDate; } });
35
35
  Object.defineProperty(exports, "listMyReceipts", { enumerable: true, get: function () { return receipts_js_1.listMyReceipts; } });
36
36
  Object.defineProperty(exports, "checkVoucherCombinationError", { enumerable: true, get: function () { return receipts_js_1.checkVoucherCombinationError; } });
37
+ Object.defineProperty(exports, "sendReceiptEmail", { enumerable: true, get: function () { return receipts_js_1.sendReceiptEmail; } });
37
38
  var cashregisters_js_1 = require("./cashregisters.js");
38
39
  Object.defineProperty(exports, "listMyCashregisters", { enumerable: true, get: function () { return cashregisters_js_1.listMyCashregisters; } });
39
40
  var reports_js_1 = require("./reports.js");
@@ -285,6 +285,63 @@ export declare function generateFullReceiptId(rufen: InternerTransport, receiptI
285
285
  * (siehe Modulkommentar oben). Mit `apiKeyAuth` ist er offen.
286
286
  */
287
287
  export declare function getFirstReceiptDate(rufen: InternerTransport): Promise<ReportMonth>;
288
+ /**
289
+ * Beleg per E-Mail an den Endkunden — die Eingabe von [sendReceiptEmail].
290
+ *
291
+ * `cashregisterId` steht hier bewusst **nicht**: der Geraeteweg bindet die
292
+ * Kasse ueber die Kopfzeile `cashregister-token`, der Kassen-Benutzer-Weg
293
+ * ueber den Parameter, den `registerUserAuth` ohnehin schon setzt. Eine
294
+ * dritte Stelle waere nur eine Gelegenheit, eine andere Kasse zu behaupten,
295
+ * als die, an der man angemeldet ist — und das Backend nimmt den Belegpfad aus
296
+ * der angemeldeten Kasse, nicht aus der Nutzlast.
297
+ */
298
+ export interface SendReceiptEmailOptions {
299
+ /** Verschluesselte Volltext-Belegnummer (siehe [generateFullReceiptId]). */
300
+ fullReceiptId: string;
301
+ /** Empfaengeradresse, wie der Gast sie am Tresen nennt. */
302
+ to: string;
303
+ /**
304
+ * Sprache der Mail. Heute wertet das Backend genau `'de'` aus; der Parameter
305
+ * steht im Vertrag, damit eine zweite Sprache spaeter kein neuer Vertrag ist.
306
+ * Ohne Angabe geht das Feld gar nicht erst hinaus.
307
+ */
308
+ sprache?: string;
309
+ }
310
+ /** Was der Versand bestaetigt (Backend: beleg-mail-endpoints.js). */
311
+ export interface SendReceiptEmailResult {
312
+ /** Adresse in der Form, in der das Backend sie protokolliert hat (getrimmt, klein). */
313
+ to: string;
314
+ /** Zeitpunkt des Versands, ISO mit Wiener Zonenoffset (`2026-09-11T14:05:00+02:00`). */
315
+ at: string;
316
+ /**
317
+ * Versandweg: `eigen` (Postfach des Betriebs), `plattform` oder
318
+ * `plattform-fallback`. `null`, wenn die Antwort ihn nicht nennt — das ist
319
+ * eine Auskunft ueber den Weg, keine ueber den Erfolg, und darf den
320
+ * bestaetigten Versand nicht zu einem Fehler machen.
321
+ */
322
+ via: string | null;
323
+ }
324
+ /**
325
+ * Schickt einen bereits ausgestellten Beleg als **Link auf die oeffentliche
326
+ * Belegseite** an eine Adresse (Endpunkt `sendReceiptEmail`, Backend
327
+ * beleg-mail-endpoints.js). Kein PDF im Anhang: die Belegseite fuehrt dasselbe
328
+ * Zeilenmodell wie Bildschirm und Bon und liefert dort auf Wunsch ein PDF.
329
+ *
330
+ * **Der Beleg bleibt unberuehrt** (BAO §131/RKSV): das Versandprotokoll fuehrt
331
+ * das Backend in einer Unter-Sammlung neben dem Beleg.
332
+ *
333
+ * **Am Code entscheiden, nie am Text:** fachliche Fehler kommen als
334
+ * [KasseneckApiError] mit `code` aus [RECEIPT_EMAIL_ERROR_CODES] heraus —
335
+ * `adresse_ungueltig`, `beleg_nicht_gefunden` (auch fuer einen Beleg einer
336
+ * fremden Kasse: das Backend gibt darueber bewusst keine Auskunft), `zu_oft`
337
+ * (5 Mails je Beleg in 24 Stunden, 30 je Kasse und Stunde) und
338
+ * `versand_fehlgeschlagen`. Dieses Paket reicht sie unveraendert durch und
339
+ * legt keine eigenen Codes an.
340
+ *
341
+ * **Kein Wiederholen ohne Zutun des Bedieners:** ein zweiter Versuch schickt
342
+ * eine zweite Mail und zaehlt auf die Schleuse.
343
+ */
344
+ export declare function sendReceiptEmail(rufen: InternerTransport, options: SendReceiptEmailOptions): Promise<SendReceiptEmailResult>;
288
345
  /**
289
346
  * Prueft die Gutschein-Kombination eines Belegs und liefert den ersten
290
347
  * Regelverstoss als Text (oder `null`) — Zwilling von
@@ -11,6 +11,7 @@ exports.getReceipt = getReceipt;
11
11
  exports.getReceiptWithCompany = getReceiptWithCompany;
12
12
  exports.generateFullReceiptId = generateFullReceiptId;
13
13
  exports.getFirstReceiptDate = getFirstReceiptDate;
14
+ exports.sendReceiptEmail = sendReceiptEmail;
14
15
  exports.checkVoucherCombinationError = checkVoucherCombinationError;
15
16
  const index_js_1 = require("../enums/index.js");
16
17
  const index_js_2 = require("../models/index.js");
@@ -327,6 +328,54 @@ async function getFirstReceiptDate(rufen) {
327
328
  throw antwortfehler('getFirstReceiptDate', 'Antwort enthaelt keinen lesbaren Zeitstempel');
328
329
  }
329
330
  }
331
+ /**
332
+ * Schickt einen bereits ausgestellten Beleg als **Link auf die oeffentliche
333
+ * Belegseite** an eine Adresse (Endpunkt `sendReceiptEmail`, Backend
334
+ * beleg-mail-endpoints.js). Kein PDF im Anhang: die Belegseite fuehrt dasselbe
335
+ * Zeilenmodell wie Bildschirm und Bon und liefert dort auf Wunsch ein PDF.
336
+ *
337
+ * **Der Beleg bleibt unberuehrt** (BAO §131/RKSV): das Versandprotokoll fuehrt
338
+ * das Backend in einer Unter-Sammlung neben dem Beleg.
339
+ *
340
+ * **Am Code entscheiden, nie am Text:** fachliche Fehler kommen als
341
+ * [KasseneckApiError] mit `code` aus [RECEIPT_EMAIL_ERROR_CODES] heraus —
342
+ * `adresse_ungueltig`, `beleg_nicht_gefunden` (auch fuer einen Beleg einer
343
+ * fremden Kasse: das Backend gibt darueber bewusst keine Auskunft), `zu_oft`
344
+ * (5 Mails je Beleg in 24 Stunden, 30 je Kasse und Stunde) und
345
+ * `versand_fehlgeschlagen`. Dieses Paket reicht sie unveraendert durch und
346
+ * legt keine eigenen Codes an.
347
+ *
348
+ * **Kein Wiederholen ohne Zutun des Bedieners:** ein zweiter Versuch schickt
349
+ * eine zweite Mail und zaehlt auf die Schleuse.
350
+ */
351
+ async function sendReceiptEmail(rufen, options) {
352
+ // Getrimmt, weil beides von Hand oder per Scanner ins Feld kommt und ein
353
+ // angehaengtes Leerzeichen sonst als ungueltige Adresse zurueckkaeme --
354
+ // nach einem Aufruf, der schon eine Zeile im Protokoll gekostet hat.
355
+ const fullReceiptId = typeof options.fullReceiptId === 'string' ? options.fullReceiptId.trim() : '';
356
+ const to = typeof options.to === 'string' ? options.to.trim() : '';
357
+ if (fullReceiptId === '') {
358
+ throw new errors_js_1.KasseneckValidationError('sendReceiptEmail', 'fullReceiptId fehlt', 'request');
359
+ }
360
+ if (to === '') {
361
+ throw new errors_js_1.KasseneckValidationError('sendReceiptEmail', 'to fehlt (Empfaengeradresse)', 'request');
362
+ }
363
+ // Die Adresse selbst wird hier NICHT geprueft: das Backend prueft sie mit
364
+ // kreiseck_validator und antwortet mit `adresse_ungueltig`. Eine zweite,
365
+ // eigene Regel im Paket koennte strenger sein als die des Backends und eine
366
+ // gueltige Adresse abweisen, ohne dass jemand die Abweichung bemerkt.
367
+ const params = { fullReceiptId, to };
368
+ if (options.sprache !== undefined && options.sprache !== '')
369
+ params.sprache = options.sprache;
370
+ const daten = await rufen('sendReceiptEmail', params);
371
+ if (typeof daten?.to !== 'string' || daten.to === '') {
372
+ throw antwortfehler('sendReceiptEmail', 'Antwort nennt keine Empfaengeradresse (data.to fehlt)');
373
+ }
374
+ if (typeof daten.at !== 'string' || daten.at === '') {
375
+ throw antwortfehler('sendReceiptEmail', 'Antwort nennt keinen Zeitpunkt (data.at fehlt)');
376
+ }
377
+ return { to: daten.to, at: daten.at, via: typeof daten.via === 'string' && daten.via !== '' ? daten.via : null };
378
+ }
330
379
  /**
331
380
  * Prueft die Gutschein-Kombination eines Belegs und liefert den ersten
332
381
  * Regelverstoss als Text (oder `null`) — Zwilling von
@@ -1,5 +1,5 @@
1
1
  export { ReceiptType, type ReceiptTypeKey, VatRate, type VatRateKey, KeckPaymentMethod, type KeckPaymentMethodKey, CreditCardProvider, type CreditCardProviderKey, VoucherType, type VoucherTypeKey, VoucherAction, type VoucherActionKey, StripeLinkMode, type StripeLinkModeKey, } from './enums/index.js';
2
- export { type ReceiptItem, type ReceiptItemPayload, type ReceiptItemPayloadRead, toReceiptItemPayload, fromReceiptItemPayload, receiptItemTotalCents, receiptItemIsValid, negateReceiptItem, type TipRecipient, isTipItem, type Voucher, type VoucherPayload, toVoucherPayload, fromVoucherPayload, voucherIsValid, type Receipt, type ReceiptPayload, type ReceiptPayloadRead, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, type CancellationOf, type CancellationItem, type Cancellation, type CancellationReason, type CancellationErrorCode, CANCELLATION_REASONS, CANCELLATION_ERROR_CODES, CANCELLATION_RESERVATION_MS, isCancellationReason, isCancellationErrorCode, remainingQuantities, type ReceiptCompany, type ReceiptCompanyPayload, fromReceiptCompanyPayload, receiptCompanyTaxInfo, type Cashregister, type CashregisterOnboarding, type CashregisterPayload, type CashregisterOnboardingPayload, fromCashregisterPayload, type ReceiptSummary, type ReceiptSummaryPayload, fromReceiptSummaryPayload, type ZeroKind, ZERO_KINDS, istZeroKind, type ReportMonth, reportMonthFromDate, previousReportMonth, nextReportMonth, reportMonthKey, reportMonthReadable, type StripeUrlSession, type StripeUrlSessionPayload, toStripeUrlSessionPayload, fromStripeUrlSessionPayload, type HobexReceipt, type HobexReceiptPayload, toHobexReceiptPayload, fromHobexReceiptPayload, hobexReceiptToCardPaymentData, hobexReceiptNeedsSignature, } from './models/index.js';
3
- export { type AuthCredentials, type KasseneckAuth, type ApiKeyAuthOptions, type RegisterUserAuthOptions, apiKeyAuth, registerUserAuth, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type HttpResponseLike, type HttpRequestInit, type FetchLike, type TransportOptions, type TransportBodyFields, type KasseneckTransport, type KasseneckBinaryTransport, AUFRUFE, type Aufruf, createTransport, createBinaryTransport, KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, type ValidationScope, type KasseneckError, type HttpFailureReason, type CauseDigest, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, type ReceiptCommonOptions, type SellReceiptOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, listMyCashregisters, checkVoucherCombinationError, downloadDailyReport, downloadMonthlyReport, type CashboxStatus, type SignatureStatus, getCashboxStatus, getSignatureStatus, type KasseneckApi, createKasseneckApi, } from './client/index.js';
2
+ export { type ReceiptItem, type ReceiptItemPayload, type ReceiptItemPayloadRead, toReceiptItemPayload, fromReceiptItemPayload, receiptItemTotalCents, receiptItemIsValid, negateReceiptItem, type TipRecipient, isTipItem, type Voucher, type VoucherPayload, toVoucherPayload, fromVoucherPayload, voucherIsValid, type Receipt, type ReceiptPayload, type ReceiptPayloadRead, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, type CancellationOf, type CancellationItem, type Cancellation, type CancellationReason, type CancellationErrorCode, CANCELLATION_REASONS, CANCELLATION_ERROR_CODES, CANCELLATION_RESERVATION_MS, isCancellationReason, isCancellationErrorCode, type ReceiptEmailErrorCode, RECEIPT_EMAIL_ERROR_CODES, isReceiptEmailErrorCode, remainingQuantities, type ReceiptCompany, type ReceiptCompanyPayload, fromReceiptCompanyPayload, receiptCompanyTaxInfo, type Cashregister, type CashregisterOnboarding, type CashregisterPayload, type CashregisterOnboardingPayload, fromCashregisterPayload, type ReceiptSummary, type ReceiptSummaryPayload, fromReceiptSummaryPayload, type ZeroKind, ZERO_KINDS, istZeroKind, type ReportMonth, reportMonthFromDate, previousReportMonth, nextReportMonth, reportMonthKey, reportMonthReadable, type StripeUrlSession, type StripeUrlSessionPayload, toStripeUrlSessionPayload, fromStripeUrlSessionPayload, type HobexReceipt, type HobexReceiptPayload, toHobexReceiptPayload, fromHobexReceiptPayload, hobexReceiptToCardPaymentData, hobexReceiptNeedsSignature, } from './models/index.js';
3
+ export { type AuthCredentials, type KasseneckAuth, type ApiKeyAuthOptions, type RegisterUserAuthOptions, apiKeyAuth, registerUserAuth, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type HttpResponseLike, type HttpRequestInit, type FetchLike, type TransportOptions, type TransportBodyFields, type KasseneckTransport, type KasseneckBinaryTransport, AUFRUFE, type Aufruf, createTransport, createBinaryTransport, KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, type ValidationScope, type KasseneckError, type HttpFailureReason, type CauseDigest, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, type ReceiptCommonOptions, type SellReceiptOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, listMyCashregisters, checkVoucherCombinationError, type SendReceiptEmailOptions, type SendReceiptEmailResult, sendReceiptEmail, downloadDailyReport, downloadMonthlyReport, type CashboxStatus, type SignatureStatus, getCashboxStatus, getSignatureStatus, type KasseneckApi, createKasseneckApi, } from './client/index.js';
4
4
  export { parseServerTimeStamp, toViennaWallClock, type ViennaWallClock } from './vienna-time.js';
5
5
  export { type KasseSettingsBetrieb, type KasseSettingsGeraet, type KasseSettings, type ArticleGroup, type KasseArtikel, KASSE_BETRIEB_STANDARD, KASSE_GERAET_STANDARD, mergeKasseSettings, fromArticleGroupPayload, fromKasseArtikelPayload, listMyArticleGroups, listMyArticles, getKasseSettings, setMyKasseSettings, setMyRegisterDeviceSettings, verteileRabatt, cancelScopeOf, receiptsScopeOf, } from './kasse/index.js';
package/dist/cjs/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createBinaryTransport = exports.createTransport = exports.AUFRUFE = exports.DEFAULT_TIMEOUT_MS = exports.DEFAULT_BASE_URL = exports.registerUserAuth = exports.apiKeyAuth = exports.hobexReceiptNeedsSignature = exports.hobexReceiptToCardPaymentData = exports.fromHobexReceiptPayload = exports.toHobexReceiptPayload = exports.fromStripeUrlSessionPayload = exports.toStripeUrlSessionPayload = exports.reportMonthReadable = exports.reportMonthKey = exports.nextReportMonth = exports.previousReportMonth = exports.reportMonthFromDate = exports.istZeroKind = exports.ZERO_KINDS = exports.fromReceiptSummaryPayload = exports.fromCashregisterPayload = exports.receiptCompanyTaxInfo = exports.fromReceiptCompanyPayload = exports.remainingQuantities = exports.isCancellationErrorCode = exports.isCancellationReason = exports.CANCELLATION_RESERVATION_MS = exports.CANCELLATION_ERROR_CODES = exports.CANCELLATION_REASONS = exports.receiptSumCents = exports.receiptSubSumCents = exports.fromReceiptPayload = exports.toReceiptPayload = exports.voucherIsValid = exports.fromVoucherPayload = exports.toVoucherPayload = exports.isTipItem = exports.negateReceiptItem = exports.receiptItemIsValid = exports.receiptItemTotalCents = exports.fromReceiptItemPayload = exports.toReceiptItemPayload = exports.StripeLinkMode = exports.VoucherAction = exports.VoucherType = exports.CreditCardProvider = exports.KeckPaymentMethod = exports.VatRate = exports.ReceiptType = void 0;
4
- exports.receiptsScopeOf = exports.cancelScopeOf = exports.verteileRabatt = exports.setMyRegisterDeviceSettings = exports.setMyKasseSettings = exports.getKasseSettings = exports.listMyArticles = exports.listMyArticleGroups = exports.fromKasseArtikelPayload = exports.fromArticleGroupPayload = exports.mergeKasseSettings = exports.KASSE_GERAET_STANDARD = exports.KASSE_BETRIEB_STANDARD = exports.toViennaWallClock = exports.parseServerTimeStamp = exports.createKasseneckApi = exports.getSignatureStatus = exports.getCashboxStatus = exports.downloadMonthlyReport = exports.downloadDailyReport = exports.checkVoucherCombinationError = exports.listMyCashregisters = exports.listMyReceipts = exports.getFirstReceiptDate = exports.generateFullReceiptId = exports.getReceiptWithCompany = exports.getReceipt = exports.zeroReceipt = exports.createCancelReceipt = exports.cancelReceipt = exports.sellReceiptWithCompany = exports.sellReceipt = exports.isKasseneckValidationError = exports.isKasseneckNetworkError = exports.isKasseneckHttpError = exports.isKasseneckAuthError = exports.isKasseneckApiError = exports.KasseneckValidationError = exports.KasseneckNetworkError = exports.KasseneckHttpError = exports.KasseneckAuthError = exports.KasseneckApiError = void 0;
3
+ exports.AUFRUFE = exports.DEFAULT_TIMEOUT_MS = exports.DEFAULT_BASE_URL = exports.registerUserAuth = exports.apiKeyAuth = exports.hobexReceiptNeedsSignature = exports.hobexReceiptToCardPaymentData = exports.fromHobexReceiptPayload = exports.toHobexReceiptPayload = exports.fromStripeUrlSessionPayload = exports.toStripeUrlSessionPayload = exports.reportMonthReadable = exports.reportMonthKey = exports.nextReportMonth = exports.previousReportMonth = exports.reportMonthFromDate = exports.istZeroKind = exports.ZERO_KINDS = exports.fromReceiptSummaryPayload = exports.fromCashregisterPayload = exports.receiptCompanyTaxInfo = exports.fromReceiptCompanyPayload = exports.remainingQuantities = exports.isReceiptEmailErrorCode = exports.RECEIPT_EMAIL_ERROR_CODES = exports.isCancellationErrorCode = exports.isCancellationReason = exports.CANCELLATION_RESERVATION_MS = exports.CANCELLATION_ERROR_CODES = exports.CANCELLATION_REASONS = exports.receiptSumCents = exports.receiptSubSumCents = exports.fromReceiptPayload = exports.toReceiptPayload = exports.voucherIsValid = exports.fromVoucherPayload = exports.toVoucherPayload = exports.isTipItem = exports.negateReceiptItem = exports.receiptItemIsValid = exports.receiptItemTotalCents = exports.fromReceiptItemPayload = exports.toReceiptItemPayload = exports.StripeLinkMode = exports.VoucherAction = exports.VoucherType = exports.CreditCardProvider = exports.KeckPaymentMethod = exports.VatRate = exports.ReceiptType = void 0;
4
+ exports.receiptsScopeOf = exports.cancelScopeOf = exports.verteileRabatt = exports.setMyRegisterDeviceSettings = exports.setMyKasseSettings = exports.getKasseSettings = exports.listMyArticles = exports.listMyArticleGroups = exports.fromKasseArtikelPayload = exports.fromArticleGroupPayload = exports.mergeKasseSettings = exports.KASSE_GERAET_STANDARD = exports.KASSE_BETRIEB_STANDARD = exports.toViennaWallClock = exports.parseServerTimeStamp = exports.createKasseneckApi = exports.getSignatureStatus = exports.getCashboxStatus = exports.downloadMonthlyReport = exports.downloadDailyReport = exports.sendReceiptEmail = exports.checkVoucherCombinationError = exports.listMyCashregisters = exports.listMyReceipts = exports.getFirstReceiptDate = exports.generateFullReceiptId = exports.getReceiptWithCompany = exports.getReceipt = exports.zeroReceipt = exports.createCancelReceipt = exports.cancelReceipt = exports.sellReceiptWithCompany = exports.sellReceipt = exports.isKasseneckValidationError = exports.isKasseneckNetworkError = exports.isKasseneckHttpError = exports.isKasseneckAuthError = exports.isKasseneckApiError = exports.KasseneckValidationError = exports.KasseneckNetworkError = exports.KasseneckHttpError = exports.KasseneckAuthError = exports.KasseneckApiError = exports.createBinaryTransport = exports.createTransport = void 0;
5
5
  var index_js_1 = require("./enums/index.js");
6
6
  Object.defineProperty(exports, "ReceiptType", { enumerable: true, get: function () { return index_js_1.ReceiptType; } });
7
7
  Object.defineProperty(exports, "VatRate", { enumerable: true, get: function () { return index_js_1.VatRate; } });
@@ -29,6 +29,8 @@ Object.defineProperty(exports, "CANCELLATION_ERROR_CODES", { enumerable: true, g
29
29
  Object.defineProperty(exports, "CANCELLATION_RESERVATION_MS", { enumerable: true, get: function () { return index_js_2.CANCELLATION_RESERVATION_MS; } });
30
30
  Object.defineProperty(exports, "isCancellationReason", { enumerable: true, get: function () { return index_js_2.isCancellationReason; } });
31
31
  Object.defineProperty(exports, "isCancellationErrorCode", { enumerable: true, get: function () { return index_js_2.isCancellationErrorCode; } });
32
+ Object.defineProperty(exports, "RECEIPT_EMAIL_ERROR_CODES", { enumerable: true, get: function () { return index_js_2.RECEIPT_EMAIL_ERROR_CODES; } });
33
+ Object.defineProperty(exports, "isReceiptEmailErrorCode", { enumerable: true, get: function () { return index_js_2.isReceiptEmailErrorCode; } });
32
34
  Object.defineProperty(exports, "remainingQuantities", { enumerable: true, get: function () { return index_js_2.remainingQuantities; } });
33
35
  Object.defineProperty(exports, "fromReceiptCompanyPayload", { enumerable: true, get: function () { return index_js_2.fromReceiptCompanyPayload; } });
34
36
  Object.defineProperty(exports, "receiptCompanyTaxInfo", { enumerable: true, get: function () { return index_js_2.receiptCompanyTaxInfo; } });
@@ -77,6 +79,7 @@ Object.defineProperty(exports, "getFirstReceiptDate", { enumerable: true, get: f
77
79
  Object.defineProperty(exports, "listMyReceipts", { enumerable: true, get: function () { return index_js_3.listMyReceipts; } });
78
80
  Object.defineProperty(exports, "listMyCashregisters", { enumerable: true, get: function () { return index_js_3.listMyCashregisters; } });
79
81
  Object.defineProperty(exports, "checkVoucherCombinationError", { enumerable: true, get: function () { return index_js_3.checkVoucherCombinationError; } });
82
+ Object.defineProperty(exports, "sendReceiptEmail", { enumerable: true, get: function () { return index_js_3.sendReceiptEmail; } });
80
83
  Object.defineProperty(exports, "downloadDailyReport", { enumerable: true, get: function () { return index_js_3.downloadDailyReport; } });
81
84
  Object.defineProperty(exports, "downloadMonthlyReport", { enumerable: true, get: function () { return index_js_3.downloadMonthlyReport; } });
82
85
  Object.defineProperty(exports, "getCashboxStatus", { enumerable: true, get: function () { return index_js_3.getCashboxStatus; } });
@@ -2,6 +2,7 @@ export { type ReceiptItem, type ReceiptItemPayload, type ReceiptItemPayloadRead,
2
2
  export { type Voucher, type VoucherPayload, toVoucherPayload, fromVoucherPayload, voucherIsValid } from './voucher.js';
3
3
  export { type Receipt, type ReceiptPayload, type ReceiptPayloadRead, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, } from './receipt.js';
4
4
  export { type CancellationOf, type CancellationItem, type Cancellation, type CancellationReason, type CancellationErrorCode, CANCELLATION_REASONS, CANCELLATION_ERROR_CODES, CANCELLATION_RESERVATION_MS, isCancellationReason, isCancellationErrorCode, remainingQuantities, } from './cancellation.js';
5
+ export { type ReceiptEmailErrorCode, RECEIPT_EMAIL_ERROR_CODES, isReceiptEmailErrorCode, } from './receipt-email.js';
5
6
  export { type ReceiptCompany, type ReceiptCompanyPayload, fromReceiptCompanyPayload, receiptCompanyTaxInfo, } from './receipt-company.js';
6
7
  export { type Cashregister, type CashregisterOnboarding, type CashregisterPayload, type CashregisterOnboardingPayload, fromCashregisterPayload, } from './cashregister.js';
7
8
  export { type ReceiptSummary, type ReceiptSummaryPayload, fromReceiptSummaryPayload, type ZeroKind, ZERO_KINDS, istZeroKind } from './receipt-summary.js';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hobexReceiptNeedsSignature = exports.hobexReceiptToCardPaymentData = exports.fromHobexReceiptPayload = exports.toHobexReceiptPayload = exports.fromStripeUrlSessionPayload = exports.toStripeUrlSessionPayload = exports.reportMonthReadable = exports.reportMonthKey = exports.nextReportMonth = exports.previousReportMonth = exports.reportMonthFromDate = exports.istZeroKind = exports.ZERO_KINDS = exports.fromReceiptSummaryPayload = exports.fromCashregisterPayload = exports.receiptCompanyTaxInfo = exports.fromReceiptCompanyPayload = exports.remainingQuantities = exports.isCancellationErrorCode = exports.isCancellationReason = exports.CANCELLATION_RESERVATION_MS = exports.CANCELLATION_ERROR_CODES = exports.CANCELLATION_REASONS = exports.receiptSumCents = exports.receiptSubSumCents = exports.fromReceiptPayload = exports.toReceiptPayload = exports.voucherIsValid = exports.fromVoucherPayload = exports.toVoucherPayload = exports.isDiscountItem = exports.isTipItem = exports.negateReceiptItem = exports.receiptItemIsValid = exports.receiptItemTotalCents = exports.fromReceiptItemPayload = exports.toReceiptItemPayload = void 0;
3
+ exports.hobexReceiptNeedsSignature = exports.hobexReceiptToCardPaymentData = exports.fromHobexReceiptPayload = exports.toHobexReceiptPayload = exports.fromStripeUrlSessionPayload = exports.toStripeUrlSessionPayload = exports.reportMonthReadable = exports.reportMonthKey = exports.nextReportMonth = exports.previousReportMonth = exports.reportMonthFromDate = exports.istZeroKind = exports.ZERO_KINDS = exports.fromReceiptSummaryPayload = exports.fromCashregisterPayload = exports.receiptCompanyTaxInfo = exports.fromReceiptCompanyPayload = exports.isReceiptEmailErrorCode = exports.RECEIPT_EMAIL_ERROR_CODES = exports.remainingQuantities = exports.isCancellationErrorCode = exports.isCancellationReason = exports.CANCELLATION_RESERVATION_MS = exports.CANCELLATION_ERROR_CODES = exports.CANCELLATION_REASONS = exports.receiptSumCents = exports.receiptSubSumCents = exports.fromReceiptPayload = exports.toReceiptPayload = exports.voucherIsValid = exports.fromVoucherPayload = exports.toVoucherPayload = exports.isDiscountItem = exports.isTipItem = exports.negateReceiptItem = exports.receiptItemIsValid = exports.receiptItemTotalCents = exports.fromReceiptItemPayload = exports.toReceiptItemPayload = void 0;
4
4
  var receipt_item_js_1 = require("./receipt-item.js");
5
5
  Object.defineProperty(exports, "toReceiptItemPayload", { enumerable: true, get: function () { return receipt_item_js_1.toReceiptItemPayload; } });
6
6
  Object.defineProperty(exports, "fromReceiptItemPayload", { enumerable: true, get: function () { return receipt_item_js_1.fromReceiptItemPayload; } });
@@ -25,6 +25,9 @@ Object.defineProperty(exports, "CANCELLATION_RESERVATION_MS", { enumerable: true
25
25
  Object.defineProperty(exports, "isCancellationReason", { enumerable: true, get: function () { return cancellation_js_1.isCancellationReason; } });
26
26
  Object.defineProperty(exports, "isCancellationErrorCode", { enumerable: true, get: function () { return cancellation_js_1.isCancellationErrorCode; } });
27
27
  Object.defineProperty(exports, "remainingQuantities", { enumerable: true, get: function () { return cancellation_js_1.remainingQuantities; } });
28
+ var receipt_email_js_1 = require("./receipt-email.js");
29
+ Object.defineProperty(exports, "RECEIPT_EMAIL_ERROR_CODES", { enumerable: true, get: function () { return receipt_email_js_1.RECEIPT_EMAIL_ERROR_CODES; } });
30
+ Object.defineProperty(exports, "isReceiptEmailErrorCode", { enumerable: true, get: function () { return receipt_email_js_1.isReceiptEmailErrorCode; } });
28
31
  var receipt_company_js_1 = require("./receipt-company.js");
29
32
  Object.defineProperty(exports, "fromReceiptCompanyPayload", { enumerable: true, get: function () { return receipt_company_js_1.fromReceiptCompanyPayload; } });
30
33
  Object.defineProperty(exports, "receiptCompanyTaxInfo", { enumerable: true, get: function () { return receipt_company_js_1.receiptCompanyTaxInfo; } });
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Beleg per E-Mail — Zwilling von `functions/beleg-mail-core.js`.
3
+ *
4
+ * Hier steht nur der Fehlercode-Katalog: der Aufruf selbst ist
5
+ * [sendReceiptEmail] (client/receipts.ts), und was verschickt wird, ist ein
6
+ * **Link auf die oeffentliche Belegseite** — der Beleg selbst bleibt
7
+ * unberuehrt (BAO §131/RKSV), das Versandprotokoll fuehrt das Backend in einer
8
+ * Unter-Sammlung neben ihm.
9
+ */
10
+ /**
11
+ * Stabile Fehlercodes von `sendReceiptEmail` — Zwilling von
12
+ * `beleg-mail-core.js` FEHLERCODES. Das Backend legt sie bei jedem fachlichen
13
+ * Fehler als `code` neben die Meldung; das Paket reicht sie als
14
+ * [KasseneckApiError.code] durch. **Entscheide am Code, nie am Text** — die
15
+ * deutsche Meldung darf sich aendern, der Code nicht.
16
+ *
17
+ * Nur Auth-/Parameterfehler (Sitzung abgelaufen, Pflichtfeld fehlt) kommen
18
+ * ohne Code; dort bleibt `code` undefined.
19
+ */
20
+ export declare const RECEIPT_EMAIL_ERROR_CODES: readonly ["adresse_ungueltig", "beleg_nicht_gefunden", "zu_oft", "versand_fehlgeschlagen"];
21
+ export type ReceiptEmailErrorCode = (typeof RECEIPT_EMAIL_ERROR_CODES)[number];
22
+ export declare function isReceiptEmailErrorCode(value: unknown): value is ReceiptEmailErrorCode;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /**
3
+ * Beleg per E-Mail — Zwilling von `functions/beleg-mail-core.js`.
4
+ *
5
+ * Hier steht nur der Fehlercode-Katalog: der Aufruf selbst ist
6
+ * [sendReceiptEmail] (client/receipts.ts), und was verschickt wird, ist ein
7
+ * **Link auf die oeffentliche Belegseite** — der Beleg selbst bleibt
8
+ * unberuehrt (BAO §131/RKSV), das Versandprotokoll fuehrt das Backend in einer
9
+ * Unter-Sammlung neben ihm.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RECEIPT_EMAIL_ERROR_CODES = void 0;
13
+ exports.isReceiptEmailErrorCode = isReceiptEmailErrorCode;
14
+ /**
15
+ * Stabile Fehlercodes von `sendReceiptEmail` — Zwilling von
16
+ * `beleg-mail-core.js` FEHLERCODES. Das Backend legt sie bei jedem fachlichen
17
+ * Fehler als `code` neben die Meldung; das Paket reicht sie als
18
+ * [KasseneckApiError.code] durch. **Entscheide am Code, nie am Text** — die
19
+ * deutsche Meldung darf sich aendern, der Code nicht.
20
+ *
21
+ * Nur Auth-/Parameterfehler (Sitzung abgelaufen, Pflichtfeld fehlt) kommen
22
+ * ohne Code; dort bleibt `code` undefined.
23
+ */
24
+ exports.RECEIPT_EMAIL_ERROR_CODES = [
25
+ 'adresse_ungueltig', // Empfaengeradresse unbrauchbar (Pruefung im Backend)
26
+ 'beleg_nicht_gefunden', // Beleg gibt es nicht ODER er gehoert einer anderen Kasse
27
+ 'zu_oft', // Schleuse: 5 Mails je Beleg (24 h), 30 je Kasse und Stunde
28
+ 'versand_fehlgeschlagen', // die Mail selbst ging nicht hinaus
29
+ ];
30
+ function isReceiptEmailErrorCode(value) {
31
+ return typeof value === 'string' && exports.RECEIPT_EMAIL_ERROR_CODES.includes(value);
32
+ }
@@ -101,6 +101,17 @@ export declare class HpsConnectTerminalError extends HpsConnectException {
101
101
  * niemals umgekehrt.
102
102
  */
103
103
  get isTerminalBusy(): boolean;
104
+ /**
105
+ * `true`, wenn dies ein HTTP `404` beim Terminal-Kontakt ist -- Lesart
106
+ * ungemessen, siehe [NOT_FOUND_HTTP_STATUS] und den Dart-Zwilling
107
+ * (`HpsHttpException.isNotFound`): es kann "diesen Vorgang kenne ich nicht"
108
+ * heissen oder "diesen Endpunkt gibt es hier nicht". `payments.ts` benennt
109
+ * beim Abbruch beide Lesarten, statt eine zu behaupten.
110
+ *
111
+ * Liest, wie [isTerminalBusy], bevorzugt [terminalHttpStatus] und faellt nur
112
+ * ohne dieses Feld auf den Meldungstext zurueck.
113
+ */
114
+ get isNotFound(): boolean;
104
115
  }
105
116
  /**
106
117
  * Connect selbst war nicht erreichbar, oder die Antwort hatte nicht die
@@ -130,6 +130,22 @@ class HpsConnectTerminalError extends HpsConnectException {
130
130
  }
131
131
  return this.connectCode === 'terminal_error' && new RegExp(`\\(HTTP ${transaction_response_js_1.TERMINAL_BUSY_HTTP_STATUS}\\)`).test(this.message);
132
132
  }
133
+ /**
134
+ * `true`, wenn dies ein HTTP `404` beim Terminal-Kontakt ist -- Lesart
135
+ * ungemessen, siehe [NOT_FOUND_HTTP_STATUS] und den Dart-Zwilling
136
+ * (`HpsHttpException.isNotFound`): es kann "diesen Vorgang kenne ich nicht"
137
+ * heissen oder "diesen Endpunkt gibt es hier nicht". `payments.ts` benennt
138
+ * beim Abbruch beide Lesarten, statt eine zu behaupten.
139
+ *
140
+ * Liest, wie [isTerminalBusy], bevorzugt [terminalHttpStatus] und faellt nur
141
+ * ohne dieses Feld auf den Meldungstext zurueck.
142
+ */
143
+ get isNotFound() {
144
+ if (this.terminalHttpStatus !== undefined) {
145
+ return this.terminalHttpStatus === transaction_response_js_1.NOT_FOUND_HTTP_STATUS;
146
+ }
147
+ return this.connectCode === 'terminal_error' && new RegExp(`\\(HTTP ${transaction_response_js_1.NOT_FOUND_HTTP_STATUS}\\)`).test(this.message);
148
+ }
133
149
  }
134
150
  exports.HpsConnectTerminalError = HpsConnectTerminalError;
135
151
  /**
@@ -23,5 +23,5 @@ export { type HpsPaymentEvent, type HpsPaymentEventKind, type HpsPaymentObserver
23
23
  export { type CardPaymentOutcome, type HpsPaymentResult, isHostUncertainResult, 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, APP_SELECT_FAILED_CODE, APPROVED_CODE, BAD_REQUEST_CODE, CARD_DECLINED_CODE, CARD_INFO_NOT_ENTERED_CODE, CARD_NOT_PRESENT_CODE, CARD_NOT_SUPPORTED_CODE, CARD_READ_FAILED_CODE, CHIP_DATA_MISMATCH_CODE, COMPLETION_FAILED_CODE, DIAGNOSIS_FAILED_CODE, HOST_COMMUNICATION_FAILED_CODE, HOST_STEP_FAILED_CODE, HOST_TIMEOUT_REVERSED_CODE, HPS_CODES, HPS_MEASURED_CODES, HPS_REASON_HINTS, INTERNAL_ERROR_CODE, INVALID_MESSAGE_TYPE_CODE, INVALID_TID_DOCUMENTED_CODE, INVALID_TX_TYPE_CODE, MAX_RETRIES_EXCEEDED_CODE, NOT_FOUND_CODE, PASSWORD_NOT_ENTERED_CODE, REFUND_DISABLED_CODE, REFUND_PASSWORD_INVALID_CODE, SCEP_ENROLLMENT_FAILED_CODE, TERMINAL_BLOCKED_CODE, TERMINAL_BUSY_CODE, TIP_SELECTION_FAILED_CODE, UNSUPPORTED_USER_DATA_CODE, hpsCodeInfo, hpsCodeReason, isHostUncertain, isHostUncertainReason, 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, isConclusiveAsStatus, isInProgress, isNoStatement, isNotAbortable, isTechnicalError, isUnknownCode, parseHpsTransactionResponse, type HpsCode, type HpsCodeEffect, type HpsCodeReason, type HpsCodeSource, type HpsMeasuredCode, type HpsTransactionResponse, } from './transaction-response.js';
26
+ export { ABORTED_CODE, APP_SELECT_FAILED_CODE, APPROVED_CODE, BAD_REQUEST_CODE, CARD_DECLINED_CODE, CARD_INFO_NOT_ENTERED_CODE, CARD_NOT_PRESENT_CODE, CARD_NOT_SUPPORTED_CODE, CARD_READ_FAILED_CODE, CHIP_DATA_MISMATCH_CODE, COMPLETION_FAILED_CODE, DIAGNOSIS_FAILED_CODE, HOST_COMMUNICATION_FAILED_CODE, HOST_STEP_FAILED_CODE, HOST_TIMEOUT_REVERSED_CODE, HPS_CODES, HPS_MEASURED_CODES, HPS_REASON_HINTS, INTERNAL_ERROR_CODE, INVALID_MESSAGE_TYPE_CODE, INVALID_TID_DOCUMENTED_CODE, INVALID_TX_TYPE_CODE, MAX_RETRIES_EXCEEDED_CODE, NOT_FOUND_CODE, PASSWORD_NOT_ENTERED_CODE, REFUND_DISABLED_CODE, REFUND_PASSWORD_INVALID_CODE, SCEP_ENROLLMENT_FAILED_CODE, TERMINAL_BLOCKED_CODE, TERMINAL_BUSY_CODE, TIP_SELECTION_FAILED_CODE, UNSUPPORTED_USER_DATA_CODE, hpsCodeInfo, hpsCodeReason, isHostUncertain, isHostUncertainReason, 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, NOT_FOUND_HTTP_STATUS, TERMINAL_BUSY_HTTP_STATUS, TRANSACTION_CANCELED_CODE, isApproved, isCanceled, isConclusive, isConclusiveAsStatus, isInProgress, isNoStatement, isNotAbortable, isTechnicalError, isUnknownCode, parseHpsTransactionResponse, type HpsCode, type HpsCodeEffect, type HpsCodeReason, type HpsCodeSource, type HpsMeasuredCode, type HpsTransactionResponse, } from './transaction-response.js';
27
27
  export { hobexReceiptFromHps } from './receipt.js';
@@ -20,7 +20,7 @@
20
20
  */
21
21
  Object.defineProperty(exports, "__esModule", { value: true });
22
22
  exports.isHostUncertain = exports.hpsCodeReason = exports.hpsCodeInfo = exports.UNSUPPORTED_USER_DATA_CODE = exports.TIP_SELECTION_FAILED_CODE = exports.TERMINAL_BUSY_CODE = exports.TERMINAL_BLOCKED_CODE = exports.SCEP_ENROLLMENT_FAILED_CODE = exports.REFUND_PASSWORD_INVALID_CODE = exports.REFUND_DISABLED_CODE = exports.PASSWORD_NOT_ENTERED_CODE = exports.NOT_FOUND_CODE = exports.MAX_RETRIES_EXCEEDED_CODE = exports.INVALID_TX_TYPE_CODE = exports.INVALID_TID_DOCUMENTED_CODE = exports.INVALID_MESSAGE_TYPE_CODE = exports.INTERNAL_ERROR_CODE = exports.HPS_REASON_HINTS = exports.HPS_MEASURED_CODES = exports.HPS_CODES = exports.HOST_TIMEOUT_REVERSED_CODE = exports.HOST_STEP_FAILED_CODE = exports.HOST_COMMUNICATION_FAILED_CODE = exports.DIAGNOSIS_FAILED_CODE = exports.COMPLETION_FAILED_CODE = exports.CHIP_DATA_MISMATCH_CODE = exports.CARD_READ_FAILED_CODE = exports.CARD_NOT_SUPPORTED_CODE = exports.CARD_NOT_PRESENT_CODE = exports.CARD_INFO_NOT_ENTERED_CODE = exports.CARD_DECLINED_CODE = exports.BAD_REQUEST_CODE = exports.APPROVED_CODE = exports.APP_SELECT_FAILED_CODE = exports.ABORTED_CODE = exports.newHpsTransactionId = exports.isValidHpsTransactionId = exports.createHpsTransactionIdGenerator = exports.MAX_TRANSACTION_ID_LENGTH = exports.createHpsPayments = exports.mayRetrySafely = exports.isHostUncertainResult = exports.PREFLIGHT_CONNECT_CODES = exports.HpsTransactionIdError = exports.HpsPreflightError = exports.HpsConnectTransportError = exports.HpsConnectTerminalError = exports.HpsConnectException = exports.HpsClarifyTimeoutError = exports.createHpsConnectClient = void 0;
23
- exports.hobexReceiptFromHps = exports.parseHpsTransactionResponse = exports.isUnknownCode = exports.isTechnicalError = exports.isNotAbortable = exports.isNoStatement = exports.isInProgress = exports.isConclusiveAsStatus = 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.isHostUncertainReason = void 0;
23
+ exports.hobexReceiptFromHps = exports.parseHpsTransactionResponse = exports.isUnknownCode = exports.isTechnicalError = exports.isNotAbortable = exports.isNoStatement = exports.isInProgress = exports.isConclusiveAsStatus = exports.isConclusive = exports.isCanceled = exports.isApproved = exports.TRANSACTION_CANCELED_CODE = exports.TERMINAL_BUSY_HTTP_STATUS = exports.NOT_FOUND_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.isHostUncertainReason = void 0;
24
24
  var connect_client_js_1 = require("./connect-client.js");
25
25
  Object.defineProperty(exports, "createHpsConnectClient", { enumerable: true, get: function () { return connect_client_js_1.createHpsConnectClient; } });
26
26
  var errors_js_1 = require("./errors.js");
@@ -86,6 +86,7 @@ Object.defineProperty(exports, "INVALID_TID_CODE", { enumerable: true, get: func
86
86
  Object.defineProperty(exports, "WRONG_PIN_CODE", { enumerable: true, get: function () { return transaction_response_js_1.WRONG_PIN_CODE; } });
87
87
  Object.defineProperty(exports, "NO_STATEMENT_CODE", { enumerable: true, get: function () { return transaction_response_js_1.NO_STATEMENT_CODE; } });
88
88
  Object.defineProperty(exports, "TECHNICAL_ERROR_CODE", { enumerable: true, get: function () { return transaction_response_js_1.TECHNICAL_ERROR_CODE; } });
89
+ Object.defineProperty(exports, "NOT_FOUND_HTTP_STATUS", { enumerable: true, get: function () { return transaction_response_js_1.NOT_FOUND_HTTP_STATUS; } });
89
90
  Object.defineProperty(exports, "TERMINAL_BUSY_HTTP_STATUS", { enumerable: true, get: function () { return transaction_response_js_1.TERMINAL_BUSY_HTTP_STATUS; } });
90
91
  Object.defineProperty(exports, "TRANSACTION_CANCELED_CODE", { enumerable: true, get: function () { return transaction_response_js_1.TRANSACTION_CANCELED_CODE; } });
91
92
  Object.defineProperty(exports, "isApproved", { enumerable: true, get: function () { return transaction_response_js_1.isApproved; } });
@@ -321,7 +321,12 @@ function createHpsPayments(client, target, options = {}) {
321
321
  res = await withinBudget(elapsedMs, () => client.abort({ ...target, transactionId: id }), abortBudgetMs);
322
322
  }
323
323
  catch (e) {
324
- steps.push(`Abbruch nicht bestaetigt (${describe(e)}) -- ob er wirkte, ist offen, Ausgang wird abgefragt`);
324
+ // Siehe Dart-Zwilling: ein 404 hat zwei Lesarten, und wir kennen die
325
+ // richtige nicht. Der Nachweistext benennt beide und behauptet keine.
326
+ steps.push(e instanceof errors_js_1.HpsConnectTerminalError && e.isNotFound
327
+ ? 'Abbruch nicht bestaetigt (HTTP 404) -- das Terminal kennt entweder diesen Vorgang nicht '
328
+ + 'oder den Abbruch-Endpunkt nicht; beides sagt nichts ueber die Zahlung, Ausgang wird abgefragt'
329
+ : `Abbruch nicht bestaetigt (${describe(e)}) -- ob er wirkte, ist offen, Ausgang wird abgefragt`);
325
330
  noteUnexpected(e, id);
326
331
  return null;
327
332
  }
@@ -216,6 +216,18 @@ export declare const INTERNAL_ERROR_CODE = "100999";
216
216
  * getrennte Auswertung.
217
217
  */
218
218
  export declare const TERMINAL_BUSY_HTTP_STATUS = 409;
219
+ /**
220
+ * HTTP `404` beim Terminal-Kontakt. **Lesart ungemessen:** am Produktivgeraet
221
+ * (TID 3556988, Firmware 2.3.9) antwortet `POST /api/transaction/abort/...`
222
+ * damit, am Testgeraet (3600335) nie. Es kann "diesen Vorgang kenne ich nicht"
223
+ * heissen oder "diesen Endpunkt gibt es hier nicht" -- beides sagt nichts ueber
224
+ * die Zahlung. Bei hobex angefragt; bis dahin benennt `payments.ts` beim
225
+ * Abbruch beide Lesarten, statt eine zu behaupten.
226
+ *
227
+ * Wie [TERMINAL_BUSY_HTTP_STATUS] bewusst KEIN Eintrag in [HPS_CODES]: ein
228
+ * HTTP-Status ist kein `responseCode`.
229
+ */
230
+ export declare const NOT_FOUND_HTTP_STATUS = 404;
219
231
  /** Der Eintrag zu [code] in [HPS_CODES], oder `undefined`, wenn seine Bedeutung nicht feststeht. */
220
232
  export declare function hpsCodeInfo(code: string | undefined): HpsCode | undefined;
221
233
  /**
@@ -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.INTERNAL_ERROR_CODE = exports.TERMINAL_BUSY_CODE = exports.HOST_TIMEOUT_REVERSED_CODE = exports.TIP_SELECTION_FAILED_CODE = exports.UNSUPPORTED_USER_DATA_CODE = exports.CHIP_DATA_MISMATCH_CODE = exports.REFUND_DISABLED_CODE = exports.COMPLETION_FAILED_CODE = exports.INVALID_MESSAGE_TYPE_CODE = exports.TERMINAL_BLOCKED_CODE = exports.PASSWORD_NOT_ENTERED_CODE = exports.REFUND_PASSWORD_INVALID_CODE = exports.SCEP_ENROLLMENT_FAILED_CODE = exports.CARD_NOT_SUPPORTED_CODE = exports.CARD_DECLINED_CODE = exports.CARD_INFO_NOT_ENTERED_CODE = exports.DIAGNOSIS_FAILED_CODE = exports.MAX_RETRIES_EXCEEDED_CODE = exports.NOT_FOUND_CODE = exports.INVALID_TX_TYPE_CODE = exports.INVALID_TID_DOCUMENTED_CODE = exports.HOST_STEP_FAILED_CODE = exports.HOST_COMMUNICATION_FAILED_CODE = exports.APP_SELECT_FAILED_CODE = exports.CARD_READ_FAILED_CODE = exports.BAD_REQUEST_CODE = 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 = exports.HPS_CODES = exports.HPS_REASON_HINTS = void 0;
31
+ exports.NOT_FOUND_HTTP_STATUS = exports.TERMINAL_BUSY_HTTP_STATUS = exports.INTERNAL_ERROR_CODE = exports.TERMINAL_BUSY_CODE = exports.HOST_TIMEOUT_REVERSED_CODE = exports.TIP_SELECTION_FAILED_CODE = exports.UNSUPPORTED_USER_DATA_CODE = exports.CHIP_DATA_MISMATCH_CODE = exports.REFUND_DISABLED_CODE = exports.COMPLETION_FAILED_CODE = exports.INVALID_MESSAGE_TYPE_CODE = exports.TERMINAL_BLOCKED_CODE = exports.PASSWORD_NOT_ENTERED_CODE = exports.REFUND_PASSWORD_INVALID_CODE = exports.SCEP_ENROLLMENT_FAILED_CODE = exports.CARD_NOT_SUPPORTED_CODE = exports.CARD_DECLINED_CODE = exports.CARD_INFO_NOT_ENTERED_CODE = exports.DIAGNOSIS_FAILED_CODE = exports.MAX_RETRIES_EXCEEDED_CODE = exports.NOT_FOUND_CODE = exports.INVALID_TX_TYPE_CODE = exports.INVALID_TID_DOCUMENTED_CODE = exports.HOST_STEP_FAILED_CODE = exports.HOST_COMMUNICATION_FAILED_CODE = exports.APP_SELECT_FAILED_CODE = exports.CARD_READ_FAILED_CODE = exports.BAD_REQUEST_CODE = 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 = exports.HPS_CODES = exports.HPS_REASON_HINTS = void 0;
32
32
  exports.isHostUncertainReason = isHostUncertainReason;
33
33
  exports.hpsCodeInfo = hpsCodeInfo;
34
34
  exports.hpsCodeReason = hpsCodeReason;
@@ -332,6 +332,18 @@ exports.INTERNAL_ERROR_CODE = '100999';
332
332
  * getrennte Auswertung.
333
333
  */
334
334
  exports.TERMINAL_BUSY_HTTP_STATUS = 409;
335
+ /**
336
+ * HTTP `404` beim Terminal-Kontakt. **Lesart ungemessen:** am Produktivgeraet
337
+ * (TID 3556988, Firmware 2.3.9) antwortet `POST /api/transaction/abort/...`
338
+ * damit, am Testgeraet (3600335) nie. Es kann "diesen Vorgang kenne ich nicht"
339
+ * heissen oder "diesen Endpunkt gibt es hier nicht" -- beides sagt nichts ueber
340
+ * die Zahlung. Bei hobex angefragt; bis dahin benennt `payments.ts` beim
341
+ * Abbruch beide Lesarten, statt eine zu behaupten.
342
+ *
343
+ * Wie [TERMINAL_BUSY_HTTP_STATUS] bewusst KEIN Eintrag in [HPS_CODES]: ein
344
+ * HTTP-Status ist kein `responseCode`.
345
+ */
346
+ exports.NOT_FOUND_HTTP_STATUS = 404;
335
347
  const CODE_BY_ID = new Map(exports.HPS_CODES.map((c) => [c.code, c]));
336
348
  /** Der Eintrag zu [code] in [HPS_CODES], oder `undefined`, wenn seine Bedeutung nicht feststeht. */
337
349
  function hpsCodeInfo(code) {