@kreiseck/kasseneck-api 0.27.2 → 0.28.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 +77 -0
- package/README.md +59 -9
- 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 +1 -1
- package/dist/cjs/partner/fehler.js +8 -3
- package/dist/cjs/partner/index.d.ts +7 -3
- package/dist/cjs/partner/index.js +7 -2
- package/dist/cjs/partner/typen.d.ts +144 -34
- 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/cjs/payments/index.d.ts +5 -4
- package/dist/cjs/payments/index.js +4 -3
- package/dist/cjs/rechnung/summen.d.ts +18 -3
- package/dist/cjs/rechnung/summen.js +18 -3
- package/dist/cjs/rechnung/typen.d.ts +1 -1
- package/dist/cjs/rechnung/vertrag.d.ts +1 -1
- package/dist/cjs/rechnung/vertrag.js +1 -1
- 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 +1 -1
- package/dist/esm/partner/fehler.js +8 -3
- package/dist/esm/partner/index.d.ts +7 -3
- package/dist/esm/partner/index.js +5 -1
- package/dist/esm/partner/typen.d.ts +144 -34
- 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/dist/esm/payments/index.d.ts +5 -4
- package/dist/esm/payments/index.js +4 -3
- package/dist/esm/rechnung/summen.d.ts +18 -3
- package/dist/esm/rechnung/summen.js +18 -3
- package/dist/esm/rechnung/typen.d.ts +1 -1
- package/dist/esm/rechnung/vertrag.d.ts +1 -1
- package/dist/esm/rechnung/vertrag.js +1 -1
- package/fixtures/hobex-hps-codes.json +1 -1
- package/fixtures/kasse-texte.json +1 -1
- package/fixtures/oberflaeche.json +3 -1
- package/fixtures/rechnung-api.schema.json +1 -1
- package/fixtures/rechnung-texte.json +1 -1
- package/package.json +1 -1
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
* einfuehrt, soll diesen Client nicht zum Absturz bringen, sondern ihn
|
|
13
13
|
* durchreichen. Eingabetypen sind dagegen eng — ein Tippfehler soll ein
|
|
14
14
|
* Compilerfehler sein und keine `validation`-Antwort vom Server.
|
|
15
|
+
*
|
|
16
|
+
* **Die Formen sind die der `/v3`** (seit 0.28.0): Feldnamen und Werte, auf
|
|
17
|
+
* die ein Programm verzweigt, sind englisch; Texte fuer Menschen (`message`,
|
|
18
|
+
* `note`, `statusText`, `nextSteps`) bleiben deutsch, die Fehlercodes ebenso.
|
|
15
19
|
*/
|
|
16
20
|
import type { KasseneckSecret } from './secret.js';
|
|
17
21
|
/**
|
|
@@ -67,9 +71,29 @@ export interface PartnerInfo {
|
|
|
67
71
|
};
|
|
68
72
|
apps: PartnerApp[];
|
|
69
73
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
74
|
+
/**
|
|
75
|
+
* Rechtsform des Betriebs, so wie `/v3` sie schreibt und liest.
|
|
76
|
+
*
|
|
77
|
+
* Die oesterreichischen Kurzformen (`eu`, `og`, `kg`, `gmbh`, `gmbhcokg`, `ag`)
|
|
78
|
+
* bleiben wie sie sind; nur die drei Woerter, die es auf Englisch gibt, sind
|
|
79
|
+
* englisch. `/v3` weist die deutschen Werte aus `/v1` (`einzel`, `verein`,
|
|
80
|
+
* `sonstige`) mit `validation` ab, statt sie still zu uebersetzen.
|
|
81
|
+
*/
|
|
82
|
+
export type LegalForm = 'sole_proprietor' | 'eu' | 'og' | 'kg' | 'gmbh' | 'gmbhcokg' | 'ag' | 'association' | 'other';
|
|
83
|
+
/** @deprecated Seit 0.28.0 dasselbe wie [LegalForm] (englische Werte der `/v3`). */
|
|
84
|
+
export type Rechtsform = LegalForm;
|
|
85
|
+
/**
|
|
86
|
+
* Bundesland als ISO-3166-2-Code: `AT-1` Burgenland, `AT-2` Kaernten,
|
|
87
|
+
* `AT-3` Niederoesterreich, `AT-4` Oberoesterreich, `AT-5` Salzburg,
|
|
88
|
+
* `AT-6` Steiermark, `AT-7` Tirol, `AT-8` Vorarlberg, `AT-9` Wien.
|
|
89
|
+
*/
|
|
90
|
+
export type AustrianState = 'AT-1' | 'AT-2' | 'AT-3' | 'AT-4' | 'AT-5' | 'AT-6' | 'AT-7' | 'AT-8' | 'AT-9';
|
|
91
|
+
/** @deprecated Seit 0.28.0 dasselbe wie [AustrianState] (ISO-Codes der `/v3`). */
|
|
92
|
+
export type Bundesland = AustrianState;
|
|
93
|
+
/** Rolle einer Kontaktperson; `/v1` sagte `geschaeftsfuehrung`, `buchhaltung`, `technik`, `kasse`. */
|
|
94
|
+
export type ContactRole = 'management' | 'accounting' | 'technical' | 'pos';
|
|
95
|
+
/** @deprecated Seit 0.28.0 dasselbe wie [ContactRole] (englische Werte der `/v3`). */
|
|
96
|
+
export type KontaktRolle = ContactRole;
|
|
73
97
|
export interface BetriebAdresse {
|
|
74
98
|
street: string;
|
|
75
99
|
/** Hausnummer, kurz und alphanumerisch: `49`, `12a`, `49/5`. */
|
|
@@ -82,8 +106,11 @@ export interface BetriebSteuer {
|
|
|
82
106
|
/** Steuernummer im Format `12-345/6789`; die Pruefziffer wird geprueft. */
|
|
83
107
|
taxNumber: string;
|
|
84
108
|
smallBusiness: boolean;
|
|
85
|
-
/**
|
|
86
|
-
|
|
109
|
+
/**
|
|
110
|
+
* UID, z. B. `ATU12345675`. Heisst auf der Leitung `vatId` (auch schon unter
|
|
111
|
+
* `/v1`); ein `uid` wies der Server als unbekanntes Feld ab.
|
|
112
|
+
*/
|
|
113
|
+
vatId?: string;
|
|
87
114
|
/** GLN, 13 Ziffern. */
|
|
88
115
|
gln?: string;
|
|
89
116
|
}
|
|
@@ -91,7 +118,7 @@ export interface BetriebKontakt {
|
|
|
91
118
|
name: string;
|
|
92
119
|
email: string;
|
|
93
120
|
phone?: string;
|
|
94
|
-
roles?:
|
|
121
|
+
roles?: ContactRole[];
|
|
95
122
|
}
|
|
96
123
|
export interface BetriebSteuerberater {
|
|
97
124
|
name: string;
|
|
@@ -115,11 +142,11 @@ export interface BetriebSteuerberater {
|
|
|
115
142
|
*/
|
|
116
143
|
export interface Betrieb {
|
|
117
144
|
companyName: string;
|
|
118
|
-
legalForm:
|
|
145
|
+
legalForm: LegalForm;
|
|
119
146
|
/** Anmeldung des Betriebs im Kasseneck-Panel; darf dort noch keinen Zugang haben. */
|
|
120
147
|
email: string;
|
|
121
148
|
address: BetriebAdresse;
|
|
122
|
-
state:
|
|
149
|
+
state: AustrianState;
|
|
123
150
|
taxDetails: BetriebSteuer;
|
|
124
151
|
/** Mindestens einer, hoechstens zehn. */
|
|
125
152
|
contacts: BetriebKontakt[];
|
|
@@ -171,6 +198,20 @@ export interface CreateCustomerOptions {
|
|
|
171
198
|
env?: PartnerEnv;
|
|
172
199
|
}
|
|
173
200
|
export type KundenStatus = 'created' | 'fon_configured' | 'signature_requested' | 'signature_ready' | 'cashregister_created' | 'live' | 'blocked' | (string & {});
|
|
201
|
+
/** Abrechnungsrhythmus eines Entgelts; `/v1` sagte `monat`, `jahr`, `einmal`. */
|
|
202
|
+
export type FeeInterval = 'monthly' | 'yearly' | 'once';
|
|
203
|
+
/**
|
|
204
|
+
* Das Entgelt, das mit einem Aufruf gebucht wurde: nur dann in der Antwort,
|
|
205
|
+
* wenn die Konditionen des Partners dafuer einen Preis vorsehen. Unter `/v1`
|
|
206
|
+
* hiess es `entgelt` mit `rhythmus`.
|
|
207
|
+
*/
|
|
208
|
+
export interface PartnerFee {
|
|
209
|
+
/** Betrag in ganzen Cent. */
|
|
210
|
+
cents: number;
|
|
211
|
+
interval: FeeInterval | (string & {});
|
|
212
|
+
/** `true` fuer einen Testbetrieb: gebucht, aber nicht verrechnet. */
|
|
213
|
+
test: boolean;
|
|
214
|
+
}
|
|
174
215
|
export interface CreateCustomerResult {
|
|
175
216
|
customerId: string;
|
|
176
217
|
status: KundenStatus;
|
|
@@ -182,24 +223,48 @@ export interface CreateCustomerResult {
|
|
|
182
223
|
sentTo: string | null;
|
|
183
224
|
};
|
|
184
225
|
nextSteps: string[];
|
|
226
|
+
/** Das gebuchte Entgelt; `null`, wenn die Konditionen keinen Preis dafuer vorsehen. */
|
|
227
|
+
fee: PartnerFee | null;
|
|
185
228
|
/** `true`, wenn derselbe `idempotencyKey` schon einmal ankam. */
|
|
186
229
|
replayed: boolean;
|
|
187
230
|
}
|
|
188
231
|
/**
|
|
189
|
-
*
|
|
232
|
+
* Wie das Partnerkonto den AVV handhabt; `/v1` sagte `direkt`, `vollmacht`,
|
|
233
|
+
* `unterauftrag`.
|
|
234
|
+
*/
|
|
235
|
+
export type AvvMode = 'direct' | 'power_of_attorney' | 'subprocessor';
|
|
236
|
+
/**
|
|
237
|
+
* Stand eines Vertrags des Betriebs mit Kasseneck: `pending` (noch nicht
|
|
238
|
+
* bestaetigt), `confirmed`, `outdated` (eine neuere Pflichtfassung ist zu
|
|
239
|
+
* bestaetigen) oder `not_required` (Testumgebung).
|
|
190
240
|
*
|
|
191
|
-
* **Vertraege wirken
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
241
|
+
* **Die Vertraege wirken:** live geht ohne beide (AVV und Nutzungsvertrag)
|
|
242
|
+
* keine Kasse live, `activateCashregister` antwortet dann `vertrag_offen`. Der
|
|
243
|
+
* Betrieb bestaetigt sie selbst ueber den Einrichtungs-Link
|
|
244
|
+
* (`sendPartnerCustomerFonLink`); die Ereignisse `customer.avv_accepted` und
|
|
245
|
+
* `customer.terms_accepted` melden die Bestaetigung. In der Testumgebung sind
|
|
246
|
+
* sie nicht noetig.
|
|
197
247
|
*/
|
|
198
|
-
export interface
|
|
199
|
-
status: string;
|
|
248
|
+
export interface VertragStand {
|
|
249
|
+
status: 'pending' | 'confirmed' | 'outdated' | 'not_required' | (string & {});
|
|
200
250
|
version: string | null;
|
|
201
251
|
confirmedAt: number | null;
|
|
202
|
-
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Stand des Auftragsverarbeitungsvertrags (AVV, Art. 28 DSGVO). Zusaetzlich zu
|
|
255
|
+
* [VertragStand] der Status `via_partner` (der Partnervertrag deckt den AVV,
|
|
256
|
+
* Weg `subprocessor`) und `mode`, der Weg des Partnerkontos.
|
|
257
|
+
*/
|
|
258
|
+
export interface AvvStand extends VertragStand {
|
|
259
|
+
status: VertragStand['status'] | 'via_partner';
|
|
260
|
+
mode: AvvMode | (string & {}) | null;
|
|
261
|
+
}
|
|
262
|
+
/** FinanzOnline-Stand in der Liste: ist der Link draussen, geoeffnet, der Zugang geprueft? */
|
|
263
|
+
export interface KundenFonStand {
|
|
264
|
+
configured: boolean;
|
|
265
|
+
linkSentAt: number | null;
|
|
266
|
+
/** Erste Oeffnung; wird mit einem Ersatz-Link zurueckgesetzt. */
|
|
267
|
+
linkOpenedAt: number | null;
|
|
203
268
|
}
|
|
204
269
|
export interface KundenZeile {
|
|
205
270
|
customerId: string;
|
|
@@ -208,12 +273,15 @@ export interface KundenZeile {
|
|
|
208
273
|
appId: string | null;
|
|
209
274
|
env: PartnerEnv;
|
|
210
275
|
createdAt: number | null;
|
|
276
|
+
/** FinanzOnline-Stand; `null`, wenn die Antwort ihn nicht fuehrt. */
|
|
277
|
+
fon: KundenFonStand | null;
|
|
211
278
|
/**
|
|
212
|
-
*
|
|
213
|
-
* nicht
|
|
214
|
-
* setzt ihn voraus.
|
|
279
|
+
* AVV-Stand; `null`, wenn die Antwort ihn nicht fuehrt. Kein erfundenes
|
|
280
|
+
* `pending`: "nicht mitgeliefert" und "nicht bestaetigt" sind zweierlei.
|
|
215
281
|
*/
|
|
216
282
|
avv: AvvStand | null;
|
|
283
|
+
/** Stand des Nutzungsvertrags; `null`, wenn die Antwort ihn nicht fuehrt. */
|
|
284
|
+
terms: VertragStand | null;
|
|
217
285
|
}
|
|
218
286
|
export interface ListCustomersOptions {
|
|
219
287
|
status?: KundenStatus;
|
|
@@ -233,9 +301,10 @@ export interface Kunde extends KundenZeile {
|
|
|
233
301
|
createdAt: number | null;
|
|
234
302
|
createdVia: string | null;
|
|
235
303
|
business: Record<string, unknown>;
|
|
236
|
-
|
|
237
|
-
|
|
304
|
+
/** In der Einzelsicht zusaetzlich: wann geprueft, an welche (maskierte) Adresse der Link ging. */
|
|
305
|
+
fon: KundenFonStand & {
|
|
238
306
|
verifiedAt: number | null;
|
|
307
|
+
linkSentTo: string | null;
|
|
239
308
|
};
|
|
240
309
|
access: {
|
|
241
310
|
email: string | null;
|
|
@@ -250,22 +319,28 @@ export interface FonLinkResult {
|
|
|
250
319
|
expiresAt: number;
|
|
251
320
|
}
|
|
252
321
|
/**
|
|
253
|
-
* `
|
|
254
|
-
* Einheit ist FinanzOnline bekannt; `
|
|
255
|
-
* Testumgebung wird ohne `
|
|
322
|
+
* `requested → assigned → registered → ready`. `registered` heisst: die
|
|
323
|
+
* Einheit ist FinanzOnline bekannt; `ready` heisst: sie darf signieren. In der
|
|
324
|
+
* Testumgebung wird ohne `registered` direkt `ready` erreicht.
|
|
256
325
|
*/
|
|
257
326
|
export type SignaturAntragStatus = 'requested' | 'assigned' | 'registered' | 'ready' | 'failed' | 'cancelled' | (string & {});
|
|
327
|
+
/**
|
|
328
|
+
* Gruende in der Historie eines Signaturantrags. `card_entered` und
|
|
329
|
+
* `finanzonline` hiessen unter `/v1` `karte_eingetragen` und `fon`.
|
|
330
|
+
*/
|
|
331
|
+
export type SignatureHistoryReason = 'api' | 'portal' | 'card_entered' | 'finanzonline' | 'automation_off' | 'test_environment' | 'no_stock' | (string & {});
|
|
258
332
|
export interface SignaturHistorieEintrag {
|
|
259
|
-
|
|
260
|
-
|
|
333
|
+
from: SignaturAntragStatus | null;
|
|
334
|
+
to: SignaturAntragStatus;
|
|
261
335
|
at: number;
|
|
262
|
-
reason:
|
|
336
|
+
reason: SignatureHistoryReason | null;
|
|
263
337
|
}
|
|
264
338
|
export interface SignaturAntrag {
|
|
265
339
|
requestId: string;
|
|
266
340
|
status: SignaturAntragStatus;
|
|
267
341
|
statusText: string;
|
|
268
|
-
|
|
342
|
+
/** Art der Signatureinheit; heute nur `signature_card`. */
|
|
343
|
+
kind: string;
|
|
269
344
|
vdaId: string | null;
|
|
270
345
|
signatureId: string | null;
|
|
271
346
|
error: {
|
|
@@ -278,18 +353,53 @@ export interface SignaturAntrag {
|
|
|
278
353
|
updatedAt: number | null;
|
|
279
354
|
history: SignaturHistorieEintrag[];
|
|
280
355
|
}
|
|
356
|
+
export interface RequestSignatureOptions {
|
|
357
|
+
/** Art der Signatureinheit; heute nur `signature_card` (Vorgabe). */
|
|
358
|
+
kind?: string;
|
|
359
|
+
/** `true` beantragt eine WEITERE Signatur, obwohl schon eine besteht. */
|
|
360
|
+
additional?: boolean;
|
|
361
|
+
}
|
|
281
362
|
export interface RequestSignatureResult {
|
|
282
363
|
request: SignaturAntrag;
|
|
283
364
|
/** `true`, wenn schon ein Antrag lief — dann ist es der laufende. */
|
|
284
365
|
replayed: boolean;
|
|
285
366
|
note: string | null;
|
|
367
|
+
/** Das gebuchte Entgelt; `null`, wenn die Konditionen keinen Preis dafuer vorsehen. */
|
|
368
|
+
fee: PartnerFee | null;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Eine Signatur des Betriebs, einzeln. Ein Betrieb kann mehrere haben
|
|
372
|
+
* (Ersatzkarte, zweiter Standort); `signatureRequestId` ist die Kennung, auf die
|
|
373
|
+
* sich eine Kasse beruft.
|
|
374
|
+
*/
|
|
375
|
+
export interface CustomerSignature {
|
|
376
|
+
signatureRequestId: string;
|
|
377
|
+
status: SignaturAntragStatus | 'decommissioned';
|
|
378
|
+
statusText: string;
|
|
379
|
+
inProgress: boolean;
|
|
380
|
+
ready: boolean;
|
|
381
|
+
kind: string;
|
|
382
|
+
vdaId: string | null;
|
|
383
|
+
requestId: string | null;
|
|
384
|
+
signatureId: string | null;
|
|
385
|
+
error: {
|
|
386
|
+
code: string | null;
|
|
387
|
+
message: string | null;
|
|
388
|
+
rc: string | null;
|
|
389
|
+
} | null;
|
|
390
|
+
createdAt: number | null;
|
|
391
|
+
updatedAt: number | null;
|
|
286
392
|
}
|
|
287
393
|
export interface SignaturStand {
|
|
288
|
-
|
|
394
|
+
customerId: string;
|
|
395
|
+
/** Die Kurzform: hat der Betrieb ueberhaupt eine brauchbare Signatur? */
|
|
396
|
+
signature: {
|
|
289
397
|
ready: boolean;
|
|
290
398
|
signatureId: string | null;
|
|
291
399
|
vdaId: string | null;
|
|
292
400
|
};
|
|
401
|
+
/** Jede Signatur einzeln. */
|
|
402
|
+
signatures: CustomerSignature[];
|
|
293
403
|
requests: SignaturAntrag[];
|
|
294
404
|
fon: {
|
|
295
405
|
present: boolean;
|
|
@@ -297,8 +407,8 @@ export interface SignaturStand {
|
|
|
297
407
|
};
|
|
298
408
|
}
|
|
299
409
|
/** Die Schritte der Inbetriebnahme, in dieser Reihenfolge. */
|
|
300
|
-
export type KassenSchritt = '
|
|
301
|
-
export type KassenStatus = 'draft' | '
|
|
410
|
+
export type KassenSchritt = 'signature' | 'register_cashregister' | 'start_receipt' | 'transmit_start_receipt' | (string & {});
|
|
411
|
+
export type KassenStatus = 'draft' | 'in_progress' | 'live' | 'failed' | (string & {});
|
|
302
412
|
export interface Kasse {
|
|
303
413
|
cashregisterId: string;
|
|
304
414
|
name: string | null;
|
|
@@ -351,7 +461,7 @@ export interface CreateCashregisterResult {
|
|
|
351
461
|
started: boolean;
|
|
352
462
|
ok: boolean | null;
|
|
353
463
|
step: KassenSchritt | null;
|
|
354
|
-
/** `signature_not_ready` oder `
|
|
464
|
+
/** `signature_not_ready` oder `automation_off`, wenn nicht gestartet wurde. */
|
|
355
465
|
reason: string | null;
|
|
356
466
|
};
|
|
357
467
|
}
|
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
* einfuehrt, soll diesen Client nicht zum Absturz bringen, sondern ihn
|
|
13
13
|
* durchreichen. Eingabetypen sind dagegen eng — ein Tippfehler soll ein
|
|
14
14
|
* Compilerfehler sein und keine `validation`-Antwort vom Server.
|
|
15
|
+
*
|
|
16
|
+
* **Die Formen sind die der `/v3`** (seit 0.28.0): Feldnamen und Werte, auf
|
|
17
|
+
* die ein Programm verzweigt, sind englisch; Texte fuer Menschen (`message`,
|
|
18
|
+
* `note`, `statusText`, `nextSteps`) bleiben deutsch, die Fehlercodes ebenso.
|
|
15
19
|
*/
|
|
16
20
|
// ---------------------------------------------------------------------------
|
|
17
21
|
// Partner und Schluessel
|
|
@@ -11,11 +11,11 @@ import { type VerifyWebhookOptions, type WebhookVerifyReason } from './webhook-s
|
|
|
11
11
|
* Alle Ereignisse, die ein Webhook abonnieren **und proben** kann. Ein
|
|
12
12
|
* Endpunkt bekommt ausschliesslich die, die in seiner `events`-Liste stehen.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
14
|
+
* **Noch nicht in der Liste:** `customer.avv_accepted` und
|
|
15
|
+
* `customer.terms_accepted`. Das Backend bietet sie inzwischen zum Abonnieren
|
|
16
|
+
* an; die Liste wird mit dem Dart-Zwilling gemeinsam erweitert, weil beide
|
|
17
|
+
* gegeneinander geprueft werden. Abonnieren geht trotzdem schon (`events`
|
|
18
|
+
* nimmt jeden Namen), die Nutzlast beschreibt [ContractAcceptedEventData].
|
|
19
19
|
*/
|
|
20
20
|
export declare const PARTNER_WEBHOOK_EVENTS: readonly ["customer.created", "customer.updated", "customer.status_changed", "customer.fon_verified", "customer.live_enabled", "signature.requested", "signature.ready", "signature.failed", "cashregister.created", "cashregister.live", "cashregister.failed", "app.version.accepted", "app.version.rejected", "webhook.test"];
|
|
21
21
|
export type PartnerWebhookEventType = typeof PARTNER_WEBHOOK_EVENTS[number];
|
|
@@ -58,6 +58,38 @@ export interface PartnerWebhookEvent<T = Record<string, unknown>> {
|
|
|
58
58
|
test: boolean;
|
|
59
59
|
data: T;
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Die Sprache der Nutzlast eines Webhooks. Ein unter `/v1` angelegter Webhook
|
|
63
|
+
* spricht `v1` (deutsche Werte), ein unter `/v3` angelegter `v3`. Umstellen
|
|
64
|
+
* geht nur vorwaerts, mit `updatePartnerWebhook(id, { apiVersion: 'v3' })`;
|
|
65
|
+
* zurueck auf `v1` gibt es absichtlich nicht.
|
|
66
|
+
*
|
|
67
|
+
* Die Sprache der **Antworten** folgt dagegen dem Pfad: dieser Client ruft
|
|
68
|
+
* `/v3` und bekommt englische Antworten, gleich welche `apiVersion` ein
|
|
69
|
+
* Webhook hat.
|
|
70
|
+
*/
|
|
71
|
+
export type WebhookApiVersion = 'v1' | 'v3';
|
|
72
|
+
/** Art des Vertrags in `customer.avv_accepted` / `customer.terms_accepted`. */
|
|
73
|
+
export type ContractKind = 'avv' | 'terms';
|
|
74
|
+
/**
|
|
75
|
+
* Wo der Betrieb bestaetigt hat. Unter `v1` hiessen die ersten fuenf
|
|
76
|
+
* `einrichten`, `prozess`, `partner_vollmacht`, `admin_papier`,
|
|
77
|
+
* `papier_upload`; `app` und `portal` sind in beiden Sprachen gleich.
|
|
78
|
+
*/
|
|
79
|
+
export type ContractSource = 'setup_link' | 'process_link' | 'partner_power_of_attorney' | 'admin_paper' | 'paper_upload' | 'app' | 'portal' | (string & {});
|
|
80
|
+
/**
|
|
81
|
+
* Nutzlast von `customer.avv_accepted` und `customer.terms_accepted` in der
|
|
82
|
+
* Sprache `v3`. Ein Webhook mit `apiVersion: 'v1'` schickt hier weiter
|
|
83
|
+
* `kind: 'nutzung'` und die deutschen Quellen.
|
|
84
|
+
*/
|
|
85
|
+
export interface ContractAcceptedEventData {
|
|
86
|
+
customerId: string;
|
|
87
|
+
companyName: string;
|
|
88
|
+
kind: ContractKind;
|
|
89
|
+
version: string;
|
|
90
|
+
confirmedAt: number;
|
|
91
|
+
source: ContractSource;
|
|
92
|
+
}
|
|
61
93
|
export type WebhookEventResult = {
|
|
62
94
|
ok: true;
|
|
63
95
|
event: PartnerWebhookEvent;
|
|
@@ -82,14 +114,23 @@ export type WebhookEventResult = {
|
|
|
82
114
|
* 30 min, 2 h, 12 h) und gilt dann als fehlgeschlagen.
|
|
83
115
|
*/
|
|
84
116
|
export declare function parseWebhookEvent(optionen: VerifyWebhookOptions): Promise<WebhookEventResult>;
|
|
117
|
+
/** Stand einer Zustellung; `/v1` sagte `offen`, `zugestellt`, `fehlgeschlagen`, `verworfen`. */
|
|
118
|
+
export type WebhookDeliveryStatus = 'pending' | 'delivered' | 'failed' | 'dropped';
|
|
85
119
|
export interface PartnerWebhook {
|
|
86
120
|
webhookId: string;
|
|
121
|
+
/** Sprache der Nutzlast; fehlt sie in der Antwort, ist es ein Bestands-Webhook und damit `v1`. */
|
|
122
|
+
apiVersion: WebhookApiVersion | (string & {});
|
|
87
123
|
url: string;
|
|
88
124
|
events: string[];
|
|
89
125
|
active: boolean;
|
|
90
126
|
description: string | null;
|
|
91
127
|
createdAt: number | null;
|
|
92
|
-
|
|
128
|
+
/** Die letzte Zustellung; `null`, solange keine versucht wurde. */
|
|
129
|
+
lastDelivery: {
|
|
130
|
+
at: number | null;
|
|
131
|
+
status: WebhookDeliveryStatus | (string & {});
|
|
132
|
+
statusCode: number | null;
|
|
133
|
+
} | null;
|
|
93
134
|
/** Fehlversuche in Folge — steigt der Wert, stimmt beim Empfaenger etwas nicht. */
|
|
94
135
|
consecutiveFailures: number;
|
|
95
136
|
}
|
|
@@ -120,6 +161,17 @@ export interface WebhookPatch {
|
|
|
120
161
|
events?: (PartnerWebhookEventType | (string & {}))[];
|
|
121
162
|
description?: string;
|
|
122
163
|
active?: boolean;
|
|
164
|
+
/**
|
|
165
|
+
* Stellt die Nutzlast auf Englisch um. Nur `'v3'` ist moeglich: zurueck auf
|
|
166
|
+
* `v1` geht nicht, damit ein Partner nicht versehentlich wieder deutsche
|
|
167
|
+
* Nutzlasten bekommt.
|
|
168
|
+
*/
|
|
169
|
+
apiVersion?: 'v3';
|
|
170
|
+
}
|
|
171
|
+
export interface DeleteWebhookResult {
|
|
172
|
+
webhookId: string;
|
|
173
|
+
/** Unter `/v1` hiess das Feld `geloescht`. */
|
|
174
|
+
deleted: boolean;
|
|
123
175
|
}
|
|
124
176
|
export interface WebhookListe {
|
|
125
177
|
webhooks: PartnerWebhook[];
|
|
@@ -134,11 +186,11 @@ export interface WebhookZustellung {
|
|
|
134
186
|
webhookId: string;
|
|
135
187
|
event: string;
|
|
136
188
|
eventId: string;
|
|
137
|
-
/** `
|
|
138
|
-
status: string;
|
|
189
|
+
/** `dropped`: der Webhook wurde vor der Faelligkeit deaktiviert oder geloescht. */
|
|
190
|
+
status: WebhookDeliveryStatus | (string & {});
|
|
139
191
|
attempts: number;
|
|
140
|
-
|
|
141
|
-
|
|
192
|
+
lastAttemptAt: number | null;
|
|
193
|
+
nextAttemptAt: number | null;
|
|
142
194
|
statusCode: number | null;
|
|
143
195
|
/** Auszug der Antwort des Empfaengers, hoechstens 500 Zeichen. */
|
|
144
196
|
response: string | null;
|
|
@@ -171,13 +223,23 @@ export declare function listPartnerWebhooks(rufen: InternerTransport): Promise<W
|
|
|
171
223
|
* tun.
|
|
172
224
|
*/
|
|
173
225
|
export declare function updatePartnerWebhook(rufen: InternerTransport, webhookId: string, patch: WebhookPatch): Promise<PartnerWebhook>;
|
|
174
|
-
/**
|
|
175
|
-
|
|
226
|
+
/**
|
|
227
|
+
* Loescht einen Endpunkt. Danach kommt dort nichts mehr an; offene
|
|
228
|
+
* Zustellungen werden verworfen (`dropped`).
|
|
229
|
+
*/
|
|
230
|
+
export declare function deletePartnerWebhook(rufen: InternerTransport, webhookId: string): Promise<DeleteWebhookResult>;
|
|
231
|
+
/** Eine Zustellung der Probe, so wie `sendPartnerWebhookTest` sie meldet. */
|
|
232
|
+
export interface WebhookTestZustellung {
|
|
233
|
+
deliveryId: string;
|
|
234
|
+
webhookId: string;
|
|
235
|
+
status: WebhookDeliveryStatus | (string & {});
|
|
236
|
+
statusCode: number | null;
|
|
237
|
+
}
|
|
176
238
|
export interface WebhookTestResult {
|
|
177
239
|
eventId: string;
|
|
178
240
|
/** Welches Ereignis geprobt wurde — ohne Angabe `webhook.test`. */
|
|
179
|
-
|
|
180
|
-
deliveries:
|
|
241
|
+
event: string;
|
|
242
|
+
deliveries: WebhookTestZustellung[];
|
|
181
243
|
}
|
|
182
244
|
/**
|
|
183
245
|
* Schickt eine Probe an genau diesen Endpunkt.
|
|
@@ -14,11 +14,11 @@ import { verifyWebhookSignature, } from './webhook-signatur.js';
|
|
|
14
14
|
* Alle Ereignisse, die ein Webhook abonnieren **und proben** kann. Ein
|
|
15
15
|
* Endpunkt bekommt ausschliesslich die, die in seiner `events`-Liste stehen.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
17
|
+
* **Noch nicht in der Liste:** `customer.avv_accepted` und
|
|
18
|
+
* `customer.terms_accepted`. Das Backend bietet sie inzwischen zum Abonnieren
|
|
19
|
+
* an; die Liste wird mit dem Dart-Zwilling gemeinsam erweitert, weil beide
|
|
20
|
+
* gegeneinander geprueft werden. Abonnieren geht trotzdem schon (`events`
|
|
21
|
+
* nimmt jeden Namen), die Nutzlast beschreibt [ContractAcceptedEventData].
|
|
22
22
|
*/
|
|
23
23
|
export const PARTNER_WEBHOOK_EVENTS = [
|
|
24
24
|
'customer.created',
|
|
@@ -100,16 +100,30 @@ export async function parseWebhookEvent(optionen) {
|
|
|
100
100
|
function objekt(wert) {
|
|
101
101
|
return wert !== null && typeof wert === 'object' && !Array.isArray(wert) ? wert : {};
|
|
102
102
|
}
|
|
103
|
+
function letzteZustellung(wert) {
|
|
104
|
+
if (wert === null || typeof wert !== 'object' || Array.isArray(wert))
|
|
105
|
+
return null;
|
|
106
|
+
const z = wert;
|
|
107
|
+
return {
|
|
108
|
+
at: typeof z['at'] === 'number' ? z['at'] : null,
|
|
109
|
+
status: typeof z['status'] === 'string' ? z['status'] : '',
|
|
110
|
+
statusCode: typeof z['statusCode'] === 'number' ? z['statusCode'] : null,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
103
113
|
function webhook(eintrag) {
|
|
104
114
|
const w = objekt(eintrag);
|
|
105
115
|
return {
|
|
106
116
|
webhookId: typeof w['webhookId'] === 'string' ? w['webhookId'] : '',
|
|
117
|
+
// Fehlt das Feld, ist es ein Bestands-Webhook: der spricht v1. Kein
|
|
118
|
+
// `v3` aus Kulanz, sonst verzweigt ein Empfaenger auf englische Werte,
|
|
119
|
+
// die nie kommen.
|
|
120
|
+
apiVersion: typeof w['apiVersion'] === 'string' && w['apiVersion'] ? w['apiVersion'] : 'v1',
|
|
107
121
|
url: typeof w['url'] === 'string' ? w['url'] : '',
|
|
108
122
|
events: Array.isArray(w['events']) ? w['events'].filter((e) => typeof e === 'string') : [],
|
|
109
123
|
active: w['active'] !== false,
|
|
110
124
|
description: typeof w['description'] === 'string' ? w['description'] : null,
|
|
111
125
|
createdAt: typeof w['createdAt'] === 'number' ? w['createdAt'] : null,
|
|
112
|
-
lastDelivery:
|
|
126
|
+
lastDelivery: letzteZustellung(w['lastDelivery']),
|
|
113
127
|
consecutiveFailures: typeof w['consecutiveFailures'] === 'number' ? w['consecutiveFailures'] : 0,
|
|
114
128
|
};
|
|
115
129
|
}
|
|
@@ -186,13 +200,19 @@ export async function updatePartnerWebhook(rufen, webhookId, patch) {
|
|
|
186
200
|
const daten = objekt(await rufen('updatePartnerWebhook', { webhookId: id, patch }));
|
|
187
201
|
return webhook(daten['webhook']);
|
|
188
202
|
}
|
|
189
|
-
/**
|
|
203
|
+
/**
|
|
204
|
+
* Loescht einen Endpunkt. Danach kommt dort nichts mehr an; offene
|
|
205
|
+
* Zustellungen werden verworfen (`dropped`).
|
|
206
|
+
*/
|
|
190
207
|
export async function deletePartnerWebhook(rufen, webhookId) {
|
|
191
208
|
const id = typeof webhookId === 'string' ? webhookId.trim() : '';
|
|
192
209
|
if (!id)
|
|
193
210
|
throw new KasseneckValidationError('deletePartnerWebhook', 'webhookId fehlt', 'request');
|
|
194
211
|
const daten = objekt(await rufen('deletePartnerWebhook', { webhookId: id }));
|
|
195
|
-
return
|
|
212
|
+
return {
|
|
213
|
+
webhookId: typeof daten['webhookId'] === 'string' ? daten['webhookId'] : id,
|
|
214
|
+
deleted: daten['deleted'] === true,
|
|
215
|
+
};
|
|
196
216
|
}
|
|
197
217
|
/**
|
|
198
218
|
* Schickt eine Probe an genau diesen Endpunkt.
|
|
@@ -222,8 +242,16 @@ export async function sendPartnerWebhookTest(rufen, webhookId, event) {
|
|
|
222
242
|
const daten = objekt(await rufen('sendPartnerWebhookTest', { webhookId: id, event: ereignis || undefined }));
|
|
223
243
|
return {
|
|
224
244
|
eventId: typeof daten['eventId'] === 'string' ? daten['eventId'] : '',
|
|
225
|
-
|
|
226
|
-
deliveries: Array.isArray(daten['deliveries']) ? daten['deliveries'] : []
|
|
245
|
+
event: typeof daten['event'] === 'string' ? daten['event'] : ereignis || 'webhook.test',
|
|
246
|
+
deliveries: (Array.isArray(daten['deliveries']) ? daten['deliveries'] : []).map((eintrag) => {
|
|
247
|
+
const z = objekt(eintrag);
|
|
248
|
+
return {
|
|
249
|
+
deliveryId: typeof z['deliveryId'] === 'string' ? z['deliveryId'] : '',
|
|
250
|
+
webhookId: typeof z['webhookId'] === 'string' ? z['webhookId'] : id,
|
|
251
|
+
status: typeof z['status'] === 'string' ? z['status'] : '',
|
|
252
|
+
statusCode: typeof z['statusCode'] === 'number' ? z['statusCode'] : null,
|
|
253
|
+
};
|
|
254
|
+
}),
|
|
227
255
|
};
|
|
228
256
|
}
|
|
229
257
|
/**
|
|
@@ -247,8 +275,8 @@ export async function listPartnerWebhookDeliveries(rufen, optionen = {}) {
|
|
|
247
275
|
eventId: txt(z['eventId']) ?? '',
|
|
248
276
|
status: txt(z['status']) ?? '',
|
|
249
277
|
attempts: zahl(z['attempts']) ?? 0,
|
|
250
|
-
|
|
251
|
-
|
|
278
|
+
lastAttemptAt: zahl(z['lastAttemptAt']),
|
|
279
|
+
nextAttemptAt: zahl(z['nextAttemptAt']),
|
|
252
280
|
statusCode: zahl(z['statusCode']),
|
|
253
281
|
response: txt(z['response']),
|
|
254
282
|
createdAt: zahl(z['createdAt']),
|
|
@@ -22,9 +22,10 @@
|
|
|
22
22
|
* Terminal spricht. Das ist kein Widerspruch zur Umgebungsgrenze, sondern ein
|
|
23
23
|
* zweiter, seit `hobex-hps.js` genutzter Weg um sie herum.
|
|
24
24
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* `
|
|
25
|
+
* Gutschrift und Storno am HPS-Terminal laufen ebenfalls ueber Connect
|
|
26
|
+
* (`POST /v1/terminal/refund` bzw. `/cancel`): `HpsPayments.refund`/`cancel`
|
|
27
|
+
* mit `HpsRefundOptions`/`HpsCancelOptions`, darunter
|
|
28
|
+
* `HpsConnectClient.refund`/`cancel`, siehe `hobex-hps/connect-client.ts`.
|
|
28
29
|
*
|
|
29
30
|
* **Kassen-Benutzer-Weg (`registerUserAuth`, Browser-Kasse):** **Keiner** der
|
|
30
31
|
* vier Cloud-Zahlungs-Endpunkte (Stripe, Hobex-Cloud) setzt `allowRegisterUser`;
|
|
@@ -42,4 +43,4 @@
|
|
|
42
43
|
export { StripeLinkMode, type StripeLinkModeKey } from '../enums/index.js';
|
|
43
44
|
export { type CreateStripeLinkOptions, type StripeCaptureResult, createStripeLink, stripeCaptureIntent, } from './stripe.js';
|
|
44
45
|
export { type HobexPayOptions, type HobexRefundOptions, type HobexTransactionIdOptions, hobexPay, hobexRefund, newHobexTransactionId, } from './hobex.js';
|
|
45
|
-
export { type CardPaymentOutcome, type HpsConnectClient, type HpsConnectClientOptions, type HpsConnectFetch, type HpsConnectFetchResponse, type HpsConnectPaymentOptions, type HpsConnectTarget, type HpsConnectTransactionOptions, type HpsCode, type HpsCodeEffect, type HpsCodeReason, type HpsCodeSource, type HpsMeasuredCode, type HpsPaymentEvent, type HpsPaymentEventKind, type HpsPaymentObserver, type HpsPaymentOptions, type HpsPayments, type HpsPaymentResult, type HpsPaymentsOptions, type HpsTransactionIdGeneratorOptions, type HpsTransactionResponse, ABORTED_CODE, APPROVED_CODE, CARD_NOT_PRESENT_CODE, createHpsConnectClient, createHpsPayments, createHpsTransactionIdGenerator, HPS_CODES, HPS_MEASURED_CODES, HPS_REASON_HINTS, hpsCodeInfo, hpsCodeReason, HpsClarifyTimeoutError, HpsConnectException, HpsConnectTerminalError, HpsConnectTransportError, HpsPreflightError, HpsTransactionIdError, INVALID_TRANSACTION_CODE, isApproved, isConclusive, isConclusiveAsStatus, isHostUncertain, isHostUncertainResult, isInProgress, isNoStatement, isNotAbortable, isTechnicalError, isUnknownCode, isValidHpsTransactionId, mayRetrySafely, MAX_TRANSACTION_ID_LENGTH, newHpsTransactionId, NOT_ABORTABLE_CODE, NO_STATEMENT_CODE, parseHpsTransactionResponse, PREFLIGHT_CONNECT_CODES, TECHNICAL_ERROR_CODE, NOT_FOUND_HTTP_STATUS, TERMINAL_BUSY_HTTP_STATUS, TRANSACTION_CANCELED_CODE, } from './hobex-hps/index.js';
|
|
46
|
+
export { type CardPaymentOutcome, type HpsConnectClient, type HpsConnectCancelOptions, type HpsConnectClientOptions, type HpsConnectFetch, type HpsConnectFetchResponse, type HpsConnectPaymentOptions, type HpsConnectRefundOptions, type HpsConnectTarget, type HpsConnectTransactionOptions, type HpsCancelOptions, type HpsCode, type HpsCodeEffect, type HpsCodeReason, type HpsCodeSource, type HpsMeasuredCode, type HpsPaymentEvent, type HpsPaymentEventKind, type HpsPaymentObserver, type HpsPaymentOptions, type HpsPayments, type HpsPaymentResult, type HpsPaymentsOptions, type HpsRefundOptions, type HpsTransactionIdGeneratorOptions, type HpsTransactionResponse, ABORTED_CODE, APPROVED_CODE, CARD_NOT_PRESENT_CODE, createHpsConnectClient, createHpsPayments, createHpsTransactionIdGenerator, HPS_CODES, HPS_MEASURED_CODES, HPS_REASON_HINTS, hpsCodeInfo, hpsCodeReason, HpsClarifyTimeoutError, HpsConnectException, HpsConnectTerminalError, HpsConnectTransportError, HpsPreflightError, HpsTransactionIdError, INVALID_TRANSACTION_CODE, isApproved, isConclusive, isConclusiveAsStatus, isHostUncertain, isHostUncertainResult, isInProgress, isNoStatement, isNotAbortable, isTechnicalError, isUnknownCode, isValidHpsTransactionId, mayRetrySafely, MAX_TRANSACTION_ID_LENGTH, newHpsTransactionId, NOT_ABORTABLE_CODE, NO_STATEMENT_CODE, parseHpsTransactionResponse, PREFLIGHT_CONNECT_CODES, TECHNICAL_ERROR_CODE, NOT_FOUND_HTTP_STATUS, TERMINAL_BUSY_HTTP_STATUS, TRANSACTION_CANCELED_CODE, } from './hobex-hps/index.js';
|
|
@@ -22,9 +22,10 @@
|
|
|
22
22
|
* Terminal spricht. Das ist kein Widerspruch zur Umgebungsgrenze, sondern ein
|
|
23
23
|
* zweiter, seit `hobex-hps.js` genutzter Weg um sie herum.
|
|
24
24
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* `
|
|
25
|
+
* Gutschrift und Storno am HPS-Terminal laufen ebenfalls ueber Connect
|
|
26
|
+
* (`POST /v1/terminal/refund` bzw. `/cancel`): `HpsPayments.refund`/`cancel`
|
|
27
|
+
* mit `HpsRefundOptions`/`HpsCancelOptions`, darunter
|
|
28
|
+
* `HpsConnectClient.refund`/`cancel`, siehe `hobex-hps/connect-client.ts`.
|
|
28
29
|
*
|
|
29
30
|
* **Kassen-Benutzer-Weg (`registerUserAuth`, Browser-Kasse):** **Keiner** der
|
|
30
31
|
* vier Cloud-Zahlungs-Endpunkte (Stripe, Hobex-Cloud) setzt `allowRegisterUser`;
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Summen einer Rechnung vorab rechnen
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Summen einer Rechnung vorab rechnen, nach der frueheren Formel (Weg 2,
|
|
3
|
+
* Gleitkomma). Gedacht fuer Shops, die kassieren, bevor die Rechnung entsteht.
|
|
4
|
+
*
|
|
5
|
+
* **Veraltet.** Seit dem 23.09.2026, 17:05 Uhr stellt der Server jede neue
|
|
6
|
+
* Rechnung ueber den exakten Ganzzahl-Kern aus (`rechnungRechnen` in
|
|
7
|
+
* `…/rechnung/rechnen`). An Halbcent-Grenzen weicht diese Funktion davon um
|
|
8
|
+
* einen Cent je Satz ab (21,35 EUR netto zu 10 %: hier 23,48 EUR, auf der
|
|
9
|
+
* Rechnung 23,49 EUR). Die Formel bleibt trotzdem, wie sie ist: der Server
|
|
10
|
+
* schaltet den Kern je Konto ueber einen Schalter und rechnet Entwuerfe
|
|
11
|
+
* ausserhalb des Ausstellens teils weiter nach Weg 2, und Backend und
|
|
12
|
+
* Dart-Zwilling pruefen gegen `fixtures/rechnung-summen.json`. Neuer Code
|
|
13
|
+
* nimmt `rechnungRechnen` oder `previewInvoice`.
|
|
5
14
|
*
|
|
6
15
|
* Die Regel (je USt-Satz, Betraege in Cent, kaufmaennisch gerundet):
|
|
7
16
|
*
|
|
@@ -38,5 +47,11 @@ export interface SummenPosition {
|
|
|
38
47
|
* Server einen steuerfreien Fall ab (etwa eine ig. Lieferung), gehoert dieser
|
|
39
48
|
* Fall hierher — sonst rechnet die Funktion Steuer, die die Rechnung nicht
|
|
40
49
|
* ausweist.
|
|
50
|
+
*
|
|
51
|
+
* @deprecated Seit 0.27.3: rechnet nach der frueheren Formel (Weg 2) und kann
|
|
52
|
+
* an Halbcent-Grenzen um einen Cent je Satz von einer heute ausgestellten
|
|
53
|
+
* Rechnung abweichen. Stattdessen `rechnungRechnen` aus
|
|
54
|
+
* `@kreiseck/kasseneck-api/rechnung/rechnen` (Euro-Positionen ueber
|
|
55
|
+
* `positionAusEuro`) oder `previewInvoice` verwenden.
|
|
41
56
|
*/
|
|
42
57
|
export declare function rechnungSummen(items: readonly SummenPosition[], priceMode: PriceMode, taxScheme?: TaxScheme): InvoiceTotals;
|