Retrieve Statuses
The Retrieve Statuses screen pulls invoice lifecycle events from the Plateforme Agréée — the status codes defined by the French e-invoicing reform (XP Z12-012): 200 Submitted, 201 Acknowledged, 206 Partially approved, 207 Disputed, 210 Refused, 213 Rejected, and the rest of the lifecycle. Each event is appended to the local lifecycle table and the invoice's current status is updated.
This screen is distinct from Sync → Import:
- Sync → Import handles the async import confirmation that follows a successful submission (
9906→10/9907). - Retrieve Statuses handles the lifecycle codes the PA emits after the import is complete (
200,201,206,207,210,213, …).
Both can run on the same scheduler with independent intervals — see Tips below.
The page applies regardless of source system — JD Edwards, SAP, NetSuite or a custom ERP — since the lifecycle reporting is a PA-side responsibility.
At a glance
Pipeline at a glance
Each run reads only the events newer than the watermark and advances it after a successful sweep — the next run picks up exactly where this one stopped.
How it works
Each click runs four steps:
- Read the watermark. The last retrieval date is stored in the e-invoicing template configuration. It is used as the
sinceparameter of the PA call. - Call the PA status-events endpoint. The list of status codes to subscribe to is configured in the same template (the configured status names). By default it matches the standard XP Z12-012 set; only the codes in the configured list are returned.
- Apply each event. For every event the PA returns:
- A new row is appended to the lifecycle table (
F564235) — this builds the full audit trail of every status the invoice has been through. - The invoice header (
F564231) is updated so the current status on the invoice list matches the latest event.
- A new row is appended to the lifecycle table (
- Advance the watermark. The
lastRetrievalDatevalue in the template is updated to the timestamp of the latest event received. The next run starts from there.
The lifecycle table is append-only: each event adds a row, no row is ever modified or removed. Re-running the retrieval cannot create duplicates because the watermark only ever moves forward.
Status codes retrieved
The lifecycle covers the post-submission codes from XP Z12-012 — 200 to 228, plus 500 / 501. The full list is documented in the Status Reference; the set actually retrieved by each run is governed by the configured status names property of the e-invoicing template.
Common subsets:
- All-codes (default) — subscribes to every code in the standard reference list. Suitable for any deployment that needs full traceability.
- Mandatory-only — limits retrieval to the PPF-mandatory codes (
200,201,213…). Reduces the volume on very high-throughput installations where intermediate statuses are not consumed downstream.
The 9906 / 9907 codes are not part of this retrieval — those are local NomaUBL statuses tied to the async-import confirmation flow handled by Sync → Import.
Run
A single section, a single button.
| Element | Description |
|---|---|
| Retrieve Statuses | Triggers the retrieval. Disabled while a run is in progress. |
| Status line | Inline feedback below the button — green on success, red on failure. |
The page has no parameters: every event newer than the watermark, for every code in the configured list, is fetched in the same call. There is no per-invoice scope.
Results
The Results section shows the structured log table — one row per event applied, plus pipeline-level events. The columns match the rest of NomaUBL's log tables (Severity / Module / Submodule / Message).
Typical log content for a successful run:
- An
INFOrow reporting how many events were returned by the PA. - One
INFOorSUCCESSrow per event applied — invoice key + new status code. - A final
INFOrow reporting the new watermark date.
When the PA call fails for transport reasons (network, timeout, credentials), the page logs an ERROR row and leaves the watermark unchanged — the next run retries from the same since date.
Integrity checks
Beyond the incremental retrieval, the page offers two on-demand checks that reconcile the recorded lifecycle with the platform and with itself. Both run in the background and are safe to re-run at any time. To run them daily without an operator, schedule them on the Lifecycle Checks page (or the matching CLI modes).
Missing statuses
Pick a period — from a date until another (empty end = now) — and optionally one company, and the check compares every platform event of that window with the lifecycle already recorded. A run scoped to a company only queries that company's status connector and only looks up its invoices, so a per-company backfill doesn't pull every company's events. The end bound reaches the connector as the {{toDate}} / {{toDateRaw}} placeholders (Esker updatedBefore); plain dates are widened to the full day. Anything missing is listed in a selectable table — apply all of them or only the rows you pick, optionally firing the notification rules (off by default). Events that don't apply are reported separately so nothing is silently changed: an obsolete internal status (a platform stage the invoice has already moved past), an unknown invoice, or a code with no mapping.
A recovered event is inserted at its chronological position — from the event's platform timestamp — not appended at the end, and the invoice's current status only moves when the recovered event is genuinely the most recent. Backfilling an old missing status therefore can't knock an invoice back to a past state. The same chronological insertion applies to the regular status poll.
While the check runs, its progress shows live under the section: pages fetched from the platform, events compared every thousand with the running counts, then a final summary. Events outside the requested window are dropped with a logged count (a connector bounding only the start date returns everything up to now), events delivered twice are collapsed, and each invoice is looked up once. The list of missing events is not capped, so Apply backfills them all in one pass; only the informational not found and unmapped rows stop being listed past two thousand, with a log line saying so.
Resent invoices. After a rejection and a resend, the statuses of the new cycle (deposited, received, transmitted…) are recorded like the first ones: a code counts as already recorded only since the invoice's last send, pending or reprocess event, while the exact same platform event — same code, same timestamp — is still recognised across cycles. The regular status poll follows the same rule.
Lifecycle ordering
The second check scans the database for lifecycle rows that are out of order — an internal platform stage recorded after a standard status, and standard statuses recorded in the wrong order (e.g. 202 Reçue before 200 Déposée, the numeric order of standard codes being canonical) — plus invalid codes (raw platform text stored by a mapping mistake). The repair re-sequences the events into the correct order (nothing is deleted; internal statuses keep their positions) and realigns the invoice's current status, with a before/after preview and per-invoice selection.
Two cases are handled on their own terms:
- Re-emitted invoices. An invoice sent again after a correction (Fix buyer, edit window, reprocess) carries several PA cycles. Each cycle — opened by a sent, pending or reprocess event — is ordered on its own, an event belonging to the cycle its timestamp falls in.
- Disputed (
207) and suspended (208). These interim statuses may be followed by a lower code such as205Approved or210Refused: they keep their chronological position within their cycle and never count as an inversion.
Histories ordered wrongly by an earlier rule are detected and put back in order by the next run.
The check also reports an invoice whose status differs from the latest real state of its history, shown as current → expected, and realigns it on apply. The latest real state looks past the reprocess marker (9912) and the mail-sent marker (9908) in whatever order they appear — so a deposited 200 NON_TRANSMISE stays as such. The same rule applies to every header realignment: integrity backfill, status poll and deletion of a history event. The mail-sent marker counts as an application event: it is never reported as misordered. A generation event sitting directly under a reprocess marker — the trace an earlier reprocess left — is ignored like the marker, and so is a history row without a code.
Check ordering and Clean N selected run in the background: the page shows the run's log as it goes, then the findings. The status-drift scan reads the history once, in a single pass, logs its progress every 50 000 rows, the result by current → expected pair and a closing summary — a large database no longer ends in a proxy error.
Tips & best practices
- Schedule the retrieval. The background scheduler in NomaUBL can run this page periodically — see the
fetchStatusIntervalproperty of the e-invoicing template (a value in minutes;0disables the scheduler). Every 15 minutes to 1 hour is typical. - Distinct from Sync → Import. Import handles the post-submission
9906→10/9907async confirmation; Retrieve Statuses handles the lifecycle codes the PA emits afterwards. Both can run on the same scheduler with different intervals. - The watermark only ever moves forward. Re-running the page has no effect on already-applied events. To replay a window (e.g. after restoring an old database backup), lower
lastRetrievalDatemanually in the e-invoicing template — the next run will re-pull every event since that date. - Trim the configured status names if volume is an issue. The default set covers every reform code; high-throughput installations that only need the PPF-mandatory codes can shrink the list to reduce PA-side and local-side load.
- The lifecycle is the audit trail. The lifecycle table (
F564235) is append-only and represents the complete history; the invoice header (F564231) only carries the most recent status. Use the lifecycle when investigating disputes or chasing a missing PA-side update.