Skip to content

[BUG] Integration/inFakt — adapter drops the invoice currency, so a EUR invoice is booked as PLN #2103

Description

Problem / Context

The neutral invoicing command carries a currency:

// libs/core/src/invoicing/domain/types/invoicing.types.ts:486
currency: string;   // ISO 4217, single-currency invoice

The inFakt request type does not have a currency field at all:

// libs/integrations/infakt/src/domain/types/infakt.types.ts:50-81
export interface InfaktInvoice {  }   // no currency / kurs field

and infakt-invoicing.adapter.ts contains zero references to .currency — the string "currency" appears only inside comments about the groszy integer format (:232, :425, :686).

So command.currency is silently dropped. Amounts are sent as plain integers in the minor unit with no currency attached, and inFakt books them in the account's default currency (PLN). A EUR 811.37 invoice is issued as PLN 811.37.

Two things make this worse than an ordinary mapping gap:

  • It is silent. No log, no validation, no business_failure. Nothing distinguishes it from a correct issuance.
  • It propagates. inFakt relays to KSeF on the seller's behalf (see the Invoicing section of docs/architecture-overview.md), so an incorrect fiscal document clears the tax authority. A cleared document is not something OL can quietly re-issue.

Surfaced while reviewing #2050 / ADR-040, whose Non-goals section draws a hard line around fiscal currency handling. Independent of that PR.

Proposed Solution

  1. Establish the contract. Determine from inFakt's API documentation how a document declares its currency — most likely an invoice-level currency field plus an optional rate, given that inFakt performs its own conversion server-side. Record the finding in the issue with a doc reference, since the current absence may be a genuine API limitation rather than an OL oversight.
  2. If inFakt supports it — add the field to InfaktInvoice and map command.currency onto it. Verify against the sandbox that the issued document actually renders in that currency.
  3. If inFakt does not support it — reject issuance for any currency other than the account's default with a terminal business_failure and an explicit reason, rather than booking in the wrong units. A refused document is recoverable; a cleared wrong one is not.
  4. Cover the sibling write pathsissueCorrection and markPaid go through the same async task endpoints and need the same treatment.

Run the same audit against the Subiekt nexo adapter (libs/integrations/subiekt/), which implements the same InvoicingPort. If it has the same gap, file it separately rather than widening this issue.

Classification

Type: Integration
Layer: Infrastructure
File(s):

  • libs/integrations/infakt/src/infrastructure/adapters/infakt-invoicing.adapter.ts
  • libs/integrations/infakt/src/domain/types/infakt.types.ts:50-81

Dependencies

Assumptions

  • Shipped inFakt accounts are PLN-denominated and every order exercised in testing so far was PLN, which is why the gap has not surfaced in practice.
  • IssueInvoiceCommand.currency is populated correctly upstream (it is echoed from the order), so the defect is confined to the adapter boundary.

Acceptance Criteria

  • Whether inFakt's API accepts a document currency is established and documented in the issue, with a link to the relevant API docs
  • If supported: command.currency reaches the request and the issued sandbox document renders in that currency
  • If unsupported: a non-default-currency order fails terminally with an explicit reason instead of being booked in the wrong currency
  • issueCorrection and markPaid are covered by the same behaviour
  • A unit test asserts a non-PLN command either carries the currency or is rejected — never silently booked as PLN
  • The Subiekt adapter is checked for the same gap and the result recorded (separate issue if it applies)
  • Tests added or updated for non-trivial logic
  • No architecture boundary violations (CORE ↔ Integration)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't workinginfaktinFakt integrationintegrationinvoicingInvoicing & fiscal documents

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions