@facturino/node 1.2.0 → 2.1.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.
@@ -5,7 +5,7 @@ export interface FacturinoConfig {
5
5
  maxRetries?: number;
6
6
  /** Timeout in ms (default: 30000). */
7
7
  timeout?: number;
8
- /** API version header (default: "2026-03-01"). */
8
+ /** API version header (default: "2026-09-01"). */
9
9
  apiVersion?: string;
10
10
  }
11
11
  export interface RequestOptions {
@@ -162,7 +162,35 @@ export interface Invoice {
162
162
  id: string;
163
163
  object: 'invoice';
164
164
  type: InvoiceType;
165
+ /**
166
+ * One-word SUMMARY derived from the three axes below — never an authority of
167
+ * its own. Prefer the axes when you need to tell transmission from collection.
168
+ */
165
169
  status: InvoiceStatus;
170
+ /** Documentary axis: is the invoice a draft, finalized, or cancelled? */
171
+ documentStatus?: DocumentStatus;
172
+ /** Transmission axis: where the invoice stands with the platform. */
173
+ transmissionStatus?: TransmissionStatus;
174
+ /** DGFiP detail inside `transmitted` / `rejected`. */
175
+ transmissionDetail?: TransmissionDetail;
176
+ /** Collection axis: what has actually been paid. */
177
+ paymentStatus?: PaymentStatus;
178
+ /** Fiscal source of the backing decision; `null` while a commercial draft has none. */
179
+ taxSource?: TaxSource | null;
180
+ /** The decision this invoice is backed by, when it has one. */
181
+ taxDecisionId?: string;
182
+ /** The frozen fiscal position, copied from the decision. */
183
+ taxSnapshot?: TaxSnapshot;
184
+ /**
185
+ * The operation a COMMERCIAL draft states, before any decision — typically a
186
+ * draft produced by `quotes.convert()`. Present only while `taxSource` is
187
+ * `null`; it disappears the moment the invoice is bound to a decision.
188
+ *
189
+ * Read its lines to build the decision that fiscalises this draft: the line
190
+ * references are assigned server-side at conversion, and the decision must
191
+ * state exactly the operation the draft carries.
192
+ */
193
+ commercialDraft?: CommercialDraft | null;
166
194
  number: string | null;
167
195
  currency: Currency;
168
196
  customer: CustomerRef;
@@ -222,18 +250,26 @@ export interface InvoiceScheduleParam {
222
250
  dueDate: string;
223
251
  label?: string;
224
252
  }
225
- export interface InvoiceCreateParams {
253
+ /** Fields every invoice creation carries alongside its decision. */
254
+ export interface InvoiceCreateBaseParams {
226
255
  customerId: string;
227
256
  type?: InvoiceType;
228
- lines: InvoiceLineItemParam[];
229
257
  buyer: InvoiceBuyerParam;
230
258
  dates: InvoiceCreateDates;
231
259
  payment: InvoicePaymentTerms;
232
260
  notes?: string;
233
261
  purchaseOrderNumber?: string;
234
- /** Deposit invoices to deduct from the amount due (CGI art. 289). Max 20. */
262
+ /**
263
+ * Fully paid deposit invoices to deduct (CGI art. 289). The decided
264
+ * `amountToCharge` is untouched: deposits seed `amountPaid` (BT-113) and
265
+ * lower `amountDue` (BT-115), settled server-side in the creation
266
+ * transaction. Max 20.
267
+ */
235
268
  deposits?: InvoiceDepositParam[];
236
- /** Payment schedule (2 to 12 instalments) summing to the total. */
269
+ /**
270
+ * Payment schedule (2 to 12 instalments). It must distribute EXACTLY the
271
+ * decided amount due — it never modifies the total.
272
+ */
237
273
  schedule?: InvoiceScheduleParam[];
238
274
  metadata?: Record<string, unknown>;
239
275
  /** Finalize the invoice in the same call (assigns its number). */
@@ -247,6 +283,34 @@ export interface InvoiceCreateParams {
247
283
  pa?: boolean;
248
284
  };
249
285
  }
286
+ /**
287
+ * Creating an invoice — ALWAYS backed by a FINAL tax decision, whatever its
288
+ * fiscal source (`facturino` or `integration`). The decided VAT, amounts and
289
+ * legal mentions are copied verbatim and frozen; `decisionLines` carries
290
+ * presentation only (unit, catalogue product), matched by `taxLineRef`. A
291
+ * final decision backs exactly ONE invoice.
292
+ */
293
+ export interface InvoiceCreateParams extends InvoiceCreateBaseParams {
294
+ taxDecisionId: string;
295
+ decisionLines: DecisionBackedLineParam[];
296
+ }
297
+ /**
298
+ * Binding a FINAL decision to a commercial draft that already exists — the
299
+ * draft produced by converting a quote.
300
+ *
301
+ * The same two fields the direct creation carries, and only those: the decision
302
+ * states the whole fiscal content, and the draft already states the buyer, the
303
+ * dates and the payment terms.
304
+ */
305
+ export interface InvoiceBindTaxDecisionParams {
306
+ taxDecisionId: string;
307
+ decisionLines: DecisionBackedLineParam[];
308
+ }
309
+ /**
310
+ * A COMMERCIAL line with an indicative VAT — used by quotes only. A quote is a
311
+ * commercial document; converting it to an invoice goes through a tax decision,
312
+ * which re-decides (or re-validates) the VAT.
313
+ */
250
314
  export interface InvoiceLineItemParam {
251
315
  description: string;
252
316
  quantity: string;
@@ -260,17 +324,16 @@ export interface InvoiceLineItemParam {
260
324
  discountPercent?: number;
261
325
  product?: string | null;
262
326
  }
327
+ /**
328
+ * Patching a draft. The fiscal content (lines, buyer, deposits, schedule) is
329
+ * frozen by the decision: only non-fiscal fields are patchable, and `dates` is
330
+ * restricted to the due date server-side.
331
+ */
263
332
  export interface InvoiceUpdateParams {
264
- buyer?: InvoiceBuyerParam;
265
- lines?: InvoiceLineItemParam[];
266
333
  dates?: Partial<InvoiceCreateDates>;
267
334
  payment?: Partial<InvoicePaymentTerms>;
268
335
  notes?: string;
269
336
  purchaseOrderNumber?: string;
270
- /** Replace the linked deposit invoices; an empty array unlinks them. */
271
- deposits?: InvoiceDepositParam[];
272
- /** Replace the payment schedule. */
273
- schedule?: InvoiceScheduleParam[];
274
337
  metadata?: Record<string, unknown>;
275
338
  }
276
339
  export interface InvoiceListParams extends PaginationParams {
@@ -586,7 +649,26 @@ export interface CreditNote {
586
649
  object: 'credit_note';
587
650
  customer: CustomerRef;
588
651
  relatedInvoiceId: string;
652
+ /**
653
+ * One-word SUMMARY derived from the three axes below — never an authority of
654
+ * its own. Prefer the axes when you need to tell transmission from collection.
655
+ */
589
656
  status: CreditNoteStatus;
657
+ /** Documentary axis. */
658
+ documentStatus?: DocumentStatus;
659
+ /** Transmission axis. */
660
+ transmissionStatus?: TransmissionStatus;
661
+ transmissionDetail?: TransmissionDetail;
662
+ /** Collection axis — a credit note follows the refund, not the invoice. */
663
+ paymentStatus?: PaymentStatus;
664
+ /** Where this credit note's VAT comes from. */
665
+ taxSource?: TaxSource;
666
+ /** The invoice this credit note credits. */
667
+ originalInvoiceId?: string;
668
+ /** The decision the credited invoice was backed by; the credit note inherits it. */
669
+ originalTaxDecisionId?: string;
670
+ /** The frozen fiscal position, inherited from the credited invoice. */
671
+ taxSnapshot?: TaxSnapshot;
590
672
  creditNoteType: CreditNoteType;
591
673
  number: string | null;
592
674
  currency: Currency;
@@ -618,21 +700,48 @@ export interface CreditNote {
618
700
  created: string;
619
701
  updated: string;
620
702
  }
621
- export interface CreditNoteCreateParams {
622
- customerId: string;
703
+ /**
704
+ * One credited line of a decision-backed invoice.
705
+ *
706
+ * State EITHER a `quantity` or an `amountTTC`, never both: they are two ways of
707
+ * saying how much of the line is credited, and stating both would state two
708
+ * different amounts. Omit both to credit the whole remaining balance of the line.
709
+ */
710
+ export interface CreditedLineParam {
711
+ /** Reference of the decided line being credited. */
712
+ taxLineRef: string;
713
+ /** Credited quantity, as a decimal string. Mutually exclusive with `amountTTC`. */
714
+ quantity?: string;
715
+ /** Credited amount in integer cents. Mutually exclusive with `quantity`. */
716
+ amountTTC?: number;
717
+ }
718
+ /** Fields every credit-note creation carries. */
719
+ export interface CreditNoteCreateBaseParams {
720
+ customerId?: string;
623
721
  relatedInvoiceId: string;
624
722
  creditNoteType: CreditNoteType;
625
723
  reasonCode: CreditNoteReasonCode;
626
724
  reason?: string;
627
- items: InvoiceLineItemParam[];
628
725
  dates?: {
629
726
  issued: string;
630
727
  };
631
728
  notes?: string;
632
729
  metadata?: Record<string, unknown>;
633
730
  }
731
+ /**
732
+ * Crediting an invoice.
733
+ *
734
+ * A credit note inherits the fiscal position of the invoice it corrects —
735
+ * source, snapshot and lines. The rate, the category, the VATEX code and the
736
+ * legal mention come from the frozen snapshot; `creditedLines` states WHICH
737
+ * original lines are credited and how much of each, nothing more.
738
+ */
739
+ export interface CreditNoteCreateParams extends CreditNoteCreateBaseParams {
740
+ creditedLines: CreditedLineParam[];
741
+ }
742
+ /** Updating a draft credit note. */
634
743
  export interface CreditNoteUpdateParams {
635
- items?: InvoiceLineItemParam[];
744
+ creditedLines?: CreditedLineParam[];
636
745
  reason?: string;
637
746
  notes?: string;
638
747
  metadata?: Record<string, unknown>;
@@ -715,6 +824,36 @@ export interface RecurringInvoice {
715
824
  created: string;
716
825
  updated: string;
717
826
  }
827
+ /**
828
+ * A commercial line of a decision-backed recurrence.
829
+ *
830
+ * It carries its own presentation because a recurrence stores no decision: each
831
+ * occurrence is decided on ITS OWN effective date, so a stored decision would
832
+ * apply last quarter's rules to this quarter's invoice.
833
+ */
834
+ export interface RecurringTaxLineParam extends TaxDecisionLineParam {
835
+ unit: Unit;
836
+ product?: string | null;
837
+ }
838
+ /** Integration line of a recurrence: supplied VAT, re-validated at EVERY occurrence. */
839
+ export interface RecurringIntegrationTaxLineParam extends IntegrationTaxDecisionLineParam {
840
+ unit: Unit;
841
+ product?: string | null;
842
+ }
843
+ /**
844
+ * Fiscal inputs of the per-occurrence decisions. The recurrence keeps ONE
845
+ * fiscal source for its whole life; each occurrence takes a NEW decision under
846
+ * it, on its own effective date.
847
+ */
848
+ export type RecurringTaxInputsParam = {
849
+ taxSource: 'facturino';
850
+ priceMode: PriceMode;
851
+ lines: RecurringTaxLineParam[];
852
+ } | {
853
+ taxSource: 'integration';
854
+ priceMode: PriceMode;
855
+ lines: RecurringIntegrationTaxLineParam[];
856
+ };
718
857
  export interface RecurringInvoiceCreateParams {
719
858
  customerId: string;
720
859
  frequency: RecurringFrequency;
@@ -722,8 +861,13 @@ export interface RecurringInvoiceCreateParams {
722
861
  nextGenerationDate: string;
723
862
  endDate?: string;
724
863
  customIntervalDays?: number;
864
+ /**
865
+ * Commercial inputs of the per-occurrence decisions. Required: an
866
+ * occurrence that cannot be decided generates no invoice.
867
+ */
868
+ taxInputs: RecurringTaxInputsParam;
869
+ /** Presentation and terms of the generated invoices — never a line. */
725
870
  templateInvoice: {
726
- items: InvoiceLineItemParam[];
727
871
  notes?: string;
728
872
  paymentMethod?: PaymentMethod;
729
873
  paymentTermsDays?: number;
@@ -732,12 +876,13 @@ export interface RecurringInvoiceCreateParams {
732
876
  autoSend?: boolean;
733
877
  }
734
878
  export interface RecurringInvoiceUpdateParams {
879
+ /** Replaces the fiscal inputs (same fiscal source for the recurrence's life). */
880
+ taxInputs?: RecurringTaxInputsParam;
735
881
  frequency?: RecurringFrequency;
736
882
  nextGenerationDate?: string;
737
883
  endDate?: string;
738
884
  customIntervalDays?: number;
739
885
  templateInvoice?: {
740
- items?: InvoiceLineItemParam[];
741
886
  notes?: string;
742
887
  paymentMethod?: PaymentMethod;
743
888
  paymentTermsDays?: number;
@@ -1061,7 +1206,7 @@ export interface BillingSubscription {
1061
1206
  currentPeriodEnd: string;
1062
1207
  cancelAtPeriodEnd: boolean;
1063
1208
  }
1064
- /** Subscription (platform) invoice issued by INTEK CENTER to the Facturino account. */
1209
+ /** Subscription (platform) invoice issued to this account. */
1065
1210
  export interface PlatformInvoice {
1066
1211
  object: 'platform_invoice';
1067
1212
  id: string;
@@ -1176,4 +1321,826 @@ export interface HealthStatus {
1176
1321
  region: string;
1177
1322
  timestamp: string;
1178
1323
  }
1324
+ /**
1325
+ * Whether the amounts you send include VAT.
1326
+ *
1327
+ * `tax_exclusive`: VAT is added to your unit amounts.
1328
+ * `tax_inclusive`: VAT is extracted from them.
1329
+ */
1330
+ export type PriceMode = 'tax_exclusive' | 'tax_inclusive';
1331
+ /**
1332
+ * Fiscal nature of a line.
1333
+ *
1334
+ * `electronically_supplied_services` carries its own place-of-supply rules and
1335
+ * is not the same as an ordinary service. `deposit` and `ancillary_costs`
1336
+ * follow the principal supply, which they must name via `relatedCategory`.
1337
+ */
1338
+ /**
1339
+ * One line of a commercial draft: the operation as stated, with NO VAT.
1340
+ *
1341
+ * `unitPrice` is in integer cents, in the draft's `priceMode`; `quantity` is a
1342
+ * decimal string. `rateCategory` is the band the seller asks for — the decision
1343
+ * concludes the actual rate.
1344
+ */
1345
+ export interface CommercialDraftLine {
1346
+ /** Stable reference, assigned server-side; the decision reuses it. */
1347
+ reference: string;
1348
+ description: string;
1349
+ quantity: string;
1350
+ unit: Unit;
1351
+ unitPrice: number;
1352
+ supplyCategory: SupplyCategory;
1353
+ rateCategory: RateCategory;
1354
+ discount?: TaxDecisionDiscount;
1355
+ product?: string | null;
1356
+ }
1357
+ /**
1358
+ * The operation an undecided draft states. Its total is COMMERCIAL: neither a
1359
+ * decided net nor a decided gross amount, because nothing has been decided yet.
1360
+ */
1361
+ export interface CommercialDraft {
1362
+ priceMode: PriceMode;
1363
+ lines: CommercialDraftLine[];
1364
+ totalCents: number;
1365
+ }
1366
+ export type SupplyCategory = 'goods' | 'services' | 'electronically_supplied_services' | 'deposit' | 'ancillary_costs';
1367
+ /** Principal supply a deposit or an ancillary cost follows. */
1368
+ export type PrimarySupplyCategory = 'goods' | 'services' | 'electronically_supplied_services';
1369
+ /** Rate band requested. The engine decides whether it actually applies. */
1370
+ export type RateCategory = 'standard' | 'intermediate' | 'reduced' | 'super_reduced' | 'specific';
1371
+ /** Where the goods physically go. Relevant to cross-border supplies of goods. */
1372
+ export type GoodsMovement = 'stays_in_seller_territory' | 'dispatched_to_buyer_territory' | 'unknown';
1373
+ /**
1374
+ * Only `final` carries amounts.
1375
+ *
1376
+ * On any other status `totals` and `amountToCharge` are `null`, never `0`:
1377
+ * absent is not "nothing to charge".
1378
+ */
1379
+ export type TaxDecisionStatus = 'final' | 'pending_verification' | 'unsupported';
1380
+ /** Explicit discount. `percent` in centi-percent (2500 = 25.00 %), `amount` in integer cents. */
1381
+ export interface TaxDecisionDiscount {
1382
+ type: 'percent' | 'amount';
1383
+ value: number;
1384
+ }
1385
+ export interface TaxDecisionLineParam {
1386
+ /** Stable caller-side reference, echoed on the decided line. */
1387
+ reference: string;
1388
+ description: string;
1389
+ category: SupplyCategory;
1390
+ /** Required when `category` is `deposit` or `ancillary_costs`. */
1391
+ relatedCategory?: PrimarySupplyCategory;
1392
+ rateCategory: RateCategory;
1393
+ /** Only `general` is implemented; anything else is reported as unsupported. */
1394
+ placeOfSupplyRule?: string;
1395
+ goodsMovement?: GoodsMovement;
1396
+ /** Unit amount in integer cents, in the request's `priceMode`. */
1397
+ unitAmount: number;
1398
+ /** Decimal quantity sent as a STRING, never a float. Up to 6 decimals. */
1399
+ quantity: string;
1400
+ discount?: TaxDecisionDiscount;
1401
+ }
1402
+ /** Kind of location signal (Implementing Regulation (EU) 282/2011). */
1403
+ export type LocationEvidenceKind = 'billing_address' | 'ip_geolocation' | 'bank_details' | 'sim_mobile_country' | 'fixed_line' | 'other_commercial';
1404
+ /** Who supplied the signal. */
1405
+ export type EvidenceSource = 'psp' | 'network' | 'bank' | 'declared' | 'other';
1406
+ /**
1407
+ * One piece of location evidence.
1408
+ *
1409
+ * Send the territorial SIGNAL, never the raw one: a country — and a postal code
1410
+ * where the territory needs one — not an IP address, a PSP payload or bank
1411
+ * account details. `reference` is a bounded opaque identifier (a PSP charge id,
1412
+ * a geolocation batch id), not the signal itself.
1413
+ */
1414
+ export interface LocationEvidenceParam {
1415
+ kind: LocationEvidenceKind;
1416
+ /** ISO 3166-1 alpha-2. */
1417
+ country: string;
1418
+ postalCode?: string;
1419
+ /** Is the evidence from a party independent of both seller and buyer? */
1420
+ thirdParty: boolean;
1421
+ source: EvidenceSource;
1422
+ /** Civil date `YYYY-MM-DD`. */
1423
+ collectedAt: string;
1424
+ reference?: string;
1425
+ }
1426
+ /** Non-EU business-status evidence (282/2011 art. 18-3). */
1427
+ export interface NonEuBusinessEvidenceParam {
1428
+ kind: 'tax_authority_certificate' | 'vat_or_similar_number' | 'other_commercial_evidence';
1429
+ reference: string;
1430
+ /** ISO 3166-1 alpha-2. */
1431
+ issuedByCountry: string;
1432
+ issuedByPostalCode?: string;
1433
+ reasonableVerificationPerformed: boolean;
1434
+ collectedAt: string;
1435
+ }
1436
+ interface TaxDecisionCreateBaseParams {
1437
+ customerId: string;
1438
+ /** Civil date `YYYY-MM-DD`. A timestamp is refused: the timezone call is yours. */
1439
+ effectiveAt: string;
1440
+ /** `eur` only in this ruleset. Any other currency is refused, never converted. */
1441
+ currency: string;
1442
+ priceMode: PriceMode;
1443
+ locationEvidence?: LocationEvidenceParam[];
1444
+ nonEuBusinessEvidence?: NonEuBusinessEvidenceParam;
1445
+ /**
1446
+ * Previous decision this one retries after supplying the missing facts. The
1447
+ * commercial operation must be identical; only the evidence may change.
1448
+ */
1449
+ retryOfTaxDecisionId?: string;
1450
+ }
1451
+ /**
1452
+ * `taxSource: 'facturino'` — the VAT is DETERMINED by Facturino. You describe
1453
+ * the operation; the rate, the category, the VATEX code, the legal mentions,
1454
+ * the amounts and the three reporting axes are decided server-side.
1455
+ */
1456
+ export interface FacturinoTaxDecisionCreateParams extends TaxDecisionCreateBaseParams {
1457
+ taxSource: 'facturino';
1458
+ lines: TaxDecisionLineParam[];
1459
+ }
1460
+ /**
1461
+ * Line of an INTEGRATION decision: the same commercial data plus the VAT your
1462
+ * own engine concluded. Facturino validates the coherence of rate/category/
1463
+ * VATEX and refuses any detectable contradiction (`integration_vat_incoherent`)
1464
+ * — it never silently corrects a supplied rate.
1465
+ */
1466
+ export interface IntegrationTaxDecisionLineParam {
1467
+ /** Stable caller-side reference, echoed on the decided line. */
1468
+ reference: string;
1469
+ description: string;
1470
+ category: SupplyCategory;
1471
+ /** Required when `category` is `deposit` or `ancillary_costs`. */
1472
+ relatedCategory?: PrimarySupplyCategory;
1473
+ /**
1474
+ * Physical movement of the goods.
1475
+ *
1476
+ * Required as soon as the buyer is a consumer established in another member
1477
+ * state: that movement decides whether the intra-EU distance-sale rule applies
1478
+ * (Directive 2006/112/CE art. 33, a), and it is never assumed. Irrelevant on a
1479
+ * service.
1480
+ */
1481
+ goodsMovement?: GoodsMovement;
1482
+ /** Unit amount in integer cents, in the request's `priceMode`. */
1483
+ unitAmount: number;
1484
+ /** Decimal quantity sent as a STRING, never a float. Up to 6 decimals. */
1485
+ quantity: string;
1486
+ discount?: TaxDecisionDiscount;
1487
+ /** Supplied VAT rate in centipercent (2000 = 20.00 %). Never corrected. */
1488
+ vatRate: number;
1489
+ /** Supplied EN 16931 category code (BT-151). */
1490
+ vatCode: VatCode;
1491
+ /** VATEX code (BT-121). Required for E/AE/K/G/O; refused for S/Z. */
1492
+ vatexCode?: string;
1493
+ /**
1494
+ * Declared place of supply (canonical territory id, e.g. `FR-MET`, `DE`).
1495
+ *
1496
+ * Required as soon as the buyer is established in a French overseas
1497
+ * collectivity or the TAAF (`PM`, `BL`, `MF`, `PF`, `NC`, `WF`, `TF`): the
1498
+ * place is what says whether the local tax of that collectivity is at stake,
1499
+ * and it is never assumed. A place located in one of those seven makes the
1500
+ * decision non-final, except the sourced New Caledonian B2B case.
1501
+ */
1502
+ placeOfSupply?: string;
1503
+ }
1504
+ /**
1505
+ * `taxSource: 'integration'` — the VAT is SUPPLIED by the integration and
1506
+ * validated for coherence. The amounts, the legal mentions and the three
1507
+ * reporting axes are still decided server-side, by the same engines.
1508
+ */
1509
+ export interface IntegrationTaxDecisionCreateParams extends TaxDecisionCreateBaseParams {
1510
+ taxSource: 'integration';
1511
+ lines: IntegrationTaxDecisionLineParam[];
1512
+ }
1513
+ /** The two fiscal journeys of the stable contract — `taxSource` is required. */
1514
+ export type TaxDecisionCreateParams = FacturinoTaxDecisionCreateParams | IntegrationTaxDecisionCreateParams;
1515
+ /** VIES consultation outcome. The status is kept, never the raw response. */
1516
+ export interface ViesResult {
1517
+ status: 'valid' | 'invalid' | 'unavailable' | 'invalid_format';
1518
+ checkedAt: string | null;
1519
+ normalizedVatNumber: string | null;
1520
+ source: 'vies';
1521
+ returnedName: string | null;
1522
+ consultationNumber: string | null;
1523
+ }
1524
+ /** Normalized territorial evidence kept with the decision. No raw signal is exposed. */
1525
+ export interface LocationEvidenceResult {
1526
+ kind: LocationEvidenceKind;
1527
+ territoryId: string;
1528
+ declaredCountry: string;
1529
+ declaredPostalCode: string | null;
1530
+ thirdParty: boolean;
1531
+ source: EvidenceSource;
1532
+ collectedAt: string;
1533
+ reference: string | null;
1534
+ }
1535
+ export interface NonEuBusinessEvidenceResult {
1536
+ kind: 'tax_authority_certificate' | 'vat_or_similar_number' | 'other_commercial_evidence';
1537
+ reference: string;
1538
+ issuedByTerritoryId: string;
1539
+ reasonableVerificationPerformed: boolean;
1540
+ collectedAt: string;
1541
+ }
1542
+ /** One decided line. Amounts in integer cents. */
1543
+ export interface TaxDecisionLine {
1544
+ reference: string;
1545
+ description: string;
1546
+ category: SupplyCategory;
1547
+ relatedCategory: PrimarySupplyCategory | null;
1548
+ effectiveCategory: string | null;
1549
+ quantity: string;
1550
+ unitAmount: number;
1551
+ discount: TaxDecisionDiscount | null;
1552
+ /** Requested rate band. `null` on an integration line: the exact rate was supplied. */
1553
+ rateCategory: RateCategory | null;
1554
+ placeOfSupplyRule: string | null;
1555
+ goodsMovement: GoodsMovement | null;
1556
+ treatment: string | null;
1557
+ vatCategoryCode: string | null;
1558
+ vatexCode: string | null;
1559
+ legalMention: string | null;
1560
+ rateCentipercent: number | null;
1561
+ rateBasis: string | null;
1562
+ placeOfSupply: string | null;
1563
+ placeOfSupplyReference: string | null;
1564
+ treatmentReference: string | null;
1565
+ amountHT: number | null;
1566
+ amountVAT: number | null;
1567
+ amountTTC: number | null;
1568
+ invoiceChannel: InvoiceChannel | null;
1569
+ transactionReporting: TransactionReporting | null;
1570
+ paymentReporting: PaymentReporting | null;
1571
+ }
1572
+ /** How much of the seller's covered activity Facturino actually sees. */
1573
+ export type EuThresholdCoverageMode = 'facturino_only' | 'mixed_channels';
1574
+ /**
1575
+ * The slice of the ANNUAL LEDGER this decision took, frozen with it.
1576
+ *
1577
+ * The running total is not a photograph left on the fiscal profile: it is a
1578
+ * transactional ledger per company, per mode and per year, and the decision
1579
+ * freezes the slice it occupied there — which ledger, at which version, at which
1580
+ * position in the total order of movements.
1581
+ */
1582
+ export interface TaxDecisionThresholdTrace {
1583
+ /**
1584
+ * Which fact settled the question. On `previous_year` the previous calendar
1585
+ * year closes it on its own, and the running total is reported without
1586
+ * deciding anything.
1587
+ */
1588
+ decidedOn: 'previous_year' | 'ledger_cumulative';
1589
+ /** Cap of art. 59 quater §1, in integer cents. */
1590
+ capCents: number;
1591
+ /** Ledger the figures come from (`2026_live`, `2026_test`). */
1592
+ stateId: string;
1593
+ year: string;
1594
+ /** Ledger version the slice was taken at. */
1595
+ stateVersion: number;
1596
+ /** Position of the operation in the ledger's total order. */
1597
+ sequence: number;
1598
+ /** Reservation the slice was held under — the decision's idempotency claim. */
1599
+ reservationId: string;
1600
+ coverageMode: EuThresholdCoverageMode;
1601
+ previousYearAmountCents: number;
1602
+ currentYearOpeningCents: number;
1603
+ openingDeclaredAt: string;
1604
+ /** Day the channels other than Facturino are declared complete through. */
1605
+ externalCompleteThroughDate: string;
1606
+ adjustmentTotalCents: number;
1607
+ adjustmentCount: number;
1608
+ /** Total that CERTAINLY precedes the operation: settled movements only. */
1609
+ cumulativeBeforeMinCents: number;
1610
+ /**
1611
+ * The same total plus every slice held by an operation being decided at the
1612
+ * same moment. The gap between the two bounds IS that concurrency, and a
1613
+ * verdict is frozen only when it holds at both — which is what makes it
1614
+ * immune to the abandonment of any of those operations.
1615
+ */
1616
+ cumulativeBeforeMaxCents: number;
1617
+ /** How many concurrent operations the upper bound accounts for. */
1618
+ pendingPredecessorCount: number;
1619
+ /**
1620
+ * Value the operation adds to the running total. Under a tax-inclusive price
1621
+ * the VAT-exclusive value depends on the rate the threshold has to decide, so
1622
+ * it is an interval; under a tax-exclusive price both bounds coincide.
1623
+ */
1624
+ operationValueMinCents: number;
1625
+ operationValueMaxCents: number;
1626
+ cumulativeAfterMinCents: number;
1627
+ cumulativeAfterMaxCents: number;
1628
+ }
1629
+ /** Why an amount already counted is taken back out of the running total. */
1630
+ export type EuThresholdCorrectionKind = 'credit_note' | 'cancellation' | 'refund';
1631
+ /** One movement of the ledger. Written once, never rewritten. */
1632
+ export interface EuThresholdLedgerEntry {
1633
+ /**
1634
+ * Deterministic, path-safe id derived from the movement. Your own `reference`
1635
+ * is DATA, never an identifier.
1636
+ */
1637
+ id: string;
1638
+ sequence: number;
1639
+ kind: 'opening' | 'external_adjustment' | 'external_correction' | 'reservation_consumed' | 'reservation_released' | 'review_opened' | 'review_resolved';
1640
+ /** Signed effect on the running total: negative for a qualified correction. */
1641
+ amountMin: number;
1642
+ amountMax: number;
1643
+ /** The same effect, in the art. 24 ter services perimeter. Independent. */
1644
+ evidenceAmountMin: number;
1645
+ evidenceAmountMax: number;
1646
+ cumulativeMin: number;
1647
+ cumulativeMax: number;
1648
+ evidenceCumulativeMin: number;
1649
+ evidenceCumulativeMax: number;
1650
+ taxDecisionId: string | null;
1651
+ effectiveAt: string | null;
1652
+ /** Your own reference, kept verbatim. */
1653
+ reference: string | null;
1654
+ correction: {
1655
+ kind: EuThresholdCorrectionKind;
1656
+ correctsEntryId: string;
1657
+ relatedResourceType: string;
1658
+ relatedResourceId: string;
1659
+ evidenceReference: string;
1660
+ } | null;
1661
+ reason: string;
1662
+ recordedAt: string;
1663
+ /** Did this movement bring turnover in, and therefore have anything to give back? */
1664
+ correctable: boolean;
1665
+ /** What it has ALREADY given back, over every correction that named it. */
1666
+ correctedMin: number;
1667
+ correctedEvidenceMin: number;
1668
+ correctionCount: number;
1669
+ /**
1670
+ * What is LEFT to give back on it. A movement gives back what it brought in,
1671
+ * ONCE, whatever the number of corrections: the balance is kept inside the
1672
+ * transaction, and a correction beyond it answers
1673
+ * `eu_threshold_correction_exceeds_counted`.
1674
+ */
1675
+ remainingMin: number;
1676
+ remainingEvidenceMin: number;
1677
+ }
1678
+ /** One page of movements, newest first. */
1679
+ export interface EuThresholdLedgerEntryList {
1680
+ object: 'list';
1681
+ url: string;
1682
+ data: EuThresholdLedgerEntry[];
1683
+ has_more: boolean;
1684
+ next_cursor: string | null;
1685
+ }
1686
+ /**
1687
+ * A slice held by a decision in flight.
1688
+ *
1689
+ * It is NOT acquired: it may still be given back, and it is published apart
1690
+ * from the acquired total for exactly that reason.
1691
+ */
1692
+ export interface EuThresholdReservation {
1693
+ id: string;
1694
+ sequence: number;
1695
+ effectiveAt: string;
1696
+ contributionMin: number;
1697
+ contributionMax: number;
1698
+ evidenceContributionMin: number;
1699
+ evidenceContributionMax: number;
1700
+ reservedAt: string;
1701
+ expiresAt: string;
1702
+ }
1703
+ /** Why the ledger stopped serving decisions. */
1704
+ export type EuThresholdReviewCode = 'consumed_slice_missing' | 'correction_not_qualifiable' | 'declared_by_administrator';
1705
+ /**
1706
+ * The annual ledger of the two EU B2C thresholds.
1707
+ *
1708
+ * It carries TWO counters, strictly apart: the common EUR 10,000 threshold
1709
+ * (art. 59 quater §1 — intra-EU distance sales of goods AND cross-border
1710
+ * services to consumers) and the EUR 100,000 location-evidence threshold
1711
+ * (Reg. 282/2011 art. 24 ter, 2nd subparagraph — electronically supplied
1712
+ * services only). A distance sale of goods raises the first and never the
1713
+ * second.
1714
+ */
1715
+ export interface EuThresholdLedger {
1716
+ object: 'eu_threshold_ledger';
1717
+ id: string;
1718
+ companyId: string;
1719
+ livemode: boolean;
1720
+ year: string;
1721
+ version: number;
1722
+ /**
1723
+ * `review_required` blocks every new reservation: the running total is known
1724
+ * to be wrong, and a decision is frozen on the figures it reads.
1725
+ */
1726
+ status: 'open' | 'review_required';
1727
+ review: {
1728
+ code: EuThresholdReviewCode;
1729
+ detail: string;
1730
+ openedAt: string;
1731
+ } | null;
1732
+ capCents: number;
1733
+ evidenceCapCents: number;
1734
+ opening: {
1735
+ previousYearAmount: number;
1736
+ currentYearOpening: number;
1737
+ previousYearEvidenceAmount: number;
1738
+ currentYearEvidenceOpening: number;
1739
+ coverageMode: EuThresholdCoverageMode;
1740
+ externalCompleteThroughDate: string;
1741
+ /** ISO instant the opening was actually declared. */
1742
+ declaredAt: string;
1743
+ };
1744
+ externalCompleteThroughDate: string;
1745
+ adjustmentTotal: number;
1746
+ adjustmentEvidenceTotal: number;
1747
+ adjustmentCount: number;
1748
+ /** Total of the qualified corrections, POSITIVE and subtracted. */
1749
+ correctionTotal: number;
1750
+ correctionEvidenceTotal: number;
1751
+ correctionCount: number;
1752
+ /** Total already ACQUIRED: opening + adjustments − corrections + final decisions. */
1753
+ acquiredMin: number;
1754
+ acquiredMax: number;
1755
+ acquiredEvidenceMin: number;
1756
+ acquiredEvidenceMax: number;
1757
+ /**
1758
+ * Slices held right now by operations being decided. NOT acquired, and never
1759
+ * summed with the figures above: they may still disappear.
1760
+ */
1761
+ reservedMin: number;
1762
+ reservedMax: number;
1763
+ reservedEvidenceMin: number;
1764
+ reservedEvidenceMax: number;
1765
+ /** What is left before each cap, on the figures already acquired. */
1766
+ remainingMin: number;
1767
+ evidenceRemainingMin: number;
1768
+ settledCount: number;
1769
+ lastConsumedEffectiveAt: string | null;
1770
+ reservations: EuThresholdReservation[];
1771
+ /** First page of movements, newest first. */
1772
+ entries: EuThresholdLedgerEntry[];
1773
+ entriesHasMore: boolean;
1774
+ entriesNextCursor: string | null;
1775
+ created: string;
1776
+ updated: string;
1777
+ }
1778
+ export interface OpenEuThresholdLedgerParams {
1779
+ year: string;
1780
+ /** Covered supplies of the PREVIOUS calendar year, VAT excluded, in cents. */
1781
+ previousYearAmount: number;
1782
+ /** Covered supplies ALREADY made this year, VAT excluded, in cents. */
1783
+ currentYearOpening: number;
1784
+ /**
1785
+ * Electronically supplied services to consumers of the Union over the same
1786
+ * period, DOMESTIC ones included — the perimeter of the EUR 100,000 art. 24b
1787
+ * location-evidence threshold. INDEPENDENT of `previousYearAmount` in both
1788
+ * directions: the common threshold counts only cross-border supplies, so this
1789
+ * figure can legitimately be larger.
1790
+ */
1791
+ previousYearEvidenceAmount: number;
1792
+ /** Same perimeter for the current year, independent of `currentYearOpening`. */
1793
+ currentYearEvidenceOpening: number;
1794
+ coverageMode: EuThresholdCoverageMode;
1795
+ /**
1796
+ * Day the channels other than Facturino are complete through. It must belong
1797
+ * to the ledger's own year and never be in the future.
1798
+ */
1799
+ externalCompleteThroughDate: string;
1800
+ }
1801
+ export interface EuThresholdAdjustmentParams {
1802
+ /**
1803
+ * Your own identifier: it is the entry's identity, so replaying the SAME body
1804
+ * adds nothing and reusing it for a different one answers
1805
+ * `eu_threshold_entry_conflict`. It never becomes a document id.
1806
+ */
1807
+ reference: string;
1808
+ /** VAT-exclusive amount to add, in cents. NEVER negative. */
1809
+ amount: number;
1810
+ /**
1811
+ * The art. 24b part of the same movement. INDEPENDENT of `amount`: a domestic
1812
+ * electronic service raises this counter and not the other.
1813
+ */
1814
+ evidenceAmount: number;
1815
+ externalCompleteThroughDate: string;
1816
+ reason: string;
1817
+ }
1818
+ /**
1819
+ * Take a qualified amount back out of the running total.
1820
+ *
1821
+ * This is NOT a negative adjustment. Directive 2006/112/EC art. 90(1) reduces
1822
+ * the taxable amount of a supply on cancellation, refusal or a price reduction
1823
+ * after the supply, and the thresholds count the VALUE of the supplies — so a
1824
+ * correction NAMES the movement it corrects, its qualification, the resource it
1825
+ * rests on and its evidence, and never gives back more than that movement
1826
+ * brought in.
1827
+ */
1828
+ export interface EuThresholdCorrectionParams {
1829
+ reference: string;
1830
+ /**
1831
+ * Movement of THIS ledger whose taxable amount is reduced. Constrained to the
1832
+ * ids the ledger mints (`opening`, or `adj_`/`cor_`/`con_`/`rel_`/`rev_`
1833
+ * followed by 32 hex characters): it reaches a document path, and free text
1834
+ * must not. A movement that brought no turnover in answers
1835
+ * `eu_threshold_correction_target_not_correctable`.
1836
+ */
1837
+ correctsEntryId: string;
1838
+ kind: EuThresholdCorrectionKind;
1839
+ /**
1840
+ * VAT-exclusive amount given back, in cents. The ledger keeps the BALANCE of
1841
+ * each movement inside the transaction: the corrections of one movement never
1842
+ * add up to more than it brought in.
1843
+ */
1844
+ amount: number;
1845
+ /** Its services part; independent of `amount`. */
1846
+ evidenceAmount: number;
1847
+ relatedResourceType: string;
1848
+ relatedResourceId: string;
1849
+ evidenceReference: string;
1850
+ reason: string;
1851
+ }
1852
+ /** Put the ledger under review: a declaration, so a stated reason is enough. */
1853
+ export interface EuThresholdReviewParams {
1854
+ reason: string;
1855
+ }
1856
+ /**
1857
+ * Settle a review — by RECONCILIATION, never by comment.
1858
+ *
1859
+ * A review says the running total is known to be wrong. Reopening the ledger on
1860
+ * a free-text note would put that same total back in front of the next verdict
1861
+ * with a sentence for only guarantee. So you state the figures you actually
1862
+ * verified, and the server compares them to its own: `reconciledVersion` pins
1863
+ * the state that was checked (a movement recorded since answers
1864
+ * `eu_threshold_reconciliation_stale`), and the two acquired totals must match
1865
+ * (`eu_threshold_reconciliation_mismatch`, which returns both figures).
1866
+ *
1867
+ * What was verified is written into the immutable `review_resolved` movement,
1868
+ * with its evidence reference.
1869
+ */
1870
+ export interface EuThresholdReviewResolutionParams {
1871
+ /** Ledger version the reconciliation was carried out against. */
1872
+ reconciledVersion: number;
1873
+ /** Acquired total of the common counter, as verified. */
1874
+ reconciledAcquiredMin: number;
1875
+ /** Acquired total of the art. 24b counter, as verified. */
1876
+ reconciledAcquiredEvidenceMin: number;
1877
+ /** Where the reconciliation itself is filed. */
1878
+ evidenceReference: string;
1879
+ reason: string;
1880
+ }
1881
+ export interface EuThresholdEntryListParams {
1882
+ limit?: number;
1883
+ starting_after?: string;
1884
+ }
1885
+ /** The rate entry a destination-taxed decision was taken under. */
1886
+ export interface TaxDecisionDestinationRate {
1887
+ registryVersion: string;
1888
+ memberState: string;
1889
+ /** Canonical territory rated — a region when the state publishes one. */
1890
+ territoryId: string;
1891
+ regionId: string | null;
1892
+ centipercent: number;
1893
+ validFrom: string;
1894
+ validTo: string | null;
1895
+ source: string;
1896
+ verifiedAt: string;
1897
+ }
1898
+ /**
1899
+ * How the tax due at destination is declared. Never a place-of-supply rule.
1900
+ *
1901
+ * The registration is DATED: a one-stop shop opened in October does not declare
1902
+ * a September sale.
1903
+ */
1904
+ export interface TaxDecisionDestinationMechanism {
1905
+ kind: 'oss_union' | 'local_registration';
1906
+ memberState: string;
1907
+ reference: string;
1908
+ /** Member state of identification of the scheme; `null` for a local one. */
1909
+ memberStateOfIdentification: string | null;
1910
+ effectiveFrom: string;
1911
+ effectiveTo: string | null;
1912
+ }
1913
+ /**
1914
+ * How the art. 24 ter single-evidence relaxation was settled, with the figures
1915
+ * it rested on.
1916
+ *
1917
+ * It is COMPUTED by the engine on the ledger's EUR 100,000 counter — the one
1918
+ * that never counts a distance sale of goods — and never declared by the
1919
+ * seller. `undeterminable` is a first-class answer: two items of evidence are
1920
+ * then required, and the issue says which fact is missing.
1921
+ */
1922
+ export interface TaxDecisionEvidenceRelief {
1923
+ status: 'available' | 'unavailable' | 'undeterminable';
1924
+ /** Cap of art. 24 ter, 2nd subparagraph, in integer cents (10,000,000). */
1925
+ capCents: number;
1926
+ stateId: string | null;
1927
+ year: string | null;
1928
+ previousYearAmountCents: number | null;
1929
+ cumulativeAfterMinCents: number | null;
1930
+ cumulativeAfterMaxCents: number | null;
1931
+ undeterminedCode: 'ledger_not_consulted' | 'ledger_unavailable' | 'amount_interval_straddles_cap' | null;
1932
+ }
1933
+ /**
1934
+ * What the EU B2C destination rule concluded, frozen as data.
1935
+ *
1936
+ * `null` on every operation the rule does not reach. Present as soon as it
1937
+ * covers a line, including on a decision that is NOT final: it then states what
1938
+ * was settled and what is missing.
1939
+ */
1940
+ export interface TaxDecisionEuB2cDestination {
1941
+ coveredLineIds: string[];
1942
+ ruleKinds: Array<'tbe_services' | 'intra_eu_distance_sale'>;
1943
+ destinationMemberState: string;
1944
+ destinationTerritoryId: string;
1945
+ place: 'origin' | 'destination' | null;
1946
+ /**
1947
+ * What settled the place. `oss_union_registration`: the seller holds an ACTIVE
1948
+ * Union one-stop-shop registration — for a French seller, registering IS how
1949
+ * the option of art. 59c(3) is exercised, so the threshold has nothing left to
1950
+ * decide and `threshold` stays `null`, exactly as on an explicit option.
1951
+ * Sourced for France only: the way the option is exercised is fixed by the
1952
+ * member state where it is exercised.
1953
+ */
1954
+ basis: 'multi_member_state_establishment' | 'destination_option' | 'oss_union_registration' | 'threshold_exceeded' | 'below_threshold' | null;
1955
+ reference: string;
1956
+ detail: string;
1957
+ threshold: TaxDecisionThresholdTrace | null;
1958
+ option: {
1959
+ effectiveFrom: string;
1960
+ effectiveTo: string | null;
1961
+ } | null;
1962
+ mechanism: TaxDecisionDestinationMechanism | null;
1963
+ rate: TaxDecisionDestinationRate | null;
1964
+ /** How the art. 24 ter relaxation was settled. `null` when the rule did not apply. */
1965
+ evidenceRelief: TaxDecisionEvidenceRelief | null;
1966
+ }
1967
+ /**
1968
+ * The axes French law settles on its own, carried by a decision that is NOT
1969
+ * final. An axis is `null` when it depends on the treatment the engines could
1970
+ * not conclude; it is never guessed.
1971
+ */
1972
+ export interface TaxDecisionSettledObligations {
1973
+ invoiceChannel: InvoiceChannel | null;
1974
+ transactionReporting: TransactionReporting | null;
1975
+ paymentReporting: PaymentReporting | null;
1976
+ }
1977
+ /** Whether the invoice travels the e-invoicing network. */
1978
+ export type InvoiceChannel = 'einvoicing' | 'none';
1979
+ /** Whether the transaction itself must be reported. */
1980
+ export type TransactionReporting = 'ereporting' | 'none' | 'outside_scope';
1981
+ /** Whether and how the collection must be reported. */
1982
+ export type PaymentReporting = 'fr212' | 'ereporting' | 'none';
1983
+ /** Buyer identity and qualification, frozen when the decision was taken. */
1984
+ export interface TaxDecisionCustomer {
1985
+ customerId: string;
1986
+ name: string;
1987
+ nature: 'business' | 'consumer';
1988
+ natureBasis: string;
1989
+ territoryId: string;
1990
+ territoryKind: string;
1991
+ declaredCountry: string;
1992
+ declaredPostalCode: string | null;
1993
+ legalRegistrationId: string | null;
1994
+ vatNumber: string | null;
1995
+ crossBorderTaxableStatus: string;
1996
+ businessStatusBasis: string;
1997
+ }
1998
+ /** Why an axis carries the obligation it does. */
1999
+ export interface TaxDecisionObligationReason {
2000
+ axis: 'invoiceChannel' | 'transactionReporting' | 'paymentReporting';
2001
+ code: string;
2002
+ reference: string;
2003
+ message: string;
2004
+ }
2005
+ /** What is missing, on a decision that is not final. */
2006
+ export interface TaxDecisionIssue {
2007
+ code: string;
2008
+ message: string;
2009
+ }
2010
+ export interface TaxDecisionVatBreakdownEntry {
2011
+ rateCentipercent: number;
2012
+ categoryCode: string;
2013
+ vatexCode: string | null;
2014
+ base: number;
2015
+ amount: number;
2016
+ }
2017
+ /**
2018
+ * An immutable fiscal position.
2019
+ *
2020
+ * It fixes the VAT, the exact amount to charge and the three reporting axes for
2021
+ * ONE commercial operation, then never changes. A decision is never modified or
2022
+ * deleted — request a new one, optionally with `retryOfTaxDecisionId`.
2023
+ */
2024
+ export interface TaxDecision {
2025
+ id: string;
2026
+ object: 'tax_decision';
2027
+ companyId: string;
2028
+ /** Fiscal source of the decision — `facturino` or `integration`. */
2029
+ taxSource: TaxSource;
2030
+ status: TaxDecisionStatus;
2031
+ customerId: string;
2032
+ customer: TaxDecisionCustomer;
2033
+ sellerProfileId: string;
2034
+ sellerProfileRevision: number;
2035
+ sellerProfile: Record<string, unknown>;
2036
+ currency: string;
2037
+ priceMode: PriceMode;
2038
+ effectiveAt: string;
2039
+ decidedAt: string;
2040
+ /** Past this instant the decision may no longer open a payment. It stays readable. */
2041
+ expiresAt: string;
2042
+ checkoutValidityPolicy: 'checkout-validity-v1';
2043
+ /** Derived from the server clock at read time, never stored. */
2044
+ expired: boolean;
2045
+ rulesVersion: string;
2046
+ reportingCalendar: string;
2047
+ roundingPolicy: string;
2048
+ /** SHA-256 of the canonical request. Never the raw idempotency key. */
2049
+ requestFingerprint: string;
2050
+ /** SHA-256 of the commercial operation, used to control retries. */
2051
+ operationFingerprint: string;
2052
+ lines: TaxDecisionLine[];
2053
+ /** `null` on any status other than `final`. */
2054
+ totals: {
2055
+ totalHT: number;
2056
+ totalVAT: number;
2057
+ totalTTC: number;
2058
+ } | null;
2059
+ vatBreakdown: TaxDecisionVatBreakdownEntry[];
2060
+ /** Exact amount to charge, in integer cents. `null` unless the decision is final. */
2061
+ amountToCharge: number | null;
2062
+ invoiceChannel: InvoiceChannel | null;
2063
+ transactionReporting: TransactionReporting | null;
2064
+ paymentReporting: PaymentReporting | null;
2065
+ /**
2066
+ * Obligation axes French law settles DESPITE a non-final decision.
2067
+ *
2068
+ * `null` on a final decision: the three axes above are the settled ones and
2069
+ * nothing duplicates them. On `pending_verification` or `unsupported`, each
2070
+ * axis is either the settled value or `null` when it genuinely depends on the
2071
+ * treatment that could not be concluded. This object authorises NOTHING: a
2072
+ * non-final decision is not invoiceable, never reaches a Plateforme Agréée and
2073
+ * never opens a payment.
2074
+ */
2075
+ settledObligations: TaxDecisionSettledObligations | null;
2076
+ /**
2077
+ * What the EU B2C destination rule concluded — verdict, threshold figures,
2078
+ * declarative mechanism and the exact rate entry with its source, its
2079
+ * verification date and its period. `null` on every operation the rule does
2080
+ * not reach, and on a decision frozen before this field existed.
2081
+ */
2082
+ euB2cDestination: TaxDecisionEuB2cDestination | null;
2083
+ /**
2084
+ * A foreign tax may apply. Facturino decides French VAT and the matching
2085
+ * French obligations; this case must be reviewed outside Facturino.
2086
+ */
2087
+ foreignTaxReviewRequired: boolean;
2088
+ vies: ViesResult | null;
2089
+ locationEvidence: LocationEvidenceResult[];
2090
+ nonEuBusinessEvidence: NonEuBusinessEvidenceResult | null;
2091
+ issues: TaxDecisionIssue[];
2092
+ obligationReasons: TaxDecisionObligationReason[];
2093
+ retryOfTaxDecisionId: string | null;
2094
+ livemode: boolean;
2095
+ created: string;
2096
+ updated: string;
2097
+ }
2098
+ /**
2099
+ * Where a document's VAT comes from — the two equal journeys of the stable
2100
+ * contract. `facturino`: the VAT was determined by the Facturino engines.
2101
+ * `integration`: the VAT was supplied by the integration and validated for
2102
+ * coherence — never silently corrected. A commercial draft created from the
2103
+ * app reads `taxSource: null` until its decision is taken.
2104
+ */
2105
+ export type TaxSource = 'facturino' | 'integration';
2106
+ /** Documentary axis. */
2107
+ export type DocumentStatus = 'draft' | 'finalized' | 'cancelled';
2108
+ /** Transmission axis. A collection never moves it. */
2109
+ export type TransmissionStatus = 'not_applicable' | 'pending' | 'sending' | 'deposited' | 'transmitted' | 'approved' | 'rejected';
2110
+ /** DGFiP detail inside `transmitted` / `rejected`. */
2111
+ export type TransmissionDetail = 'available' | 'received' | 'suspended' | 'refused' | null;
2112
+ /** Collection axis. A refund does not erase the collection that happened. */
2113
+ export type PaymentStatus = 'unpaid' | 'partially_paid' | 'paid' | 'partially_refunded' | 'refunded';
2114
+ /**
2115
+ * A presentation-only line of a decision-backed document.
2116
+ *
2117
+ * It carries no VAT: the rate, the category, the VATEX code and the legal
2118
+ * mention all come from the decision line it references.
2119
+ */
2120
+ export interface DecisionBackedLineParam {
2121
+ /** Reference of the decided line this document line renders. */
2122
+ taxLineRef: string;
2123
+ unit: Unit;
2124
+ product?: string | null;
2125
+ }
2126
+ /** The frozen fiscal position copied onto a document. */
2127
+ export interface TaxSnapshot {
2128
+ taxDecisionId: string;
2129
+ /** Fiscal source of the decision, frozen with it. */
2130
+ taxSource?: TaxSource;
2131
+ priceMode: PriceMode;
2132
+ currency: string;
2133
+ rulesVersion?: string;
2134
+ reportingCalendar?: string;
2135
+ effectiveAt?: string;
2136
+ invoiceChannel?: InvoiceChannel | null;
2137
+ transactionReporting?: TransactionReporting | null;
2138
+ paymentReporting?: PaymentReporting | null;
2139
+ amountToChargeCents?: number;
2140
+ legalMentions?: string[];
2141
+ lines?: Array<Record<string, unknown>>;
2142
+ totals?: Record<string, number>;
2143
+ vatBreakdown?: Array<Record<string, unknown>>;
2144
+ }
2145
+ export {};
1179
2146
  //# sourceMappingURL=types.d.ts.map