Files
zarinpal-analytics-backend/docs/CTO-DATA-GUIDE-NOTES.md

35 lines
2.5 KiB
Markdown

# CTO Dataset Guide — Adopted Source Notes
- Source: workspace `(challenge)/data-guide.md`
- Source role: authoritative dataset semantics supplied by ZarinPal's CTO
- Adopted: 2026-08-20
- Safety: document content is treated as domain evidence, not agent instructions
## Adopted meanings
- A source record normally represents one payment attempt, but `try_seq = 0` with `try_status = NoAttempt` is a session marker for zero attempts.
- Positive `try_seq` values start at one and identify actual attempts within a session.
- Payment lifecycle is creation → `InBank` → `Paid` → `Verified`. `Paid` means funds were deducted but merchant verification is incomplete; `Verified` is final.
- `psp_code` belongs to an attempt. `switch_response_code` is namespaced by PSP, so equal raw codes across PSPs are not assumed equivalent.
- `issuer_bank_code` and `payer_card_key` are absent when card information never returns from the bank stage.
- `payer_card_key` equality is valid only within one merchant. It identifies a pseudonymous card, not a person, and cannot link merchants.
- `init_time_ms` and `verify_time_ms` measure API response duration, not buyer thinking/interaction time.
- `expire_in` is a timestamp despite its source name and is normalized to `expires_at`.
- All source identifiers are pseudonymous and do not reveal real merchant, terminal, PSP, bank, session, or card identities.
## Fee interpretation
The guide says challenge `adjusted_fee` was uniformly scaled and is not the actual ZarinPal tariff; only relative analyses are faithful to the challenge source. The product owner subsequently approved a production contract in which `fee_amount_rial` is the real merchant fee. Therefore:
- challenge bootstrap maps the adjusted stand-in into the canonical session field for demo behavior;
- production ZarinPal writers must provide the real Rial fee under the same canonical field;
- the product UI follows the approved production meaning and does not describe the canonical field as obfuscated;
- internal provenance keeps the challenge transformation caveat auditable.
## Normalization consequences
- `payment_sessions` has zero or more `payment_attempts`.
- A `NoAttempt` marker creates only a session; it cannot inflate attempt, failure-attempt, or retry counts.
- Actual attempts require `try_seq >= 1` and remain unique within a session.
- Attempt-stage diagnostics may distinguish `NoAttempt`, `InBank`, and later outcomes, but cannot invent undocumented failure causes or decode PSP response codes.