OpenPoly logo
Polyflight

Operations, reconciliation, and rollback

Reconcile Polyflight wallet effects, handle failures safely, and contain incidents without changing committed results.

Operations, reconciliation, and rollback

Polyflight separates an authoritative game result from wallet delivery. A ticket can be definitively won or refunded while its payout or refund remains owed, or definitively lost while its zero-amount result acknowledgement remains outstanding. Never change a result, committed proof, or statement to hide a wallet failure.

Operator and Polynion responsibilities

Operator staffAuthorized Polynion operations
Inspect operator-owned flights, tickets, wallet operations, statements, payments, and correctionsResolve an ambiguous operation after reviewing authoritative evidence
Query the operator wallet ledger by the original wallet idempotency key, including zero-amount loss acknowledgement recordsRecord the audited resolution decision and evidence reference
Supply redacted ledger evidence and remote referenceResume the original key only when non-application is definitive and same-key behavior permits it
Reconcile exports against the wallet ledger and bank evidenceRecord interparty payments and additive statement corrections
Pause the operator-side adapter if its behavior is unsafeSuspend new Polyflight purchases or coordinate wider incident containment

Operator dashboard/API access is read-only for resolutions, terms, statement finalization, payments, and corrections. Do not treat the absence of a write button or API route as a reason to replay money yourself.

Start from the dashboard

Open Operator Dashboard → Polyflight and follow this order:

  1. Tickets — establish the authoritative ticket result and paymentStatus.
  2. Wallet operations — find the exact effect, original idempotency key, state, attempts, remote reference, and request/response evidence.
  3. Flights — confirm flight state and cohort liability.
  4. Settlement reports — confirm whether the liability is carried in a finalized month.
  5. Webhook deliveries — confirm notification delivery separately from money delivery.

The overview's Unresolved wallet effects count includes sent, unknown, and manual_review operations, including loss deliveries. A zero count does not mean all user liabilities are paid; check unpaid winnings, refunds, and compensations too. Conversely, an unresolved loss delivery is not a monetary liability and does not block flight financial settlement.

Trace one immutable effect

For every wallet-effect case, preserve and correlate:

  1. purchase request or ticket ID;
  2. operation ID, effect, direction, original idempotencyKey, and pinned wallet transport;
  3. immutable request/response evidence and optional remoteReference;
  4. payment obligation ID and state, for both money owed and zero-amount loss delivery;
  5. webhook event_id and delivery attempts;
  6. accounting event and confirmed cash clearing, for monetary effects only;
  7. current liability or finalized statement/payment/correction record, when money is involved.

The public request trace ID is diagnostic only. Query the wallet ledger by the financial idempotency key.

Find unresolved operations

Required scopes are polyflight:read and balance_operations:read.

curl -sS -G \
  -H "Authorization: Bearer ${OPERATOR_API_KEY}" \
  --data-urlencode "status=sent,unknown,manual_review" \
  --data-urlencode "search=operator-user-123" \
  "https://your-beacon-origin.example.com/api/operator/polyflight/balance-operations"

search matches only external user ID or idempotency key. For each match, request the detail evidence:

curl -sS \
  -H "Authorization: Bearer ${OPERATOR_API_KEY}" \
  "https://your-beacon-origin.example.com/api/operator/polyflight/balance-operations/{operationId}"

Use Balance operations API for exact filters, statuses, and response fields.

Interpret operation, ticket, and payment state

EvidenceMeaningOperator action
operation plannedDurable effect exists but dispatch has not been confirmedDo not create a replacement key
operation sentRequest was dispatched without a terminal recorded answerTreat delivery as unresolved; a loss still has zero cash impact
operation retryingIntermediate recovery state on the same durable operationObserve; do not race it with a manual replay
operation succeededWallet effect is confirmed, including a loss acknowledgementMatch amount, user, reason, key, and optional remote reference
operation failedRecorded attempt did not applyPreserve evidence; do not infer anything about a different attempt
operation unknown or manual_reviewApplication remains ambiguous or requires authenticated evidenceFreeze replay and escalate with ledger proof
ticket won + payment owedResult is final; payout is an outstanding liabilityReconcile the win-credit obligation
ticket won + payment manual_reviewResult is final; the attempted payout was rejected or is ambiguousReconcile the linked operation; never rerun the game
ticket lost + payment not paidResult is final; zero-amount acknowledgement is outstanding or under reviewReconcile the :loss operation; no payout or liability exists
ticket refunded + payment not paidCancellation/refund result is final; delivery remains outstandingReconcile the full original stake
payment paidThe linked credit/reversal or loss acknowledgement is confirmedMatch cash outflow for monetary effects; loss acknowledgement has no outflow

A newly settled lost ticket has an obligation with effect loss and amount 0, linked to a loss_credit operation. It uses reason mini_app_polyflight_loss and key mini_app_polyflight_ticket:{ticketId}:loss. It tracks delivery, not debt. The existing ticket.resolved event carries the obligation ID; no loss payout pending/processed event is emitted. Historical losses are not backfilled. A refund and a winning payout cannot coexist for the same ticket.

Reconciliation procedure

  1. Freeze automated or human replay for the affected effect.
  2. Capture operator, external user, purchase/ticket/flight/obligation IDs, operation ID, original idempotency key, pinned transport, UTC window, and webhook event IDs.
  3. Read the operation detail and retain requestJson, responseJson, failureReason, attemptCount, stateVersion, and remoteReference.
  4. Query the simulator or REST v1 wallet ledger by the financial idempotency key.
  5. Compare external user, currency, amount, reason, operation metadata, and transport with the immutable OpenPoly request evidence.
  6. Determine only what the ledger proves: applied, not applied, or still unknown.
  7. Send the authenticated evidence/reference to Polynion operations. Do not mutate the operation through an operator API; no such route exists.
  8. An authorized Polynion administrator records confirmed_applied or confirmed_not_applied with a reason, evidence reference, and expected state version. authorized_original_key_resume is reserved for definitive non-application when same-key behavior permits safe resumption.
  9. Recheck the same operation, ticket payment status, overview liability, webhook delivery, and any affected statement/correction.

If non-application is definitive but the external system cannot safely accept the original key again, resolve the existing monetary obligation with authenticated manual payment evidence. For a loss, the evidence must prove that the zero-amount result was recorded under the existing key; there is no manual cash payment to make. Never invent a new key to bypass uncertainty.

Common failure cases

Purchase debit definitely rejected

Expected: no ticket, no fee or position accounting, and no compensation operation because no money moved.

Purchase debit applied, response timed out

Expected: no automatic primary replay and no ticket until authoritative evidence confirms application. After confirmation, clearing is recorded once; the ticket is admitted only if still eligible, otherwise the exact debit becomes compensation payable.

Debit confirmed after gate closure

The gate wins over request start time. No late ticket enters the committed snapshot. The full debit is reversed through mini_app_polyflight_purchase_compensation.

Admission response lost

Query/retry the same durable purchase intent. If admission committed, the existing ticket is returned. Do not reverse a debit merely because an internal response was lost.

Winning credit unresolved

The ticket remains won. Payment remains owed, in_flight, or manual_review; the winnings liability remains visible. Do not label it paid or alter signed position income.

Losing-result acknowledgement unresolved

The ticket remains lost, with paymentEffect: "loss" and paymentAmountMinor: "0". Delivery can be owed, in_flight, or manual_review; paid means acknowledged, not paid cash. Follow the same ambiguity and authenticated manual-resolution process using the original :loss key. The wallet must durably record the result with an unchanged balance; remote_reference is optional. No clearing entry, financial liability, loss payout callback, or financial-settlement delay is introduced.

Retain the original request/response evidence and pinned transport. Older already-planned/dispatched win requests are not rewritten to add result: "won", and historical losses are not replayed to generate deliveries.

Cancellation refund unresolved

Fee entitlement ends at cancellation. The full original stake remains refund payable until confirmed; delivery timing does not restore the fee.

Duplicate delivery or notification

The same financial key and parameters must return the original effective result. A different payload under the same key is a conflict and must not mutate money. Webhook replay may repeat an event envelope, so receivers deduplicate by event_id; it never authorizes wallet mutation replay.

Missing or stale comparison rate

No FX lookup occurs during purchase, payout, or gate processing. A committed cached fallback rate remains frozen and is disclosed after reveal. If no valid pre-boarding observation exists, IDR entry is unavailable for that flight; existing global Credits progress is unaffected.

Operator outage or suspension

Block new admission. Continue recovery for existing payout, loss acknowledgement, refund, compensation, reconciliation, webhook evidence, and report reads. One operator outage does not change or withhold the global result.

Reconcile statement impact

After wallet state is resolved:

  1. Check /api/operator/polyflight/overview for the current liability and confirmed clearing totals.
  2. Find the ticket and verify result separately from paymentStatus.
  3. Confirm that a successful monetary credit/reversal appears as clearing outflow and releases the matching liability, without changing fee or position allocation. A successful loss acknowledgement creates no accounting entry, clearing movement, or liability change; unresolved zero-amount delivery does not block flight financial settlement.
  4. If the economic period is already finalized, inspect /{statementId}/adjustments; the original signed statement remains immutable and any late correction is applied to a later open statement.
  5. Download the canonical statement JSON and payment history for the case file.

See Terms, statements, and settlement and Settlement reports API.

Safe rollback and incident containment

First disable new Polyflight operator purchases for the affected operator or adapter. Keep payout, loss acknowledgement, refund, compensation, reconciliation, webhook evidence, and report reads running.

Safe actions:

  • disable operator Polyflight entry or pause the affected adapter;
  • pause future global generation when protocol integrity is in question;
  • deploy a forward fix or the last build that can still read and process protocol v5;
  • revert only future, unclaimed-wave policy after accounting for existing flights;
  • preserve operations, events, statements, proof artifacts, and audit history.

Unsafe actions:

  • roll back to a binary that cannot read v5 while v5 flights or obligations exist;
  • drop or reverse financial/proof tables as a traffic rollback;
  • change a committed valuation, snapshot, result, winner, payout, or terms version;
  • cancel a post-commitment flight through normal operations;
  • replay an ambiguous primary mutation or invent a new idempotency key;
  • delete evidence or rewrite a finalized statement;
  • switch all operator users to simulator mode.

After containment, reconcile the oldest unresolved operations and liabilities first, verify webhook delivery, compare statement/export parity, and retain redacted evidence. Production deployment or operator enablement is a separate authorized action; staging readiness does not imply it.

Required staging drills

Use dedicated user-scoped simulator wallets to exercise definite rejection, applied-then-timeout, credit applied-then-timeout, same-key duplicate/conflict, admitted cancellation/refund, late confirmed debit/compensation, win owed/paid/manual-review, and loss acknowledged/unresolved/manual-review. For loss, verify the exactly zero /credit, operation: "loss" / result: "lost" metadata, unchanged balance, same-key acknowledgement, no monetary accounting entry, and no loss payout pending/processed callback. Certify the same narrow zero-amount contract against the real adapter; generic simulator/manual wallet-operation amounts remain positive.

Launch the user from Operator Dashboard → Simulator → Users → Simulator, select product polyflight, and follow the single-use launch URL into Mini App Client. Do not substitute direct session-cookie injection or API-only testing. Simulator evidence proves OpenPoly's state machine, not a real operator adapter; certify REST v1 separately against dedicated non-production wallet infrastructure with small amounts.

Copyright © 2026