Currency & NBP
A non-PLN invoice is converted to złoty at the NBP average rate of the last business day before the tax point (the date the VAT obligation arises — art. 31a). This is the rate KSeF requires for the FA(3) P_14_xW field.
The rule
- Currency = PLN → no conversion.
- Currency ≠ PLN → NBP average rate (table A) of the last business day before the tax point.
For a continuous service (a SaaS subscription) the tax point is the end of the billing period. When the invoice is issued in arrears (after the period closes), the binding date is the period end, not the later issue date. When the invoice is issued before the obligation arises (advance billing), the issue date binds — so we take the earlier of the two dates.
NBP table A is published only on business days, so we query a short window ending the day before the binding date and take the latest published rate in it.
What we do NOT use
Stripe's settlement FX rate. That is the wrong rate for tax purposes — KSeF requires the NBP average rate, not the rate at which Stripe settled the payment.
Source
NBP API, table A:
https://api.nbp.pl/api/exchangerates/rates/A/{currency}/{from}/{to}/?format=json
We take the mid field (average rate) of the latest entry in the window. A missing rate or network error means the invoice is not silently filed with a wrong rate — the error is raised.