Skip to content

Syrve test payment write — 2026-06-19 15:30 ​

Historical snapshot (2026-06-19). Flag names and values below record the runtime model used during this test. Those capability/verification/bypass flags have since been removed and must not be used as current deployment instructions. Current runtime is always-on with mandatory ApprovalRequired workflow and full safety preflight.

Result: PASS_WRITE / FAIL_RECONCILE
Environment: Test (https://200-137-733.iiko.it)
Operator: Local dev iteration

Read status ​

CheckResult
REST authOK (read path healthy)
Sync docs13
Unpaid docs1 (OutgoingInvoice, 100.00 IDR) at start of run
Generic RPC verifyforbidden (403 on verify RPC)
Method preflightWriteEligible with ForbiddenButNonBlocking

Write profile flags (test only) ​

FlagValue
PaymentWriteEnabledtrue
AllowTestEnvironmentWritestrue
AllowProductionWritesfalse
RequireMethodSpecificPreflighttrue
AllowGenericRpcVerifyForbiddenForTesttrue
PaymentWriteRequiresApprovaltrue

Target payment method ​

  • Method: setPaymentsForOutgoingDocuments (UnpaidDocuments.setPaymentsForOutgoingDocuments)
  • Posting type: OutgoingDocumentPayment
  • Document: 399ae6b5-79fe-45e0-aaeb-5a8d74bba7cc (OutgoingInvoice, 100.00 IDR)

Implementation delivered this iteration ​

  1. Method-specific preflight (ISyrvePaymentWritePreflightService) — generic RPC forbidden non-blocking when REST/read healthy.
  2. Gates — preflight WriteEligible replaces strict connected requirement; dry-run skips approval gate.
  3. Account discovery — GET /api/syrve/references/accounts via getAccountsBalanceForDepartments; default sort prefers IikoPaymentDocumentLiveCycleDefaults.OutgoingPaymentAccountId (59f13a63-d259-355e-f81b-18dc52f3aca5).
  4. Outgoing idempotency — IikoPaymentWriteFacade builds outgoing request hash (OUTGOING_INVOICE mapping).
  5. Queue — no placeholder RequestHash until dry-run computes canonical hash.
  6. Evidence — SyrvePostingEvidenceBuilder null-safe decimal parsing for dry-run.

Live attempt timeline ​

StepPostingStatus
Queue + wrong account019edf90-e972-7c55-a1a3-372333d41837Failed rpc_failure (iiko access denied on account)
Queue + correct account019edf94-9256-7313-8d51-abc0b109fcebSee below

Successful posting (019edf94-9256-7313-8d51-abc0b109fceb) ​

StepStatus
Allocation confirmOK
Queue postingOK
Write targetOK — account 59f13a63-d259-355e-f81b-18dc52f3aca5, cash-flow 14c0fe4b-76ec-2681-846e-81d1ec32db08
PreflightWriteEligible
Dry-runOK (isAllowed=true)
ApproveOK
Worker RPC writeOK — PostedAtUtc set, ExternalPaymentId 5916c554-2e0e-46ec-9dda-2d2a46d1990f
ReconcileFailed reconciliation_amount_mismatch

Reconcile failure detail ​

  • Allocation expected ExpectedUnpaidAmountAfter = 0.00 (full 100.00 payment).
  • Immediate readback via getUnpaidSumForAGivenInvoice (OUTGOING_INVOICE) still returned 100.00 unpaid ~1s after RPC success.
  • Evidence after block is optimistic (computed locally), not live iiko readback.
  • Later background sync (11:17:08 UTC) updated snapshot to UnpaidAmount=200.00, PaymentStatus=Overpaid on the same 100.00 document — anomalous; requires BackOffice inspection.

Sanitized identifiers (successful posting) ​

FieldValue
PostingId019edf94-9256-7313-8d51-abc0b109fceb
AccountId59f13a63-d259-355e-f81b-18dc52f3aca5
CashFlowArticleId14c0fe4b-76ec-2681-846e-81d1ec32db08
RequestHashsha256:d3d3ac21fa8b5d60ea245b48751c0b7d3c0683e5554a3ed19d59e6aa6212d7d3
IdempotencyKeylive-77483761

Prior blockers (resolved) ​

IssueResolution
Dry-run HTTP 500Fixed null JSON number parsing in evidence builder
idempotency_conflictRemoved queue-time placeholder hash; dry-run sets canonical hash
rpc_failure on wrong accountUse outgoing default account 59f13a63-… or IIKO_TEST_PAYMENT_ACCOUNT_FROM

BackOffice verification ​

Required. Confirm in iiko BackOffice for document 399ae6b5-79fe-45e0-aaeb-5a8d74bba7cc:

  • Whether outgoing payment 5916c554-2e0e-46ec-9dda-2d2a46d1990f exists
  • Actual paid/unpaid balance (local readback shows inconsistent values)
  • Whether multiple test postings created duplicate payments

Open follow-ups ​

  1. Outgoing readback — reconcile uses getUnpaidSumForAGivenInvoice; may need delay/retry or alternate probe (getPaymentTransactions / getAbstractDocument) for OUTGOING_INVOICE.
  2. Transaction type guard — IikoPaymentWriteFacade does not yet assert OUTGOING_DOCUMENT_PAYMENT on RPC response (live orchestrator does).
  3. Reconcile worker timing — manual reconcile ran before reconciliation worker; consider backoff when readback lags.

Safety confirmations ​

  • AllowProductionWrites=false
  • No direct controller/UI execute endpoint
  • Write path remains worker-only after approve
  • No secrets in this report

Anomaly control verification (2026-06-19 15:30+) ​

Manual reconcile on posting 019edf94-9256-7313-8d51-abc0b109fceb without a new live write:

CheckResult
POST .../reconcileOK — live readback UnpaidAmount=200, Overpaid
Anomaly createdOK — 019edfdc-1153-798d-88aa-a347285bfb2c, type overpaid_after_write, severity Critical
Posting openAnomalyIdLinked to anomaly
Notifications2 unread (payment_reconciliation_failed, payment_manual_review_required)
Evidence liveReadbackPresent; optimisticAfter separate from live state
Reconcile API responseFixed evidence merge serialization (typed SyrvePostingEvidenceJson via PayJsonSerializer)
Retry gateAPI now blocks retry when open critical anomaly (payment_anomaly_open); UI buttons already disabled via openAnomalyId

Operator action: acknowledge/resolve anomaly in UI or BackOffice after manual iiko inspection. Do not retry write until resolved.