Skip to content

Diagnostic Rules

Ratomir Jovanovic edited this page Oct 25, 2026 · 2 revisions

Diagnostic Rules

Rules are deterministic checks over the normalized events. Each finding has a severity, a confidence, a short explanation, the ids of the events it is based on, a recommended action and its limitations. Rule texts never contain raw identifiers, so masking in exports always works.

The rule set has a catalog version (shown in reports and by pandapaylens version). It changes whenever a rule's behavior changes.

General rules

Rule Triggers when
PAYMENT_FAILURE the provider reports a failed payment, capture or refund
UNRESOLVED_OUTCOME the supplied events do not show a final payment state
POSSIBLE_RETRY_RISK the records suggest an unsafe retry pattern, for example a retry after an unknown outcome
POTENTIAL_STATE_INCONSISTENCY observed states contradict documented provider state transitions
CONFLICTING_OBSERVATIONS repeated deliveries of one event report incompatible states
DUPLICATE_DELIVERY the same provider event appears more than once
OUT_OF_ORDER_ARRIVAL an event arrived after an event that was created later
MISSING_REFERENCE an event cannot be linked to a payment
UNKNOWN_EVENT_TYPE an event type PandaPayLens has no semantics for

Lifecycle rules

Rule Triggers when
RECURRING_PAYMENT_FAILED a recurring (rebill) charge failed, possibly after earlier successful cycles
CAPTURE_FAILED_AFTER_AUTHORIZATION an authorization succeeded but a later capture failed
CHARGEBACK_REPORTED a dispute or chargeback is reported, linked to an earlier payment when the data shows it
PAYOUT_STATUS a payout failed or remains unconfirmed
AMOUNT_MISMATCH refunded or captured amounts exceed the paid or authorized amount, or currencies differ
REFUND_PENDING a refund was initiated but its completion is not shown

Lifecycle rules are provider-agnostic. They read only the normalized stage, outcome, amount and subscription fields, so every adapter benefits from them.

Notes on specific rules

  • Duplicates are confirmed when two events share a delivery key: an event id, or a documented combination of fields. When a provider sends no such key, records with identical content are reported as a possible repeat and counted once by the other rules. Where a provider documents that identical records can be separate events (for example two equal partial refunds), they are never merged.
  • Amount mismatch for subscriptions compares refunds with the total of all billed cycles, not with one cycle.
  • Retry risk never assumes that a timed-out request failed.
  • A finding is a pointer for investigation, not a verdict. "This is not a defect by itself" is said explicitly where it applies, for example for out-of-order delivery.

Severity

critical, high, medium, low and info. The CLI option --fail-on <severity> turns findings at or above a level into a non-zero exit code, which is useful in CI.

Clone this wiki locally