Appearance
Payment anomaly control
Purpose
After PASS_WRITE / FAIL_RECONCILE, payment write is proven but reconciliation is unsafe. The system must:
- Record anomalies when live readback disagrees with expected state
- Notify operators
- Block repeat writes on documents with open Critical anomalies
- Keep posting in Posted but not Reconciled until live readback confirms
PASS_WRITE vs PASS_RECONCILE
| Stage | Meaning |
|---|---|
| PASS_WRITE | iiko RPC accepted payment (PostedAtUtc, ExternalPaymentId) |
| PASS_RECONCILE | Live readback matches ExpectedUnpaidAmountAfter |
Optimistic optimisticAfter in evidence is not confirmation — only liveReadback counts.
Anomaly lifecycle
Open → Acknowledged → Resolved / ResolvedManually / Dismissed
Critical open anomalies block queue/approve/live write for the same ExternalDocumentId.
Reconciliation retry
Config: Syrve__Reconciliation__ReadbackRetryDelaysSeconds=5,30,120,300
Worker keeps ReadbackPending until escalate threshold; then creates Critical anomaly and sets posting Failed.
BackOffice verification
POST /api/payment-anomalies/{id}/backoffice-verification records operator findings without writing to iiko.
- Requires
location.anomalies.manage(scoped). - Does not fake live readback.
ResolvedManuallyonly when verified values match expected unpaid/status.- Creates
backoffice_verification_recordednotification for scoped users.
OUTGOING_INVOICE readback probes
OutgoingInvoiceReadbackStrategy runs probes in order:
getUnpaidSumForAGivenInvoice(OUTGOING_INVOICE)documentRefreshviaSyrveDocumentLiveReadergetAbstractDocumentgetPaymentTransactions— not implemented in IikoConnector yetlocalSnapshot— weak fallback, flagged in warnings
Probe metadata is exposed on SyrvePaymentReadbackResult.Probes.
Duplicate-write guard
Open Critical anomaly on ExternalDocumentId blocks approve/queue/worker execute. Reconcile retry and BackOffice verification remain allowed.