@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.
- package/CHANGELOG.md +94 -0
- package/README.md +87 -2
- package/dist/cjs/partner/ablauf.d.ts +4 -3
- package/dist/cjs/partner/ablauf.js +4 -3
- package/dist/cjs/partner/api.d.ts +20 -8
- package/dist/cjs/partner/api.js +12 -1
- package/dist/cjs/partner/endpunkte.d.ts +9 -12
- package/dist/cjs/partner/endpunkte.js +85 -26
- package/dist/cjs/partner/fehler.d.ts +28 -2
- package/dist/cjs/partner/fehler.js +58 -9
- package/dist/cjs/partner/index.d.ts +7 -3
- package/dist/cjs/partner/index.js +7 -2
- package/dist/cjs/partner/typen.d.ts +152 -35
- package/dist/cjs/partner/typen.js +4 -0
- package/dist/cjs/partner/webhooks.d.ts +76 -14
- package/dist/cjs/partner/webhooks.js +40 -12
- package/dist/esm/partner/ablauf.d.ts +4 -3
- package/dist/esm/partner/ablauf.js +4 -3
- package/dist/esm/partner/api.d.ts +20 -8
- package/dist/esm/partner/api.js +11 -1
- package/dist/esm/partner/endpunkte.d.ts +9 -12
- package/dist/esm/partner/endpunkte.js +85 -26
- package/dist/esm/partner/fehler.d.ts +28 -2
- package/dist/esm/partner/fehler.js +58 -9
- package/dist/esm/partner/index.d.ts +7 -3
- package/dist/esm/partner/index.js +5 -1
- package/dist/esm/partner/typen.d.ts +152 -35
- package/dist/esm/partner/typen.js +4 -0
- package/dist/esm/partner/webhooks.d.ts +76 -14
- package/dist/esm/partner/webhooks.js +40 -12
- package/fixtures/hobex-hps-codes.json +1 -1
- package/fixtures/kasse-texte.json +1 -1
- package/fixtures/oberflaeche.json +12 -4
- package/fixtures/rechnung-api.schema.json +1 -1
- package/fixtures/rechnung-texte.json +1 -1
- 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):
|
|
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
|
-
* **
|
|
14
|
-
*
|
|
15
|
-
*
|
|
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
|
-
* **
|
|
15
|
-
*
|
|
16
|
-
*
|
|
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
|
-
/**
|
|
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<
|
|
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.
|
package/dist/cjs/partner/api.js
CHANGED
|
@@ -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: `
|
|
80
|
-
* zugleich die `
|
|
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
|
-
|
|
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 `
|
|
98
|
+
* muss `signatureRequestId` dastehen (`signature_ambiguous`).
|
|
102
99
|
*
|
|
103
100
|
* **Darf vor der fertigen Signatur aufgerufen werden:** die Kasse bleibt dann
|
|
104
|
-
* auf `
|
|
105
|
-
* (`automatic:true`, Vorgabe). `
|
|
106
|
-
* nichts lief: `signature_not_ready` oder `
|
|
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
|
|
225
|
+
const f = wert;
|
|
216
226
|
return {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
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: {
|
|
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
|
-
|
|
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
|
-
|
|
308
|
-
|
|
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: `
|
|
321
|
-
* zugleich die `
|
|
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
|
-
|
|
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
|
-
|
|
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['
|
|
405
|
+
const signatur = objekt(daten['signature']);
|
|
349
406
|
const fon = objekt(daten['fon']);
|
|
350
407
|
return {
|
|
351
|
-
|
|
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 `
|
|
454
|
+
* muss `signatureRequestId` dastehen (`signature_ambiguous`).
|
|
396
455
|
*
|
|
397
456
|
* **Darf vor der fertigen Signatur aufgerufen werden:** die Kasse bleibt dann
|
|
398
|
-
* auf `
|
|
399
|
-
* (`automatic:true`, Vorgabe). `
|
|
400
|
-
* nichts lief: `signature_not_ready` oder `
|
|
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", "
|
|
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.
|
|
87
|
+
* Kontakt: `address.zip`, `taxDetails.taxNumber`, `contacts.0.email`.
|
|
62
88
|
*/
|
|
63
89
|
field: string;
|
|
64
90
|
message: string;
|