🧾 Unified Register of Tax Invoices (ЄРПН) tax invoice
Updated
How the Ukrainian package turns a posted sales realization into a tax-invoice envelope for the Unified Register of Tax Invoices (ЄРПН), and where the business boundary is between ZuloOne, M.E.Doc and the State Tax Service (ДПС). Screen steps are in the user page; operator seating is M.E.Doc at a customer.
How the process works#
ZuloOne does not sign the document and does not compose the State Tax
Service XML. On an eligible posted sales realization (SalesRealization, shown as
Sales realization), the Ukrainian package creates a shared TaxDocument envelope
with M.E.Doc MakeDoc cells in Payload. M.E.Doc then builds the XML and signs
it with the qualified electronic signature (КЕП) that already lives on the
accountant's machine.
The automatic points are:
| Source document | State where the package acts | Result |
|---|---|---|
Sales realization (SalesRealization) |
Issued / visible state Released |
one TaxDocument with EInvoiceKind = INVOICE, subtype Issued, and a queued erpn-send MakeDoc message |
Sales credit note (SalesCreditNote) |
Posted |
one TaxDocument with EInvoiceKind = ADJUSTMENT, a reference to the original invoice, and a queued erpn-send MakeDoc message |
Nothing is created on reservation, picking, packing or shipment before the
invoice reaches Issued. Nothing is created for a legal entity that does not
charge VAT (ПДВ), and nothing is created when the contour is switched off.
After MakeDoc succeeds, ExternalId on the envelope is the M.E.Doc CardCode.
The PullUaTaxInvoiceReceipts job then queues erpn-gov (ToGov) and later
asks erpn-receipt (GetDocInfo / GetDocKVT). A successful MakeDoc only
means "the draft is in M.E.Doc"; the envelope becomes Cleared only when the
receipt says the tax invoice is registered. A refusal moves it to Rejected
and writes the reason on the envelope.
Settings#
Ukraine settings#
Go to Ukraine → Settings → Ukraine settings (LocalizationUkraineSettings).
| Field | Values | Default / empty | What changes |
|---|---|---|---|
| E-invoice (tax invoice) enabled | yes / no | no | yes lets the service create TaxDocument envelopes from posted sales realizations and credit notes. no leaves the VAT accounting in place but creates no envelope. |
| Tax invoice form code | the current DPS form code, for example J1201010 for a legal entity or F1201010 for a sole proprietor |
empty | empty blocks invoice envelopes. The package does not guess the form version. |
| Tax invoice adjustment form code | the current adjustment form code, for example J12012010 or F12012010 |
empty | empty blocks credit-note adjustment envelopes. It does not reuse the invoice form code. |
Changing these settings affects only future postings and future credit-note
postings. Existing TaxDocument envelopes are not rebuilt by changing the
codes on the settings card.
Legal entity#
The source legal entity must be a VAT (ПДВ) payer. In the Ukrainian regime field on the legal entity, the paying regimes are VAT payer, general system and Simplified 3% with VAT. Simplified 5% without VAT and General system, not a VAT payer do not draw up a tax invoice.
The seller's tax identifiers come from the legal entity, not from Ukraine settings:
- registration number / EDRPOU from
LegalEntity.RegistrationNumber; - VAT number from
LegalEntity.TaxRegistrationNumber; - name and legal address from the same legal entity card.
Operator connection#
Go to Tax → Settings → Authority connections (TaxAuthorityConnection) and
create the row for the same legal entity.
| Field | Value for M.E.Doc | Empty |
|---|---|---|
| Legal entity | the seller that issues the invoices | the envelope can be created, but there is no connection reference for the queue |
| Base URL | usually http://127.0.0.1:63777 on the accountant's PC |
the record will not save |
| Agent tag | the tag of the ZuloOne agent on that PC | loopback is refused by the host; it is an SSRF boundary |
| Credential reference | the M.E.Doc REST user name | login is skipped or M.E.Doc refuses the call when authorization is on |
| Environment | a human label such as prod or test |
the resolver passes no environment; it does not change the URL |
The password is not stored on the card. It is server configuration
Integration__Credentials__<Credential reference>.
Example with numbers#
The first-event rule means VAT (ПДВ) is booked when the first of two events happens: shipment or money. The e-invoice envelope follows the posted sales invoice, but the amount inside it reflects the VAT base that has already been accounted for by the Ukrainian first-event register.
| Step | Business event | Register effect | Tax invoice effect |
|---|---|---|---|
| 1 | Customer prepays 1,200 ₴ at 20% VAT | UaVatFirstEvent.Paid += 1,200; the VAT base is 1,000 ₴ and UaVatPayable accrues 200 ₴ |
no TaxDocument: a payment is not a sales realization |
| 2 | Sales realization is issued for goods with net 1,000 ₴, VAT 200 ₴, gross 1,200 ₴ | UaVatFirstEvent.Shipped += 1,000; max(Shipped, Paid-net) does not increase, so no second VAT accrual |
one TaxDocument in Issued, MakeDoc payload for 1,000 ₴ base and 200 ₴ VAT |
| 3 | M.E.Doc MakeDoc succeeds | accounting does not change | ExternalId becomes the M.E.Doc CardCode; the invoice is still not registered in ЄРПН |
| 4 | DPS receipt says registered | accounting still does not change | the envelope moves from Issued to Cleared |
If the same invoice is issued first and payment comes later, step 2 creates the VAT accounting and the envelope at once; the later payment does not create a second envelope and does not book the same VAT again.
Boundaries and edge cases#
- The subtype transition is not a manual selector. Users post the sales realization with the normal command; after the document is saved, the state is locked.
- A credit note without an original invoice produces no adjustment envelope. The State Tax Service will not accept an adjustment with no reference.
- A non-VAT legal entity produces no envelope even if the switch is on and the form code is filled.
- A successful operator send is not registration. Only the receipt closes the
TaxDocumentasClearedorRejected. - The Ask the operator about this invoice command on the envelope asks for
the receipt again. It does not submit the document again and does not call
ToGov. - Reposting is idempotent for the same source document: an existing
TaxDocumentis reused instead of creating a second envelope.
What is posted#
The e-invoice contour itself posts no accounting entries. Accounting has already been written by the source documents and the Ukrainian totals drivers:
| Document | State | What moves |
|---|---|---|
Sales realization (SalesRealization) |
Issued / Released |
UaVatFirstEvent.Shipped; the UaVatFirstEvent driver writes UaVatPayable when the first-event base increases |
| Customer payment | Paid |
UaVatFirstEvent.Paid; the same driver writes UaVatPayable when money is the first event |
Sales credit note (SalesCreditNote) |
Posted |
UaVatFirstEvent.Shipped with a minus; the driver releases VAT only when the first-event base decreases |
TaxDocument |
Issued → Cleared / Rejected |
no accounting register; it stores the envelope status, CardCode / receipt id and refusal text |
What's not there yet#
- There is no direct State Tax Service cabinet connector.
- There is no Diia (Дія) signing or sharing channel.
- ZuloOne does not store or use the qualified electronic signature (КЕП). M.E.Doc signs on the accountant's machine.
- There is no cloud M.E.Doc sandbox. A live check needs networked M.E.Doc with the integration licence and a ZuloOne agent on the same PC.
- The middle of the live exchange with M.E.Doc is not covered by an integration test; the package tests cover envelope creation, gates, idempotency and applying outcomes.
Same topic for other readers: User · Developer