106 lines
6.4 KiB
Markdown
106 lines
6.4 KiB
Markdown
# Analytics Metric Catalogue
|
||
|
||
- Status: Draft — listed definitions approved
|
||
- Version: 0.4.0
|
||
- Last updated: 2026-08-20
|
||
|
||
Every merchant-facing number identifies its grain, formula, source fields, filters, Tehran-local period, unit, missing-data behavior, trace path, and definition version.
|
||
|
||
## Bank-paid sessions
|
||
|
||
- Canonical id: `bank_paid_sessions`
|
||
- Grain: distinct payment session
|
||
- Formula: count sessions where `session_status IN ('Paid', 'Verified')`
|
||
- Meaning: the buyer completed the bank payment and funds were deducted
|
||
- Unit: sessions
|
||
- Time attribution: session `created_at` in `Asia/Tehran`
|
||
- Traceability: merchant-scoped session identifiers and attempt histories
|
||
|
||
## Payment success rate
|
||
|
||
- Canonical id: `payment_success_rate`
|
||
- Numerator: `bank_paid_sessions`
|
||
- Denominator: sessions where `session_status IN ('Paid', 'Verified', 'Failed', 'Reversed')`
|
||
- Formula: numerator / denominator; undefined when denominator is zero
|
||
- Unknown statuses: excluded from both sides and disclosed as coverage/quality evidence until classified
|
||
- Unit: percentage
|
||
|
||
## Verified sessions
|
||
|
||
- Canonical id: `verified_sessions`
|
||
- Formula: count sessions where `session_status = 'Verified'`
|
||
- Meaning: bank payment and merchant verification are complete; the payment is finalized
|
||
- Unit: sessions
|
||
|
||
## Unverified paid sessions
|
||
|
||
- Canonical id: `unverified_paid_sessions`
|
||
- Formula: count sessions where `session_status = 'Paid'`
|
||
- Meaning: bank payment succeeded and funds were deducted, but merchant verification is incomplete
|
||
- Presentation: actionable verification gap; never label as failure
|
||
- Unit: sessions
|
||
|
||
## Verification completion rate
|
||
|
||
- Canonical id: `verification_completion_rate`
|
||
- Formula: `verified_sessions / bank_paid_sessions`; undefined when no bank-paid sessions exist
|
||
- Unit: percentage
|
||
|
||
## Paid volume
|
||
|
||
- Canonical id: `bank_paid_amount_rial`
|
||
- Formula: sum session `amount` once where `session_status IN ('Paid', 'Verified')`
|
||
- Unit: Rial
|
||
- Subsets: `verified_amount_rial` uses `Verified`; `unverified_paid_amount_rial` uses `Paid`
|
||
|
||
## Retried sessions and eventual payment
|
||
|
||
- `retried_sessions`: count sessions containing more than one payment attempt
|
||
- `eventually_paid_after_retry_sessions`: count retried sessions whose final session status is `Paid` or `Verified` and which contain a lower-`try_seq` attempt whose status is neither `Paid` nor `Verified`
|
||
- `retry_recovery_rate`: `eventually_paid_after_retry_sessions / retried_sessions`; undefined when no retried sessions exist
|
||
- Grain/unit: distinct sessions
|
||
- Traceability: ordered merchant-scoped attempt history; never depend on CSV row order
|
||
|
||
## Payment-stage diagnostics
|
||
|
||
- `no_attempt_sessions`: count sessions with zero normalized payment attempts. During challenge bootstrap this corresponds to the source marker `try_seq = 0 AND try_status = 'NoAttempt'`; the marker itself is not an attempt.
|
||
- `reached_bank_sessions`: count distinct sessions containing at least one attempt with `try_status IN ('InBank', 'Paid', 'Verified', 'Reversed')`.
|
||
- `in_bank_without_result_sessions`: count sessions whose latest positive-sequence attempt is `InBank` and which have no later `Paid`, `Verified`, `Failed`, or `Reversed` attempt.
|
||
- `failed_sessions`: count sessions with final `session_status = 'Failed'`; drill-down may distinguish zero-attempt, reached-bank, and other observable stages without inventing undocumented failure causes.
|
||
- Grain/unit: distinct payment sessions; attempt-stage counts must deduplicate by session when presented as sessions.
|
||
|
||
## Processing time
|
||
|
||
- Report median (p50) and p95 separately for `init_time_ms` and `verify_time_ms`
|
||
- Include only non-null values for the relevant field
|
||
- Always show contributing sample count and coverage percentage
|
||
- Do not replace missing timing with zero
|
||
- Unit: milliseconds, with human-readable seconds allowed as an additional presentation
|
||
|
||
## Merchant fee
|
||
|
||
- Canonical field: `fee_amount_rial`, sourced from CSV `adjusted_fee` and stored once per session
|
||
- `paid_fee_amount_rial`: sum session fee once where `session_status IN ('Paid', 'Verified')`
|
||
- `paid_fee_rate`: `paid_fee_amount_rial / bank_paid_amount_rial`; undefined when paid amount is zero
|
||
- Meaning/presentation: real merchant fee in Rial; do not label it obfuscated or relative-only in the product
|
||
- Retry rule: never sum the repeated source value per attempt
|
||
|
||
## Common behavior
|
||
|
||
- Rates are recomputed from summed numerator/denominator components for every selected day, Saturday–Friday week, Jalali month, and Persian season.
|
||
- Zero, undefined, missing, suppressed peer value, and calculation failure remain distinct states.
|
||
- `Paid` and `Verified` are both bank-payment successes, but only `Verified` is finalized.
|
||
- `Reversed` is not in the success numerator; display it separately when non-zero.
|
||
- `NoAttempt` is a source session marker, not a failed payment attempt. `InBank` means the user reached a bank gateway but no later outcome was recorded for that attempt; do not call it a bank rejection.
|
||
|
||
## Peer comparison
|
||
|
||
- Cohort: eligible merchants in the active merchant's category for the same selected reporting period; always exclude the active merchant.
|
||
- Availability: return a typed suppressed state unless at least 10 other merchants and 1,000 combined peer payment sessions contribute. Suppression never hides the active merchant's own metrics.
|
||
- Weighting: calculate each eligible peer merchant's metric independently, then use the median of those merchant values. Every merchant contributes one value regardless of payment volume.
|
||
- Rationale: merchant volume is extremely skewed (median 78 attempts, p95 8,915, maximum 1,138,592). A transaction-weighted average would mostly describe the largest merchants, while a merchant-weighted median represents a typical peer and resists extreme values.
|
||
- Output: expose the cohort median and the active merchant's performance percentile; never expose an individual peer's identity, value, or rank.
|
||
- Percentile direction: a higher displayed percentile always means better performance. Use the natural direction for payment success, verification completion, and retry recovery; invert the ranking direction for processing time and paid fee rate, where lower is better.
|
||
- Benchmarked metrics: `payment_success_rate`, `verification_completion_rate`, `retry_recovery_rate`, `init_time_ms` p50/p95, `verify_time_ms` p50/p95, and `paid_fee_rate`.
|
||
- Periods: calculate benchmarks for the same selected day, Saturday–Friday week, Jalali month, or Persian season as the active merchant value. Never compare unlike periods.
|