Skip to content

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 ​

StageMeaning
PASS_WRITEiiko RPC accepted payment (PostedAtUtc, ExternalPaymentId)
PASS_RECONCILELive 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.
  • ResolvedManually only when verified values match expected unpaid/status.
  • Creates backoffice_verification_recorded notification for scoped users.

OUTGOING_INVOICE readback probes ​

OutgoingInvoiceReadbackStrategy runs probes in order:

  1. getUnpaidSumForAGivenInvoice (OUTGOING_INVOICE)
  2. documentRefresh via SyrveDocumentLiveReader
  3. getAbstractDocument
  4. getPaymentTransactions — not implemented in IikoConnector yet
  5. localSnapshot — 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.