Appearance
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
ApprovalRequiredworkflow and full safety preflight.
Result: PASS_WRITE / FAIL_RECONCILE
Environment: Test (https://200-137-733.iiko.it)
Operator: Local dev iteration
Read status
| Check | Result |
|---|---|
| REST auth | OK (read path healthy) |
| Sync docs | 13 |
| Unpaid docs | 1 (OutgoingInvoice, 100.00 IDR) at start of run |
| Generic RPC verify | forbidden (403 on verify RPC) |
| Method preflight | WriteEligible with ForbiddenButNonBlocking |
Write profile flags (test only)
| Flag | Value |
|---|---|
| PaymentWriteEnabled | true |
| AllowTestEnvironmentWrites | true |
| AllowProductionWrites | false |
| RequireMethodSpecificPreflight | true |
| AllowGenericRpcVerifyForbiddenForTest | true |
| PaymentWriteRequiresApproval | true |
Target payment method
- Method:
setPaymentsForOutgoingDocuments(UnpaidDocuments.setPaymentsForOutgoingDocuments) - Posting type:
OutgoingDocumentPayment - Document:
399ae6b5-79fe-45e0-aaeb-5a8d74bba7cc(OutgoingInvoice, 100.00 IDR)
Implementation delivered this iteration
- Method-specific preflight (
ISyrvePaymentWritePreflightService) — generic RPCforbiddennon-blocking when REST/read healthy. - Gates — preflight
WriteEligiblereplaces strictconnectedrequirement; dry-run skips approval gate. - Account discovery —
GET /api/syrve/references/accountsviagetAccountsBalanceForDepartments; default sort prefersIikoPaymentDocumentLiveCycleDefaults.OutgoingPaymentAccountId(59f13a63-d259-355e-f81b-18dc52f3aca5). - Outgoing idempotency —
IikoPaymentWriteFacadebuilds outgoing request hash (OUTGOING_INVOICEmapping). - Queue — no placeholder
RequestHashuntil dry-run computes canonical hash. - Evidence —
SyrvePostingEvidenceBuildernull-safe decimal parsing for dry-run.
Live attempt timeline
| Step | Posting | Status |
|---|---|---|
| Queue + wrong account | 019edf90-e972-7c55-a1a3-372333d41837 | Failed rpc_failure (iiko access denied on account) |
| Queue + correct account | 019edf94-9256-7313-8d51-abc0b109fceb | See below |
Successful posting (019edf94-9256-7313-8d51-abc0b109fceb)
| Step | Status |
|---|---|
| Allocation confirm | OK |
| Queue posting | OK |
| Write target | OK — account 59f13a63-d259-355e-f81b-18dc52f3aca5, cash-flow 14c0fe4b-76ec-2681-846e-81d1ec32db08 |
| Preflight | WriteEligible |
| Dry-run | OK (isAllowed=true) |
| Approve | OK |
| Worker RPC write | OK — PostedAtUtc set, ExternalPaymentId 5916c554-2e0e-46ec-9dda-2d2a46d1990f |
| Reconcile | Failed 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
afterblock is optimistic (computed locally), not live iiko readback. - Later background sync (
11:17:08 UTC) updated snapshot toUnpaidAmount=200.00,PaymentStatus=Overpaidon the same 100.00 document — anomalous; requires BackOffice inspection.
Sanitized identifiers (successful posting)
| Field | Value |
|---|---|
| PostingId | 019edf94-9256-7313-8d51-abc0b109fceb |
| AccountId | 59f13a63-d259-355e-f81b-18dc52f3aca5 |
| CashFlowArticleId | 14c0fe4b-76ec-2681-846e-81d1ec32db08 |
| RequestHash | sha256:d3d3ac21fa8b5d60ea245b48751c0b7d3c0683e5554a3ed19d59e6aa6212d7d3 |
| IdempotencyKey | live-77483761 |
Prior blockers (resolved)
| Issue | Resolution |
|---|---|
| Dry-run HTTP 500 | Fixed null JSON number parsing in evidence builder |
idempotency_conflict | Removed queue-time placeholder hash; dry-run sets canonical hash |
rpc_failure on wrong account | Use 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-2d2a46d1990fexists - Actual paid/unpaid balance (local readback shows inconsistent values)
- Whether multiple test postings created duplicate payments
Open follow-ups
- Outgoing readback — reconcile uses
getUnpaidSumForAGivenInvoice; may need delay/retry or alternate probe (getPaymentTransactions/getAbstractDocument) forOUTGOING_INVOICE. - Transaction type guard —
IikoPaymentWriteFacadedoes not yet assertOUTGOING_DOCUMENT_PAYMENTon RPC response (live orchestrator does). - 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:
| Check | Result |
|---|---|
POST .../reconcile | OK — live readback UnpaidAmount=200, Overpaid |
| Anomaly created | OK — 019edfdc-1153-798d-88aa-a347285bfb2c, type overpaid_after_write, severity Critical |
Posting openAnomalyId | Linked to anomaly |
| Notifications | 2 unread (payment_reconciliation_failed, payment_manual_review_required) |
Evidence liveReadback | Present; optimisticAfter separate from live state |
| Reconcile API response | Fixed evidence merge serialization (typed SyrvePostingEvidenceJson via PayJsonSerializer) |
| Retry gate | API 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.