@kreiseck/kasseneck-api 0.27.3 → 0.29.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 (36) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/README.md +87 -2
  3. package/dist/cjs/partner/ablauf.d.ts +4 -3
  4. package/dist/cjs/partner/ablauf.js +4 -3
  5. package/dist/cjs/partner/api.d.ts +20 -8
  6. package/dist/cjs/partner/api.js +12 -1
  7. package/dist/cjs/partner/endpunkte.d.ts +9 -12
  8. package/dist/cjs/partner/endpunkte.js +85 -26
  9. package/dist/cjs/partner/fehler.d.ts +28 -2
  10. package/dist/cjs/partner/fehler.js +58 -9
  11. package/dist/cjs/partner/index.d.ts +7 -3
  12. package/dist/cjs/partner/index.js +7 -2
  13. package/dist/cjs/partner/typen.d.ts +152 -35
  14. package/dist/cjs/partner/typen.js +4 -0
  15. package/dist/cjs/partner/webhooks.d.ts +76 -14
  16. package/dist/cjs/partner/webhooks.js +40 -12
  17. package/dist/esm/partner/ablauf.d.ts +4 -3
  18. package/dist/esm/partner/ablauf.js +4 -3
  19. package/dist/esm/partner/api.d.ts +20 -8
  20. package/dist/esm/partner/api.js +11 -1
  21. package/dist/esm/partner/endpunkte.d.ts +9 -12
  22. package/dist/esm/partner/endpunkte.js +85 -26
  23. package/dist/esm/partner/fehler.d.ts +28 -2
  24. package/dist/esm/partner/fehler.js +58 -9
  25. package/dist/esm/partner/index.d.ts +7 -3
  26. package/dist/esm/partner/index.js +5 -1
  27. package/dist/esm/partner/typen.d.ts +152 -35
  28. package/dist/esm/partner/typen.js +4 -0
  29. package/dist/esm/partner/webhooks.d.ts +76 -14
  30. package/dist/esm/partner/webhooks.js +40 -12
  31. package/fixtures/hobex-hps-codes.json +1 -1
  32. package/fixtures/kasse-texte.json +1 -1
  33. package/fixtures/oberflaeche.json +12 -4
  34. package/fixtures/rechnung-api.schema.json +1 -1
  35. package/fixtures/rechnung-texte.json +1 -1
  36. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,100 @@ 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.29.0
8
+
9
+ - **Bricht `./partner` (und nur das): `PARTNER_FEHLER_CODES` ist jetzt durchgehend englisch,
10
+ wie der Rest von `/v3`.** `zugang_nicht_erlaubt` → `access_not_allowed`, `kennung_fehlt` →
11
+ `tax_number_missing`, `vertrag_offen` → `contracts_pending` (Sätze unverändert, nur der
12
+ Schlüssel neu); die `RAT`-Tabelle und `partnerFehlerRat` folgen. Grund: 0.28.0 stellte den
13
+ Partner-Teil auf `/v3` um, liess aber ein paar Codes, die der Server bis dahin noch roh
14
+ durchreichte, unuebersetzt in ihrer `/v1`-Schreibweise stehen (siehe dessen Eintrag "Die
15
+ Fehlercodes bleiben in dieser Stufe wie in `/v1`"): der Server schickt seit dieser Version
16
+ wirklich nur noch englische Codes, und dieses Paket folgt.
17
+ - **`PARTNER_FEHLER_CODES` um neun Codes von `reportCustomerContract` ergänzt**: `kind_not_allowed`,
18
+ `mode_not_allowed`, `power_of_attorney_missing`, `not_found`, `no_version`, `not_required`,
19
+ `unknown_version`, `text_changed`, `already_accepted`, mit Handlungssatz. Der Katalog des
20
+ Backends (`partner-core.FEHLER_KATALOG`, Fläche `api`/`beide`) führt sie für die Schnittstelle,
21
+ obwohl dieses Paket `reportCustomerContract` selbst nicht anbietet: derselbe Grund wie bei den
22
+ Portal-Codes: eine halbe Liste ist schlimmer als keine, und ein Code, den nur eine Seite kennt,
23
+ ist für einen Aufrufer nicht von "gibt es nicht" zu unterscheiden.
24
+ - **`kein_partnerbetrieb` und `request_not_found` aus `PARTNER_FEHLER_CODES` entfernt.** Beide sind
25
+ admin-only (`partner-endpoints.js`) und stehen gar nicht in `partner-core.FEHLER_KATALOG`; ein
26
+ Partner-Aufruf konnte sie unter keinem Pfad je bekommen. Sie standen seit jeher versehentlich in
27
+ der Liste; ein Aufrufer, der auf sie prüfte, prüfte auf einen Fall, der nie eintritt.
28
+ - `module_inactive`s Handlungssatz nennt jetzt `data.module`/`data.detail` statt `data.modul` (die
29
+ Werte selbst, z. B. `cash_register`, waren mit 0.28.0 schon englisch, nur der Text hier hinkte
30
+ nach).
31
+ - Neuer Typ `SignatureErrorCode` (`customer_not_found` | `incomplete` | `finanzonline_error`) für
32
+ `SignaturAntrag.error.code` und `CustomerSignature.error.code` (bisher `string | null` ohne
33
+ jeden Hinweis auf die möglichen Werte), nach demselben Muster wie `SignatureHistoryReason`.
34
+ - `PartnerFeldFehler.field`s Beispiele sind nicht mehr `address.land`/`tax_details.ustid` (Namen,
35
+ die `/v3` als unbekanntes Feld abweist), sondern echte `/v3`-Pfade: `address.zip`,
36
+ `taxDetails.taxNumber`, `contacts.0.email`.
37
+ - Die Tests lesen wieder echte `/v3`-Fehlerantworten: `scripts/partner-v3-antworten.cjs` schickt
38
+ jeden Code aus `fehlerKatalogFuer('api')` jetzt durch denselben Fehlerzweig wie eine echte
39
+ Antwort (`antwortNachAussen` statt der rohen Katalogwerte), und `getCustomerSignatureStatus`
40
+ trägt in der Fixture einen zweiten, fehlgeschlagenen Antrag (`fon_fehler` → `finanzonline_error`)
41
+ als Beleg dafür, dass `request.error.code` denselben Rand durchläuft wie jede Fehlerhülle.
42
+
43
+ ## 0.28.0
44
+
45
+ - **Bricht `./partner` (und nur das): der Partner-Teil spricht jetzt die englische Partner-API
46
+ `/v3`.** Vorgabe-Adresse ist `PARTNER_BASE_URL` (`https://api.kasseneck.at/v3`), `baseUrl` bleibt
47
+ einstellbar. Grund: das Backend führt die Partner-API ab `/v3` durchgehend englisch (Feldnamen
48
+ und jeder Wert, auf den ein Programm verzweigt), `/v1` ist abgekündigt (Kopfzeilen `Deprecation`
49
+ und `Sunset`). `/v3` weist die deutschen Werte der `/v1` mit `validation` ab statt sie still zu
50
+ übersetzen; ein Client, der weiter `einzel` oder `wien` schickt, bekäme nur noch Fehler.
51
+ Minor-Sprung, weil 0.x: wer `./partner` benutzt, muss umstellen, alles andere nicht.
52
+ - Umbenannte Werte (alt → neu): `legalForm` `einzel`/`verein`/`sonstige` →
53
+ `sole_proprietor`/`association`/`other`; `state` `burgenland` … `wien` → `AT-1` … `AT-9`;
54
+ Kontaktrollen `geschaeftsfuehrung`/`buchhaltung`/`technik`/`kasse` →
55
+ `management`/`accounting`/`technical`/`pos`; `avv.mode` `direkt`/`vollmacht`/`unterauftrag` →
56
+ `direct`/`power_of_attorney`/`subprocessor`; Entgelt `entgelt {cents, rhythmus, test}` →
57
+ `fee {cents, interval, test}` mit `monthly`/`yearly`/`once` (neu gelesen an
58
+ `createPartnerCustomer` und `requestCustomerSignature`); Historiengründe
59
+ `karte_eingetragen`/`fon` → `card_entered`/`finanzonline`; Zustellstatus
60
+ `zugestellt`/`offen`/`fehlgeschlagen`/`verworfen` → `delivered`/`pending`/`failed`/`dropped`;
61
+ `deletePartnerWebhook` liefert `{ webhookId, deleted }` statt nur der Kennung; Ereignisse
62
+ `customer.terms_accepted`/`customer.avv_accepted` mit `kind` `terms`/`avv` und den englischen
63
+ Quellen (`setup_link`, `process_link`, `partner_power_of_attorney`, `admin_paper`,
64
+ `paper_upload`), beschrieben durch den neuen Typ `ContractAcceptedEventData`.
65
+ - Neue englische Typen `LegalForm`, `AustrianState`, `ContactRole`, `AvvMode`, `FeeInterval`,
66
+ `PartnerFee`, `SignatureHistoryReason`, `WebhookApiVersion`, `WebhookDeliveryStatus`;
67
+ `Rechtsform`, `Bundesland` und `KontaktRolle` bleiben als veraltete Aliase.
68
+ - **Webhooks tragen `apiVersion`** (`v1` oder `v3`; fehlt es, ist es ein Bestands-Webhook und damit
69
+ `v1`). Die Sprache der Nutzlast folgt dem Webhook, nicht dem Pfad: ein unter `/v1` angelegter
70
+ schickt weiter deutsch, bis er mit `updatePartnerWebhook(id, { apiVersion: 'v3' })` umgestellt
71
+ wird; zurück gibt es nicht. `lastDelivery` ist jetzt das Objekt `{ at, status, statusCode }`,
72
+ das der Server schon immer schickte (der Typ sagte `number`).
73
+ - Dabei berichtigt, was schon unter `/v1` englisch war und hier noch deutsch gelesen wurde (und
74
+ darum leer blieb): `getCustomerSignatureStatus` liest `signature` statt `signatur` und neu
75
+ `signatures[]` und `customerId`; ein Antrag trägt `kind` statt `art`, die Historie `from`/`to`
76
+ statt `von`/`nach`; `requestCustomerSignature` sendet `kind` statt `art`;
77
+ `sendPartnerWebhookTest` liest `event` statt `ereignis`; Zustellungen tragen
78
+ `lastAttemptAt`/`nextAttemptAt`; `BetriebSteuer.uid` heißt `vatId` (ein `uid` wies der Server
79
+ als unbekanntes Feld ab); Kassenschritt `signature` statt `signatur`, Kassenstatus
80
+ `in_progress` statt `laeuft`.
81
+ - **`PARTNER_FEHLER_CODES` um `kennung_fehlt` und `vertrag_offen` ergänzt**, beide mit
82
+ Handlungssatz. Grund: der Katalog des Backends (`partner-core.FEHLER_KATALOG`, Fläche `beide`)
83
+ führt sie für die Schnittstelle; `kennung_fehlt` kommt aus `sendPartnerCustomerFonLink`,
84
+ `vertrag_offen` live aus `activateCashregister`. Ein Code, den das Paket nicht kennt, sah für
85
+ einen Aufrufer aus wie „gibt es nicht“.
86
+ - **Liste und Einzelsicht eines Betriebs führen `fon`, `avv` und `terms`** in der Form, die der
87
+ Server schickt (`VertragStand`, `KundenFonStand`; die Einzelsicht zusätzlich `verifiedAt` und
88
+ `linkSentTo`). Fehlen sie in der Antwort, bleibt es bei `null`. Der Kommentar an `AvvStand`
89
+ behauptete, Verträge wirkten im Partner-Weg nicht mehr; tatsächlich geht live ohne AVV und
90
+ Nutzungsvertrag keine Kasse live (`vertrag_offen`). Berichtigt, ebenso in `ablauf.ts`.
91
+ - `check:erreichbar` prüft die Partner-Aufrufe unter `/v3` (abgelesen aus der Partner-Fassade des
92
+ Baus), alles andere weiter unter `/v1`. Ein `not_found` aus JSON gilt nicht mehr als erreichbar:
93
+ unter `/v3` antwortet der Rand auf einen nicht gerouteten Namen selbst mit JSON.
94
+ - **Unverändert:** Belege, Rechnungen, Kasse, Druck, Zahlungen und React sprechen weiter `/v1`
95
+ (`DEFAULT_BASE_URL`), bis es dort eine `/v3` gibt. Die Fehlercodes bleiben in dieser Stufe wie
96
+ in `/v1`, ebenso die Prüfung der Webhook-Signatur. `reportCustomerVertrag` (unter `/v3`
97
+ `reportCustomerContract`) führt dieses Paket nicht und bekommt es auch jetzt nicht.
98
+ - Die Tests lesen echte `/v3`-Antworten: `test/fixtures/partner-v3-antworten.json` entsteht aus
99
+ den Sichten des Backends, durch dessen `/v3`-Rand gereicht (`scripts/partner-v3-antworten.cjs`).
100
+
7
101
  ## 0.27.3
8
102
 
9
103
  - **`rechnungSummen` ist als veraltet markiert** (`@deprecated`), das Rechenergebnis bleibt
package/README.md CHANGED
@@ -167,7 +167,7 @@ adapter:
167
167
  | `…/payments` | Stripe payment links, Hobex cloud (both HTTP endpoints of the backend), and Hobex **HPS** via **Kasseneck Connect** (local device agent that talks to the terminal). |
168
168
  | `…/register` | Sign-in for the browser register: pair and unpair a device, list its users and sessions, sign in by PIN, renew and end the session. |
169
169
  | `…/kasse` | Tile register: register settings (business-wide and per device), article groups and articles for tiles, discount distribution per VAT rate, scopes of register permissions, network printers and print jobs, tip recipients, the register's message catalogue. |
170
- | `…/partner` | Partner API: create businesses, FinanzOnline link, signature, cash registers, credentials, webhooks with signature verification. **Belongs on a server.** |
170
+ | `…/partner` | Partner API (`/v3`, English): create businesses, FinanzOnline link, signature, cash registers, credentials, webhooks with signature verification. **Belongs on a server.** |
171
171
  | `…/rechnung` | Invoice API: create and search customers, issue finalised invoices, credit notes and cancellation, PDF and e-invoice XML, the contract as data. **Belongs on a server.** |
172
172
  | `…/rechnung/rechnen` | Pure calculation core for invoice totals (integers, no transport, no dependency beyond types). Safe to run in the browser. |
173
173
  | `…/react` | Thin React adapter that renders a receipt layout or a receipt sheet. Needs React. |
@@ -537,6 +537,14 @@ receipts on their behalf.
537
537
  The partner key (`pk_live_…`) belongs on a **server**. It can create
538
538
  businesses and, with the extra scope `credentials:read`, fetch their secrets.
539
539
 
540
+ This subpath talks to the English Partner API **`/v3`**
541
+ (`PARTNER_BASE_URL`, `https://api.kasseneck.at/v3`): every field name and
542
+ every value your code branches on is English, including every error code
543
+ (`PARTNER_FEHLER_CODES`). Texts for humans (`message`, `note`, `statusText`,
544
+ `nextSteps`) stay German. Everything else in this package (receipts,
545
+ invoices, the register, printing, payments) still uses `/v1`
546
+ (`DEFAULT_BASE_URL`) until those endpoints have a `/v3` of their own.
547
+
540
548
  ```ts
541
549
  import { createPartnerApi, istPartnerFehler } from '@kreiseck/kasseneck-api/partner';
542
550
 
@@ -545,7 +553,7 @@ const partner = createPartnerApi({ partnerKey: process.env.KASSENECK_PARTNER_KEY
545
553
  const { customerId } = await partner.createPartnerCustomer({
546
554
  appId: 'app_…',
547
555
  idempotencyKey: customerNumber, // your own number; protects against duplicates
548
- business, // master data (type Betrieb): name, legal form, address, tax details, contacts
556
+ business, // master data (type Betrieb): legalForm 'sole_proprietor', state 'AT-5', …
549
557
  // env: 'test' is allowed even with a LIVE key: that is how you rehearse the
550
558
  // whole chain without a second key. Never the other way round.
551
559
  });
@@ -572,6 +580,83 @@ try {
572
580
  }
573
581
  ```
574
582
 
583
+ ### Migrating from 0.27.x
584
+
585
+ 0.28.0 is a breaking change for `./partner` only. The client now calls `/v3`
586
+ instead of `/v1`, and `/v3` rejects the German values of `/v1` with
587
+ `validation` instead of translating them. Stored data that goes into
588
+ `createPartnerCustomer` must use the new values:
589
+
590
+ | Where | 0.27.x (`/v1`) | 0.28.0 (`/v3`) |
591
+ |---|---|---|
592
+ | `business.legalForm` | `einzel`, `verein`, `sonstige` | `sole_proprietor`, `association`, `other` (`eu`, `og`, `kg`, `gmbh`, `gmbhcokg`, `ag` unchanged) |
593
+ | `business.state` | `burgenland` … `wien` | `AT-1` … `AT-9` (ISO 3166-2) |
594
+ | `business.contacts[].roles` | `geschaeftsfuehrung`, `buchhaltung`, `technik`, `kasse` | `management`, `accounting`, `technical`, `pos` |
595
+ | `business.taxDetails` | `uid` (type only; the server always wanted `vatId`) | `vatId` |
596
+ | `avv.mode` | `direkt`, `vollmacht`, `unterauftrag` | `direct`, `power_of_attorney`, `subprocessor` |
597
+ | fee on `createPartnerCustomer` / `requestCustomerSignature` | not read (`entgelt {cents, rhythmus, test}`) | `fee {cents, interval, test}`, `interval`: `monthly`, `yearly`, `once` |
598
+ | signature `history[].reason` | `karte_eingetragen`, `fon` | `card_entered`, `finanzonline` |
599
+ | delivery `status`, `lastDelivery.status` | `zugestellt`, `offen`, `fehlgeschlagen`, `verworfen` | `delivered`, `pending`, `failed`, `dropped` |
600
+ | `deletePartnerWebhook` | returned the `webhookId` | returns `{ webhookId, deleted }` |
601
+ | event `customer.terms_accepted` | `kind: 'nutzung'` | `kind: 'terms'` |
602
+ | event `source` | `einrichten`, `prozess`, `partner_vollmacht`, `admin_papier`, `papier_upload` | `setup_link`, `process_link`, `partner_power_of_attorney`, `admin_paper`, `paper_upload` |
603
+
604
+ Field names in this client that were German are English now as well:
605
+ `SignaturStand.signatur` is `signature` (plus `signatures[]`), a request's
606
+ `art` is `kind`, history `von`/`nach` are `from`/`to`,
607
+ `WebhookTestResult.ereignis` is `event`, a delivery's
608
+ `letzterVersuchAt`/`naechsterVersuchAt` are `lastAttemptAt`/`nextAttemptAt`,
609
+ and `requestCustomerSignature(id, { kind })` replaces `{ art }`. A webhook
610
+ now shows `apiVersion` and `lastDelivery { at, status, statusCode }`. The
611
+ types `Rechtsform`, `Bundesland` and `KontaktRolle` remain as deprecated
612
+ aliases of `LegalForm`, `AustrianState` and `ContactRole`.
613
+
614
+ **Webhook payloads have a language of their own.** A webhook created through
615
+ `/v1` keeps sending German payloads (`apiVersion: 'v1'`), whatever path you
616
+ call. Switch it once, there is no way back:
617
+
618
+ ```ts
619
+ await partner.updatePartnerWebhook(webhookId, { apiVersion: 'v3' });
620
+ ```
621
+
622
+ Webhook signature verification is unchanged.
623
+
624
+ ### Migrating from 0.28.x
625
+
626
+ 0.29.0 is a breaking change for `./partner` only, and only for
627
+ `PARTNER_FEHLER_CODES`: three codes that the server still sent in their
628
+ German `/v1` spelling under 0.28.0 now come through English, matching every
629
+ other value on `/v3`.
630
+
631
+ | 0.28.x | 0.29.0 |
632
+ |---|---|
633
+ | `zugang_nicht_erlaubt` | `access_not_allowed` |
634
+ | `kennung_fehlt` | `tax_number_missing` |
635
+ | `vertrag_offen` | `contracts_pending` |
636
+
637
+ `partnerFehlerRat()` and `istPartnerFehler()` follow: look up the new,
638
+ English key. A build that still checks the old German string will no longer
639
+ match, silently, so this is worth a search across your codebase.
640
+
641
+ Two codes that never reached this package's own error handling
642
+ (`kein_partnerbetrieb`, `request_not_found`, both admin-only and outside the
643
+ backend's public catalog) are gone from `PARTNER_FEHLER_CODES`. If you were
644
+ checking for them, that check was already dead code: the server never sent
645
+ them to a partner call.
646
+
647
+ `PARTNER_FEHLER_CODES` also gained nine codes for `reportCustomerContract`
648
+ (`kind_not_allowed`, `mode_not_allowed`, `power_of_attorney_missing`,
649
+ `not_found`, `no_version`, `not_required`, `unknown_version`, `text_changed`,
650
+ `already_accepted`), each with a `partnerFehlerRat()` sentence. This package
651
+ still does not expose that endpoint; the codes are here for completeness (a
652
+ catalog page, or code that reads the raw error yourself), not because a call
653
+ of this client can produce them.
654
+
655
+ The signature error type `SignaturAntrag.error.code` /
656
+ `CustomerSignature.error.code` is now `SignatureErrorCode`
657
+ (`customer_not_found` | `incomplete` | `finanzonline_error` | any other
658
+ string), a documented union instead of a bare `string | null`.
659
+
575
660
  ### A test event is not a cash register
576
661
 
577
662
  `sendPartnerWebhookTest(webhookId, 'cashregister.live')` fires exactly the
@@ -10,9 +10,10 @@
10
10
  * Fehler. Hier steht sie vorher — abfragbar, ausgebbar, und in
11
11
  * [naechsterSchritt] auch beantwortbar.
12
12
  *
13
- * **Ohne Vertragsschritt.** Auftragsverarbeitungsvertraege wirken in diesem
14
- * Weg nicht mehr (Stand 2026-08-31): kein Aufruf meldet einen, keine Kasse
15
- * bleibt deswegen stehen.
13
+ * **Kein eigener Vertragsschritt.** AVV und Nutzungsvertrag bestaetigt der
14
+ * Betrieb ueber denselben Einrichtungs-Link wie seinen FinanzOnline-Zugang
15
+ * (Schritt `fon`). Live geht ohne beide keine Kasse live
16
+ * (`vertrag_offen`); den Stand zeigen `avv` und `terms` am Betrieb.
16
17
  *
17
18
  * Zwei Dinge laufen bewusst **parallel**: der Signaturantrag und das Anlegen
18
19
  * der Kasse. Eine mit `automatic:true` angelegte Kasse wartet, bis die
@@ -11,9 +11,10 @@
11
11
  * Fehler. Hier steht sie vorher — abfragbar, ausgebbar, und in
12
12
  * [naechsterSchritt] auch beantwortbar.
13
13
  *
14
- * **Ohne Vertragsschritt.** Auftragsverarbeitungsvertraege wirken in diesem
15
- * Weg nicht mehr (Stand 2026-08-31): kein Aufruf meldet einen, keine Kasse
16
- * bleibt deswegen stehen.
14
+ * **Kein eigener Vertragsschritt.** AVV und Nutzungsvertrag bestaetigt der
15
+ * Betrieb ueber denselben Einrichtungs-Link wie seinen FinanzOnline-Zugang
16
+ * (Schritt `fon`). Live geht ohne beide keine Kasse live
17
+ * (`vertrag_offen`); den Stand zeigen `avv` und `terms` am Betrieb.
17
18
  *
18
19
  * Zwei Dinge laufen bewusst **parallel**: der Signaturantrag und das Anlegen
19
20
  * der Kasse. Eine mit `automatic:true` angelegte Kasse wartet, bis die
@@ -5,12 +5,27 @@
5
5
  * Funktionen und bleiben einzeln importierbar.
6
6
  */
7
7
  import { type FetchLike } from '../client/transport.js';
8
- import { type CreateWebhookOptions, type CreateWebhookResult, type PartnerWebhook, type WebhookListe, type PartnerWebhookEventType, type WebhookPatch, type WebhookTestResult, type WebhookZustellung } from './webhooks.js';
9
- import type { ActivateCashregisterResult, CreateCashregisterOptions, CreateCashregisterResult, CreateCustomerOptions, CreateCustomerResult, CustomerCredentials, FonLinkResult, KassenListe, Kunde, KundenListe, ListCustomersOptions, PartnerInfo, RequestSignatureResult, SignaturStand } from './typen.js';
8
+ import { type CreateWebhookOptions, type CreateWebhookResult, type DeleteWebhookResult, type PartnerWebhook, type WebhookListe, type PartnerWebhookEventType, type WebhookPatch, type WebhookTestResult, type WebhookZustellung } from './webhooks.js';
9
+ import type { ActivateCashregisterResult, CreateCashregisterOptions, CreateCashregisterResult, CreateCustomerOptions, CreateCustomerResult, CustomerCredentials, FonLinkResult, KassenListe, Kunde, KundenListe, ListCustomersOptions, PartnerInfo, RequestSignatureOptions, RequestSignatureResult, SignaturStand } from './typen.js';
10
+ /**
11
+ * Die Basis-URL der Partner-API: `/v3`, die englische Fassung.
12
+ *
13
+ * Nur der Partner-Teil spricht `/v3`. Belege, Rechnungen, Kasse und Zahlungen
14
+ * laufen weiter ueber [DEFAULT_BASE_URL] (`/v1`), bis es fuer sie eine `/v3`
15
+ * gibt. Die Partner-Endpunkte unter `/v1` antworten weiter, deutsch und
16
+ * abgekuendigt (Kopfzeilen `Deprecation`/`Sunset`); dieser Client spricht sie
17
+ * nicht mehr.
18
+ */
19
+ export declare const PARTNER_BASE_URL = "https://api.kasseneck.at/v3";
10
20
  export interface PartnerApiOptions {
11
21
  /** Partner-Schluessel `pk_test_…` / `pk_live_…`. Gehoert auf einen Server. */
12
22
  partnerKey: string;
13
- /** Abweichende Basis-URL; Vorgabe `https://api.kasseneck.at/v1`. */
23
+ /**
24
+ * Abweichende Basis-URL; Vorgabe [PARTNER_BASE_URL]
25
+ * (`https://api.kasseneck.at/v3`). Die Antworten werden in der Form der
26
+ * `/v3` gelesen: eine `/v1`-Adresse hier liefert deutsche Werte, die diese
27
+ * Typen nicht beschreiben.
28
+ */
14
29
  baseUrl?: string;
15
30
  /** Zeitlimit je Aufruf in Millisekunden. */
16
31
  timeoutMs?: number;
@@ -23,10 +38,7 @@ export interface PartnerApi {
23
38
  listPartnerCustomers(optionen?: ListCustomersOptions): Promise<KundenListe>;
24
39
  getPartnerCustomer(customerId: string): Promise<Kunde>;
25
40
  sendPartnerCustomerFonLink(customerId: string): Promise<FonLinkResult>;
26
- requestCustomerSignature(customerId: string, optionen?: {
27
- art?: string;
28
- additional?: boolean;
29
- }): Promise<RequestSignatureResult>;
41
+ requestCustomerSignature(customerId: string, optionen?: RequestSignatureOptions): Promise<RequestSignatureResult>;
30
42
  getCustomerSignatureStatus(customerId: string): Promise<SignaturStand>;
31
43
  createCustomerCashregister(optionen: CreateCashregisterOptions): Promise<CreateCashregisterResult>;
32
44
  activateCashregister(customerId: string, cashregisterId: string): Promise<ActivateCashregisterResult>;
@@ -42,7 +54,7 @@ export interface PartnerApi {
42
54
  createPartnerWebhook(optionen: CreateWebhookOptions): Promise<CreateWebhookResult>;
43
55
  listPartnerWebhooks(): Promise<WebhookListe>;
44
56
  updatePartnerWebhook(webhookId: string, patch: WebhookPatch): Promise<PartnerWebhook>;
45
- deletePartnerWebhook(webhookId: string): Promise<string>;
57
+ deletePartnerWebhook(webhookId: string): Promise<DeleteWebhookResult>;
46
58
  /**
47
59
  * Neues Secret fuer denselben Endpunkt — dieselbe `webhookId`, dieselben
48
60
  * Ereignisse. Das alte gilt ab der Antwort nicht mehr.
@@ -6,16 +6,27 @@
6
6
  * Funktionen und bleiben einzeln importierbar.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.PARTNER_BASE_URL = void 0;
9
10
  exports.createPartnerApi = createPartnerApi;
10
11
  const transport_js_1 = require("../client/transport.js");
11
12
  const auth_js_1 = require("./auth.js");
12
13
  const fehler_js_1 = require("./fehler.js");
13
14
  const endpunkte_js_1 = require("./endpunkte.js");
14
15
  const webhooks_js_1 = require("./webhooks.js");
16
+ /**
17
+ * Die Basis-URL der Partner-API: `/v3`, die englische Fassung.
18
+ *
19
+ * Nur der Partner-Teil spricht `/v3`. Belege, Rechnungen, Kasse und Zahlungen
20
+ * laufen weiter ueber [DEFAULT_BASE_URL] (`/v1`), bis es fuer sie eine `/v3`
21
+ * gibt. Die Partner-Endpunkte unter `/v1` antworten weiter, deutsch und
22
+ * abgekuendigt (Kopfzeilen `Deprecation`/`Sunset`); dieser Client spricht sie
23
+ * nicht mehr.
24
+ */
25
+ exports.PARTNER_BASE_URL = 'https://api.kasseneck.at/v3';
15
26
  function createPartnerApi(optionen) {
16
27
  const rufen = (0, transport_js_1.createTransport)({
17
28
  auth: (0, auth_js_1.partnerKeyAuth)({ partnerKey: optionen.partnerKey }),
18
- baseUrl: optionen.baseUrl,
29
+ baseUrl: optionen.baseUrl ?? exports.PARTNER_BASE_URL,
19
30
  timeoutMs: optionen.timeoutMs,
20
31
  fetch: optionen.fetch,
21
32
  });
@@ -19,7 +19,7 @@
19
19
  * einen `TypeError` an unpassender Stelle.
20
20
  */
21
21
  import type { InternerTransport } from '../client/aufrufe.js';
22
- import type { ActivateCashregisterResult, CreateCashregisterOptions, CreateCashregisterResult, CreateCustomerOptions, CreateCustomerResult, CustomerCredentials, FonLinkResult, KassenListe, Kunde, KundenListe, ListCustomersOptions, PartnerInfo, RequestSignatureResult, SignaturStand } from './typen.js';
22
+ import type { ActivateCashregisterResult, CreateCashregisterOptions, CreateCashregisterResult, CreateCustomerOptions, CreateCustomerResult, CustomerCredentials, FonLinkResult, KassenListe, Kunde, KundenListe, ListCustomersOptions, PartnerInfo, RequestSignatureOptions, RequestSignatureResult, SignaturStand } from './typen.js';
23
23
  /**
24
24
  * Wer bin ich, in welcher Umgebung, mit welchen Rechten — und welche Apps
25
25
  * gehoeren mir. `apps[].id` ist die `appId` fuer [createPartnerCustomer].
@@ -76,8 +76,8 @@ export declare function sendPartnerCustomerFonLink(rufen: InternerTransport, cus
76
76
  * Vertrauensdiensteanbieter **auf diesen Betrieb** ausstellen und meldet sie
77
77
  * bei FinanzOnline an; einen Vorrat fertiger Karten gibt es nicht.
78
78
  *
79
- * Der Antrag erzeugt sofort ein Signatur-OBJEKT: `antrag.requestId` ist
80
- * zugleich die `signaturId`, auf die sich eine Kasse beruft — auch solange
79
+ * Der Antrag erzeugt sofort ein Signatur-OBJEKT: `request.requestId` ist
80
+ * zugleich die `signatureRequestId`, auf die sich eine Kasse beruft — auch solange
81
81
  * noch keine Karte zugewiesen ist.
82
82
  *
83
83
  * **Je Betrieb laeuft nur ein Antrag.** Ein zweiter Aufruf liefert den
@@ -87,23 +87,20 @@ export declare function sendPartnerCustomerFonLink(rufen: InternerTransport, cus
87
87
  * Abschluss kommt als Ereignis `signature.ready`, nicht als Antwort auf diesen
88
88
  * Aufruf.
89
89
  */
90
- export declare function requestCustomerSignature(rufen: InternerTransport, customerId: string, optionen?: {
91
- art?: string;
92
- additional?: boolean;
93
- }): Promise<RequestSignatureResult>;
94
- /** Stand der Signatur eines Betriebs samt aller Antraege und des FON-Zugangs. */
90
+ export declare function requestCustomerSignature(rufen: InternerTransport, customerId: string, optionen?: RequestSignatureOptions): Promise<RequestSignatureResult>;
91
+ /** Stand der Signatur eines Betriebs samt aller Signaturen, Antraege und des FON-Zugangs. */
95
92
  export declare function getCustomerSignatureStatus(rufen: InternerTransport, customerId: string): Promise<SignaturStand>;
96
93
  /**
97
94
  * Legt eine Kasse an.
98
95
  *
99
96
  * **Jede Kasse bezieht sich auf eine Signatur.** Ohne eine einzige — auch eine
100
97
  * noch laufende zaehlt — entsteht keine (`signature_missing`); bei mehreren
101
- * muss `signaturId` dastehen (`signature_ambiguous`).
98
+ * muss `signatureRequestId` dastehen (`signature_ambiguous`).
102
99
  *
103
100
  * **Darf vor der fertigen Signatur aufgerufen werden:** die Kasse bleibt dann
104
- * auf `entwurf` und geht von selbst live, sobald IHRE Signatur bereit ist
105
- * (`automatic:true`, Vorgabe). `inbetriebnahme.reason` sagt, warum gerade
106
- * nichts lief: `signature_not_ready` oder `automatik_aus`.
101
+ * auf `draft` und geht von selbst live, sobald IHRE Signatur bereit ist
102
+ * (`automatic:true`, Vorgabe). `activation.reason` sagt, warum gerade
103
+ * nichts lief: `signature_not_ready` oder `automation_off`.
107
104
  *
108
105
  * Hoechstens 20 Kassen je Betrieb (`cashregister_limit`); ohne gebuchtes Modul
109
106
  * `module_inactive`.
@@ -59,6 +59,19 @@ function zahlOderNull(wert) {
59
59
  function jaNein(wert, rueckfall = false) {
60
60
  return typeof wert === 'boolean' ? wert : rueckfall;
61
61
  }
62
+ /**
63
+ * Das gebuchte Entgelt (`fee`), falls die Antwort eines fuehrt. Ohne Betrag
64
+ * ist es keines: ein erfundenes `0` saehe aus wie ein kostenloser Posten.
65
+ */
66
+ function entgelt(wert) {
67
+ if (wert === null || typeof wert !== 'object' || Array.isArray(wert))
68
+ return null;
69
+ const f = wert;
70
+ const cents = zahlOderNull(f['cents']);
71
+ if (cents === null)
72
+ return null;
73
+ return { cents, interval: text(f['interval']), test: jaNein(f['test']) };
74
+ }
62
75
  /**
63
76
  * Verlangt ein Feld der Antwort. Der Fehler nennt das Feld und den Vorgang,
64
77
  * damit ein Aufrufer nicht raten muss, welcher der Aufrufe etwas anderes
@@ -172,6 +185,7 @@ async function createPartnerCustomer(rufen, optionen) {
172
185
  appId: text(daten['appId'], appId),
173
186
  access: { invited: jaNein(zugang['invited']), sentTo: textOderNull(zugang['sentTo']) },
174
187
  nextSteps: liste(daten['nextSteps']).filter((s) => typeof s === 'string'),
188
+ fee: entgelt(daten['fee']),
175
189
  replayed: jaNein(daten['replayed']),
176
190
  };
177
191
  }
@@ -200,26 +214,38 @@ function kundenZeile(eintrag) {
200
214
  appId: textOderNull(k['appId']),
201
215
  env: text(k['env']) === 'test' ? 'test' : 'live',
202
216
  createdAt: zahlOderNull(k['createdAt']),
217
+ fon: fonStand(k['fon']),
203
218
  avv: avvStand(k['avv']),
219
+ terms: vertragStand(k['terms']),
204
220
  };
205
221
  }
206
- /**
207
- * Der Vertragsstand, **falls** die Antwort ihn ueberhaupt fuehrt — heute tut
208
- * sie das nicht, dann bleibt es bei `null`. Kein erfundenes `offen`: „nicht
209
- * mitgeliefert" und „nicht bestaetigt" duerfen fuer einen Aufrufer nicht
210
- * dasselbe sein.
211
- */
212
- function avvStand(wert) {
222
+ function fonStand(wert) {
213
223
  if (wert === null || typeof wert !== 'object' || Array.isArray(wert))
214
224
  return null;
215
- const a = wert;
225
+ const f = wert;
216
226
  return {
217
- status: text(a['status']),
218
- version: textOderNull(a['version']),
219
- confirmedAt: zahlOderNull(a['confirmedAt']),
220
- mode: textOderNull(a['mode']),
227
+ configured: jaNein(f['configured']),
228
+ linkSentAt: zahlOderNull(f['linkSentAt']),
229
+ linkOpenedAt: zahlOderNull(f['linkOpenedAt']),
221
230
  };
222
231
  }
232
+ function vertragStand(wert) {
233
+ if (wert === null || typeof wert !== 'object' || Array.isArray(wert))
234
+ return null;
235
+ const v = wert;
236
+ return { status: text(v['status']), version: textOderNull(v['version']), confirmedAt: zahlOderNull(v['confirmedAt']) };
237
+ }
238
+ /**
239
+ * Der AVV-Stand, **falls** die Antwort ihn fuehrt; sonst `null`. Kein
240
+ * erfundenes `pending`: „nicht mitgeliefert" und „nicht bestaetigt" duerfen
241
+ * fuer einen Aufrufer nicht dasselbe sein.
242
+ */
243
+ function avvStand(wert) {
244
+ const v = vertragStand(wert);
245
+ if (!v)
246
+ return null;
247
+ return { ...v, mode: textOderNull(wert['mode']) };
248
+ }
223
249
  /** Ein Betrieb mit allem, was der Partner ueber ihn sehen darf — nie Geheimnisse. */
224
250
  async function getPartnerCustomer(rufen, customerId) {
225
251
  const id = pflicht(customerId, 'getPartnerCustomer', 'customerId');
@@ -234,7 +260,13 @@ async function getPartnerCustomer(rufen, customerId) {
234
260
  createdAt: zahlOderNull(k['createdAt']),
235
261
  createdVia: textOderNull(k['createdVia']),
236
262
  business: objekt(k['business']),
237
- fon: { configured: jaNein(fon['configured']), verifiedAt: zahlOderNull(fon['verifiedAt']) },
263
+ fon: {
264
+ configured: jaNein(fon['configured']),
265
+ verifiedAt: zahlOderNull(fon['verifiedAt']),
266
+ linkSentAt: zahlOderNull(fon['linkSentAt']),
267
+ linkSentTo: textOderNull(fon['linkSentTo']),
268
+ linkOpenedAt: zahlOderNull(fon['linkOpenedAt']),
269
+ },
238
270
  access: zugang === null || typeof zugang !== 'object'
239
271
  ? null
240
272
  : {
@@ -288,7 +320,7 @@ function antrag(eintrag) {
288
320
  requestId: text(a['requestId']),
289
321
  status: text(a['status']),
290
322
  statusText: text(a['statusText']),
291
- art: text(a['art'], 'signature_card'),
323
+ kind: text(a['kind'], 'signature_card'),
292
324
  vdaId: textOderNull(a['vdaId']),
293
325
  signatureId: textOderNull(a['signatureId']),
294
326
  error: fehler === null || typeof fehler !== 'object'
@@ -304,8 +336,8 @@ function antrag(eintrag) {
304
336
  history: liste(a['history']).map((h) => {
305
337
  const e = objekt(h);
306
338
  return {
307
- von: textOderNull(e['von']),
308
- nach: text(e['nach']),
339
+ from: textOderNull(e['from']),
340
+ to: text(e['to']),
309
341
  at: zahlOderNull(e['at']) ?? 0,
310
342
  reason: textOderNull(e['reason']),
311
343
  };
@@ -317,8 +349,8 @@ function antrag(eintrag) {
317
349
  * Vertrauensdiensteanbieter **auf diesen Betrieb** ausstellen und meldet sie
318
350
  * bei FinanzOnline an; einen Vorrat fertiger Karten gibt es nicht.
319
351
  *
320
- * Der Antrag erzeugt sofort ein Signatur-OBJEKT: `antrag.requestId` ist
321
- * zugleich die `signaturId`, auf die sich eine Kasse beruft — auch solange
352
+ * Der Antrag erzeugt sofort ein Signatur-OBJEKT: `request.requestId` ist
353
+ * zugleich die `signatureRequestId`, auf die sich eine Kasse beruft — auch solange
322
354
  * noch keine Karte zugewiesen ist.
323
355
  *
324
356
  * **Je Betrieb laeuft nur ein Antrag.** Ein zweiter Aufruf liefert den
@@ -332,27 +364,54 @@ async function requestCustomerSignature(rufen, customerId, optionen = {}) {
332
364
  const id = pflicht(customerId, 'requestCustomerSignature', 'customerId');
333
365
  const daten = objekt(await rufen('requestCustomerSignature', {
334
366
  customerId: id,
335
- art: optionen.art,
367
+ kind: optionen.kind,
336
368
  additional: optionen.additional,
337
369
  }));
338
370
  return {
339
371
  request: antrag(verlangt(daten['request'], 'requestCustomerSignature', 'request')),
340
372
  replayed: jaNein(daten['replayed']),
341
373
  note: textOderNull(daten['note']),
374
+ fee: entgelt(daten['fee']),
342
375
  };
343
376
  }
344
- /** Stand der Signatur eines Betriebs samt aller Antraege und des FON-Zugangs. */
377
+ function signaturEinzeln(eintrag) {
378
+ const s = objekt(eintrag);
379
+ const fehler = s['error'];
380
+ return {
381
+ signatureRequestId: text(s['signatureRequestId']),
382
+ status: text(s['status']),
383
+ statusText: text(s['statusText']),
384
+ inProgress: jaNein(s['inProgress']),
385
+ ready: jaNein(s['ready']),
386
+ kind: text(s['kind'], 'signature_card'),
387
+ vdaId: textOderNull(s['vdaId']),
388
+ requestId: textOderNull(s['requestId']),
389
+ signatureId: textOderNull(s['signatureId']),
390
+ error: fehler === null || typeof fehler !== 'object'
391
+ ? null
392
+ : {
393
+ code: textOderNull(objekt(fehler)['code']),
394
+ message: textOderNull(objekt(fehler)['message']),
395
+ rc: textOderNull(objekt(fehler)['rc']),
396
+ },
397
+ createdAt: zahlOderNull(s['createdAt']),
398
+ updatedAt: zahlOderNull(s['updatedAt']),
399
+ };
400
+ }
401
+ /** Stand der Signatur eines Betriebs samt aller Signaturen, Antraege und des FON-Zugangs. */
345
402
  async function getCustomerSignatureStatus(rufen, customerId) {
346
403
  const id = pflicht(customerId, 'getCustomerSignatureStatus', 'customerId');
347
404
  const daten = objekt(await rufen('getCustomerSignatureStatus', { customerId: id }));
348
- const signatur = objekt(daten['signatur']);
405
+ const signatur = objekt(daten['signature']);
349
406
  const fon = objekt(daten['fon']);
350
407
  return {
351
- signatur: {
408
+ customerId: text(daten['customerId'], id),
409
+ signature: {
352
410
  ready: jaNein(signatur['ready']),
353
411
  signatureId: textOderNull(signatur['signatureId']),
354
412
  vdaId: textOderNull(signatur['vdaId']),
355
413
  },
414
+ signatures: liste(daten['signatures']).map(signaturEinzeln),
356
415
  requests: liste(daten['requests']).map(antrag),
357
416
  fon: { present: jaNein(fon['present']), verifiedAt: zahlOderNull(fon['verifiedAt']) },
358
417
  };
@@ -392,12 +451,12 @@ function kasse(eintrag) {
392
451
  *
393
452
  * **Jede Kasse bezieht sich auf eine Signatur.** Ohne eine einzige — auch eine
394
453
  * noch laufende zaehlt — entsteht keine (`signature_missing`); bei mehreren
395
- * muss `signaturId` dastehen (`signature_ambiguous`).
454
+ * muss `signatureRequestId` dastehen (`signature_ambiguous`).
396
455
  *
397
456
  * **Darf vor der fertigen Signatur aufgerufen werden:** die Kasse bleibt dann
398
- * auf `entwurf` und geht von selbst live, sobald IHRE Signatur bereit ist
399
- * (`automatic:true`, Vorgabe). `inbetriebnahme.reason` sagt, warum gerade
400
- * nichts lief: `signature_not_ready` oder `automatik_aus`.
457
+ * auf `draft` und geht von selbst live, sobald IHRE Signatur bereit ist
458
+ * (`automatic:true`, Vorgabe). `activation.reason` sagt, warum gerade
459
+ * nichts lief: `signature_not_ready` oder `automation_off`.
401
460
  *
402
461
  * Hoechstens 20 Kassen je Betrieb (`cashregister_limit`); ohne gebuchtes Modul
403
462
  * `module_inactive`.
@@ -19,6 +19,32 @@
19
19
  * unterscheiden. Deshalb stehen hier BEIDE Flaechen: die der Schnittstelle
20
20
  * ([PARTNER_FEHLER_CODES]) und die des Partner-Portals
21
21
  * ([PARTNER_PORTAL_FEHLER_CODES]).
22
+ *
23
+ * **Seit 0.29.0 englisch, wie der Rest von `/v3`.** Dieser Client spricht seit
24
+ * 0.28.0 ausschliesslich `/v3` (`PARTNER_BASE_URL`): die paar deutschen Codes,
25
+ * die der Server bis dahin noch roh durchreichte, kommen jetzt genauso englisch
26
+ * an wie alle anderen. [PARTNER_FEHLER_CODES] fuehrt deshalb ausnahmslos die
27
+ * `/v3`-Schreibweise aus `fehlercodes.json`s `v3`-Zuordnung (deutsch -> englisch);
28
+ * ein Aufrufer bekommt vom Server nie mehr die deutsche Form.
29
+ *
30
+ * **`kein_partnerbetrieb` und `request_not_found` fehlen absichtlich.** Beide
31
+ * sind admin-only (`partner-endpoints.js`, ausserhalb von `FEHLER_KATALOG`) und
32
+ * erreichen `/v3` nie: ein Partner-Aufruf kann sie unter keinem Pfad bekommen.
33
+ * Sie standen frueher versehentlich in dieser Liste; `dart-partner.json` (ein
34
+ * eingefrorener Abzug aus Dart 5.3.0, bevor das korrigiert wurde) fuehrt sie
35
+ * weiterhin, siehe die Ausnahme in `test/partner-enums.test.ts`.
36
+ *
37
+ * **Die Vertrags-Codes (`kind_not_allowed`, `mode_not_allowed`,
38
+ * `power_of_attorney_missing`, `not_found`, `no_version`,
39
+ * `unknown_version`, `text_changed`, `already_accepted`) stehen hier, obwohl
40
+ * dieses Paket `reportCustomerContract` nicht anbietet.** Der Katalog des
41
+ * Backends fuehrt sie mit `flaeche: 'api'`/`'beide'`, dieselbe Regel wie bei
42
+ * den Portal-Codes oben: vollstaendig heisst vollstaendig, auch fuer einen
43
+ * Endpunkt, den (noch) kein Aufruf dieses Clients ausloest. Ein Server-Update,
44
+ * das den Endpunkt ergaenzt, bräuchte dann keinen zweiten Fehlerkatalog-Umbau.
45
+ * `not_required` fehlt bewusst: derselbe gemeinsame Server-Zweig wie die
46
+ * anderen sechs, aber ueber die Partner-API nicht erreichbar (der Server hat
47
+ * ihn aus `FEHLER_KATALOG` entfernt, siehe `partner-core.js` im Backend).
22
48
  */
23
49
  /**
24
50
  * Alle Codes, die die **Schnittstelle** kennt. Als Liste und nicht nur als
@@ -27,7 +53,7 @@
27
53
  *
28
54
  * Reihenfolge und Bestand wie im Abzug des Backends.
29
55
  */
30
- export declare const PARTNER_FEHLER_CODES: readonly ["validation", "rate_limited", "app_not_found", "app_not_accepted", "kein_partnerbetrieb", "live_not_allowed", "customer_exists", "customer_conflict", "customer_limit", "zugang_nicht_erlaubt", "email_taken", "no_email", "fon_missing", "signature_pending", "request_not_found", "signature_missing", "signature_unknown", "signature_ambiguous", "signature_not_ready", "signature_limit", "signature_failed", "module_inactive", "cashregister_limit", "cashregister_not_found", "activation_failed", "webhook_limit", "webhook_inactive", "event_not_subscribed"];
56
+ export declare const PARTNER_FEHLER_CODES: readonly ["validation", "rate_limited", "app_not_found", "app_not_accepted", "live_not_allowed", "customer_exists", "customer_conflict", "customer_limit", "access_not_allowed", "email_taken", "no_email", "tax_number_missing", "fon_missing", "signature_pending", "signature_missing", "signature_unknown", "signature_ambiguous", "signature_not_ready", "signature_limit", "signature_failed", "module_inactive", "cashregister_limit", "cashregister_not_found", "contracts_pending", "kind_not_allowed", "mode_not_allowed", "power_of_attorney_missing", "not_found", "no_version", "unknown_version", "text_changed", "already_accepted", "activation_failed", "webhook_limit", "webhook_inactive", "event_not_subscribed"];
31
57
  /**
32
58
  * Die Codes, die nur im **Partner-Portal** entstehen — beim Pflegen der App,
33
59
  * der Schluessel, der Mitglieder und der Signaturkarten.
@@ -58,7 +84,7 @@ export declare function istPartnerFehler(error: unknown, code: PartnerCode): boo
58
84
  export interface PartnerFeldFehler {
59
85
  /**
60
86
  * Der Feldpfad, so wie er im gesendeten Betrieb steht — verschachtelt und je
61
- * Kontakt: `address.land`, `tax_details.ustid`, `contacts.1.abteilung`.
87
+ * Kontakt: `address.zip`, `taxDetails.taxNumber`, `contacts.0.email`.
62
88
  */
63
89
  field: string;
64
90
  message: string;