Skip to content

How Analysis Works

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

How Analysis Works

Every analysis runs the same deterministic pipeline. The same input always gives the same output. There is no machine learning or remote service in the diagnostic path.

raw text
  -> 1. parse        bounded parsing into records (JSON, JSON Lines, form, HTTP, URL)
  -> 2. sanitize     prototype keys dropped; sensitive fields detected
  -> 3. detect       each adapter scores each record by structure
  -> 4. normalize    the winning adapter turns records into normalized events
  -> 5. decode       provider codes become decoded errors
  -> 6. correlate    events are grouped by explicit identifiers
  -> 7. rules        diagnostic rules produce findings
  -> 8. report       timeline, findings, exports (identifiers masked by default)

1. Parse

The input is split into records. A JSON array becomes one record per element, JSON Lines one per line, a form body one record, and a raw HTTP message one record whose body is parsed by its content type. Parsing has hard limits on size, depth, record count and string length (see Input Formats), so a hostile or huge input cannot freeze the page.

2. Sanitize

Keys that could be used for prototype pollution (__proto__, constructor, prototype) are dropped from every record. Sensitive fields (card numbers, security codes, tokens, secrets, signatures, personal and bank data) are detected and listed in the sensitive-data warning.

Adapters read the original record, but copy only allowlisted, non-sensitive fields into events, and provider messages pass through a sanitizer. Everything PandaPayLens shows or exports, including the raw data view, is redacted. See Privacy and Security.

3. Detect

Each provider adapter looks at the structure of a record (which fields exist, their shapes and documented values) and returns a confidence score with reasons. Adapters never match on a brand name in a string. The highest score wins if it is high enough and clearly ahead of the others. If two adapters are close, the record is marked ambiguous and you can choose the provider manually.

Generic shapes such as a bare { "error": ... } or { "status": ... } are never claimed with high confidence. Such records are analyzed only when you pick the provider yourself.

4. Normalize

The adapter turns each record into one or more normalized events. An event keeps the provider's own status and event name and adds common fields:

Field Meaning
stage payment, authorization, authentication, capture, refund, dispute, payout, subscription, ...
outcome success, failure, pending or unknown
occurredAt event time, only when the provider sends one with a known time zone
amount integer minor units with currency, never floating point
references payment, related, subscription and attempt references used for correlation

Semantics are kept honest: an authorization is not a capture, a capture is not a settlement, a refund request is not a completed refund, and a wallet approval is not a card authorization. Unknown statuses stay unknown.

5. Decode

Provider codes are looked up in catalogs built from official documentation. See Error Decoding.

6. Correlate

Events are grouped into transactions using only explicit identifiers. See Timeline and Correlation.

7. Rules

Rules read the normalized events and groups and produce findings with severity, confidence, evidence and limitations. See Diagnostic Rules.

8. Report

The result is shown in the browser or printed by the CLI and can be exported. See Exports and Reports.

Where the code lives

Path Contents
packages/core parsing, redaction, detection, engine, reports
packages/adapters/<id> one provider adapter each
packages/providers registry of adapters, manifests and the roadmap
packages/rules diagnostic rules
packages/cli command-line interface
apps/web Next.js application
apps/pages static GitHub Pages build of the same pages
fixtures synthetic fixtures and the example catalog

In the browser, the engine runs in a Web Worker with a 20 second time limit, so the page stays responsive.

Clone this wiki locally