Finance & Tax
Closing the books and keeping an audit trail are the same ledger.
Finance needs to know where every invoice stands without chasing a status email. Tax needs every submission checked against the actual mandatory field set, not a best-effort mapping. Both run off one ledger with one state machine.
The cost of inaction
Non-compliance isn’t a risk. It’s a monthly invoice from the FTA.
These penalties apply once a business is in a mandatory phase (Wave 1 = January 2027); voluntary participants are exempt.
Not appointing an Accredited Service Provider by the deadline.
Kodowo's BYOK bridge connects you to your ASP in hours, not weeks. The meter never starts.
Each invoice or credit note that fails to transmit on time, capped at AED 5,000/month, with invoices and credit notes each carrying their own cap.
Deterministic validation against all 62 required fields (51 official MoF + 11 more) catches errors before the network rejects them.
A system failure not reported to the FTA in time.
Live monitoring and failure alerts so an outage never goes unreported.
Administrative penalties per Cabinet Decision No. 106 of 2025.
Validation confirms conformance to these checks. It is not a guarantee the FTA will accept a given invoice.
Closing the books
A fixed set of states, not a black hole.
Every invoice you submit lands in one of a fixed set of ledger states and stays there until it reaches a terminal one. Month-end reconciliation is a query against that state, not a spreadsheet someone rebuilds by hand.
Status is always queryable
Per-invoice status is returned on every submit and stays queryable by source_reference, with no phone call needed to find out where an invoice is stuck.
Failures surface before month-end
A failure webhook fires the moment an invoice needs attention, so a rejected submission is a same-day fix, not a surprise during close.
Retries never duplicate
Submissions are idempotent on (tenant, source_reference) and chaos-tested under concurrent load, so retrying after a timeout never risks a second FTA transmission.
The audit trail is the evidence
Every transition is written to an append-only, trigger-enforced audit trail: the record an auditor asks for already exists.
Ledger state machine
Three failure-shaped states are reachable from any stage, each one a persisted status, not a dropped request.
Keeping an audit trail
Validation runs against the actual mandate, not a summary of it.
Every submission is checked against the official MoF mandatory field set and the official Peppol PINT-AE VAT codelist, including the cross-consistency and line-math checks that are easy to miss when a mapping is built by hand.
The official field set, not our interpretation of it
Validation targets the MoF mandatory field set (51 fields, V1.0 23 Feb 2026; 62 with documented extensions) and the Peppol PINT-AE VAT codelist directly.
TRN and TIN are checked, not just present
Format rules and the cross-consistency check between the Tax Registration Number and the Peppol TIN run on every submission, not just at onboarding.
Rate coherence per category
A standard-rate line can't carry a zero VAT rate, and an exempt line can't skip its exemption reason: the category and the rate are checked together.
vat_categoryenumRequiredOne of S, Z, E, O, AE, N: the official Peppol PINT-AE codes.
vat_ratedecimalRequiredMust match the category's allowed rate set (S/N: 5.00; Z/E/O: 0.00; AE: 0.00 or 5.00).
supplier_trnstring(15)Required15-digit FTA Tax Registration Number, or a standalone 10-digit TIN.
vat_exemption_reasonstringRequired whenever vat_category is E or O.