@taxora/sdk 1.8.0 → 1.9.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/dist/index.js CHANGED
@@ -440,6 +440,213 @@ var AuthEndpoint = class {
440
440
  }
441
441
  };
442
442
 
443
+ // src/dto/UsageSummary.ts
444
+ function asRecord(value) {
445
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
446
+ }
447
+ function asRecordList(value) {
448
+ return Array.isArray(value) ? value.filter((row) => asRecord(row) !== null) : [];
449
+ }
450
+ function asString(value, fallback = "") {
451
+ return typeof value === "string" ? value : fallback;
452
+ }
453
+ function asNullableString(value) {
454
+ return typeof value === "string" ? value : null;
455
+ }
456
+ function asNumber(value) {
457
+ return typeof value === "number" ? value : Number(value ?? 0) || 0;
458
+ }
459
+ function asNullableNumber(value) {
460
+ if (value === null || value === void 0 || value === "") return null;
461
+ const num = Number(value);
462
+ return Number.isFinite(num) ? num : null;
463
+ }
464
+ var UsageSummary = class _UsageSummary {
465
+ constructor(id, companyId, feature, country, regime, billingPeriod, eventCount, billableAmount, state, stateLabel, periodClosedAt, billingTriggeredAt, billedAt, stripeInvoiceId, stripeSubscriptionItemId, billingNotes, events, createdAt, updatedAt) {
466
+ this.id = id;
467
+ this.companyId = companyId;
468
+ this.feature = feature;
469
+ this.country = country;
470
+ this.regime = regime;
471
+ this.billingPeriod = billingPeriod;
472
+ this.eventCount = eventCount;
473
+ this.billableAmount = billableAmount;
474
+ this.state = state;
475
+ this.stateLabel = stateLabel;
476
+ this.periodClosedAt = periodClosedAt;
477
+ this.billingTriggeredAt = billingTriggeredAt;
478
+ this.billedAt = billedAt;
479
+ this.stripeInvoiceId = stripeInvoiceId;
480
+ this.stripeSubscriptionItemId = stripeSubscriptionItemId;
481
+ this.billingNotes = billingNotes;
482
+ this.events = events;
483
+ this.createdAt = createdAt;
484
+ this.updatedAt = updatedAt;
485
+ }
486
+ id;
487
+ companyId;
488
+ feature;
489
+ country;
490
+ regime;
491
+ billingPeriod;
492
+ eventCount;
493
+ billableAmount;
494
+ state;
495
+ stateLabel;
496
+ periodClosedAt;
497
+ billingTriggeredAt;
498
+ billedAt;
499
+ stripeInvoiceId;
500
+ stripeSubscriptionItemId;
501
+ billingNotes;
502
+ events;
503
+ createdAt;
504
+ updatedAt;
505
+ static fromArray(data) {
506
+ const amount = data["billable_amount"];
507
+ return new _UsageSummary(
508
+ asNumber(data["id"]),
509
+ asNumber(data["company_id"]),
510
+ asString(data["feature"]),
511
+ asNullableString(data["country"]),
512
+ asNullableString(data["regime"]),
513
+ asString(data["billing_period"]),
514
+ asNumber(data["event_count"]),
515
+ typeof amount === "string" ? amount : typeof amount === "number" ? String(amount) : null,
516
+ asNullableString(data["state"]),
517
+ asNullableString(data["state_label"]),
518
+ asNullableString(data["period_closed_at"]),
519
+ asNullableString(data["billing_triggered_at"]),
520
+ asNullableString(data["billed_at"]),
521
+ asNullableString(data["stripe_invoice_id"]),
522
+ asNullableString(data["stripe_subscription_item_id"]),
523
+ asNullableString(data["billing_notes"]),
524
+ asRecordList(data["events"]).map((event) => ({
525
+ id: asNumber(event["id"]),
526
+ usageSummaryId: asNullableNumber(event["usage_summary_id"]),
527
+ feature: asString(event["feature"]),
528
+ country: asNullableString(event["country"]),
529
+ regime: asNullableString(event["regime"]),
530
+ billingPeriod: asString(event["billing_period"]),
531
+ resourceType: asNullableString(event["resource_type"]),
532
+ resourceId: asNullableNumber(event["resource_id"]),
533
+ stripeUsageRecordId: asNullableString(event["stripe_usage_record_id"]),
534
+ stripeReportedAt: asNullableString(event["stripe_reported_at"]),
535
+ createdAt: asNullableString(event["created_at"])
536
+ })),
537
+ asNullableString(data["created_at"]),
538
+ asNullableString(data["updated_at"])
539
+ );
540
+ }
541
+ };
542
+ var UsageSummaryPage = class _UsageSummaryPage {
543
+ constructor(rows, currentPage, perPage, total, lastPage) {
544
+ this.rows = rows;
545
+ this.currentPage = currentPage;
546
+ this.perPage = perPage;
547
+ this.total = total;
548
+ this.lastPage = lastPage;
549
+ }
550
+ rows;
551
+ currentPage;
552
+ perPage;
553
+ total;
554
+ lastPage;
555
+ static fromResponse(payload) {
556
+ const obj = asRecord(payload) ?? {};
557
+ const rows = asRecordList(obj["data"]).map(UsageSummary.fromArray);
558
+ const meta = asRecord(obj["meta"]) ?? {};
559
+ const num = (value, fallback) => typeof value === "number" ? value : fallback;
560
+ return new _UsageSummaryPage(
561
+ rows,
562
+ num(meta["current_page"], 1),
563
+ num(meta["per_page"], rows.length),
564
+ num(meta["total"], rows.length),
565
+ num(meta["last_page"], 1)
566
+ );
567
+ }
568
+ [Symbol.iterator]() {
569
+ return this.rows[Symbol.iterator]();
570
+ }
571
+ get length() {
572
+ return this.rows.length;
573
+ }
574
+ };
575
+
576
+ // src/endpoints/BillingEndpoint.ts
577
+ var PERIOD_REGEX = /^\d{4}-(0[1-9]|1[0-2])$/;
578
+ var BillingEndpoint = class {
579
+ constructor(baseUrl, apiKey, tokenStorage, httpClient, retryPolicy = new RetryPolicy()) {
580
+ this.baseUrl = baseUrl;
581
+ this.apiKey = apiKey;
582
+ this.tokenStorage = tokenStorage;
583
+ this.httpClient = httpClient;
584
+ this.retryPolicy = retryPolicy;
585
+ }
586
+ baseUrl;
587
+ apiKey;
588
+ tokenStorage;
589
+ httpClient;
590
+ retryPolicy;
591
+ /** Paginated usage summaries, newest billing period first. `perPage` is clamped to 1-100 server-side. */
592
+ async listUsageSummaries(page = 1, perPage = 25) {
593
+ const params = new URLSearchParams();
594
+ params.set("page", String(page));
595
+ params.set("per_page", String(perPage));
596
+ const data = await this.getJson(`${this.baseUrl}/billing/usage-summaries?${params.toString()}`);
597
+ return UsageSummaryPage.fromResponse(data);
598
+ }
599
+ /**
600
+ * The usage summaries of one billing period (YYYY-MM), one per feature,
601
+ * each with its usage events. A period without usage yields a 404 (HttpException).
602
+ */
603
+ async getUsageSummaries(period) {
604
+ if (!PERIOD_REGEX.test(period)) {
605
+ throw new TaxoraException(`Invalid billing period "${period}". Expected YYYY-MM, e.g. "2026-09".`);
606
+ }
607
+ const data = await this.getJson(`${this.baseUrl}/billing/usage-summaries/${period}`);
608
+ return Array.isArray(data) ? data.filter((row) => typeof row === "object" && row !== null).map(UsageSummary.fromArray) : [];
609
+ }
610
+ buildHeaders() {
611
+ const headers = {
612
+ "Content-Type": "application/json",
613
+ "x-api-key": this.apiKey
614
+ };
615
+ const token = this.tokenStorage.get();
616
+ if (token) {
617
+ headers["Authorization"] = `Bearer ${token.accessToken}`;
618
+ }
619
+ return headers;
620
+ }
621
+ /** GET + envelope unwrap (`{success, data}` → data, which may be an object or an array). */
622
+ async getJson(url) {
623
+ return withRetries(this.retryPolicy, "billing request", async () => {
624
+ const response = await this.httpClient.request("GET", url, { headers: this.buildHeaders() });
625
+ const responseText = await response.text();
626
+ if (!response.ok) {
627
+ throw new HttpException(
628
+ describeApiError(responseText, response.status),
629
+ response.status,
630
+ responseText,
631
+ {},
632
+ response.headers.get("retry-after")
633
+ );
634
+ }
635
+ let parsed;
636
+ try {
637
+ parsed = JSON.parse(responseText);
638
+ } catch {
639
+ throw new HttpException("Invalid JSON response", response.status, responseText);
640
+ }
641
+ if (typeof parsed !== "object" || parsed === null) {
642
+ throw new HttpException("Unexpected response format", response.status, responseText);
643
+ }
644
+ const obj = parsed;
645
+ return obj["data"] !== void 0 && obj["data"] !== null ? obj["data"] : obj;
646
+ });
647
+ }
648
+ };
649
+
443
650
  // src/dto/CompanyResource.ts
444
651
  function normalizeCompanyResource(data) {
445
652
  const apiRateLimit = typeof data["api_rate_limit"] === "number" ? data["api_rate_limit"] : void 0;
@@ -566,13 +773,13 @@ function describeComplianceService(service) {
566
773
  }
567
774
 
568
775
  // src/dto/ComplianceEnrollment.ts
569
- function asString(value, fallback = "") {
776
+ function asString2(value, fallback = "") {
570
777
  return typeof value === "string" ? value : fallback;
571
778
  }
572
- function asNullableString(value) {
779
+ function asNullableString2(value) {
573
780
  return typeof value === "string" ? value : null;
574
781
  }
575
- function asNumber(value) {
782
+ function asNumber2(value) {
576
783
  return typeof value === "number" ? value : Number(value ?? 0) || 0;
577
784
  }
578
785
  var ComplianceEnrollment = class _ComplianceEnrollment {
@@ -619,29 +826,114 @@ var ComplianceEnrollment = class _ComplianceEnrollment {
619
826
  static fromArray(data) {
620
827
  const regimeConfig = typeof data["regime_config"] === "object" && data["regime_config"] !== null && !Array.isArray(data["regime_config"]) ? data["regime_config"] : null;
621
828
  return new _ComplianceEnrollment(
622
- asNumber(data["id"]),
623
- asNumber(data["company_id"]),
624
- asString(data["country"]),
625
- asString(data["regime"]),
626
- asString(data["provider"]),
829
+ asNumber2(data["id"]),
830
+ asNumber2(data["company_id"]),
831
+ asString2(data["country"]),
832
+ asString2(data["regime"]),
833
+ asString2(data["provider"]),
627
834
  toComplianceEnrollmentStatus(data["status"]),
628
- asString(data["status_label"]),
629
- asNullableString(data["status_error"]),
630
- asNullableString(data["provider_account_id"]),
631
- asNullableString(data["tax_id"]),
632
- asNullableString(data["company_register_id"]),
633
- asNullableString(data["company_register_scheme"]),
835
+ asString2(data["status_label"]),
836
+ asNullableString2(data["status_error"]),
837
+ asNullableString2(data["provider_account_id"]),
838
+ asNullableString2(data["tax_id"]),
839
+ asNullableString2(data["company_register_id"]),
840
+ asNullableString2(data["company_register_scheme"]),
634
841
  regimeConfig,
635
- asNullableString(data["reporting_start_date"]),
636
- asNullableString(data["notification_email"]),
842
+ asNullableString2(data["reporting_start_date"]),
843
+ asNullableString2(data["notification_email"]),
637
844
  data["auto_send"] === true,
638
- asNullableString(data["created_at"]),
639
- asNullableString(data["updated_at"]),
845
+ asNullableString2(data["created_at"]),
846
+ asNullableString2(data["updated_at"]),
640
847
  toComplianceService(data["service"])
641
848
  );
642
849
  }
643
850
  };
644
851
 
852
+ // src/dto/ComplianceOfferings.ts
853
+ function asRecord2(value) {
854
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
855
+ }
856
+ function asRecordList2(value) {
857
+ return Array.isArray(value) ? value.filter((row) => asRecord2(row) !== null) : [];
858
+ }
859
+ function asString3(value, fallback = "") {
860
+ return typeof value === "string" ? value : fallback;
861
+ }
862
+ function asNullableString3(value) {
863
+ return typeof value === "string" ? value : null;
864
+ }
865
+ function asNullableNumber2(value) {
866
+ if (typeof value === "number" && Number.isFinite(value)) return value;
867
+ if (typeof value === "string" && value.trim() !== "" && Number.isFinite(Number(value))) return Number(value);
868
+ return null;
869
+ }
870
+ function asStringList(value) {
871
+ return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
872
+ }
873
+ function toRequires(value) {
874
+ const record = asRecord2(value);
875
+ return record === null ? null : { country: asString3(record["country"]), service: asString3(record["service"]) };
876
+ }
877
+ var ComplianceOfferings = class _ComplianceOfferings {
878
+ constructor(offerings, coverage, access, accessByCountry) {
879
+ this.offerings = offerings;
880
+ this.coverage = coverage;
881
+ this.access = access;
882
+ this.accessByCountry = accessByCountry;
883
+ }
884
+ offerings;
885
+ coverage;
886
+ access;
887
+ accessByCountry;
888
+ static fromArray(data) {
889
+ const offerings = asRecordList2(data["data"]).map((row) => ({
890
+ country: asString3(row["country"]),
891
+ service: asString3(row["service"]),
892
+ currency: asString3(row["currency"], "EUR"),
893
+ active: row["active"] === true,
894
+ viaStripe: row["via_stripe"] === true,
895
+ plan: asNullableString3(row["plan"]),
896
+ status: asNullableString3(row["status"]),
897
+ enrolled: row["enrolled"] === true,
898
+ plans: asRecordList2(row["plans"]).map((plan) => ({
899
+ key: asString3(plan["key"]),
900
+ monthlyFee: asNullableNumber2(plan["monthly_fee"]),
901
+ setupFee: asNullableNumber2(plan["setup_fee"]),
902
+ usageTiers: Array.isArray(plan["usage_tiers"]) ? plan["usage_tiers"] : [],
903
+ volumeLimit: plan["volume_limit"] ?? null,
904
+ contactOnly: plan["contact_only"] === true,
905
+ checkoutAvailable: plan["checkout_available"] === true,
906
+ requires: toRequires(plan["requires"]),
907
+ eligible: plan["eligible"] === true
908
+ }))
909
+ }));
910
+ const coverage = asRecordList2(data["coverage"]).map((row) => ({
911
+ country: asString3(row["country"]),
912
+ availability: asString3(row["availability"]),
913
+ services: asStringList(row["services"]),
914
+ network: asNullableString3(row["network"]),
915
+ format: asNullableString3(row["format"]),
916
+ mandate: asNullableString3(row["mandate"]),
917
+ support: asString3(row["support"], "yes")
918
+ }));
919
+ const access = asRecord2(data["access"]) ?? {};
920
+ const accessByCountry = {};
921
+ for (const [country, services] of Object.entries(asRecord2(data["access_by_country"]) ?? {})) {
922
+ const flags = {};
923
+ for (const [service, value] of Object.entries(asRecord2(services) ?? {})) {
924
+ flags[service] = value === true;
925
+ }
926
+ accessByCountry[country] = flags;
927
+ }
928
+ return new _ComplianceOfferings(
929
+ offerings,
930
+ coverage,
931
+ { eReporting: access["e_reporting"] === true, eInvoicing: access["e_invoicing"] === true },
932
+ accessByCountry
933
+ );
934
+ }
935
+ };
936
+
645
937
  // src/dto/ComplianceEnrollmentPage.ts
646
938
  var ComplianceEnrollmentPage = class _ComplianceEnrollmentPage {
647
939
  constructor(rows, currentPage, perPage, total, lastPage) {
@@ -711,16 +1003,16 @@ function describeComplianceTaxReportState(state) {
711
1003
  }
712
1004
 
713
1005
  // src/dto/ComplianceTaxReport.ts
714
- function asString2(value, fallback = "") {
1006
+ function asString4(value, fallback = "") {
715
1007
  return typeof value === "string" ? value : fallback;
716
1008
  }
717
- function asNullableString2(value) {
1009
+ function asNullableString4(value) {
718
1010
  return typeof value === "string" ? value : null;
719
1011
  }
720
- function asNumber2(value) {
1012
+ function asNumber3(value) {
721
1013
  return typeof value === "number" ? value : Number(value ?? 0) || 0;
722
1014
  }
723
- function asNullableNumber(value) {
1015
+ function asNullableNumber3(value) {
724
1016
  return typeof value === "number" ? value : null;
725
1017
  }
726
1018
  function asMoney(value) {
@@ -771,25 +1063,25 @@ var ComplianceTaxReport = class _ComplianceTaxReport {
771
1063
  updatedAt;
772
1064
  static fromArray(data) {
773
1065
  return new _ComplianceTaxReport(
774
- asNumber2(data["id"]),
775
- asNumber2(data["company_id"]),
776
- asNullableNumber(data["compliance_transaction_id"]),
777
- asNullableNumber(data["ledger_id"]),
778
- asString2(data["country"]),
779
- asString2(data["regime"]),
1066
+ asNumber3(data["id"]),
1067
+ asNumber3(data["company_id"]),
1068
+ asNullableNumber3(data["compliance_transaction_id"]),
1069
+ asNullableNumber3(data["ledger_id"]),
1070
+ asString4(data["country"]),
1071
+ asString4(data["regime"]),
780
1072
  toComplianceTaxReportState(data["state"]),
781
- asString2(data["state_label"]),
1073
+ asString4(data["state_label"]),
782
1074
  data["is_terminal"] === true,
783
- asNullableString2(data["provider_tax_report_id"]),
784
- asNullableString2(data["provider_ledger_id"]),
1075
+ asNullableString4(data["provider_tax_report_id"]),
1076
+ asNullableString4(data["provider_ledger_id"]),
785
1077
  asMoney(data["base_amount"]),
786
1078
  asMoney(data["tax_amount"]),
787
1079
  asMoney(data["total_amount"]),
788
- asNullableString2(data["refusal_reason"]),
789
- asNullableString2(data["registered_at"]),
790
- asNullableString2(data["refused_at"]),
791
- asNullableString2(data["created_at"]),
792
- asNullableString2(data["updated_at"])
1080
+ asNullableString4(data["refusal_reason"]),
1081
+ asNullableString4(data["registered_at"]),
1082
+ asNullableString4(data["refused_at"]),
1083
+ asNullableString4(data["created_at"]),
1084
+ asNullableString4(data["updated_at"])
793
1085
  );
794
1086
  }
795
1087
  };
@@ -860,6 +1152,8 @@ var ComplianceTransactionState = {
860
1152
  SENDING: "sending",
861
1153
  SUBMITTED: "submitted",
862
1154
  ERROR: "error",
1155
+ /** E-invoicing only: the buyer cannot receive e-invoices — nothing was sent or billed; send your regular invoice. */
1156
+ NOT_REQUIRED: "not_required",
863
1157
  UNKNOWN: "unknown"
864
1158
  };
865
1159
  var VALUES5 = Object.values(ComplianceTransactionState);
@@ -877,6 +1171,7 @@ var DESCRIPTIONS5 = {
877
1171
  [ComplianceTransactionState.SENDING]: "Submission to the provider in progress.",
878
1172
  [ComplianceTransactionState.SUBMITTED]: "Successfully submitted to the provider.",
879
1173
  [ComplianceTransactionState.ERROR]: "Submission failed. See submissionError.",
1174
+ [ComplianceTransactionState.NOT_REQUIRED]: "The buyer cannot receive e-invoices, so none was sent or billed. Send your regular invoice instead.",
880
1175
  [ComplianceTransactionState.UNKNOWN]: "Unknown state."
881
1176
  };
882
1177
  function describeComplianceTransactionState(state) {
@@ -915,13 +1210,13 @@ function describeComplianceTransactionType(type) {
915
1210
  }
916
1211
 
917
1212
  // src/dto/ComplianceTransaction.ts
918
- function asString3(value, fallback = "") {
1213
+ function asString5(value, fallback = "") {
919
1214
  return typeof value === "string" ? value : fallback;
920
1215
  }
921
- function asNullableString3(value) {
1216
+ function asNullableString5(value) {
922
1217
  return typeof value === "string" ? value : null;
923
1218
  }
924
- function asNumber3(value) {
1219
+ function asNumber4(value) {
925
1220
  return typeof value === "number" ? value : Number(value ?? 0) || 0;
926
1221
  }
927
1222
  function asMoney2(value) {
@@ -929,34 +1224,55 @@ function asMoney2(value) {
929
1224
  if (typeof value === "number" && Number.isFinite(value)) return String(value);
930
1225
  return "0.00";
931
1226
  }
932
- function asNullableNumber2(value) {
1227
+ function asNullableNumber4(value) {
933
1228
  if (typeof value === "number" && Number.isFinite(value)) return value;
934
1229
  if (typeof value === "string" && value.trim() !== "" && Number.isFinite(Number(value))) return Number(value);
935
1230
  return null;
936
1231
  }
937
- function asRecord(value) {
1232
+ function asRecord3(value) {
938
1233
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
939
1234
  }
940
- function asRecordList(value) {
941
- return Array.isArray(value) ? value.filter((row) => asRecord(row) !== null) : [];
1235
+ function asRecordList3(value) {
1236
+ return Array.isArray(value) ? value.filter((row) => asRecord3(row) !== null) : [];
1237
+ }
1238
+ function toInvoicePdf(value) {
1239
+ const pdf = asRecord3(value);
1240
+ if (pdf === null) return null;
1241
+ return {
1242
+ filename: asNullableString5(pdf["filename"]),
1243
+ size: asNullableNumber4(pdf["size"]),
1244
+ attached: pdf["attached"] === true
1245
+ };
1246
+ }
1247
+ function toEurEquivalent(value) {
1248
+ const eur = asRecord3(value);
1249
+ if (eur === null) return null;
1250
+ return {
1251
+ subtotal: asMoney2(eur["subtotal"]),
1252
+ taxAmount: asMoney2(eur["tax_amount"]),
1253
+ total: asMoney2(eur["total"]),
1254
+ rate: asString5(eur["rate"]),
1255
+ rateDate: asNullableString5(eur["rate_date"]),
1256
+ source: asString5(eur["source"], "ECB")
1257
+ };
942
1258
  }
943
1259
  function toInvoiceLines(providerPayload) {
944
- const invoice = asRecord(asRecord(providerPayload)?.["invoice"]);
945
- return asRecordList(invoice?.["invoice_lines_attributes"]).map((line) => ({
946
- description: asString3(line["description"]),
947
- quantity: asNullableNumber2(line["quantity"]),
1260
+ const invoice = asRecord3(asRecord3(providerPayload)?.["invoice"]);
1261
+ return asRecordList3(invoice?.["invoice_lines_attributes"]).map((line) => ({
1262
+ description: asString5(line["description"]),
1263
+ quantity: asNullableNumber4(line["quantity"]),
948
1264
  price: asMoney2(line["price"]),
949
- unit: asNullableNumber2(line["unit"]),
950
- taxes: asRecordList(line["taxes_attributes"]).map((tax) => ({
951
- name: asString3(tax["name"]),
952
- percent: asNullableNumber2(tax["percent"]),
953
- category: asNullableString3(tax["category"]),
954
- comment: asNullableString3(tax["comment"])
1265
+ unit: asNullableNumber4(line["unit"]),
1266
+ taxes: asRecordList3(line["taxes_attributes"]).map((tax) => ({
1267
+ name: asString5(tax["name"]),
1268
+ percent: asNullableNumber4(tax["percent"]),
1269
+ category: asNullableString5(tax["category"]),
1270
+ comment: asNullableString5(tax["comment"])
955
1271
  }))
956
1272
  }));
957
1273
  }
958
1274
  var ComplianceTransaction = class _ComplianceTransaction {
959
- constructor(id, companyId, complianceEnrollmentId, country, regime, transactionType, transactionTypeLabel, state, stateLabel, invoiceNumber, invoiceDate, dueDate, currency, subtotal, taxAmount, total, counterpartyName, counterpartyCountry, counterpartyVatNumber, isPaid, paidAt, providerInvoiceId, submissionError, reportedAt, taxReport, createdAt, updatedAt, counterpartyRegisterId = null, counterpartyAddress = null, counterpartyCity = null, counterpartyPostalcode = null, counterpartyEmail = null, buyerReference = null, documentType = ComplianceDocumentType.INVOICE, amendedNumber = null, amendedDate = null, providerState = null, invoiceLines = []) {
1275
+ constructor(id, companyId, complianceEnrollmentId, country, regime, transactionType, transactionTypeLabel, state, stateLabel, invoiceNumber, invoiceDate, dueDate, currency, subtotal, taxAmount, total, counterpartyName, counterpartyCountry, counterpartyVatNumber, isPaid, paidAt, providerInvoiceId, submissionError, reportedAt, taxReport, createdAt, updatedAt, counterpartyRegisterId = null, counterpartyAddress = null, counterpartyCity = null, counterpartyPostalcode = null, counterpartyEmail = null, buyerReference = null, documentType = ComplianceDocumentType.INVOICE, amendedNumber = null, amendedDate = null, providerState = null, invoiceLines = [], documentUrl = null, deliveryCheck = null, invoicePdf = null, internalReference = null, pdfUrl = null, buyerRejected = false, rejectionReason = null, eurEquivalent = null) {
960
1276
  this.id = id;
961
1277
  this.companyId = companyId;
962
1278
  this.complianceEnrollmentId = complianceEnrollmentId;
@@ -995,6 +1311,14 @@ var ComplianceTransaction = class _ComplianceTransaction {
995
1311
  this.amendedDate = amendedDate;
996
1312
  this.providerState = providerState;
997
1313
  this.invoiceLines = invoiceLines;
1314
+ this.documentUrl = documentUrl;
1315
+ this.deliveryCheck = deliveryCheck;
1316
+ this.invoicePdf = invoicePdf;
1317
+ this.internalReference = internalReference;
1318
+ this.pdfUrl = pdfUrl;
1319
+ this.buyerRejected = buyerRejected;
1320
+ this.rejectionReason = rejectionReason;
1321
+ this.eurEquivalent = eurEquivalent;
998
1322
  }
999
1323
  id;
1000
1324
  companyId;
@@ -1034,50 +1358,66 @@ var ComplianceTransaction = class _ComplianceTransaction {
1034
1358
  amendedDate;
1035
1359
  providerState;
1036
1360
  invoiceLines;
1361
+ documentUrl;
1362
+ deliveryCheck;
1363
+ invoicePdf;
1364
+ internalReference;
1365
+ pdfUrl;
1366
+ buyerRejected;
1367
+ rejectionReason;
1368
+ eurEquivalent;
1037
1369
  get isCreditNote() {
1038
1370
  return this.documentType === ComplianceDocumentType.CREDIT_NOTE;
1039
1371
  }
1040
1372
  static fromArray(data) {
1041
1373
  const taxReport = typeof data["tax_report"] === "object" && data["tax_report"] !== null && !Array.isArray(data["tax_report"]) ? ComplianceTaxReport.fromArray(data["tax_report"]) : void 0;
1042
1374
  return new _ComplianceTransaction(
1043
- asNumber3(data["id"]),
1044
- asNumber3(data["company_id"]),
1045
- asNumber3(data["compliance_enrollment_id"]),
1046
- asString3(data["country"]),
1047
- asString3(data["regime"]),
1375
+ asNumber4(data["id"]),
1376
+ asNumber4(data["company_id"]),
1377
+ asNumber4(data["compliance_enrollment_id"]),
1378
+ asString5(data["country"]),
1379
+ asString5(data["regime"]),
1048
1380
  toComplianceTransactionType(data["transaction_type"]),
1049
- asString3(data["transaction_type_label"]),
1381
+ asString5(data["transaction_type_label"]),
1050
1382
  toComplianceTransactionState(data["state"]),
1051
- asString3(data["state_label"]),
1052
- asString3(data["invoice_number"]),
1053
- asNullableString3(data["invoice_date"]),
1054
- asNullableString3(data["due_date"]),
1055
- asString3(data["currency"], "EUR"),
1383
+ asString5(data["state_label"]),
1384
+ asString5(data["invoice_number"]),
1385
+ asNullableString5(data["invoice_date"]),
1386
+ asNullableString5(data["due_date"]),
1387
+ asString5(data["currency"], "EUR"),
1056
1388
  asMoney2(data["subtotal"]),
1057
1389
  asMoney2(data["tax_amount"]),
1058
1390
  asMoney2(data["total"]),
1059
- asNullableString3(data["counterparty_name"]),
1060
- asNullableString3(data["counterparty_country"]),
1061
- asNullableString3(data["counterparty_vat_number"]),
1391
+ asNullableString5(data["counterparty_name"]),
1392
+ asNullableString5(data["counterparty_country"]),
1393
+ asNullableString5(data["counterparty_vat_number"]),
1062
1394
  data["is_paid"] === true,
1063
- asNullableString3(data["paid_at"]),
1064
- asNullableString3(data["provider_invoice_id"]),
1065
- asNullableString3(data["submission_error"]),
1066
- asNullableString3(data["reported_at"]),
1395
+ asNullableString5(data["paid_at"]),
1396
+ asNullableString5(data["provider_invoice_id"]),
1397
+ asNullableString5(data["submission_error"]),
1398
+ asNullableString5(data["reported_at"]),
1067
1399
  taxReport,
1068
- asNullableString3(data["created_at"]),
1069
- asNullableString3(data["updated_at"]),
1070
- asNullableString3(data["counterparty_register_id"]),
1071
- asNullableString3(data["counterparty_address"]),
1072
- asNullableString3(data["counterparty_city"]),
1073
- asNullableString3(data["counterparty_postalcode"]),
1074
- asNullableString3(data["counterparty_email"]),
1075
- asNullableString3(data["buyer_reference"]),
1400
+ asNullableString5(data["created_at"]),
1401
+ asNullableString5(data["updated_at"]),
1402
+ asNullableString5(data["counterparty_register_id"]),
1403
+ asNullableString5(data["counterparty_address"]),
1404
+ asNullableString5(data["counterparty_city"]),
1405
+ asNullableString5(data["counterparty_postalcode"]),
1406
+ asNullableString5(data["counterparty_email"]),
1407
+ asNullableString5(data["buyer_reference"]),
1076
1408
  data["document_type"] === void 0 || data["document_type"] === null ? ComplianceDocumentType.INVOICE : toComplianceDocumentType(data["document_type"]),
1077
- asNullableString3(data["amended_number"]),
1078
- asNullableString3(data["amended_date"]),
1079
- asNullableString3(data["provider_state"]),
1080
- toInvoiceLines(data["provider_payload"])
1409
+ asNullableString5(data["amended_number"]),
1410
+ asNullableString5(data["amended_date"]),
1411
+ asNullableString5(data["provider_state"]),
1412
+ toInvoiceLines(data["provider_payload"]),
1413
+ asNullableString5(data["document_url"]),
1414
+ asRecord3(data["delivery_check"]),
1415
+ toInvoicePdf(data["invoice_pdf"]),
1416
+ asNullableString5(data["internal_reference"]),
1417
+ asNullableString5(data["pdf_url"]),
1418
+ data["buyer_rejected"] === true,
1419
+ asNullableString5(data["rejection_reason"]),
1420
+ toEurEquivalent(data["eur_equivalent"])
1081
1421
  );
1082
1422
  }
1083
1423
  };
@@ -1164,10 +1504,10 @@ function describePeppolLookupStatus(status) {
1164
1504
  }
1165
1505
 
1166
1506
  // src/dto/PeppolLookupResult.ts
1167
- function asString4(value, fallback = "") {
1507
+ function asString6(value, fallback = "") {
1168
1508
  return typeof value === "string" ? value : fallback;
1169
1509
  }
1170
- function asNullableString4(value) {
1510
+ function asNullableString6(value) {
1171
1511
  return typeof value === "string" ? value : null;
1172
1512
  }
1173
1513
  var PeppolLookupResult = class _PeppolLookupResult {
@@ -1198,21 +1538,21 @@ var PeppolLookupResult = class _PeppolLookupResult {
1198
1538
  return new _PeppolLookupResult(
1199
1539
  toPeppolLookupStatus(data["status"]),
1200
1540
  typeof data["reachable"] === "boolean" ? data["reachable"] : null,
1201
- asString4(data["country"]),
1202
- asString4(data["scheme"]),
1203
- asString4(data["id"]),
1541
+ asString6(data["country"]),
1542
+ asString6(data["scheme"]),
1543
+ asString6(data["id"]),
1204
1544
  documentTypes,
1205
- asNullableString4(data["transport_type_code"]),
1206
- asNullableString4(data["checked_at"])
1545
+ asNullableString6(data["transport_type_code"]),
1546
+ asNullableString6(data["checked_at"])
1207
1547
  );
1208
1548
  }
1209
1549
  };
1210
1550
 
1211
1551
  // src/dto/RegistryCompany.ts
1212
- function asString5(value, fallback = "") {
1552
+ function asString7(value, fallback = "") {
1213
1553
  return typeof value === "string" ? value : fallback;
1214
1554
  }
1215
- function asNullableString5(value) {
1555
+ function asNullableString7(value) {
1216
1556
  return typeof value === "string" ? value : null;
1217
1557
  }
1218
1558
  var RegistryCompany = class _RegistryCompany {
@@ -1244,27 +1584,27 @@ var RegistryCompany = class _RegistryCompany {
1244
1584
  country;
1245
1585
  static fromArray(data) {
1246
1586
  return new _RegistryCompany(
1247
- asString5(data["org_number"]),
1248
- asString5(data["company_name"]),
1249
- asNullableString5(data["organisation_form"]),
1587
+ asString7(data["org_number"]),
1588
+ asString7(data["company_name"]),
1589
+ asNullableString7(data["organisation_form"]),
1250
1590
  data["vat_registered"] === true,
1251
- asNullableString5(data["vat_number"]),
1591
+ asNullableString7(data["vat_number"]),
1252
1592
  data["enterprise_register"] === true,
1253
1593
  data["bankrupt"] === true,
1254
1594
  data["under_liquidation"] === true,
1255
- asNullableString5(data["address"]),
1256
- asNullableString5(data["postalcode"]),
1257
- asNullableString5(data["city"]),
1258
- asString5(data["country"])
1595
+ asNullableString7(data["address"]),
1596
+ asNullableString7(data["postalcode"]),
1597
+ asNullableString7(data["city"]),
1598
+ asString7(data["country"])
1259
1599
  );
1260
1600
  }
1261
1601
  };
1262
1602
 
1263
1603
  // src/dto/RevenueStatistics.ts
1264
- function asString6(value, fallback = "") {
1604
+ function asString8(value, fallback = "") {
1265
1605
  return typeof value === "string" ? value : fallback;
1266
1606
  }
1267
- function asNumber4(value) {
1607
+ function asNumber5(value) {
1268
1608
  return typeof value === "number" ? value : Number(value ?? 0) || 0;
1269
1609
  }
1270
1610
  function asMoney3(value) {
@@ -1276,7 +1616,7 @@ function asRecords(value) {
1276
1616
  }
1277
1617
  function toTotals(data) {
1278
1618
  return {
1279
- count: asNumber4(data["count"]),
1619
+ count: asNumber5(data["count"]),
1280
1620
  subtotal: asMoney3(data["subtotal"]),
1281
1621
  taxAmount: asMoney3(data["tax_amount"]),
1282
1622
  total: asMoney3(data["total"])
@@ -1313,35 +1653,35 @@ var RevenueStatistics = class _RevenueStatistics {
1313
1653
  typeof data["totals"] === "object" && data["totals"] !== null ? data["totals"] : {}
1314
1654
  );
1315
1655
  const timeSeries = asRecords(data["time_series"]).map((row) => ({
1316
- bucket: asString6(row["bucket"]),
1656
+ bucket: asString8(row["bucket"]),
1317
1657
  ...toTotals(row)
1318
1658
  }));
1319
1659
  const byType = asRecords(data["by_type"]).map((row) => ({
1320
- type: asString6(row["type"]),
1321
- typeLabel: asString6(row["type_label"]),
1322
- count: asNumber4(row["count"]),
1660
+ type: asString8(row["type"]),
1661
+ typeLabel: asString8(row["type_label"]),
1662
+ count: asNumber5(row["count"]),
1323
1663
  total: asMoney3(row["total"])
1324
1664
  }));
1325
1665
  const byCountry = asRecords(data["by_country"]).map((row) => ({
1326
- country: asString6(row["country"], "unknown"),
1327
- count: asNumber4(row["count"]),
1666
+ country: asString8(row["country"], "unknown"),
1667
+ count: asNumber5(row["count"]),
1328
1668
  total: asMoney3(row["total"])
1329
1669
  }));
1330
1670
  const byState = asRecords(data["by_state"]).map((row) => ({
1331
- state: asString6(row["state"]),
1332
- stateLabel: asString6(row["state_label"]),
1333
- count: asNumber4(row["count"]),
1671
+ state: asString8(row["state"]),
1672
+ stateLabel: asString8(row["state_label"]),
1673
+ count: asNumber5(row["count"]),
1334
1674
  total: asMoney3(row["total"])
1335
1675
  }));
1336
1676
  const byCurrency = asRecords(data["by_currency"]).map((row) => ({
1337
- currency: asString6(row["currency"]),
1677
+ currency: asString8(row["currency"]),
1338
1678
  ...toTotals(row)
1339
1679
  }));
1340
1680
  return new _RevenueStatistics(
1341
- asString6(range["date_from"]) || void 0,
1342
- asString6(range["date_to"]) || void 0,
1343
- asString6(range["interval"]) || void 0,
1344
- asString6(data["primary_currency"], "EUR"),
1681
+ asString8(range["date_from"]) || void 0,
1682
+ asString8(range["date_to"]) || void 0,
1683
+ asString8(range["interval"]) || void 0,
1684
+ asString8(data["primary_currency"], "EUR"),
1345
1685
  data["is_multi_currency"] === true,
1346
1686
  totals,
1347
1687
  timeSeries,
@@ -1354,10 +1694,10 @@ var RevenueStatistics = class _RevenueStatistics {
1354
1694
  };
1355
1695
 
1356
1696
  // src/dto/SireneLookupResult.ts
1357
- function asString7(value, fallback = "") {
1697
+ function asString9(value, fallback = "") {
1358
1698
  return typeof value === "string" ? value : fallback;
1359
1699
  }
1360
- function asNullableString6(value) {
1700
+ function asNullableString8(value) {
1361
1701
  return typeof value === "string" ? value : null;
1362
1702
  }
1363
1703
  var SireneLookupResult = class _SireneLookupResult {
@@ -1383,24 +1723,24 @@ var SireneLookupResult = class _SireneLookupResult {
1383
1723
  postalcode;
1384
1724
  static fromArray(data) {
1385
1725
  return new _SireneLookupResult(
1386
- asString7(data["company_name"]),
1387
- asString7(data["siren"]),
1388
- asNullableString6(data["siret"]),
1389
- asNullableString6(data["naf_code"]),
1390
- asNullableString6(data["naf_full"]),
1391
- asNullableString6(data["enterprise_size"]),
1392
- asNullableString6(data["address"]),
1393
- asNullableString6(data["city"]),
1394
- asNullableString6(data["postalcode"])
1726
+ asString9(data["company_name"]),
1727
+ asString9(data["siren"]),
1728
+ asNullableString8(data["siret"]),
1729
+ asNullableString8(data["naf_code"]),
1730
+ asNullableString8(data["naf_full"]),
1731
+ asNullableString8(data["enterprise_size"]),
1732
+ asNullableString8(data["address"]),
1733
+ asNullableString8(data["city"]),
1734
+ asNullableString8(data["postalcode"])
1395
1735
  );
1396
1736
  }
1397
1737
  };
1398
1738
 
1399
1739
  // src/dto/VatRates.ts
1400
- function asString8(value, fallback = "") {
1740
+ function asString10(value, fallback = "") {
1401
1741
  return typeof value === "string" ? value : fallback;
1402
1742
  }
1403
- function asNumber5(value) {
1743
+ function asNumber6(value) {
1404
1744
  return typeof value === "number" ? value : Number(value ?? 0) || 0;
1405
1745
  }
1406
1746
  var VatRates = class _VatRates {
@@ -1414,13 +1754,13 @@ var VatRates = class _VatRates {
1414
1754
  rates;
1415
1755
  static fromArray(data) {
1416
1756
  const rates = (Array.isArray(data["rates"]) ? data["rates"] : []).filter((row) => typeof row === "object" && row !== null).map((row) => ({
1417
- percent: asNumber5(row["percent"]),
1418
- category: asString8(row["category"]),
1419
- labelKey: asString8(row["label_key"]),
1420
- taxName: asString8(row["tax_name"]),
1757
+ percent: asNumber6(row["percent"]),
1758
+ category: asString10(row["category"]),
1759
+ labelKey: asString10(row["label_key"]),
1760
+ taxName: asString10(row["tax_name"]),
1421
1761
  requiresVatex: row["requires_vatex"] === true
1422
1762
  }));
1423
- return new _VatRates(asString8(data["country"]), asString8(data["currency"], "EUR"), rates);
1763
+ return new _VatRates(asString10(data["country"]), asString10(data["currency"], "EUR"), rates);
1424
1764
  }
1425
1765
  };
1426
1766
 
@@ -1479,10 +1819,15 @@ var DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
1479
1819
  var NAF_CODE_REGEX = /^\d{2}$/;
1480
1820
  var COUNTRY_REGEX = /^[A-Za-z]{2}$/;
1481
1821
  var PEPPOL_SCHEME_REGEX = /^\d{4}$/;
1822
+ var INVOICE_PDF_MAX_BYTES = 10 * 1024 * 1024;
1823
+ var INVOICE_PDF_MAGIC = [37, 80, 68, 70, 45];
1482
1824
  var INTERVALS = ["day", "week", "month"];
1483
1825
  var SERVICES = ["e_reporting", "e_invoicing"];
1484
1826
  var ENTERPRISE_SIZES = ["micro", "pme", "eti", "ge"];
1485
1827
  var TYPE_OPERATIONS = ["services", "goods", "mixed"];
1828
+ var NOTIFICATION_LANGUAGES = ["de", "en"];
1829
+ var NOTIFICATION_DIGESTS = ["off", "daily", "weekly"];
1830
+ var NOTIFICATION_MAX_RECIPIENTS = 5;
1486
1831
  var TRANSACTION_TYPES = [
1487
1832
  "b2c_outbound",
1488
1833
  "b2b_domestic_outbound",
@@ -1677,6 +2022,8 @@ var EReportingEndpoint = class {
1677
2022
  this.validateInvoiceLines(input.invoiceLines);
1678
2023
  this.validateOptionalCodes(input);
1679
2024
  this.validateBuyerFields(input);
2025
+ this.validateInternalReference(input.internalReference);
2026
+ this.validateInvoicePdfFilename(input);
1680
2027
  const body = {
1681
2028
  compliance_enrollment_id: input.complianceEnrollmentId,
1682
2029
  transaction_type: input.transactionType,
@@ -1692,23 +2039,9 @@ var EReportingEndpoint = class {
1692
2039
  const data = await this.parseJsonResponse(response);
1693
2040
  return ComplianceTransaction.fromArray(data);
1694
2041
  }
1695
- /** Paginated list of the company's transactions (newest invoice date first), filterable by date / state / type / enrollment / country. */
2042
+ /** Paginated list of the company's transactions (newest invoice date first), filterable by date / state / type / enrollment / country / search / internal reference / provider state. */
1696
2043
  async listTransactions(filters = {}) {
1697
- if (filters.complianceEnrollmentId !== void 0) {
1698
- this.validateId(filters.complianceEnrollmentId, "complianceEnrollmentId");
1699
- }
1700
- if (filters.country !== void 0 && !COUNTRY_REGEX.test(filters.country)) {
1701
- throw new TaxoraException("country must be a 2-character ISO 3166-1 alpha-2 code.");
1702
- }
1703
- const params = new URLSearchParams();
1704
- if (filters.dateFrom !== void 0) params.set("date_from", this.formatDate(filters.dateFrom));
1705
- if (filters.dateTo !== void 0) params.set("date_to", this.formatDate(filters.dateTo));
1706
- if (filters.state !== void 0) params.set("state", filters.state);
1707
- if (filters.transactionType !== void 0) params.set("transaction_type", filters.transactionType);
1708
- if (filters.complianceEnrollmentId !== void 0) {
1709
- params.set("compliance_enrollment_id", String(filters.complianceEnrollmentId));
1710
- }
1711
- if (filters.country !== void 0) params.set("country", filters.country.toUpperCase());
2044
+ const params = this.buildTransactionFilterParams(filters);
1712
2045
  if (filters.page !== void 0) params.set("page", String(filters.page));
1713
2046
  if (filters.perPage !== void 0) params.set("per_page", String(filters.perPage));
1714
2047
  const queryString = params.toString();
@@ -1716,6 +2049,27 @@ var EReportingEndpoint = class {
1716
2049
  const response = await this.sendRequest("GET", url);
1717
2050
  return ComplianceTransactionPage.fromResponse(await this.parseJsonResponse(response));
1718
2051
  }
2052
+ /**
2053
+ * All transactions matching the filters as raw CSV for bookkeeping
2054
+ * (semicolon-separated) — the same filters as listTransactions() without
2055
+ * pagination. Columns: invoice_number, internal_reference, invoice_date,
2056
+ * due_date, country, transaction_type, document_type, state, delivery_state,
2057
+ * buyer_rejected, rejection_reason, counterparty_name, counterparty_country,
2058
+ * counterparty_vat_number, currency, subtotal, tax_amount, total, eur_rate,
2059
+ * eur_rate_date, eur_subtotal, eur_tax_amount, eur_total, provider_invoice_id,
2060
+ * created_at. The eur_* columns hold the ECB reference conversion for non-EUR
2061
+ * invoices (empty for EUR). Max 50,000 rows server-side. The body is returned
2062
+ * verbatim, a UTF-8 BOM included when the API sends one.
2063
+ */
2064
+ async exportTransactionsCsv(filters = {}) {
2065
+ const queryString = this.buildTransactionFilterParams(filters).toString();
2066
+ const url = `${this.baseUrl}/compliance/transactions/export.csv${queryString ? `?${queryString}` : ""}`;
2067
+ const response = await this.sendDownloadRequest(url, "text/csv, application/json");
2068
+ if (!response.ok) {
2069
+ await this.parseJsonResponse(response);
2070
+ }
2071
+ return new TextDecoder("utf-8", { ignoreBOM: true }).decode(await response.arrayBuffer());
2072
+ }
1719
2073
  /** Get a single transaction by id (includes its tax report when one exists). */
1720
2074
  async getTransaction(id) {
1721
2075
  this.validateId(id, "id");
@@ -1731,6 +2085,8 @@ var EReportingEndpoint = class {
1731
2085
  if (input.invoiceLines !== void 0) this.validateInvoiceLines(input.invoiceLines);
1732
2086
  this.validateOptionalCodes(input);
1733
2087
  this.validateBuyerFields(input);
2088
+ this.validateInternalReference(input.internalReference);
2089
+ this.validateInvoicePdfFilename(input);
1734
2090
  const body = {};
1735
2091
  if (input.transactionType !== void 0) body["transaction_type"] = input.transactionType;
1736
2092
  if (input.invoiceNumber !== void 0) body["invoice_number"] = input.invoiceNumber;
@@ -1765,6 +2121,47 @@ var EReportingEndpoint = class {
1765
2121
  const data = await this.parseJsonResponse(response);
1766
2122
  return ComplianceTransaction.fromArray(data);
1767
2123
  }
2124
+ /**
2125
+ * Download the legal e-invoice document of a sent transaction (e-invoicing,
2126
+ * e.g. the EHF/UBL XML for Norway). Available once `documentUrl` on the
2127
+ * transaction is set.
2128
+ *
2129
+ * Errors: 404 (HttpException) for an unknown transaction; 409 (HttpException)
2130
+ * when no document exists (yet) — e.g. e-reporting, not sent, or the network
2131
+ * has not produced it yet (try again in a few minutes); 502 on provider failure.
2132
+ */
2133
+ async getTransactionDocument(id) {
2134
+ this.validateId(id, "id");
2135
+ const response = await this.sendDownloadRequest(`${this.baseUrl}/compliance/transactions/${id}/document`, "*/*");
2136
+ if (!response.ok) {
2137
+ await this.parseJsonResponse(response);
2138
+ }
2139
+ return {
2140
+ content: new Uint8Array(await response.arrayBuffer()),
2141
+ contentType: response.headers.get("content-type") ?? "application/octet-stream",
2142
+ filename: this.filenameFromDisposition(response.headers.get("content-disposition"))
2143
+ };
2144
+ }
2145
+ /**
2146
+ * Download the invoice as a readable PDF — the seller's attached PDF, or the
2147
+ * provider's rendering of the e-invoice. Available once `pdfUrl` on the
2148
+ * transaction is set.
2149
+ *
2150
+ * Errors: 404 (HttpException) for an unknown transaction; 409 (HttpException)
2151
+ * when no PDF exists (yet); 502 on provider failure.
2152
+ */
2153
+ async getTransactionPdf(id) {
2154
+ this.validateId(id, "id");
2155
+ const response = await this.sendDownloadRequest(`${this.baseUrl}/compliance/transactions/${id}/pdf`, "*/*");
2156
+ if (!response.ok) {
2157
+ await this.parseJsonResponse(response);
2158
+ }
2159
+ return {
2160
+ content: new Uint8Array(await response.arrayBuffer()),
2161
+ contentType: response.headers.get("content-type") ?? "application/octet-stream",
2162
+ filename: this.filenameFromDisposition(response.headers.get("content-disposition"))
2163
+ };
2164
+ }
1768
2165
  /**
1769
2166
  * Bulk-import transactions from a semicolon-separated CSV (one row per invoice
1770
2167
  * line; rows sharing an invoice_number are grouped into one transaction).
@@ -1796,6 +2193,9 @@ var EReportingEndpoint = class {
1796
2193
  * months and a monthly interval.
1797
2194
  */
1798
2195
  async getRevenueStatistics(filters = {}) {
2196
+ if (filters.complianceEnrollmentId !== void 0) {
2197
+ this.validateId(filters.complianceEnrollmentId, "complianceEnrollmentId");
2198
+ }
1799
2199
  if (filters.interval !== void 0 && !INTERVALS.includes(filters.interval)) {
1800
2200
  throw new TaxoraException(
1801
2201
  `Invalid statistics interval "${String(filters.interval)}". Expected one of: ${INTERVALS.join(", ")}.`
@@ -1807,12 +2207,42 @@ var EReportingEndpoint = class {
1807
2207
  if (filters.interval !== void 0) params.set("interval", filters.interval);
1808
2208
  if (filters.transactionType !== void 0) params.set("transaction_type", filters.transactionType);
1809
2209
  if (filters.state !== void 0) params.set("state", filters.state);
2210
+ if (filters.complianceEnrollmentId !== void 0) {
2211
+ params.set("compliance_enrollment_id", String(filters.complianceEnrollmentId));
2212
+ }
1810
2213
  const queryString = params.toString();
1811
2214
  const url = `${this.baseUrl}/compliance/revenue-statistics${queryString ? `?${queryString}` : ""}`;
1812
2215
  const response = await this.sendRequest("GET", url);
1813
2216
  const data = await this.parseJsonResponse(response);
1814
2217
  return RevenueStatistics.fromArray(data);
1815
2218
  }
2219
+ /**
2220
+ * Net and VAT per month, currency and tax rate as raw CSV (semicolon-separated,
2221
+ * computed from the invoice lines) — for reconciling the reported figures with
2222
+ * your VAT return. Same filters as getRevenueStatistics() (without
2223
+ * `interval`); defaults to the last 12 months. The body is returned verbatim,
2224
+ * a UTF-8 BOM included when the API sends one.
2225
+ */
2226
+ async exportRevenueTaxRatesCsv(filters = {}) {
2227
+ if (filters.complianceEnrollmentId !== void 0) {
2228
+ this.validateId(filters.complianceEnrollmentId, "complianceEnrollmentId");
2229
+ }
2230
+ const params = new URLSearchParams();
2231
+ if (filters.dateFrom !== void 0) params.set("date_from", this.formatDate(filters.dateFrom));
2232
+ if (filters.dateTo !== void 0) params.set("date_to", this.formatDate(filters.dateTo));
2233
+ if (filters.transactionType !== void 0) params.set("transaction_type", filters.transactionType);
2234
+ if (filters.state !== void 0) params.set("state", filters.state);
2235
+ if (filters.complianceEnrollmentId !== void 0) {
2236
+ params.set("compliance_enrollment_id", String(filters.complianceEnrollmentId));
2237
+ }
2238
+ const queryString = params.toString();
2239
+ const url = `${this.baseUrl}/compliance/revenue-statistics/tax-rates.csv${queryString ? `?${queryString}` : ""}`;
2240
+ const response = await this.sendDownloadRequest(url, "text/csv, application/json");
2241
+ if (!response.ok) {
2242
+ await this.parseJsonResponse(response);
2243
+ }
2244
+ return new TextDecoder("utf-8", { ignoreBOM: true }).decode(await response.arrayBuffer());
2245
+ }
1816
2246
  /**
1817
2247
  * The canonical VAT rates & DGFiP tax categories for a reporting country
1818
2248
  * (the seller's reporting-country rates, not the counterparty's). Falls back
@@ -1827,12 +2257,19 @@ var EReportingEndpoint = class {
1827
2257
  const data = await this.parseJsonResponse(response);
1828
2258
  return VatRates.fromArray(data);
1829
2259
  }
1830
- /** Paginated list of the company's tax reports (newest first), optionally filtered by state. */
1831
- async listTaxReports(page = 1, perPage = 25, state) {
2260
+ /**
2261
+ * Paginated list of the company's tax reports (newest first), optionally
2262
+ * filtered by state and by country (2-letter ISO code, case-insensitive).
2263
+ */
2264
+ async listTaxReports(page = 1, perPage = 25, state, country) {
2265
+ if (country !== void 0 && !COUNTRY_REGEX.test(country)) {
2266
+ throw new TaxoraException("country must be a 2-character ISO 3166-1 alpha-2 code.");
2267
+ }
1832
2268
  const params = new URLSearchParams();
1833
2269
  params.set("page", String(page));
1834
2270
  params.set("per_page", String(perPage));
1835
2271
  if (state !== void 0) params.set("state", state);
2272
+ if (country !== void 0) params.set("country", country.toUpperCase());
1836
2273
  const response = await this.sendRequest("GET", `${this.baseUrl}/compliance/tax-reports?${params.toString()}`);
1837
2274
  return ComplianceTaxReportPage.fromResponse(await this.parseJsonResponse(response));
1838
2275
  }
@@ -1874,8 +2311,177 @@ var EReportingEndpoint = class {
1874
2311
  await this.parseJsonResponse(response);
1875
2312
  }
1876
2313
  // ---------------------------------------------------------------------
2314
+ // Self-service plans (Stripe) — not gated by compliance access
2315
+ // ---------------------------------------------------------------------
2316
+ /**
2317
+ * Bookable compliance plans per country (net EUR prices), every country
2318
+ * Taxora reaches, and which services the company has unlocked. Works for
2319
+ * companies without compliance access.
2320
+ */
2321
+ async getOfferings() {
2322
+ const response = await this.sendRequest("GET", `${this.baseUrl}/compliance/offerings`);
2323
+ return ComplianceOfferings.fromArray(await this.parseJsonResponse(response));
2324
+ }
2325
+ /**
2326
+ * Start a Stripe Checkout for a plan (see getOfferings() — `checkoutAvailable`).
2327
+ * Open the returned `url` in the browser. After payment Stripe redirects to
2328
+ * the Taxora portal, which activates the plan; call confirmCheckout() with the
2329
+ * session id to activate it from your side (idempotent).
2330
+ *
2331
+ * Errors: 422 (ValidationException) for an unknown or contact-only plan or a
2332
+ * plan that is already active; 502 (HttpException) on a Stripe error.
2333
+ */
2334
+ async createCheckout(country, plan) {
2335
+ if (!COUNTRY_REGEX.test(country)) {
2336
+ throw new TaxoraException("country must be a 2-character ISO 3166-1 alpha-2 code.");
2337
+ }
2338
+ if (plan.trim() === "" || plan.length > 30) {
2339
+ throw new TaxoraException("plan must be a non-empty plan key of at most 30 characters.");
2340
+ }
2341
+ const response = await this.sendRequest("POST", `${this.baseUrl}/compliance/checkout`, {
2342
+ country: country.toUpperCase(),
2343
+ plan
2344
+ });
2345
+ const data = await this.parseJsonResponse(response);
2346
+ return { id: String(data["id"] ?? ""), url: String(data["url"] ?? "") };
2347
+ }
2348
+ /** Confirm a finished Stripe Checkout and activate its plan. Idempotent. */
2349
+ async confirmCheckout(sessionId) {
2350
+ if (sessionId.trim() === "" || sessionId.length > 255) {
2351
+ throw new TaxoraException("sessionId must be a non-empty string of at most 255 characters.");
2352
+ }
2353
+ const response = await this.sendRequest("POST", `${this.baseUrl}/compliance/checkout/confirm`, {
2354
+ session_id: sessionId
2355
+ });
2356
+ const data = await this.parseJsonResponse(response);
2357
+ const str = (value) => typeof value === "string" ? value : null;
2358
+ return {
2359
+ active: data["active"] === true,
2360
+ country: str(data["country"]),
2361
+ service: str(data["service"]),
2362
+ plan: str(data["plan"]),
2363
+ status: str(data["status"])
2364
+ };
2365
+ }
2366
+ /**
2367
+ * URL of the Stripe billing portal for the company's compliance plans
2368
+ * (invoices, payment method, cancellation). The portal returns to the Taxora
2369
+ * portal. 404 (HttpException) when no plan was bought via Stripe.
2370
+ */
2371
+ async createBillingPortalSession() {
2372
+ const response = await this.sendRequest("POST", `${this.baseUrl}/compliance/billing-portal`);
2373
+ const data = await this.parseJsonResponse(response);
2374
+ return String(data["url"] ?? "");
2375
+ }
2376
+ // ---------------------------------------------------------------------
2377
+ // Notification emails
2378
+ // ---------------------------------------------------------------------
2379
+ /**
2380
+ * The company's opt-in e-reporting / e-invoicing emails: recipients, language,
2381
+ * the "buyer not on Peppol" email and the digest. Readable by every member.
2382
+ */
2383
+ async getNotificationSettings() {
2384
+ const response = await this.sendRequest("GET", `${this.baseUrl}/compliance/notification-settings`);
2385
+ return this.toNotificationSettings(await this.parseJsonResponse(response));
2386
+ }
2387
+ /**
2388
+ * Change the company's e-reporting / e-invoicing emails; only the provided
2389
+ * fields change. `notOnPeppol` only reports invoices held back after it was
2390
+ * switched on.
2391
+ *
2392
+ * Errors: 422 (ValidationException) when an email is switched on without any
2393
+ * recipient; 403 (HttpException, body code `admin_only` or `read_only_role`)
2394
+ * for users who are not company admins.
2395
+ */
2396
+ async updateNotificationSettings(input) {
2397
+ const body = {};
2398
+ if (input.recipients !== void 0) {
2399
+ if (!Array.isArray(input.recipients)) {
2400
+ throw new TaxoraException("recipients must be an array of email addresses.");
2401
+ }
2402
+ if (input.recipients.length > NOTIFICATION_MAX_RECIPIENTS) {
2403
+ throw new TaxoraException(`recipients must not contain more than ${NOTIFICATION_MAX_RECIPIENTS} entries.`);
2404
+ }
2405
+ body["recipients"] = input.recipients.map((recipient, index) => {
2406
+ const email = typeof recipient === "string" ? recipient.trim() : recipient;
2407
+ this.validateEmail(email, `recipients[${index}]`);
2408
+ if (email.length > 191) {
2409
+ throw new TaxoraException(`recipients[${index}] must not exceed 191 characters.`);
2410
+ }
2411
+ return email;
2412
+ });
2413
+ }
2414
+ if (input.language !== void 0) {
2415
+ if (!NOTIFICATION_LANGUAGES.includes(input.language)) {
2416
+ throw new TaxoraException(
2417
+ `Invalid language "${String(input.language)}". Expected one of: ${NOTIFICATION_LANGUAGES.join(", ")}.`
2418
+ );
2419
+ }
2420
+ body["language"] = input.language;
2421
+ }
2422
+ if (input.notOnPeppol !== void 0) {
2423
+ if (typeof input.notOnPeppol !== "boolean") {
2424
+ throw new TaxoraException("notOnPeppol must be a boolean.");
2425
+ }
2426
+ body["not_on_peppol"] = input.notOnPeppol;
2427
+ }
2428
+ if (input.digest !== void 0) {
2429
+ if (!NOTIFICATION_DIGESTS.includes(input.digest)) {
2430
+ throw new TaxoraException(
2431
+ `Invalid digest "${String(input.digest)}". Expected one of: ${NOTIFICATION_DIGESTS.join(", ")}.`
2432
+ );
2433
+ }
2434
+ body["digest"] = input.digest;
2435
+ }
2436
+ if (Object.keys(body).length === 0) {
2437
+ throw new TaxoraException("updateNotificationSettings requires at least one field to update.");
2438
+ }
2439
+ const response = await this.sendRequest("PUT", `${this.baseUrl}/compliance/notification-settings`, body);
2440
+ return this.toNotificationSettings(await this.parseJsonResponse(response));
2441
+ }
2442
+ toNotificationSettings(data) {
2443
+ const recipients = Array.isArray(data["recipients"]) ? data["recipients"].filter((r) => typeof r === "string" && r !== "") : [];
2444
+ const digest = data["digest"];
2445
+ return {
2446
+ recipients,
2447
+ language: data["language"] === "en" ? "en" : "de",
2448
+ notOnPeppol: data["not_on_peppol"] === true,
2449
+ digest: digest === "daily" || digest === "weekly" ? digest : "off",
2450
+ digestSentAt: typeof data["digest_sent_at"] === "string" ? data["digest_sent_at"] : null
2451
+ };
2452
+ }
2453
+ // ---------------------------------------------------------------------
1877
2454
  // Input validation (fail fast, before any request is sent)
1878
2455
  // ---------------------------------------------------------------------
2456
+ /** Validated transaction-list filters as query params (shared by listTransactions and exportTransactionsCsv). */
2457
+ buildTransactionFilterParams(filters) {
2458
+ if (filters.complianceEnrollmentId !== void 0) {
2459
+ this.validateId(filters.complianceEnrollmentId, "complianceEnrollmentId");
2460
+ }
2461
+ if (filters.country !== void 0 && !COUNTRY_REGEX.test(filters.country)) {
2462
+ throw new TaxoraException("country must be a 2-character ISO 3166-1 alpha-2 code.");
2463
+ }
2464
+ if (filters.search !== void 0 && filters.search.length > 100) {
2465
+ throw new TaxoraException("search must not exceed 100 characters.");
2466
+ }
2467
+ this.validateInternalReference(filters.internalReference);
2468
+ if (filters.providerState !== void 0 && !/^[a-z_]{1,30}$/.test(filters.providerState)) {
2469
+ throw new TaxoraException('providerState must be 1-30 lowercase letters or underscores (e.g. "refused").');
2470
+ }
2471
+ const params = new URLSearchParams();
2472
+ if (filters.dateFrom !== void 0) params.set("date_from", this.formatDate(filters.dateFrom));
2473
+ if (filters.dateTo !== void 0) params.set("date_to", this.formatDate(filters.dateTo));
2474
+ if (filters.state !== void 0) params.set("state", filters.state);
2475
+ if (filters.transactionType !== void 0) params.set("transaction_type", filters.transactionType);
2476
+ if (filters.complianceEnrollmentId !== void 0) {
2477
+ params.set("compliance_enrollment_id", String(filters.complianceEnrollmentId));
2478
+ }
2479
+ if (filters.country !== void 0) params.set("country", filters.country.toUpperCase());
2480
+ if (filters.search !== void 0) params.set("search", filters.search);
2481
+ if (filters.internalReference !== void 0) params.set("internal_reference", filters.internalReference);
2482
+ if (filters.providerState !== void 0) params.set("provider_state", filters.providerState);
2483
+ return params;
2484
+ }
1879
2485
  validateEnrollmentInput(input) {
1880
2486
  if (input.siret === void 0 && input.siren === void 0) {
1881
2487
  throw new TaxoraException("Either siret or siren is required.");
@@ -2003,6 +2609,20 @@ var EReportingEndpoint = class {
2003
2609
  }
2004
2610
  });
2005
2611
  }
2612
+ validateInvoicePdfFilename(input) {
2613
+ if (input.invoicePdfFilename === void 0) return;
2614
+ if (input.invoicePdfFilename.length > 120) {
2615
+ throw new TaxoraException("invoicePdfFilename must not exceed 120 characters.");
2616
+ }
2617
+ if (input.invoicePdf === void 0) {
2618
+ throw new TaxoraException("invoicePdfFilename requires invoicePdf.");
2619
+ }
2620
+ }
2621
+ validateInternalReference(internalReference) {
2622
+ if (internalReference !== void 0 && internalReference.length > 100) {
2623
+ throw new TaxoraException("internalReference must not exceed 100 characters.");
2624
+ }
2625
+ }
2006
2626
  validateOptionalCodes(input) {
2007
2627
  if (input.currency !== void 0 && input.currency.length !== 3) {
2008
2628
  throw new TaxoraException("currency must be a 3-character ISO 4217 code.");
@@ -2084,6 +2704,29 @@ var EReportingEndpoint = class {
2084
2704
  if (input.amendedNumber !== void 0) body["amended_number"] = input.amendedNumber;
2085
2705
  if (input.amendedDate !== void 0) body["amended_date"] = this.formatDate(input.amendedDate);
2086
2706
  if (input.extraInfo !== void 0) body["extra_info"] = input.extraInfo;
2707
+ if (input.internalReference !== void 0) body["internal_reference"] = input.internalReference;
2708
+ if (input.invoicePdf !== void 0) body["invoice_pdf"] = this.encodeInvoicePdf(input.invoicePdf);
2709
+ if (input.invoicePdfFilename !== void 0) body["invoice_pdf_filename"] = input.invoicePdfFilename;
2710
+ }
2711
+ /** Bytes → base64 (validated as a PDF of at most 10 MB); strings are taken as already base64. */
2712
+ encodeInvoicePdf(pdf) {
2713
+ if (typeof pdf === "string") {
2714
+ if (pdf.trim() === "") {
2715
+ throw new TaxoraException("invoicePdf must not be empty.");
2716
+ }
2717
+ return pdf;
2718
+ }
2719
+ const bytes = pdf instanceof Uint8Array ? pdf : new Uint8Array(pdf);
2720
+ if (bytes.byteLength === 0) {
2721
+ throw new TaxoraException("invoicePdf must not be empty.");
2722
+ }
2723
+ if (bytes.byteLength > INVOICE_PDF_MAX_BYTES) {
2724
+ throw new TaxoraException("invoicePdf must not exceed 10 MB.");
2725
+ }
2726
+ if (!INVOICE_PDF_MAGIC.every((byte, index) => bytes[index] === byte)) {
2727
+ throw new TaxoraException('invoicePdf must be a PDF file (content must start with "%PDF-").');
2728
+ }
2729
+ return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64");
2087
2730
  }
2088
2731
  // ---------------------------------------------------------------------
2089
2732
  // HTTP plumbing (kept in sync with SmartEnrichmentEndpoint)
@@ -2107,6 +2750,30 @@ var EReportingEndpoint = class {
2107
2750
  const send = () => this.httpClient.request(method, url, options);
2108
2751
  return method === "GET" ? withResponseRetries(this.retryPolicy, "e-reporting request", send) : send();
2109
2752
  }
2753
+ /** GET for a non-JSON download (CSV / document): no JSON Content-Type, retried like other GETs. */
2754
+ async sendDownloadRequest(url, accept) {
2755
+ const headers = this.buildHeaders(false);
2756
+ headers["Accept"] = accept;
2757
+ return withResponseRetries(
2758
+ this.retryPolicy,
2759
+ "e-reporting download",
2760
+ () => this.httpClient.request("GET", url, { headers })
2761
+ );
2762
+ }
2763
+ /** `attachment; filename="x.xml"` (or RFC 5987 `filename*=UTF-8''x.xml`) → "x.xml". */
2764
+ filenameFromDisposition(header) {
2765
+ if (header === null) return null;
2766
+ const extended = /filename\*\s*=\s*(?:UTF-8|utf-8)''([^;]+)/.exec(header);
2767
+ if (extended?.[1] !== void 0) {
2768
+ try {
2769
+ return decodeURIComponent(extended[1].trim());
2770
+ } catch {
2771
+ }
2772
+ }
2773
+ const plain = /filename\s*=\s*"([^"]*)"|filename\s*=\s*([^;]+)/.exec(header);
2774
+ const name = (plain?.[1] ?? plain?.[2])?.trim();
2775
+ return name !== void 0 && name !== "" ? name : null;
2776
+ }
2110
2777
  /** Multipart upload: Content-Type is left to fetch so the boundary is set correctly. */
2111
2778
  async sendMultipartRequest(method, url, form) {
2112
2779
  return this.httpClient.request(method, url, { headers: this.buildHeaders(false), body: form });
@@ -2688,13 +3355,13 @@ var SmartEnrichmentHistoryPage = class _SmartEnrichmentHistoryPage {
2688
3355
  };
2689
3356
 
2690
3357
  // src/dto/SmartEnrichmentStatistics.ts
2691
- function asString9(value, fallback = "") {
3358
+ function asString11(value, fallback = "") {
2692
3359
  return typeof value === "string" ? value : fallback;
2693
3360
  }
2694
- function asNumber6(value) {
3361
+ function asNumber7(value) {
2695
3362
  return typeof value === "number" ? value : Number(value ?? 0) || 0;
2696
3363
  }
2697
- function asRecord2(value) {
3364
+ function asRecord4(value) {
2698
3365
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
2699
3366
  }
2700
3367
  function asRecords2(value) {
@@ -2717,39 +3384,39 @@ var SmartEnrichmentStatistics = class _SmartEnrichmentStatistics {
2717
3384
  byOutcome;
2718
3385
  confidenceBuckets;
2719
3386
  static fromArray(data) {
2720
- const range = asRecord2(data["range"]);
2721
- const totals = asRecord2(data["totals"]);
3387
+ const range = asRecord4(data["range"]);
3388
+ const totals = asRecord4(data["totals"]);
2722
3389
  const timeSeries = asRecords2(data["time_series"]).map((row) => ({
2723
- bucket: asString9(row["bucket"]),
2724
- jobs: asNumber6(row["jobs"]),
2725
- items: asNumber6(row["items"]),
2726
- found: asNumber6(row["found"])
3390
+ bucket: asString11(row["bucket"]),
3391
+ jobs: asNumber7(row["jobs"]),
3392
+ items: asNumber7(row["items"]),
3393
+ found: asNumber7(row["found"])
2727
3394
  }));
2728
3395
  const bySource = asRecords2(data["by_source"]).map((row) => ({
2729
- source: asString9(row["source"]),
2730
- jobs: asNumber6(row["jobs"]),
2731
- found: asNumber6(row["found"])
3396
+ source: asString11(row["source"]),
3397
+ jobs: asNumber7(row["jobs"]),
3398
+ found: asNumber7(row["found"])
2732
3399
  }));
2733
3400
  const byOutcome = asRecords2(data["by_outcome"]).map((row) => ({
2734
- outcome: asString9(row["outcome"]),
2735
- count: asNumber6(row["count"])
3401
+ outcome: asString11(row["outcome"]),
3402
+ count: asNumber7(row["count"])
2736
3403
  }));
2737
3404
  const confidenceBuckets = asRecords2(data["confidence_buckets"]).map((row) => ({
2738
- bucket: asString9(row["bucket"]),
2739
- count: asNumber6(row["count"])
3405
+ bucket: asString11(row["bucket"]),
3406
+ count: asNumber7(row["count"])
2740
3407
  }));
2741
3408
  return new _SmartEnrichmentStatistics(
2742
3409
  {
2743
- dateFrom: asString9(range["date_from"]),
2744
- dateTo: asString9(range["date_to"]),
2745
- interval: asString9(range["interval"])
3410
+ dateFrom: asString11(range["date_from"]),
3411
+ dateTo: asString11(range["date_to"]),
3412
+ interval: asString11(range["interval"])
2746
3413
  },
2747
3414
  {
2748
- jobs: asNumber6(totals["jobs"]),
2749
- items: asNumber6(totals["items"]),
2750
- found: asNumber6(totals["found"]),
2751
- foundRate: asNumber6(totals["found_rate"]),
2752
- avgConfidence: asNumber6(totals["avg_confidence"])
3415
+ jobs: asNumber7(totals["jobs"]),
3416
+ items: asNumber7(totals["items"]),
3417
+ found: asNumber7(totals["found"]),
3418
+ foundRate: asNumber7(totals["found_rate"]),
3419
+ avgConfidence: asNumber7(totals["avg_confidence"])
2753
3420
  },
2754
3421
  timeSeries,
2755
3422
  bySource,
@@ -4029,7 +4696,7 @@ var AuthRetryHttpClient = class {
4029
4696
  };
4030
4697
 
4031
4698
  // src/version.ts
4032
- var SDK_VERSION = "1.8.0";
4699
+ var SDK_VERSION = "1.9.0";
4033
4700
 
4034
4701
  // src/http/SdkVersionHttpClient.ts
4035
4702
  var SDK_VERSION_HEADER = "X-Taxora-SDK-Version";
@@ -4056,6 +4723,7 @@ var TaxoraClient = class {
4056
4723
  company;
4057
4724
  smartEnrichment;
4058
4725
  eReporting;
4726
+ billing;
4059
4727
  baseUrl;
4060
4728
  constructor(options) {
4061
4729
  const environment = options.environment ?? Environment.SANDBOX;
@@ -4076,6 +4744,7 @@ var TaxoraClient = class {
4076
4744
  retryPolicy
4077
4745
  );
4078
4746
  this.eReporting = new EReportingEndpoint(this.baseUrl, options.apiKey, tokenStorage, retryClient, retryPolicy);
4747
+ this.billing = new BillingEndpoint(this.baseUrl, options.apiKey, tokenStorage, retryClient, retryPolicy);
4079
4748
  }
4080
4749
  };
4081
4750
 
@@ -4215,17 +4884,24 @@ function toBytes(rawBody) {
4215
4884
  "invalid_body"
4216
4885
  );
4217
4886
  }
4887
+
4888
+ // src/webhooks/WebhookEvent.ts
4889
+ function isTransactionBuyerRejected(object) {
4890
+ return object.buyer_rejected === true;
4891
+ }
4218
4892
  export {
4219
4893
  ApiVersion,
4220
4894
  AuthEndpoint,
4221
4895
  AuthRetryHttpClient,
4222
4896
  AuthenticationException,
4897
+ BillingEndpoint,
4223
4898
  CompanyAddress,
4224
4899
  CompanyEndpoint,
4225
4900
  ComplianceDocumentType,
4226
4901
  ComplianceEnrollment,
4227
4902
  ComplianceEnrollmentPage,
4228
4903
  ComplianceEnrollmentStatus,
4904
+ ComplianceOfferings,
4229
4905
  ComplianceService,
4230
4906
  ComplianceTaxReport,
4231
4907
  ComplianceTaxReportPage,
@@ -4269,6 +4945,8 @@ export {
4269
4945
  TaxoraClientFactory,
4270
4946
  TaxoraException,
4271
4947
  Token,
4948
+ UsageSummary,
4949
+ UsageSummaryPage,
4272
4950
  ValidationException,
4273
4951
  VatCertificateExport,
4274
4952
  VatCollection,
@@ -4297,6 +4975,7 @@ export {
4297
4975
  generateWebhookSignatureHeader,
4298
4976
  getBaseUrl,
4299
4977
  getFailedVatStates,
4978
+ isTransactionBuyerRejected,
4300
4979
  parseLocalTaxNumbersCsv,
4301
4980
  parseWebhookSignatureHeader,
4302
4981
  toComplianceDocumentType,