@kreiseck/kasseneck-api 0.17.0 → 0.18.0

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 (34) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +26 -0
  3. package/dist/cjs/client/aufrufe.d.ts +1 -1
  4. package/dist/cjs/client/aufrufe.js +1 -0
  5. package/dist/cjs/rechnung/api.d.ts +3 -1
  6. package/dist/cjs/rechnung/api.js +1 -0
  7. package/dist/cjs/rechnung/endpunkte.d.ts +11 -1
  8. package/dist/cjs/rechnung/endpunkte.js +22 -0
  9. package/dist/cjs/rechnung/index.d.ts +3 -3
  10. package/dist/cjs/rechnung/index.js +4 -1
  11. package/dist/cjs/rechnung/typen.d.ts +48 -1
  12. package/dist/cjs/rechnung/vertrag.d.ts +24 -2
  13. package/dist/cjs/rechnung/vertrag.js +43 -1
  14. package/dist/esm/client/aufrufe.d.ts +1 -1
  15. package/dist/esm/client/aufrufe.js +1 -0
  16. package/dist/esm/rechnung/api.d.ts +3 -1
  17. package/dist/esm/rechnung/api.js +2 -1
  18. package/dist/esm/rechnung/endpunkte.d.ts +11 -1
  19. package/dist/esm/rechnung/endpunkte.js +21 -0
  20. package/dist/esm/rechnung/index.d.ts +3 -3
  21. package/dist/esm/rechnung/index.js +2 -2
  22. package/dist/esm/rechnung/typen.d.ts +48 -1
  23. package/dist/esm/rechnung/vertrag.d.ts +24 -2
  24. package/dist/esm/rechnung/vertrag.js +42 -0
  25. package/fixtures/hobex-hps-codes.json +1 -1
  26. package/fixtures/kasse-texte.json +1 -1
  27. package/fixtures/oberflaeche.json +16 -3
  28. package/fixtures/rechnung-api-beispiele/issue-bezahlt.json +32 -0
  29. package/fixtures/rechnung-api-beispiele/issue-fehler-zahlungsart.json +26 -0
  30. package/fixtures/rechnung-api-beispiele/zahlung-fehler-ohne-schluessel.json +14 -0
  31. package/fixtures/rechnung-api-beispiele/zahlung-nachtrag.json +14 -0
  32. package/fixtures/rechnung-api.schema.json +82 -2
  33. package/fixtures/rechnung-texte.json +1 -1
  34. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,36 @@ 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.18.0
8
+
9
+ ### Rechnungs-API: bezahlte Rechnung und Zahlungen nachtragen
10
+
11
+ **Anlass:** Die API wird vor allem von Online-Shops benutzt, die **vor** der
12
+ Rechnung kassieren. Bisher entstand immer eine offene Rechnung — mit Giro-QR
13
+ und Fälligkeit auf dem Blatt, obwohl das Geld längst da war.
14
+
15
+ - `issueInvoice` nimmt `payment` (`method`, optional `amountCents`, `paidAt`,
16
+ `reference`). Die Zahlung entsteht in **derselben** Transaktion wie das
17
+ Festschreiben; ohne `amountCents` gilt der volle Bruttobetrag.
18
+ - Neuer Aufruf `recordInvoicePayment` für später eintreffende Zahlungen, mit
19
+ **pflichtigem** `idempotencyKey` — ohne ihn bucht ein Wiederholungslauf nach
20
+ einem Zeitlimit eine zweite Zahlung.
21
+ - `INVOICE_PAYMENT_METHODS` (`transfer`, `card`, `online`, `cash`);
22
+ `Invoice.paidCents` und `Invoice.openCents`.
23
+ - Neue Fehlercodes `not_payable` (storniert oder Gutschrift) und
24
+ `payment_exceeds_invoice` (mit `remainingCents`).
25
+ - Neu: **Hinweise** an einer erfolgreichen Antwort (`INVOICE_NOTICE_CODES`,
26
+ `data.notice`). Bisheriger Fall: `cash_receipt_required`. Grund: eine
27
+ Barzahlung ist ein Barumsatz und braucht einen Beleg (§ 132a BAO), bei
28
+ Registrierkassenpflicht über die Registrierkasse — der Bezahlt-Vermerk ist
29
+ Buchhaltung und ersetzt ihn nicht. Die Rechnung selbst ist bei jeder
30
+ Zahlungsart erlaubt (§ 11 UStG), deshalb wird `cash` gebucht und nicht
31
+ abgewiesen.
32
+
33
+ `reference` wird gespeichert, aber nicht gedruckt: die Rechnung wird sieben
34
+ Jahre aufbewahrt und vervielfältigt, und dem Empfänger nützt die Zahlungs-ID
35
+ des Shops nichts.
36
+
7
37
  ## 0.17.0
8
38
 
9
39
  ### Rechnungs-API: Sprache (de/en) und Marke je Rechnung
package/README.md CHANGED
@@ -524,6 +524,32 @@ bzw. `pcs` —, und die E-Rechnung trägt den UN/ECE-Code aus
524
524
  `RECHNUNG_EINHEITEN_CODES` (`C62`, `HUR`, …). Freier Text wie `"Std"` ist
525
525
  `validation` mit Feld `items[0].unit`.
526
526
 
527
+ **Schon bezahlt?** Wer online kassiert und danach die Rechnung stellt, gibt die
528
+ Zahlung gleich mit: sie entsteht in derselben Transaktion wie das Festschreiben,
529
+ und das PDF trägt dann keinen Zahlungskasten und keinen Giro-QR.
530
+
531
+ ```ts
532
+ const { invoice } = await rechnungen.issueInvoice({
533
+ idempotencyKey: `bestellung-${bestellnummer}`,
534
+ customerId: kunde.id,
535
+ taxScheme: 'normal', priceMode: 'net', serviceStart: '2026-09-16',
536
+ items: [{ description: 'Beratung', quantity: 2, unitPriceCents: 5000, vatRate: 20, unit: 'hour' }],
537
+ payment: { method: 'card', reference: zahlung.id }, // ohne amountCents: voll bezahlt
538
+ }); // invoice.openCents === 0
539
+
540
+ // Trifft das Geld erst später ein (Überweisung, Teilzahlung):
541
+ await rechnungen.recordInvoicePayment({
542
+ idempotencyKey: `zahlung-${zahlung.id}`, // Pflicht: sonst bucht eine Wiederholung zweimal
543
+ invoiceId: invoice.id, method: 'transfer', amountCents: 12000, paidAt: '2026-09-20',
544
+ });
545
+ ```
546
+
547
+ `reference` wird gespeichert, aber **nicht gedruckt**; Kartendaten gehören
548
+ ohnehin nicht auf eine Rechnung. Bei `method: 'cash'` wird die Zahlung gebucht
549
+ und die Antwort trägt zusätzlich `notice.code = 'cash_receipt_required'`: eine
550
+ Barzahlung ist ein Barumsatz und braucht einen Beleg (§ 132a BAO), bei
551
+ Registrierkassenpflicht über die Kasse — der Vermerk hier ersetzt ihn nicht.
552
+
527
553
  **Nach einem Zeitlimit mit demselben `idempotencyKey` wiederholen**, nie mit
528
554
  einem neuen: dann kommt die schon ausgestellte Rechnung zurück
529
555
  (`replayed: true`). Derselbe Schlüssel mit anderen Daten ergibt
@@ -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", "cancelInvoice", "cancelReceipt", "createCreditNote", "createCustomer", "createCustomerCashregister", "createPartnerCustomer", "checkPartnerCustomerEmail", "createPartnerWebhook", "createPaymentLinkStripe", "createPrintJob", "createReceipt", "deletePartnerWebhook", "downloadDailyReport", "downloadReport", "endRegisterSession", "financeWebService", "generateFullReceiptId", "getCustomer", "getCustomerCredentials", "getCustomerSignatureStatus", "getFirstReceiptDate", "getInvoice", "getInvoicePdf", "getInvoiceSetupStatus", "getInvoiceXml", "getKasseSettings", "getPartnerCustomer", "getPartnerInfo", "getPrintJob", "getReceipt", "hobexPayApi", "hobexRefundApi", "issueInvoice", "listCustomerCashregisters", "listInvoices", "listBrands", "listMyArticleGroups", "listMyArticles", "listMyCashregisters", "listMyPrinters", "listMyReceipts", "listMyTipRecipients", "listPartnerCustomers", "listPartnerWebhookDeliveries", "listPartnerWebhooks", "listRegisterUsersForDevice", "listRegisterSessionsForDevice", "pairRegisterDevice", "registerPinLogin", "registerUserLogin", "renewRegisterSession", "requestCustomerSignature", "searchCustomers", "sendPartnerCustomerFonLink", "sendPartnerWebhookTest", "sendReceiptEmail", "setMyKasseSettings", "setMyRegisterDeviceSettings", "stripeCaptureIntent", "unpairRegisterDevice", "rotatePartnerWebhookSecret", "updateCustomer", "updatePartnerWebhook"];
16
+ export declare const AUFRUFE: readonly ["activateCashregister", "cancelInvoice", "cancelReceipt", "createCreditNote", "createCustomer", "createCustomerCashregister", "createPartnerCustomer", "checkPartnerCustomerEmail", "createPartnerWebhook", "createPaymentLinkStripe", "createPrintJob", "createReceipt", "deletePartnerWebhook", "downloadDailyReport", "downloadReport", "endRegisterSession", "financeWebService", "generateFullReceiptId", "getCustomer", "getCustomerCredentials", "getCustomerSignatureStatus", "getFirstReceiptDate", "getInvoice", "getInvoicePdf", "getInvoiceSetupStatus", "getInvoiceXml", "getKasseSettings", "getPartnerCustomer", "getPartnerInfo", "getPrintJob", "getReceipt", "hobexPayApi", "hobexRefundApi", "issueInvoice", "listCustomerCashregisters", "listInvoices", "listBrands", "listMyArticleGroups", "listMyArticles", "listMyCashregisters", "listMyPrinters", "listMyReceipts", "listMyTipRecipients", "listPartnerCustomers", "listPartnerWebhookDeliveries", "listPartnerWebhooks", "listRegisterUsersForDevice", "listRegisterSessionsForDevice", "pairRegisterDevice", "recordInvoicePayment", "registerPinLogin", "registerUserLogin", "renewRegisterSession", "requestCustomerSignature", "searchCustomers", "sendPartnerCustomerFonLink", "sendPartnerWebhookTest", "sendReceiptEmail", "setMyKasseSettings", "setMyRegisterDeviceSettings", "stripeCaptureIntent", "unpairRegisterDevice", "rotatePartnerWebhookSecret", "updateCustomer", "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>;
@@ -51,6 +51,7 @@ exports.AUFRUFE = [
51
51
  'listRegisterUsersForDevice',
52
52
  'listRegisterSessionsForDevice',
53
53
  'pairRegisterDevice',
54
+ 'recordInvoicePayment',
54
55
  'registerPinLogin',
55
56
  'registerUserLogin',
56
57
  'renewRegisterSession',
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { type FetchLike } from '../client/transport.js';
8
8
  import type { EInvoiceFormat, InvoiceLanguage } from './vertrag.js';
9
- import type { Brand, CancelInvoiceRequest, CancelResult, CreditNoteRequest, CreditNoteResult, Customer, CustomerInput, CustomerPage, CustomerSearch, InvoiceDetail, InvoiceListQuery, InvoicePage, InvoiceSetupStatus, IssueInvoiceRequest, IssueResult } from './typen.js';
9
+ import type { Brand, CancelInvoiceRequest, CancelResult, CreditNoteRequest, CreditNoteResult, Customer, CustomerInput, CustomerPage, CustomerSearch, InvoiceDetail, InvoiceListQuery, InvoicePage, InvoiceSetupStatus, IssueInvoiceRequest, IssueResult, RecordPaymentRequest, RecordPaymentResult } from './typen.js';
10
10
  export interface RechnungApiOptions {
11
11
  /** `api_key` des Kontos (`kr_live_…` / `kr_test_…`). Gehoert auf einen Server. */
12
12
  apiKey: string;
@@ -37,6 +37,8 @@ export interface RechnungApi {
37
37
  number: string;
38
38
  }): Promise<InvoiceDetail>;
39
39
  listInvoices(abfrage?: InvoiceListQuery): Promise<InvoicePage>;
40
+ /** Eine spaeter eingetroffene Zahlung nachtragen; `idempotencyKey` ist Pflicht. */
41
+ recordInvoicePayment(anfrage: RecordPaymentRequest): Promise<RecordPaymentResult>;
40
42
  /** Mit `language` ungleich der Rechnungssprache: gekennzeichnete Uebersetzungskopie. */
41
43
  getInvoicePdf(invoiceId: string, optionen?: {
42
44
  language?: InvoiceLanguage;
@@ -32,6 +32,7 @@ function createRechnungApi(optionen) {
32
32
  getInvoicePdf: (id, o) => (0, endpunkte_js_1.getInvoicePdf)(rufenBinaer, id, o),
33
33
  getInvoiceXml: (id, format) => (0, endpunkte_js_1.getInvoiceXml)(rufen, id, format),
34
34
  getInvoiceSetupStatus: () => (0, endpunkte_js_1.getInvoiceSetupStatus)(rufen),
35
+ recordInvoicePayment: (anfrage) => (0, endpunkte_js_1.recordInvoicePayment)(rufen, anfrage),
35
36
  listBrands: () => (0, endpunkte_js_1.listBrands)(rufen),
36
37
  };
37
38
  }
@@ -18,7 +18,7 @@
18
18
  */
19
19
  import type { InternerBinaerTransport, InternerTransport } from '../client/aufrufe.js';
20
20
  import type { EInvoiceFormat, InvoiceLanguage } from './vertrag.js';
21
- import type { Brand, CancelInvoiceRequest, CancelResult, CreditNoteRequest, CreditNoteResult, Customer, CustomerInput, CustomerPage, CustomerSearch, InvoiceDetail, InvoiceListQuery, InvoicePage, InvoiceSetupStatus, IssueInvoiceRequest, IssueResult } from './typen.js';
21
+ import type { Brand, CancelInvoiceRequest, CancelResult, CreditNoteRequest, CreditNoteResult, Customer, CustomerInput, CustomerPage, CustomerSearch, InvoiceDetail, InvoiceListQuery, InvoicePage, InvoiceSetupStatus, IssueInvoiceRequest, IssueResult, RecordPaymentRequest, RecordPaymentResult } from './typen.js';
22
22
  export declare function createCustomer(rufen: InternerTransport, customer: CustomerInput, optionen?: {
23
23
  idempotencyKey?: string;
24
24
  }): Promise<Customer>;
@@ -53,6 +53,16 @@ export declare function getInvoiceSetupStatus(rufen: InternerTransport): Promise
53
53
  export declare function getInvoicePdf(rufenBinaer: InternerBinaerTransport, invoiceId: string, optionen?: {
54
54
  language?: InvoiceLanguage;
55
55
  }): Promise<Uint8Array>;
56
+ /**
57
+ * Eine Zahlung nachtragen, die nach dem Ausstellen eingetroffen ist
58
+ * (Ueberweisung, Teilzahlung). Der `idempotencyKey` ist Pflicht: ohne ihn
59
+ * bucht ein Wiederholungslauf nach einem Zeitlimit eine zweite Zahlung.
60
+ *
61
+ * Bei `method: 'cash'` wird die Zahlung gebucht und die Antwort traegt
62
+ * zusaetzlich `notice` — eine Barzahlung ist ein Barumsatz und braucht einen
63
+ * Beleg (§ 132a BAO), den dieser Vermerk nicht ersetzt.
64
+ */
65
+ export declare function recordInvoicePayment(rufen: InternerTransport, anfrage: RecordPaymentRequest): Promise<RecordPaymentResult>;
56
66
  /** Die Marken des Kontos — die Kennung geht als `brandId` in `issueInvoice`. */
57
67
  export declare function listBrands(rufen: InternerTransport): Promise<Brand[]>;
58
68
  /**
@@ -29,6 +29,7 @@ exports.getInvoice = getInvoice;
29
29
  exports.listInvoices = listInvoices;
30
30
  exports.getInvoiceSetupStatus = getInvoiceSetupStatus;
31
31
  exports.getInvoicePdf = getInvoicePdf;
32
+ exports.recordInvoicePayment = recordInvoicePayment;
32
33
  exports.listBrands = listBrands;
33
34
  exports.getInvoiceXml = getInvoiceXml;
34
35
  const errors_js_1 = require("../client/errors.js");
@@ -141,6 +142,27 @@ function getInvoicePdf(rufenBinaer, invoiceId, optionen = {}) {
141
142
  params['language'] = optionen.language;
142
143
  return rufenBinaer('getInvoicePdf', params);
143
144
  }
145
+ /**
146
+ * Eine Zahlung nachtragen, die nach dem Ausstellen eingetroffen ist
147
+ * (Ueberweisung, Teilzahlung). Der `idempotencyKey` ist Pflicht: ohne ihn
148
+ * bucht ein Wiederholungslauf nach einem Zeitlimit eine zweite Zahlung.
149
+ *
150
+ * Bei `method: 'cash'` wird die Zahlung gebucht und die Antwort traegt
151
+ * zusaetzlich `notice` — eine Barzahlung ist ein Barumsatz und braucht einen
152
+ * Beleg (§ 132a BAO), den dieser Vermerk nicht ersetzt.
153
+ */
154
+ async function recordInvoicePayment(rufen, anfrage) {
155
+ const daten = await rufen('recordInvoicePayment', nutzlast(anfrage));
156
+ const roh = objekt(daten);
157
+ const ergebnis = {
158
+ invoice: pflichtObjekt('recordInvoicePayment', daten, 'invoice'),
159
+ payment: pflichtObjekt('recordInvoicePayment', daten, 'payment'),
160
+ replayed: roh['replayed'] === true,
161
+ };
162
+ if (roh['notice'])
163
+ ergebnis.notice = roh['notice'];
164
+ return ergebnis;
165
+ }
144
166
  /** Die Marken des Kontos — die Kennung geht als `brandId` in `issueInvoice`. */
145
167
  async function listBrands(rufen) {
146
168
  const brands = objekt(await rufen('listBrands', {}))['brands'];
@@ -13,7 +13,7 @@
13
13
  export { createRechnungApi, type RechnungApi, type RechnungApiOptions } from './api.js';
14
14
  export { rechnungKeyAuth, type RechnungKeyAuthOptions } from './auth.js';
15
15
  export { istRechnungFehler, rechnungFehlerCode, rechnungFeldFehler, type RechnungFeldFehler, } from './fehler.js';
16
- export { cancelInvoice, createCreditNote, createCustomer, getCustomer, getInvoice, getInvoicePdf, getInvoiceSetupStatus, getInvoiceXml, issueInvoice, listBrands, listInvoices, searchCustomers, updateCustomer, } from './endpunkte.js';
17
- export type { Brand, CancelInvoiceRequest, CancelResult, CreditNoteRequest, CreditNoteResult, Customer, CustomerInput, CustomerPage, CustomerSearch, EInvoiceStatus, Invoice, InvoiceDetail, InvoiceItem, InvoiceItemInput, InvoiceListQuery, InvoicePage, InvoiceRecipient, InvoiceSetupGap, InvoiceSetupStatus, InvoiceTotals, IssueInvoiceRequest, IssueResult, } from './typen.js';
16
+ export { cancelInvoice, createCreditNote, createCustomer, getCustomer, getInvoice, getInvoicePdf, getInvoiceSetupStatus, getInvoiceXml, issueInvoice, listBrands, listInvoices, recordInvoicePayment, searchCustomers, updateCustomer, } from './endpunkte.js';
17
+ export type { Brand, CancelInvoiceRequest, CancelResult, CreditNoteRequest, CreditNoteResult, Customer, CustomerInput, CustomerPage, CustomerSearch, EInvoiceStatus, Invoice, InvoiceDetail, InvoiceItem, InvoiceItemInput, InvoiceListQuery, InvoicePage, InvoiceRecipient, InvoiceSetupGap, InvoiceSetupStatus, InvoiceTotals, InvoiceNotice, InvoicePayment, IssueInvoiceRequest, IssueResult, PaymentInput, RecordPaymentRequest, RecordPaymentResult, } from './typen.js';
18
18
  export { RECHNUNG_TEXTE, rechnungText, type RechnungTextSchluessel } from './texte.js';
19
- export { RECHNUNG_VERTRAG_VERSION, RECHNUNG_AUFRUFE, INVOICE_ERROR_CODES, CREDIT_NOTE_REASONS, TAX_SCHEMES, PRICE_MODES, VAT_RATES, CUSTOMER_TYPES, INVOICE_LIST_STATUS, DOC_TYPES, EINVOICE_FORMATS, INVOICE_LANGUAGES, INVOICE_UNITS, RECHNUNG_EINHEITEN_CODES, INVOICE_SETUP_REQUIREMENTS, KUNDE_FELDER, POSITION_FELDER, RECHNUNG_ANFRAGEN, RECHNUNG_GENAU_EINS, RECHNUNG_MINDESTENS_EINS, type RechnungAufruf, type InvoiceErrorCode, type CreditNoteReason, type TaxScheme, type PriceMode, type VatRatePercent, type CustomerType, type InvoiceListStatus, type DocType, type EInvoiceFormat, type InvoiceLanguage, type InvoiceUnit, type InvoiceSetupRequirement, type Format, type Feld, } from './vertrag.js';
19
+ export { RECHNUNG_VERTRAG_VERSION, RECHNUNG_AUFRUFE, INVOICE_ERROR_CODES, CREDIT_NOTE_REASONS, TAX_SCHEMES, PRICE_MODES, VAT_RATES, CUSTOMER_TYPES, INVOICE_LIST_STATUS, DOC_TYPES, EINVOICE_FORMATS, INVOICE_LANGUAGES, INVOICE_PAYMENT_METHODS, INVOICE_NOTICE_CODES, INVOICE_UNITS, RECHNUNG_EINHEITEN_CODES, INVOICE_SETUP_REQUIREMENTS, KUNDE_FELDER, POSITION_FELDER, RECHNUNG_ANFRAGEN, RECHNUNG_GENAU_EINS, RECHNUNG_MINDESTENS_EINS, type RechnungAufruf, type InvoiceErrorCode, type CreditNoteReason, type TaxScheme, type PriceMode, type VatRatePercent, type CustomerType, type InvoiceListStatus, type DocType, type EInvoiceFormat, type InvoiceLanguage, type InvoicePaymentMethod, type InvoiceNoticeCode, type InvoiceUnit, type InvoiceSetupRequirement, type Format, type Feld, } from './vertrag.js';
@@ -12,7 +12,7 @@
12
12
  * Benutzung des Clients.
13
13
  */
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.RECHNUNG_MINDESTENS_EINS = exports.RECHNUNG_GENAU_EINS = exports.RECHNUNG_ANFRAGEN = exports.POSITION_FELDER = exports.KUNDE_FELDER = exports.INVOICE_SETUP_REQUIREMENTS = exports.RECHNUNG_EINHEITEN_CODES = exports.INVOICE_UNITS = exports.INVOICE_LANGUAGES = exports.EINVOICE_FORMATS = exports.DOC_TYPES = exports.INVOICE_LIST_STATUS = exports.CUSTOMER_TYPES = exports.VAT_RATES = exports.PRICE_MODES = exports.TAX_SCHEMES = exports.CREDIT_NOTE_REASONS = exports.INVOICE_ERROR_CODES = exports.RECHNUNG_AUFRUFE = exports.RECHNUNG_VERTRAG_VERSION = exports.rechnungText = exports.RECHNUNG_TEXTE = exports.updateCustomer = exports.searchCustomers = exports.listInvoices = exports.listBrands = exports.issueInvoice = exports.getInvoiceXml = exports.getInvoiceSetupStatus = exports.getInvoicePdf = exports.getInvoice = exports.getCustomer = exports.createCustomer = exports.createCreditNote = exports.cancelInvoice = exports.rechnungFeldFehler = exports.rechnungFehlerCode = exports.istRechnungFehler = exports.rechnungKeyAuth = exports.createRechnungApi = void 0;
15
+ exports.RECHNUNG_MINDESTENS_EINS = exports.RECHNUNG_GENAU_EINS = exports.RECHNUNG_ANFRAGEN = exports.POSITION_FELDER = exports.KUNDE_FELDER = exports.INVOICE_SETUP_REQUIREMENTS = exports.RECHNUNG_EINHEITEN_CODES = exports.INVOICE_UNITS = exports.INVOICE_NOTICE_CODES = exports.INVOICE_PAYMENT_METHODS = exports.INVOICE_LANGUAGES = exports.EINVOICE_FORMATS = exports.DOC_TYPES = exports.INVOICE_LIST_STATUS = exports.CUSTOMER_TYPES = exports.VAT_RATES = exports.PRICE_MODES = exports.TAX_SCHEMES = exports.CREDIT_NOTE_REASONS = exports.INVOICE_ERROR_CODES = exports.RECHNUNG_AUFRUFE = exports.RECHNUNG_VERTRAG_VERSION = exports.rechnungText = exports.RECHNUNG_TEXTE = exports.updateCustomer = exports.searchCustomers = exports.recordInvoicePayment = exports.listInvoices = exports.listBrands = exports.issueInvoice = exports.getInvoiceXml = exports.getInvoiceSetupStatus = exports.getInvoicePdf = exports.getInvoice = exports.getCustomer = exports.createCustomer = exports.createCreditNote = exports.cancelInvoice = exports.rechnungFeldFehler = exports.rechnungFehlerCode = exports.istRechnungFehler = exports.rechnungKeyAuth = exports.createRechnungApi = void 0;
16
16
  var api_js_1 = require("./api.js");
17
17
  Object.defineProperty(exports, "createRechnungApi", { enumerable: true, get: function () { return api_js_1.createRechnungApi; } });
18
18
  var auth_js_1 = require("./auth.js");
@@ -33,6 +33,7 @@ Object.defineProperty(exports, "getInvoiceXml", { enumerable: true, get: functio
33
33
  Object.defineProperty(exports, "issueInvoice", { enumerable: true, get: function () { return endpunkte_js_1.issueInvoice; } });
34
34
  Object.defineProperty(exports, "listBrands", { enumerable: true, get: function () { return endpunkte_js_1.listBrands; } });
35
35
  Object.defineProperty(exports, "listInvoices", { enumerable: true, get: function () { return endpunkte_js_1.listInvoices; } });
36
+ Object.defineProperty(exports, "recordInvoicePayment", { enumerable: true, get: function () { return endpunkte_js_1.recordInvoicePayment; } });
36
37
  Object.defineProperty(exports, "searchCustomers", { enumerable: true, get: function () { return endpunkte_js_1.searchCustomers; } });
37
38
  Object.defineProperty(exports, "updateCustomer", { enumerable: true, get: function () { return endpunkte_js_1.updateCustomer; } });
38
39
  var texte_js_1 = require("./texte.js");
@@ -51,6 +52,8 @@ Object.defineProperty(exports, "INVOICE_LIST_STATUS", { enumerable: true, get: f
51
52
  Object.defineProperty(exports, "DOC_TYPES", { enumerable: true, get: function () { return vertrag_js_1.DOC_TYPES; } });
52
53
  Object.defineProperty(exports, "EINVOICE_FORMATS", { enumerable: true, get: function () { return vertrag_js_1.EINVOICE_FORMATS; } });
53
54
  Object.defineProperty(exports, "INVOICE_LANGUAGES", { enumerable: true, get: function () { return vertrag_js_1.INVOICE_LANGUAGES; } });
55
+ Object.defineProperty(exports, "INVOICE_PAYMENT_METHODS", { enumerable: true, get: function () { return vertrag_js_1.INVOICE_PAYMENT_METHODS; } });
56
+ Object.defineProperty(exports, "INVOICE_NOTICE_CODES", { enumerable: true, get: function () { return vertrag_js_1.INVOICE_NOTICE_CODES; } });
54
57
  Object.defineProperty(exports, "INVOICE_UNITS", { enumerable: true, get: function () { return vertrag_js_1.INVOICE_UNITS; } });
55
58
  Object.defineProperty(exports, "RECHNUNG_EINHEITEN_CODES", { enumerable: true, get: function () { return vertrag_js_1.RECHNUNG_EINHEITEN_CODES; } });
56
59
  Object.defineProperty(exports, "INVOICE_SETUP_REQUIREMENTS", { enumerable: true, get: function () { return vertrag_js_1.INVOICE_SETUP_REQUIREMENTS; } });
@@ -5,7 +5,7 @@
5
5
  * Betraege sind ueberall ganze Cent. Datumsangaben sind `YYYY-MM-DD` nach
6
6
  * Wiener Kalender.
7
7
  */
8
- import type { CreditNoteReason, CustomerType, DocType, InvoiceLanguage, InvoiceUnit, InvoiceSetupRequirement, InvoiceListStatus, PriceMode, TaxScheme, VatRatePercent } from './vertrag.js';
8
+ import type { CreditNoteReason, CustomerType, DocType, InvoiceLanguage, InvoiceNoticeCode, InvoicePaymentMethod, InvoiceUnit, InvoiceSetupRequirement, InvoiceListStatus, PriceMode, TaxScheme, VatRatePercent } from './vertrag.js';
9
9
  export interface CustomerInput {
10
10
  type: CustomerType;
11
11
  name: string;
@@ -102,6 +102,49 @@ export interface IssueInvoiceRequest {
102
102
  language?: InvoiceLanguage;
103
103
  /** Marke (Kennung aus `listBrands`); sonst die Standardmarke. Unbekannt = `brand_not_found`. */
104
104
  brandId?: string;
105
+ /**
106
+ * Schon bezahlt (Shop kassiert online, Rechnung folgt). Die Zahlung entsteht
107
+ * in derselben Transaktion wie das Festschreiben: das PDF traegt dann keine
108
+ * Zahlungsinformationen und keinen Giro-QR.
109
+ */
110
+ payment?: PaymentInput;
111
+ }
112
+ /** Eine Zahlung, wie das Fremdsystem sie meldet. */
113
+ export interface PaymentInput {
114
+ method: InvoicePaymentMethod;
115
+ /** Ohne Angabe der volle Bruttobetrag. */
116
+ amountCents?: number;
117
+ /** Ohne Angabe der heutige Wiener Tag; nie in der Zukunft. */
118
+ paidAt?: string;
119
+ /** Zahlungskennung des Fremdsystems — gespeichert, aber nicht gedruckt. */
120
+ reference?: string;
121
+ }
122
+ export interface RecordPaymentRequest extends PaymentInput {
123
+ /** Pflicht: ohne ihn bucht eine Wiederholung eine zweite Zahlung. */
124
+ idempotencyKey: string;
125
+ invoiceId: string;
126
+ }
127
+ /** Eine gebuchte Zahlung, wie die API sie zurueckgibt. */
128
+ export interface InvoicePayment {
129
+ id: string;
130
+ amountCents: number;
131
+ paidAt: string;
132
+ method: InvoicePaymentMethod;
133
+ reference: string | null;
134
+ }
135
+ /**
136
+ * Ein Hinweis zu einer erfolgreichen Antwort — kein Fehler, sondern etwas,
137
+ * das der Aufrufer wissen sollte (heute nur `cash_receipt_required`).
138
+ */
139
+ export interface InvoiceNotice {
140
+ code: InvoiceNoticeCode;
141
+ message: string;
142
+ }
143
+ export interface RecordPaymentResult {
144
+ invoice: Invoice;
145
+ payment: InvoicePayment;
146
+ replayed: boolean;
147
+ notice?: InvoiceNotice;
105
148
  }
106
149
  export interface CancelInvoiceRequest {
107
150
  idempotencyKey: string;
@@ -147,6 +190,10 @@ export interface Invoice {
147
190
  id: string | null;
148
191
  name: string | null;
149
192
  } | null;
193
+ /** Summe der gebuchten Zahlungen. */
194
+ paidCents: number;
195
+ /** Was noch offen ist; `0` heisst bezahlt. */
196
+ openCents: number;
150
197
  }
151
198
  /** Eine Marke des Kontos (Logo, Farbe, Absender) — `id` geht als `brandId` in `issueInvoice`. */
152
199
  export interface Brand {
@@ -18,13 +18,13 @@
18
18
  * Nummer, Summen — ist bewusst **nicht** setzbar.
19
19
  */
20
20
  export declare const RECHNUNG_VERTRAG_VERSION = 1;
21
- export declare const RECHNUNG_AUFRUFE: readonly ["createCustomer", "getCustomer", "updateCustomer", "searchCustomers", "issueInvoice", "cancelInvoice", "createCreditNote", "getInvoice", "listInvoices", "getInvoicePdf", "getInvoiceXml", "getInvoiceSetupStatus", "listBrands"];
21
+ export declare const RECHNUNG_AUFRUFE: readonly ["createCustomer", "getCustomer", "updateCustomer", "searchCustomers", "issueInvoice", "cancelInvoice", "createCreditNote", "getInvoice", "listInvoices", "getInvoicePdf", "getInvoiceXml", "getInvoiceSetupStatus", "listBrands", "recordInvoicePayment"];
22
22
  export type RechnungAufruf = (typeof RECHNUNG_AUFRUFE)[number];
23
23
  /**
24
24
  * Stabile Fehlercodes. Das Fremdsystem verzweigt am Code, der Text darf sich
25
25
  * aendern. `validation` traegt zusaetzlich `errors: [{ field, message }]`.
26
26
  */
27
- export declare const INVOICE_ERROR_CODES: readonly ["validation", "idempotency_conflict", "module_inactive", "customer_not_found", "customer_exists", "short_code_taken", "short_code_immutable", "recipient_required", "invoice_requirements_missing", "invoice_not_found", "invoice_ambiguous", "not_cancellable", "partial_credit_exists", "credit_exceeds_invoice", "einvoice_incomplete", "invoice_api_not_enabled", "invoice_setup_incomplete", "language_not_allowed", "brand_not_found"];
27
+ export declare const INVOICE_ERROR_CODES: readonly ["validation", "idempotency_conflict", "module_inactive", "customer_not_found", "customer_exists", "short_code_taken", "short_code_immutable", "recipient_required", "invoice_requirements_missing", "invoice_not_found", "invoice_ambiguous", "not_cancellable", "partial_credit_exists", "credit_exceeds_invoice", "einvoice_incomplete", "invoice_api_not_enabled", "invoice_setup_incomplete", "language_not_allowed", "brand_not_found", "not_payable", "payment_exceeds_invoice"];
28
28
  export type InvoiceErrorCode = (typeof INVOICE_ERROR_CODES)[number];
29
29
  /** Gruende einer Gutschrift. Der Server druckt den deutschen Anzeigetext. */
30
30
  export declare const CREDIT_NOTE_REASONS: readonly ["cancellation", "price_reduction", "return", "incorrect_invoice", "other"];
@@ -51,6 +51,20 @@ export type EInvoiceFormat = (typeof EINVOICE_FORMATS)[number];
51
51
  */
52
52
  export declare const INVOICE_LANGUAGES: readonly ["de", "en"];
53
53
  export type InvoiceLanguage = (typeof INVOICE_LANGUAGES)[number];
54
+ /**
55
+ * Wie eine Rechnung bezahlt wurde. Der Vermerk ist Buchhaltung, kein Beleg:
56
+ * `cash` wird gebucht, die Antwort traegt dann zusaetzlich den Hinweis
57
+ * `cash_receipt_required` — eine Barzahlung ist ein Barumsatz und braucht
58
+ * einen Beleg (§ 132a BAO), bei Registrierkassenpflicht ueber die Kasse.
59
+ */
60
+ export declare const INVOICE_PAYMENT_METHODS: readonly ["transfer", "card", "online", "cash"];
61
+ export type InvoicePaymentMethod = (typeof INVOICE_PAYMENT_METHODS)[number];
62
+ /**
63
+ * Hinweise, die eine erfolgreiche Antwort zusaetzlich tragen kann (`data.notice`).
64
+ * Sie sind keine Fehler: der Aufruf hat gewirkt, es gibt nur etwas zu wissen.
65
+ */
66
+ export declare const INVOICE_NOTICE_CODES: readonly ["cash_receipt_required"];
67
+ export type InvoiceNoticeCode = (typeof INVOICE_NOTICE_CODES)[number];
54
68
  /**
55
69
  * Einheiten einer Position. Die API nimmt nur diese Schluessel an; gedruckt
56
70
  * wird das Kuerzel in der Sprache der Rechnung (`RECHNUNG_TEXTE`,
@@ -129,6 +143,14 @@ export type Feld = {
129
143
  export declare const KUNDE_FELDER: Readonly<Record<string, Feld>>;
130
144
  /** Eine Rechnungs- oder Gutschriftsposition. Preise in ganzen Cent. */
131
145
  export declare const POSITION_FELDER: Readonly<Record<string, Feld>>;
146
+ /**
147
+ * Eine Zahlung zu einer Rechnung. Ohne `amountCents` gilt der volle
148
+ * Bruttobetrag, ohne `paidAt` der heutige Wiener Tag. `reference` ist die
149
+ * Zahlungskennung des Fremdsystems (z. B. `pi_3Q...`) — sie wird gespeichert,
150
+ * aber **nicht gedruckt**: die Rechnung wird aufbewahrt und vervielfaeltigt,
151
+ * und dem Empfaenger nuetzt sie nichts.
152
+ */
153
+ export declare const PAYMENT_FELDER: Readonly<Record<string, Feld>>;
132
154
  export declare const RECHNUNG_ANFRAGEN: Readonly<Record<RechnungAufruf, Readonly<Record<string, Feld>>>>;
133
155
  /** Genau eines dieser Felder muss gesetzt sein (je Aufruf, je Gruppe). */
134
156
  export declare const RECHNUNG_GENAU_EINS: Readonly<Partial<Record<RechnungAufruf, readonly (readonly string[])[]>>>;
@@ -19,7 +19,7 @@
19
19
  * Nummer, Summen — ist bewusst **nicht** setzbar.
20
20
  */
21
21
  Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.RECHNUNG_MINDESTENS_EINS = exports.RECHNUNG_GENAU_EINS = exports.RECHNUNG_ANFRAGEN = exports.POSITION_FELDER = exports.KUNDE_FELDER = exports.INVOICE_SETUP_REQUIREMENTS = exports.RECHNUNG_EINHEITEN_CODES = exports.INVOICE_UNITS = exports.INVOICE_LANGUAGES = exports.EINVOICE_FORMATS = exports.DOC_TYPES = exports.INVOICE_LIST_STATUS = exports.CUSTOMER_TYPES = exports.VAT_RATES = exports.PRICE_MODES = exports.TAX_SCHEMES = exports.CREDIT_NOTE_REASONS = exports.INVOICE_ERROR_CODES = exports.RECHNUNG_AUFRUFE = exports.RECHNUNG_VERTRAG_VERSION = void 0;
22
+ exports.RECHNUNG_MINDESTENS_EINS = exports.RECHNUNG_GENAU_EINS = exports.RECHNUNG_ANFRAGEN = exports.PAYMENT_FELDER = exports.POSITION_FELDER = exports.KUNDE_FELDER = exports.INVOICE_SETUP_REQUIREMENTS = exports.RECHNUNG_EINHEITEN_CODES = exports.INVOICE_UNITS = exports.INVOICE_NOTICE_CODES = exports.INVOICE_PAYMENT_METHODS = exports.INVOICE_LANGUAGES = exports.EINVOICE_FORMATS = exports.DOC_TYPES = exports.INVOICE_LIST_STATUS = exports.CUSTOMER_TYPES = exports.VAT_RATES = exports.PRICE_MODES = exports.TAX_SCHEMES = exports.CREDIT_NOTE_REASONS = exports.INVOICE_ERROR_CODES = exports.RECHNUNG_AUFRUFE = exports.RECHNUNG_VERTRAG_VERSION = void 0;
23
23
  exports.RECHNUNG_VERTRAG_VERSION = 1;
24
24
  exports.RECHNUNG_AUFRUFE = [
25
25
  'createCustomer',
@@ -35,6 +35,7 @@ exports.RECHNUNG_AUFRUFE = [
35
35
  'getInvoiceXml',
36
36
  'getInvoiceSetupStatus',
37
37
  'listBrands',
38
+ 'recordInvoicePayment',
38
39
  ];
39
40
  /**
40
41
  * Stabile Fehlercodes. Das Fremdsystem verzweigt am Code, der Text darf sich
@@ -60,6 +61,8 @@ exports.INVOICE_ERROR_CODES = [
60
61
  'invoice_setup_incomplete',
61
62
  'language_not_allowed',
62
63
  'brand_not_found',
64
+ 'not_payable',
65
+ 'payment_exceeds_invoice',
63
66
  ];
64
67
  /** Gruende einer Gutschrift. Der Server druckt den deutschen Anzeigetext. */
65
68
  exports.CREDIT_NOTE_REASONS = [
@@ -83,6 +86,18 @@ exports.EINVOICE_FORMATS = ['ubl', 'cii'];
83
86
  * oesterreichisch formatiert.
84
87
  */
85
88
  exports.INVOICE_LANGUAGES = ['de', 'en'];
89
+ /**
90
+ * Wie eine Rechnung bezahlt wurde. Der Vermerk ist Buchhaltung, kein Beleg:
91
+ * `cash` wird gebucht, die Antwort traegt dann zusaetzlich den Hinweis
92
+ * `cash_receipt_required` — eine Barzahlung ist ein Barumsatz und braucht
93
+ * einen Beleg (§ 132a BAO), bei Registrierkassenpflicht ueber die Kasse.
94
+ */
95
+ exports.INVOICE_PAYMENT_METHODS = ['transfer', 'card', 'online', 'cash'];
96
+ /**
97
+ * Hinweise, die eine erfolgreiche Antwort zusaetzlich tragen kann (`data.notice`).
98
+ * Sie sind keine Fehler: der Aufruf hat gewirkt, es gibt nur etwas zu wissen.
99
+ */
100
+ exports.INVOICE_NOTICE_CODES = ['cash_receipt_required'];
86
101
  /**
87
102
  * Einheiten einer Position. Die API nimmt nur diese Schluessel an; gedruckt
88
103
  * wird das Kuerzel in der Sprache der Rechnung (`RECHNUNG_TEXTE`,
@@ -264,6 +279,19 @@ exports.POSITION_FELDER = Object.freeze({
264
279
  discountPct: { typ: 'number', pflicht: false, min: 0, max: 100, nachkomma: 2 },
265
280
  });
266
281
  const positionen = { typ: 'list', pflicht: true, min: 1, max: 500, eintrag: { typ: 'object', pflicht: true, felder: exports.POSITION_FELDER } };
282
+ /**
283
+ * Eine Zahlung zu einer Rechnung. Ohne `amountCents` gilt der volle
284
+ * Bruttobetrag, ohne `paidAt` der heutige Wiener Tag. `reference` ist die
285
+ * Zahlungskennung des Fremdsystems (z. B. `pi_3Q...`) — sie wird gespeichert,
286
+ * aber **nicht gedruckt**: die Rechnung wird aufbewahrt und vervielfaeltigt,
287
+ * und dem Empfaenger nuetzt sie nichts.
288
+ */
289
+ exports.PAYMENT_FELDER = Object.freeze({
290
+ method: { typ: 'enum', pflicht: true, werte: exports.INVOICE_PAYMENT_METHODS },
291
+ amountCents: { typ: 'integer', pflicht: false, min: 1, max: 100_000_000 },
292
+ paidAt: datum(),
293
+ reference: text(100),
294
+ });
267
295
  exports.RECHNUNG_ANFRAGEN = Object.freeze({
268
296
  createCustomer: {
269
297
  customer: { typ: 'object', pflicht: true, felder: exports.KUNDE_FELDER },
@@ -305,6 +333,12 @@ exports.RECHNUNG_ANFRAGEN = Object.freeze({
305
333
  language: { typ: 'enum', pflicht: false, werte: exports.INVOICE_LANGUAGES },
306
334
  /** Marke (Kennung aus `listBrands`); sonst die Standardmarke. */
307
335
  brandId: id,
336
+ /**
337
+ * Schon bezahlt: die Zahlung entsteht in **derselben** Transaktion wie das
338
+ * Festschreiben. Sonst gaebe es einen Moment, in dem die Rechnung offen ist
339
+ * und ein sofort geholtes PDF Zahlungsinformationen traegt.
340
+ */
341
+ payment: { typ: 'object', pflicht: false, felder: exports.PAYMENT_FELDER },
308
342
  },
309
343
  cancelInvoice: {
310
344
  idempotencyKey: idempotencyKey(true),
@@ -343,6 +377,14 @@ exports.RECHNUNG_ANFRAGEN = Object.freeze({
343
377
  },
344
378
  getInvoiceSetupStatus: {},
345
379
  listBrands: {},
380
+ recordInvoicePayment: {
381
+ idempotencyKey: idempotencyKey(true),
382
+ invoiceId: idPflicht,
383
+ method: { typ: 'enum', pflicht: true, werte: exports.INVOICE_PAYMENT_METHODS },
384
+ amountCents: { typ: 'integer', pflicht: false, min: 1, max: 100_000_000 },
385
+ paidAt: datum(),
386
+ reference: text(100),
387
+ },
346
388
  });
347
389
  /** Genau eines dieser Felder muss gesetzt sein (je Aufruf, je Gruppe). */
348
390
  exports.RECHNUNG_GENAU_EINS = Object.freeze({
@@ -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", "cancelInvoice", "cancelReceipt", "createCreditNote", "createCustomer", "createCustomerCashregister", "createPartnerCustomer", "checkPartnerCustomerEmail", "createPartnerWebhook", "createPaymentLinkStripe", "createPrintJob", "createReceipt", "deletePartnerWebhook", "downloadDailyReport", "downloadReport", "endRegisterSession", "financeWebService", "generateFullReceiptId", "getCustomer", "getCustomerCredentials", "getCustomerSignatureStatus", "getFirstReceiptDate", "getInvoice", "getInvoicePdf", "getInvoiceSetupStatus", "getInvoiceXml", "getKasseSettings", "getPartnerCustomer", "getPartnerInfo", "getPrintJob", "getReceipt", "hobexPayApi", "hobexRefundApi", "issueInvoice", "listCustomerCashregisters", "listInvoices", "listBrands", "listMyArticleGroups", "listMyArticles", "listMyCashregisters", "listMyPrinters", "listMyReceipts", "listMyTipRecipients", "listPartnerCustomers", "listPartnerWebhookDeliveries", "listPartnerWebhooks", "listRegisterUsersForDevice", "listRegisterSessionsForDevice", "pairRegisterDevice", "registerPinLogin", "registerUserLogin", "renewRegisterSession", "requestCustomerSignature", "searchCustomers", "sendPartnerCustomerFonLink", "sendPartnerWebhookTest", "sendReceiptEmail", "setMyKasseSettings", "setMyRegisterDeviceSettings", "stripeCaptureIntent", "unpairRegisterDevice", "rotatePartnerWebhookSecret", "updateCustomer", "updatePartnerWebhook"];
16
+ export declare const AUFRUFE: readonly ["activateCashregister", "cancelInvoice", "cancelReceipt", "createCreditNote", "createCustomer", "createCustomerCashregister", "createPartnerCustomer", "checkPartnerCustomerEmail", "createPartnerWebhook", "createPaymentLinkStripe", "createPrintJob", "createReceipt", "deletePartnerWebhook", "downloadDailyReport", "downloadReport", "endRegisterSession", "financeWebService", "generateFullReceiptId", "getCustomer", "getCustomerCredentials", "getCustomerSignatureStatus", "getFirstReceiptDate", "getInvoice", "getInvoicePdf", "getInvoiceSetupStatus", "getInvoiceXml", "getKasseSettings", "getPartnerCustomer", "getPartnerInfo", "getPrintJob", "getReceipt", "hobexPayApi", "hobexRefundApi", "issueInvoice", "listCustomerCashregisters", "listInvoices", "listBrands", "listMyArticleGroups", "listMyArticles", "listMyCashregisters", "listMyPrinters", "listMyReceipts", "listMyTipRecipients", "listPartnerCustomers", "listPartnerWebhookDeliveries", "listPartnerWebhooks", "listRegisterUsersForDevice", "listRegisterSessionsForDevice", "pairRegisterDevice", "recordInvoicePayment", "registerPinLogin", "registerUserLogin", "renewRegisterSession", "requestCustomerSignature", "searchCustomers", "sendPartnerCustomerFonLink", "sendPartnerWebhookTest", "sendReceiptEmail", "setMyKasseSettings", "setMyRegisterDeviceSettings", "stripeCaptureIntent", "unpairRegisterDevice", "rotatePartnerWebhookSecret", "updateCustomer", "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>;
@@ -48,6 +48,7 @@ export const AUFRUFE = [
48
48
  'listRegisterUsersForDevice',
49
49
  'listRegisterSessionsForDevice',
50
50
  'pairRegisterDevice',
51
+ 'recordInvoicePayment',
51
52
  'registerPinLogin',
52
53
  'registerUserLogin',
53
54
  'renewRegisterSession',
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { type FetchLike } from '../client/transport.js';
8
8
  import type { EInvoiceFormat, InvoiceLanguage } from './vertrag.js';
9
- import type { Brand, CancelInvoiceRequest, CancelResult, CreditNoteRequest, CreditNoteResult, Customer, CustomerInput, CustomerPage, CustomerSearch, InvoiceDetail, InvoiceListQuery, InvoicePage, InvoiceSetupStatus, IssueInvoiceRequest, IssueResult } from './typen.js';
9
+ import type { Brand, CancelInvoiceRequest, CancelResult, CreditNoteRequest, CreditNoteResult, Customer, CustomerInput, CustomerPage, CustomerSearch, InvoiceDetail, InvoiceListQuery, InvoicePage, InvoiceSetupStatus, IssueInvoiceRequest, IssueResult, RecordPaymentRequest, RecordPaymentResult } from './typen.js';
10
10
  export interface RechnungApiOptions {
11
11
  /** `api_key` des Kontos (`kr_live_…` / `kr_test_…`). Gehoert auf einen Server. */
12
12
  apiKey: string;
@@ -37,6 +37,8 @@ export interface RechnungApi {
37
37
  number: string;
38
38
  }): Promise<InvoiceDetail>;
39
39
  listInvoices(abfrage?: InvoiceListQuery): Promise<InvoicePage>;
40
+ /** Eine spaeter eingetroffene Zahlung nachtragen; `idempotencyKey` ist Pflicht. */
41
+ recordInvoicePayment(anfrage: RecordPaymentRequest): Promise<RecordPaymentResult>;
40
42
  /** Mit `language` ungleich der Rechnungssprache: gekennzeichnete Uebersetzungskopie. */
41
43
  getInvoicePdf(invoiceId: string, optionen?: {
42
44
  language?: InvoiceLanguage;
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { createBinaryTransport, createTransport } from '../client/transport.js';
8
8
  import { rechnungKeyAuth } from './auth.js';
9
- import { cancelInvoice, createCreditNote, createCustomer, getCustomer, getInvoice, getInvoicePdf, getInvoiceSetupStatus, getInvoiceXml, issueInvoice, listBrands, listInvoices, searchCustomers, updateCustomer, } from './endpunkte.js';
9
+ import { cancelInvoice, createCreditNote, createCustomer, getCustomer, getInvoice, getInvoicePdf, getInvoiceSetupStatus, getInvoiceXml, issueInvoice, listBrands, listInvoices, recordInvoicePayment, searchCustomers, updateCustomer, } from './endpunkte.js';
10
10
  export function createRechnungApi(optionen) {
11
11
  const transportOptionen = {
12
12
  auth: rechnungKeyAuth({ apiKey: optionen.apiKey }),
@@ -29,6 +29,7 @@ export function createRechnungApi(optionen) {
29
29
  getInvoicePdf: (id, o) => getInvoicePdf(rufenBinaer, id, o),
30
30
  getInvoiceXml: (id, format) => getInvoiceXml(rufen, id, format),
31
31
  getInvoiceSetupStatus: () => getInvoiceSetupStatus(rufen),
32
+ recordInvoicePayment: (anfrage) => recordInvoicePayment(rufen, anfrage),
32
33
  listBrands: () => listBrands(rufen),
33
34
  };
34
35
  }
@@ -18,7 +18,7 @@
18
18
  */
19
19
  import type { InternerBinaerTransport, InternerTransport } from '../client/aufrufe.js';
20
20
  import type { EInvoiceFormat, InvoiceLanguage } from './vertrag.js';
21
- import type { Brand, CancelInvoiceRequest, CancelResult, CreditNoteRequest, CreditNoteResult, Customer, CustomerInput, CustomerPage, CustomerSearch, InvoiceDetail, InvoiceListQuery, InvoicePage, InvoiceSetupStatus, IssueInvoiceRequest, IssueResult } from './typen.js';
21
+ import type { Brand, CancelInvoiceRequest, CancelResult, CreditNoteRequest, CreditNoteResult, Customer, CustomerInput, CustomerPage, CustomerSearch, InvoiceDetail, InvoiceListQuery, InvoicePage, InvoiceSetupStatus, IssueInvoiceRequest, IssueResult, RecordPaymentRequest, RecordPaymentResult } from './typen.js';
22
22
  export declare function createCustomer(rufen: InternerTransport, customer: CustomerInput, optionen?: {
23
23
  idempotencyKey?: string;
24
24
  }): Promise<Customer>;
@@ -53,6 +53,16 @@ export declare function getInvoiceSetupStatus(rufen: InternerTransport): Promise
53
53
  export declare function getInvoicePdf(rufenBinaer: InternerBinaerTransport, invoiceId: string, optionen?: {
54
54
  language?: InvoiceLanguage;
55
55
  }): Promise<Uint8Array>;
56
+ /**
57
+ * Eine Zahlung nachtragen, die nach dem Ausstellen eingetroffen ist
58
+ * (Ueberweisung, Teilzahlung). Der `idempotencyKey` ist Pflicht: ohne ihn
59
+ * bucht ein Wiederholungslauf nach einem Zeitlimit eine zweite Zahlung.
60
+ *
61
+ * Bei `method: 'cash'` wird die Zahlung gebucht und die Antwort traegt
62
+ * zusaetzlich `notice` — eine Barzahlung ist ein Barumsatz und braucht einen
63
+ * Beleg (§ 132a BAO), den dieser Vermerk nicht ersetzt.
64
+ */
65
+ export declare function recordInvoicePayment(rufen: InternerTransport, anfrage: RecordPaymentRequest): Promise<RecordPaymentResult>;
56
66
  /** Die Marken des Kontos — die Kennung geht als `brandId` in `issueInvoice`. */
57
67
  export declare function listBrands(rufen: InternerTransport): Promise<Brand[]>;
58
68
  /**
@@ -126,6 +126,27 @@ export function getInvoicePdf(rufenBinaer, invoiceId, optionen = {}) {
126
126
  params['language'] = optionen.language;
127
127
  return rufenBinaer('getInvoicePdf', params);
128
128
  }
129
+ /**
130
+ * Eine Zahlung nachtragen, die nach dem Ausstellen eingetroffen ist
131
+ * (Ueberweisung, Teilzahlung). Der `idempotencyKey` ist Pflicht: ohne ihn
132
+ * bucht ein Wiederholungslauf nach einem Zeitlimit eine zweite Zahlung.
133
+ *
134
+ * Bei `method: 'cash'` wird die Zahlung gebucht und die Antwort traegt
135
+ * zusaetzlich `notice` — eine Barzahlung ist ein Barumsatz und braucht einen
136
+ * Beleg (§ 132a BAO), den dieser Vermerk nicht ersetzt.
137
+ */
138
+ export async function recordInvoicePayment(rufen, anfrage) {
139
+ const daten = await rufen('recordInvoicePayment', nutzlast(anfrage));
140
+ const roh = objekt(daten);
141
+ const ergebnis = {
142
+ invoice: pflichtObjekt('recordInvoicePayment', daten, 'invoice'),
143
+ payment: pflichtObjekt('recordInvoicePayment', daten, 'payment'),
144
+ replayed: roh['replayed'] === true,
145
+ };
146
+ if (roh['notice'])
147
+ ergebnis.notice = roh['notice'];
148
+ return ergebnis;
149
+ }
129
150
  /** Die Marken des Kontos — die Kennung geht als `brandId` in `issueInvoice`. */
130
151
  export async function listBrands(rufen) {
131
152
  const brands = objekt(await rufen('listBrands', {}))['brands'];
@@ -13,7 +13,7 @@
13
13
  export { createRechnungApi, type RechnungApi, type RechnungApiOptions } from './api.js';
14
14
  export { rechnungKeyAuth, type RechnungKeyAuthOptions } from './auth.js';
15
15
  export { istRechnungFehler, rechnungFehlerCode, rechnungFeldFehler, type RechnungFeldFehler, } from './fehler.js';
16
- export { cancelInvoice, createCreditNote, createCustomer, getCustomer, getInvoice, getInvoicePdf, getInvoiceSetupStatus, getInvoiceXml, issueInvoice, listBrands, listInvoices, searchCustomers, updateCustomer, } from './endpunkte.js';
17
- export type { Brand, CancelInvoiceRequest, CancelResult, CreditNoteRequest, CreditNoteResult, Customer, CustomerInput, CustomerPage, CustomerSearch, EInvoiceStatus, Invoice, InvoiceDetail, InvoiceItem, InvoiceItemInput, InvoiceListQuery, InvoicePage, InvoiceRecipient, InvoiceSetupGap, InvoiceSetupStatus, InvoiceTotals, IssueInvoiceRequest, IssueResult, } from './typen.js';
16
+ export { cancelInvoice, createCreditNote, createCustomer, getCustomer, getInvoice, getInvoicePdf, getInvoiceSetupStatus, getInvoiceXml, issueInvoice, listBrands, listInvoices, recordInvoicePayment, searchCustomers, updateCustomer, } from './endpunkte.js';
17
+ export type { Brand, CancelInvoiceRequest, CancelResult, CreditNoteRequest, CreditNoteResult, Customer, CustomerInput, CustomerPage, CustomerSearch, EInvoiceStatus, Invoice, InvoiceDetail, InvoiceItem, InvoiceItemInput, InvoiceListQuery, InvoicePage, InvoiceRecipient, InvoiceSetupGap, InvoiceSetupStatus, InvoiceTotals, InvoiceNotice, InvoicePayment, IssueInvoiceRequest, IssueResult, PaymentInput, RecordPaymentRequest, RecordPaymentResult, } from './typen.js';
18
18
  export { RECHNUNG_TEXTE, rechnungText, type RechnungTextSchluessel } from './texte.js';
19
- export { RECHNUNG_VERTRAG_VERSION, RECHNUNG_AUFRUFE, INVOICE_ERROR_CODES, CREDIT_NOTE_REASONS, TAX_SCHEMES, PRICE_MODES, VAT_RATES, CUSTOMER_TYPES, INVOICE_LIST_STATUS, DOC_TYPES, EINVOICE_FORMATS, INVOICE_LANGUAGES, INVOICE_UNITS, RECHNUNG_EINHEITEN_CODES, INVOICE_SETUP_REQUIREMENTS, KUNDE_FELDER, POSITION_FELDER, RECHNUNG_ANFRAGEN, RECHNUNG_GENAU_EINS, RECHNUNG_MINDESTENS_EINS, type RechnungAufruf, type InvoiceErrorCode, type CreditNoteReason, type TaxScheme, type PriceMode, type VatRatePercent, type CustomerType, type InvoiceListStatus, type DocType, type EInvoiceFormat, type InvoiceLanguage, type InvoiceUnit, type InvoiceSetupRequirement, type Format, type Feld, } from './vertrag.js';
19
+ export { RECHNUNG_VERTRAG_VERSION, RECHNUNG_AUFRUFE, INVOICE_ERROR_CODES, CREDIT_NOTE_REASONS, TAX_SCHEMES, PRICE_MODES, VAT_RATES, CUSTOMER_TYPES, INVOICE_LIST_STATUS, DOC_TYPES, EINVOICE_FORMATS, INVOICE_LANGUAGES, INVOICE_PAYMENT_METHODS, INVOICE_NOTICE_CODES, INVOICE_UNITS, RECHNUNG_EINHEITEN_CODES, INVOICE_SETUP_REQUIREMENTS, KUNDE_FELDER, POSITION_FELDER, RECHNUNG_ANFRAGEN, RECHNUNG_GENAU_EINS, RECHNUNG_MINDESTENS_EINS, type RechnungAufruf, type InvoiceErrorCode, type CreditNoteReason, type TaxScheme, type PriceMode, type VatRatePercent, type CustomerType, type InvoiceListStatus, type DocType, type EInvoiceFormat, type InvoiceLanguage, type InvoicePaymentMethod, type InvoiceNoticeCode, type InvoiceUnit, type InvoiceSetupRequirement, type Format, type Feld, } from './vertrag.js';
@@ -13,6 +13,6 @@
13
13
  export { createRechnungApi } from './api.js';
14
14
  export { rechnungKeyAuth } from './auth.js';
15
15
  export { istRechnungFehler, rechnungFehlerCode, rechnungFeldFehler, } from './fehler.js';
16
- export { cancelInvoice, createCreditNote, createCustomer, getCustomer, getInvoice, getInvoicePdf, getInvoiceSetupStatus, getInvoiceXml, issueInvoice, listBrands, listInvoices, searchCustomers, updateCustomer, } from './endpunkte.js';
16
+ export { cancelInvoice, createCreditNote, createCustomer, getCustomer, getInvoice, getInvoicePdf, getInvoiceSetupStatus, getInvoiceXml, issueInvoice, listBrands, listInvoices, recordInvoicePayment, searchCustomers, updateCustomer, } from './endpunkte.js';
17
17
  export { RECHNUNG_TEXTE, rechnungText } from './texte.js';
18
- export { RECHNUNG_VERTRAG_VERSION, RECHNUNG_AUFRUFE, INVOICE_ERROR_CODES, CREDIT_NOTE_REASONS, TAX_SCHEMES, PRICE_MODES, VAT_RATES, CUSTOMER_TYPES, INVOICE_LIST_STATUS, DOC_TYPES, EINVOICE_FORMATS, INVOICE_LANGUAGES, INVOICE_UNITS, RECHNUNG_EINHEITEN_CODES, INVOICE_SETUP_REQUIREMENTS, KUNDE_FELDER, POSITION_FELDER, RECHNUNG_ANFRAGEN, RECHNUNG_GENAU_EINS, RECHNUNG_MINDESTENS_EINS, } from './vertrag.js';
18
+ export { RECHNUNG_VERTRAG_VERSION, RECHNUNG_AUFRUFE, INVOICE_ERROR_CODES, CREDIT_NOTE_REASONS, TAX_SCHEMES, PRICE_MODES, VAT_RATES, CUSTOMER_TYPES, INVOICE_LIST_STATUS, DOC_TYPES, EINVOICE_FORMATS, INVOICE_LANGUAGES, INVOICE_PAYMENT_METHODS, INVOICE_NOTICE_CODES, INVOICE_UNITS, RECHNUNG_EINHEITEN_CODES, INVOICE_SETUP_REQUIREMENTS, KUNDE_FELDER, POSITION_FELDER, RECHNUNG_ANFRAGEN, RECHNUNG_GENAU_EINS, RECHNUNG_MINDESTENS_EINS, } from './vertrag.js';
@@ -5,7 +5,7 @@
5
5
  * Betraege sind ueberall ganze Cent. Datumsangaben sind `YYYY-MM-DD` nach
6
6
  * Wiener Kalender.
7
7
  */
8
- import type { CreditNoteReason, CustomerType, DocType, InvoiceLanguage, InvoiceUnit, InvoiceSetupRequirement, InvoiceListStatus, PriceMode, TaxScheme, VatRatePercent } from './vertrag.js';
8
+ import type { CreditNoteReason, CustomerType, DocType, InvoiceLanguage, InvoiceNoticeCode, InvoicePaymentMethod, InvoiceUnit, InvoiceSetupRequirement, InvoiceListStatus, PriceMode, TaxScheme, VatRatePercent } from './vertrag.js';
9
9
  export interface CustomerInput {
10
10
  type: CustomerType;
11
11
  name: string;
@@ -102,6 +102,49 @@ export interface IssueInvoiceRequest {
102
102
  language?: InvoiceLanguage;
103
103
  /** Marke (Kennung aus `listBrands`); sonst die Standardmarke. Unbekannt = `brand_not_found`. */
104
104
  brandId?: string;
105
+ /**
106
+ * Schon bezahlt (Shop kassiert online, Rechnung folgt). Die Zahlung entsteht
107
+ * in derselben Transaktion wie das Festschreiben: das PDF traegt dann keine
108
+ * Zahlungsinformationen und keinen Giro-QR.
109
+ */
110
+ payment?: PaymentInput;
111
+ }
112
+ /** Eine Zahlung, wie das Fremdsystem sie meldet. */
113
+ export interface PaymentInput {
114
+ method: InvoicePaymentMethod;
115
+ /** Ohne Angabe der volle Bruttobetrag. */
116
+ amountCents?: number;
117
+ /** Ohne Angabe der heutige Wiener Tag; nie in der Zukunft. */
118
+ paidAt?: string;
119
+ /** Zahlungskennung des Fremdsystems — gespeichert, aber nicht gedruckt. */
120
+ reference?: string;
121
+ }
122
+ export interface RecordPaymentRequest extends PaymentInput {
123
+ /** Pflicht: ohne ihn bucht eine Wiederholung eine zweite Zahlung. */
124
+ idempotencyKey: string;
125
+ invoiceId: string;
126
+ }
127
+ /** Eine gebuchte Zahlung, wie die API sie zurueckgibt. */
128
+ export interface InvoicePayment {
129
+ id: string;
130
+ amountCents: number;
131
+ paidAt: string;
132
+ method: InvoicePaymentMethod;
133
+ reference: string | null;
134
+ }
135
+ /**
136
+ * Ein Hinweis zu einer erfolgreichen Antwort — kein Fehler, sondern etwas,
137
+ * das der Aufrufer wissen sollte (heute nur `cash_receipt_required`).
138
+ */
139
+ export interface InvoiceNotice {
140
+ code: InvoiceNoticeCode;
141
+ message: string;
142
+ }
143
+ export interface RecordPaymentResult {
144
+ invoice: Invoice;
145
+ payment: InvoicePayment;
146
+ replayed: boolean;
147
+ notice?: InvoiceNotice;
105
148
  }
106
149
  export interface CancelInvoiceRequest {
107
150
  idempotencyKey: string;
@@ -147,6 +190,10 @@ export interface Invoice {
147
190
  id: string | null;
148
191
  name: string | null;
149
192
  } | null;
193
+ /** Summe der gebuchten Zahlungen. */
194
+ paidCents: number;
195
+ /** Was noch offen ist; `0` heisst bezahlt. */
196
+ openCents: number;
150
197
  }
151
198
  /** Eine Marke des Kontos (Logo, Farbe, Absender) — `id` geht als `brandId` in `issueInvoice`. */
152
199
  export interface Brand {
@@ -18,13 +18,13 @@
18
18
  * Nummer, Summen — ist bewusst **nicht** setzbar.
19
19
  */
20
20
  export declare const RECHNUNG_VERTRAG_VERSION = 1;
21
- export declare const RECHNUNG_AUFRUFE: readonly ["createCustomer", "getCustomer", "updateCustomer", "searchCustomers", "issueInvoice", "cancelInvoice", "createCreditNote", "getInvoice", "listInvoices", "getInvoicePdf", "getInvoiceXml", "getInvoiceSetupStatus", "listBrands"];
21
+ export declare const RECHNUNG_AUFRUFE: readonly ["createCustomer", "getCustomer", "updateCustomer", "searchCustomers", "issueInvoice", "cancelInvoice", "createCreditNote", "getInvoice", "listInvoices", "getInvoicePdf", "getInvoiceXml", "getInvoiceSetupStatus", "listBrands", "recordInvoicePayment"];
22
22
  export type RechnungAufruf = (typeof RECHNUNG_AUFRUFE)[number];
23
23
  /**
24
24
  * Stabile Fehlercodes. Das Fremdsystem verzweigt am Code, der Text darf sich
25
25
  * aendern. `validation` traegt zusaetzlich `errors: [{ field, message }]`.
26
26
  */
27
- export declare const INVOICE_ERROR_CODES: readonly ["validation", "idempotency_conflict", "module_inactive", "customer_not_found", "customer_exists", "short_code_taken", "short_code_immutable", "recipient_required", "invoice_requirements_missing", "invoice_not_found", "invoice_ambiguous", "not_cancellable", "partial_credit_exists", "credit_exceeds_invoice", "einvoice_incomplete", "invoice_api_not_enabled", "invoice_setup_incomplete", "language_not_allowed", "brand_not_found"];
27
+ export declare const INVOICE_ERROR_CODES: readonly ["validation", "idempotency_conflict", "module_inactive", "customer_not_found", "customer_exists", "short_code_taken", "short_code_immutable", "recipient_required", "invoice_requirements_missing", "invoice_not_found", "invoice_ambiguous", "not_cancellable", "partial_credit_exists", "credit_exceeds_invoice", "einvoice_incomplete", "invoice_api_not_enabled", "invoice_setup_incomplete", "language_not_allowed", "brand_not_found", "not_payable", "payment_exceeds_invoice"];
28
28
  export type InvoiceErrorCode = (typeof INVOICE_ERROR_CODES)[number];
29
29
  /** Gruende einer Gutschrift. Der Server druckt den deutschen Anzeigetext. */
30
30
  export declare const CREDIT_NOTE_REASONS: readonly ["cancellation", "price_reduction", "return", "incorrect_invoice", "other"];
@@ -51,6 +51,20 @@ export type EInvoiceFormat = (typeof EINVOICE_FORMATS)[number];
51
51
  */
52
52
  export declare const INVOICE_LANGUAGES: readonly ["de", "en"];
53
53
  export type InvoiceLanguage = (typeof INVOICE_LANGUAGES)[number];
54
+ /**
55
+ * Wie eine Rechnung bezahlt wurde. Der Vermerk ist Buchhaltung, kein Beleg:
56
+ * `cash` wird gebucht, die Antwort traegt dann zusaetzlich den Hinweis
57
+ * `cash_receipt_required` — eine Barzahlung ist ein Barumsatz und braucht
58
+ * einen Beleg (§ 132a BAO), bei Registrierkassenpflicht ueber die Kasse.
59
+ */
60
+ export declare const INVOICE_PAYMENT_METHODS: readonly ["transfer", "card", "online", "cash"];
61
+ export type InvoicePaymentMethod = (typeof INVOICE_PAYMENT_METHODS)[number];
62
+ /**
63
+ * Hinweise, die eine erfolgreiche Antwort zusaetzlich tragen kann (`data.notice`).
64
+ * Sie sind keine Fehler: der Aufruf hat gewirkt, es gibt nur etwas zu wissen.
65
+ */
66
+ export declare const INVOICE_NOTICE_CODES: readonly ["cash_receipt_required"];
67
+ export type InvoiceNoticeCode = (typeof INVOICE_NOTICE_CODES)[number];
54
68
  /**
55
69
  * Einheiten einer Position. Die API nimmt nur diese Schluessel an; gedruckt
56
70
  * wird das Kuerzel in der Sprache der Rechnung (`RECHNUNG_TEXTE`,
@@ -129,6 +143,14 @@ export type Feld = {
129
143
  export declare const KUNDE_FELDER: Readonly<Record<string, Feld>>;
130
144
  /** Eine Rechnungs- oder Gutschriftsposition. Preise in ganzen Cent. */
131
145
  export declare const POSITION_FELDER: Readonly<Record<string, Feld>>;
146
+ /**
147
+ * Eine Zahlung zu einer Rechnung. Ohne `amountCents` gilt der volle
148
+ * Bruttobetrag, ohne `paidAt` der heutige Wiener Tag. `reference` ist die
149
+ * Zahlungskennung des Fremdsystems (z. B. `pi_3Q...`) — sie wird gespeichert,
150
+ * aber **nicht gedruckt**: die Rechnung wird aufbewahrt und vervielfaeltigt,
151
+ * und dem Empfaenger nuetzt sie nichts.
152
+ */
153
+ export declare const PAYMENT_FELDER: Readonly<Record<string, Feld>>;
132
154
  export declare const RECHNUNG_ANFRAGEN: Readonly<Record<RechnungAufruf, Readonly<Record<string, Feld>>>>;
133
155
  /** Genau eines dieser Felder muss gesetzt sein (je Aufruf, je Gruppe). */
134
156
  export declare const RECHNUNG_GENAU_EINS: Readonly<Partial<Record<RechnungAufruf, readonly (readonly string[])[]>>>;
@@ -32,6 +32,7 @@ export const RECHNUNG_AUFRUFE = [
32
32
  'getInvoiceXml',
33
33
  'getInvoiceSetupStatus',
34
34
  'listBrands',
35
+ 'recordInvoicePayment',
35
36
  ];
36
37
  /**
37
38
  * Stabile Fehlercodes. Das Fremdsystem verzweigt am Code, der Text darf sich
@@ -57,6 +58,8 @@ export const INVOICE_ERROR_CODES = [
57
58
  'invoice_setup_incomplete',
58
59
  'language_not_allowed',
59
60
  'brand_not_found',
61
+ 'not_payable',
62
+ 'payment_exceeds_invoice',
60
63
  ];
61
64
  /** Gruende einer Gutschrift. Der Server druckt den deutschen Anzeigetext. */
62
65
  export const CREDIT_NOTE_REASONS = [
@@ -80,6 +83,18 @@ export const EINVOICE_FORMATS = ['ubl', 'cii'];
80
83
  * oesterreichisch formatiert.
81
84
  */
82
85
  export const INVOICE_LANGUAGES = ['de', 'en'];
86
+ /**
87
+ * Wie eine Rechnung bezahlt wurde. Der Vermerk ist Buchhaltung, kein Beleg:
88
+ * `cash` wird gebucht, die Antwort traegt dann zusaetzlich den Hinweis
89
+ * `cash_receipt_required` — eine Barzahlung ist ein Barumsatz und braucht
90
+ * einen Beleg (§ 132a BAO), bei Registrierkassenpflicht ueber die Kasse.
91
+ */
92
+ export const INVOICE_PAYMENT_METHODS = ['transfer', 'card', 'online', 'cash'];
93
+ /**
94
+ * Hinweise, die eine erfolgreiche Antwort zusaetzlich tragen kann (`data.notice`).
95
+ * Sie sind keine Fehler: der Aufruf hat gewirkt, es gibt nur etwas zu wissen.
96
+ */
97
+ export const INVOICE_NOTICE_CODES = ['cash_receipt_required'];
83
98
  /**
84
99
  * Einheiten einer Position. Die API nimmt nur diese Schluessel an; gedruckt
85
100
  * wird das Kuerzel in der Sprache der Rechnung (`RECHNUNG_TEXTE`,
@@ -261,6 +276,19 @@ export const POSITION_FELDER = Object.freeze({
261
276
  discountPct: { typ: 'number', pflicht: false, min: 0, max: 100, nachkomma: 2 },
262
277
  });
263
278
  const positionen = { typ: 'list', pflicht: true, min: 1, max: 500, eintrag: { typ: 'object', pflicht: true, felder: POSITION_FELDER } };
279
+ /**
280
+ * Eine Zahlung zu einer Rechnung. Ohne `amountCents` gilt der volle
281
+ * Bruttobetrag, ohne `paidAt` der heutige Wiener Tag. `reference` ist die
282
+ * Zahlungskennung des Fremdsystems (z. B. `pi_3Q...`) — sie wird gespeichert,
283
+ * aber **nicht gedruckt**: die Rechnung wird aufbewahrt und vervielfaeltigt,
284
+ * und dem Empfaenger nuetzt sie nichts.
285
+ */
286
+ export const PAYMENT_FELDER = Object.freeze({
287
+ method: { typ: 'enum', pflicht: true, werte: INVOICE_PAYMENT_METHODS },
288
+ amountCents: { typ: 'integer', pflicht: false, min: 1, max: 100_000_000 },
289
+ paidAt: datum(),
290
+ reference: text(100),
291
+ });
264
292
  export const RECHNUNG_ANFRAGEN = Object.freeze({
265
293
  createCustomer: {
266
294
  customer: { typ: 'object', pflicht: true, felder: KUNDE_FELDER },
@@ -302,6 +330,12 @@ export const RECHNUNG_ANFRAGEN = Object.freeze({
302
330
  language: { typ: 'enum', pflicht: false, werte: INVOICE_LANGUAGES },
303
331
  /** Marke (Kennung aus `listBrands`); sonst die Standardmarke. */
304
332
  brandId: id,
333
+ /**
334
+ * Schon bezahlt: die Zahlung entsteht in **derselben** Transaktion wie das
335
+ * Festschreiben. Sonst gaebe es einen Moment, in dem die Rechnung offen ist
336
+ * und ein sofort geholtes PDF Zahlungsinformationen traegt.
337
+ */
338
+ payment: { typ: 'object', pflicht: false, felder: PAYMENT_FELDER },
305
339
  },
306
340
  cancelInvoice: {
307
341
  idempotencyKey: idempotencyKey(true),
@@ -340,6 +374,14 @@ export const RECHNUNG_ANFRAGEN = Object.freeze({
340
374
  },
341
375
  getInvoiceSetupStatus: {},
342
376
  listBrands: {},
377
+ recordInvoicePayment: {
378
+ idempotencyKey: idempotencyKey(true),
379
+ invoiceId: idPflicht,
380
+ method: { typ: 'enum', pflicht: true, werte: INVOICE_PAYMENT_METHODS },
381
+ amountCents: { typ: 'integer', pflicht: false, min: 1, max: 100_000_000 },
382
+ paidAt: datum(),
383
+ reference: text(100),
384
+ },
343
385
  });
344
386
  /** Genau eines dieser Felder muss gesetzt sein (je Aufruf, je Gruppe). */
345
387
  export const RECHNUNG_GENAU_EINS = Object.freeze({
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.17.0",
2
+ "version": "0.18.0",
3
3
  "gemessenAn": {
4
4
  "tid": "3600335",
5
5
  "hpsVersion": "1.10.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.17.0",
2
+ "version": "0.18.0",
3
3
  "meldungen": {
4
4
  "netz.keine_verbindung": {
5
5
  "text": "Keine Verbindung zum Server. Bitte die Internetverbindung prüfen und erneut versuchen."
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.17.0",
2
+ "version": "0.18.0",
3
3
  "aufrufe": [
4
4
  "activateCashregister",
5
5
  "cancelInvoice",
@@ -50,6 +50,7 @@
50
50
  "listRegisterUsersForDevice",
51
51
  "listRegisterSessionsForDevice",
52
52
  "pairRegisterDevice",
53
+ "recordInvoicePayment",
53
54
  "registerPinLogin",
54
55
  "registerUserLogin",
55
56
  "renewRegisterSession",
@@ -401,7 +402,9 @@
401
402
  "invoice_api_not_enabled",
402
403
  "invoice_setup_incomplete",
403
404
  "language_not_allowed",
404
- "brand_not_found"
405
+ "brand_not_found",
406
+ "not_payable",
407
+ "payment_exceeds_invoice"
405
408
  ],
406
409
  "invoiceLanguages": [
407
410
  "de",
@@ -414,6 +417,15 @@
414
417
  "open",
415
418
  "overdue"
416
419
  ],
420
+ "invoiceNoticeCodes": [
421
+ "cash_receipt_required"
422
+ ],
423
+ "invoicePaymentMethods": [
424
+ "transfer",
425
+ "card",
426
+ "online",
427
+ "cash"
428
+ ],
417
429
  "invoiceSetupRequirements": [
418
430
  "module_active",
419
431
  "api_enabled",
@@ -492,7 +504,8 @@
492
504
  "getInvoicePdf",
493
505
  "getInvoiceXml",
494
506
  "getInvoiceSetupStatus",
495
- "listBrands"
507
+ "listBrands",
508
+ "recordInvoicePayment"
496
509
  ],
497
510
  "taxSchemes": [
498
511
  "normal",
@@ -0,0 +1,32 @@
1
+ {
2
+ "aufruf": "issueInvoice",
3
+ "beschreibung": "Shop kassiert per Karte, Rechnung entsteht bezahlt",
4
+ "anfrage": {
5
+ "idempotencyKey": "bsp-bezahlt",
6
+ "customerId": "kunde_beispiel",
7
+ "taxScheme": "normal",
8
+ "priceMode": "net",
9
+ "serviceStart": "2026-09-16",
10
+ "items": [
11
+ {
12
+ "description": "Beratung",
13
+ "quantity": 2,
14
+ "unitPriceCents": 5000,
15
+ "vatRate": 20,
16
+ "unit": "hour"
17
+ }
18
+ ],
19
+ "payment": {
20
+ "method": "card",
21
+ "reference": "pi_3QbeispielXYZ"
22
+ }
23
+ },
24
+ "erwartet": {
25
+ "ok": true,
26
+ "totals": {
27
+ "netCents": 10000,
28
+ "vatCents": 2000,
29
+ "grossCents": 12000
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "aufruf": "issueInvoice",
3
+ "beschreibung": "Unbekannte Zahlungsart",
4
+ "anfrage": {
5
+ "idempotencyKey": "bsp-zahlungsart",
6
+ "taxScheme": "normal",
7
+ "priceMode": "net",
8
+ "serviceStart": "2026-09-16",
9
+ "items": [
10
+ {
11
+ "description": "Beratung",
12
+ "quantity": 1,
13
+ "unitPriceCents": 5000,
14
+ "vatRate": 20
15
+ }
16
+ ],
17
+ "payment": {
18
+ "method": "bitcoin"
19
+ }
20
+ },
21
+ "erwartet": {
22
+ "ok": false,
23
+ "code": "validation",
24
+ "fields": ["payment.method"]
25
+ }
26
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "aufruf": "recordInvoicePayment",
3
+ "beschreibung": "Ohne Idempotenz-Schluessel — eine Wiederholung wuerde zweimal buchen",
4
+ "anfrage": {
5
+ "invoiceId": "rechnung_beispiel",
6
+ "method": "transfer",
7
+ "amountCents": 12000
8
+ },
9
+ "erwartet": {
10
+ "ok": false,
11
+ "code": "validation",
12
+ "fields": ["idempotencyKey"]
13
+ }
14
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "aufruf": "recordInvoicePayment",
3
+ "beschreibung": "Ueberweisung trifft spaeter ein",
4
+ "anfrage": {
5
+ "idempotencyKey": "bsp-zahlung-1",
6
+ "invoiceId": "rechnung_beispiel",
7
+ "method": "transfer",
8
+ "amountCents": 12000,
9
+ "paidAt": "2026-09-20"
10
+ },
11
+ "erwartet": {
12
+ "ok": true
13
+ }
14
+ }
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "title": "Kasseneck Rechnungs-API",
4
4
  "version": 1,
5
- "paket": "0.17.0",
5
+ "paket": "0.18.0",
6
6
  "aufrufe": {
7
7
  "createCustomer": {
8
8
  "anfrage": {
@@ -464,6 +464,38 @@
464
464
  "type": "string",
465
465
  "minLength": 1,
466
466
  "maxLength": 128
467
+ },
468
+ "payment": {
469
+ "type": "object",
470
+ "properties": {
471
+ "method": {
472
+ "enum": [
473
+ "transfer",
474
+ "card",
475
+ "online",
476
+ "cash"
477
+ ]
478
+ },
479
+ "amountCents": {
480
+ "type": "integer",
481
+ "minimum": 1,
482
+ "maximum": 100000000
483
+ },
484
+ "paidAt": {
485
+ "type": "string",
486
+ "minLength": 10,
487
+ "maxLength": 10,
488
+ "format": "date"
489
+ },
490
+ "reference": {
491
+ "type": "string",
492
+ "maxLength": 100
493
+ }
494
+ },
495
+ "required": [
496
+ "method"
497
+ ],
498
+ "additionalProperties": false
467
499
  }
468
500
  },
469
501
  "required": [
@@ -784,6 +816,52 @@
784
816
  "properties": {},
785
817
  "additionalProperties": false
786
818
  }
819
+ },
820
+ "recordInvoicePayment": {
821
+ "anfrage": {
822
+ "type": "object",
823
+ "properties": {
824
+ "idempotencyKey": {
825
+ "type": "string",
826
+ "minLength": 1,
827
+ "maxLength": 120
828
+ },
829
+ "invoiceId": {
830
+ "type": "string",
831
+ "minLength": 1,
832
+ "maxLength": 128
833
+ },
834
+ "method": {
835
+ "enum": [
836
+ "transfer",
837
+ "card",
838
+ "online",
839
+ "cash"
840
+ ]
841
+ },
842
+ "amountCents": {
843
+ "type": "integer",
844
+ "minimum": 1,
845
+ "maximum": 100000000
846
+ },
847
+ "paidAt": {
848
+ "type": "string",
849
+ "minLength": 10,
850
+ "maxLength": 10,
851
+ "format": "date"
852
+ },
853
+ "reference": {
854
+ "type": "string",
855
+ "maxLength": 100
856
+ }
857
+ },
858
+ "required": [
859
+ "idempotencyKey",
860
+ "invoiceId",
861
+ "method"
862
+ ],
863
+ "additionalProperties": false
864
+ }
787
865
  }
788
866
  },
789
867
  "codes": [
@@ -805,7 +883,9 @@
805
883
  "invoice_api_not_enabled",
806
884
  "invoice_setup_incomplete",
807
885
  "language_not_allowed",
808
- "brand_not_found"
886
+ "brand_not_found",
887
+ "not_payable",
888
+ "payment_exceeds_invoice"
809
889
  ],
810
890
  "gruende": [
811
891
  "cancellation",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.17.0",
2
+ "version": "0.18.0",
3
3
  "sprachen": [
4
4
  "de",
5
5
  "en"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kreiseck/kasseneck-api",
3
- "version": "0.17.0",
3
+ "version": "0.18.0",
4
4
  "description": "RKSV-Registrierkasse fuer JavaScript und TypeScript: signierte Belege, Storno, Kartenzahlung, Bondruck. Austrian fiscal cash register (RKSV) API client.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Kreiseck",