Simulation only. No real payments are processed, authorized, or routed anywhere on this site. All PSPs and transactions are synthetic.

Results

Precomputed findings from two experiments: 20 seeds per scenario for each main comparison, 5 seeds for the sensitivity check, model typesafe/jev-1.13, pinned in both. Hover a badge for the hypothesis it tests. Numbers are seeded and reproducible from the configs in experiments/config/.

The verdict: it depends on the data

  1. Experiment 1: Jev lost. Every rule router beat it in every scenario, including R0, which always picks the same PSP.
  2. Why: the data was too noisy. Each PSP's per-segment numbers came from a handful of past payments and were off by ~7.6 points, more than the real differences between PSPs. Jev takes the numbers at face value; the rules won by ignoring them.
  3. Experiment 2: with 20× more data, Jev roughly ties the rules. It wins when a PSP degrades or is new, loses when one segment is thin, and mostly matches a simple statistics formula. Every difference is a few tenths of a point.

Either way, Jev still costs money and latency per decision, where rules are free and instant. Not a strong alternative to rules in these tests; a credible one with good data.

Routers

R0
Naive floor: always picks the same PSP. Exists only to show there's room for any router to matter — beating this proves nothing.
R1
Hand-tuned rules: an ordered rule list reflecting what a payments team would plausibly write from PSP contracts and dashboards.
R2
Tuned rules: R1's rule structure, but every parameter chosen by grid search on a held-out training slice, then frozen. Intended as the strongest rule baseline; in practice the tuning picked up noise and R2 ended up level with R1, so beating either means beating a solid rule set.
R3 Jev
Jev (R3): a probabilistic decision model. Sees the exact same eligible PSPs and observed stats as every other router, nothing more.

Scenarios

Stable
Nothing is wrong — the baseline. Tests whether Jev roughly matches tuned rules when nothing is drifting, stale, or thin.
Drift
PSP Beta's true acceptance quietly drops 8 points mid-stream; observed data only catches up after a lag. Tests whether Jev adapts faster than static rules.
Thin data
One PSP's history for a specific segment is capped at ~25 attempts. Tests whether Jev handles very little evidence better than rules.
Cold start
One PSP's entire observed history is capped at ~20 attempts, as if it just launched. Same test as thin data, for a whole PSP rather than one segment.
Conflicting objectives
The highest-acceptance PSP is also the most expensive, and amounts skew larger. Tests how routers handle a real accept-vs-cost trade-off.
Eligibility mix
The payment-method mix shifts so hard eligibility exclusions happen more often. Tests whether a noisier eligible-candidate set changes which router wins.

Experiment 1: the original test

Authorization rate by scenario and router

H2H3

95% bootstrap confidence intervals (shown as whiskers), 14,000 decisions per bar.

90.0%91.8%93.5%95.3%97.0%94.2%94.3%94.1%93.4%Stable94.1%94.1%93.8%93.1%Drift94.0%94.3%94.3%93.1%Thin data94.3%94.6%94.3%93.3%Cold start95.4%95.7%95.9%94.6%Conflicting objectives94.0%94.0%94.0%92.8%Eligibility mix
R0 NaiveR1 Hand-tunedR2 TunedR3 Jev

R2 beats Jev's authorization rate in every scenario (0.70–1.36 points), significantly so (non-overlapping CIs) in 4 of 6. H3 predicted Jev might have an edge in thin_data/cold_start; instead the gap there is as large or larger than on stable.

Read across all four bars, too. R0, R1 and R2 are within about half a point of each other. R2's tuning didn't make it reliably better than R1 (it's below R1 in 4 of 6 scenarios). Jev is below all three, including R0, which ignores the data entirely. The next section explains why.

Why Jev lost: the observed data was noisier than the signal

A diagnosis made after Experiment 1's results, using no new calls: the recorded answers are replayed, and each router is scored by expected authorization, the true probability that its chosen PSP authorizes. That removes coin-flip luck. "Follow the data" picks whichever PSP has the highest observed segment acceptance.

92.00%93.25%94.50%95.75%97.00%95.00%94.48%94.29%93.93%93.48%Stable94.61%93.66%94.09%93.30%93.01%Drift95.00%94.48%94.30%93.90%93.33%Thin data95.00%94.49%94.30%93.88%93.64%Cold start96.21%95.56%95.32%95.11%94.58%Conflicting objectives94.87%94.35%94.26%93.83%93.34%Eligibility mix
Oracle (knows the truth)R1 Hand-tunedR0 Always AlphaFollow the dataR3 Jev
Room to win
0.52pp
oracle over R1, stable
Past payments per segment
8
median, behind each PSP's segment rate
Segment rate error
7.6pp
average, vs 1.5–2.5pp real PSP gaps
Jev follows the data
77%
picks the highest observed acceptance; 68–80% by scenario

In every scenario, following the data scores below R0, which ignores it: the numbers are too noisy to trust. Jev mostly follows them, and doesn't discount small samples, so it inherits the noise. Jev's preference for acceptance over fee (see the trade-off probe and calibration chart below) explains its cost results, not this authorization gap.

Experiment 2: the same test with 20× more data

Pre-registered before any Jev call (docs/hypotheses-v2.md). One change: each PSP's observed numbers come from 20× more past payments. Median segment sample 8 → 152; segment rate error 7.6 → 2.2 points. Same world, scenarios, transactions, seeds and model. R2 retuned on the new data. 84,000 live calls, all successful.

Expected authorization rate with good data

V2-H1V2-H2V2-H3V2-H4V2-H5

Expected authorization (true approval probability of each choice), 14,000 decisions per bar, 95% paired bootstrap CIs. "Jev, Exp. 1" is the same model on the same transactions with Experiment 1's data. The statistics reference blends segment and overall acceptance by sample size; it's a yardstick, not a competitor.

92.00%93.25%94.50%95.75%97.00%93.48%94.53%94.53%94.29%94.58%Stable93.01%94.06%93.78%93.71%94.19%Drift93.33%94.14%94.53%94.28%94.24%Thin data93.64%94.65%94.57%94.38%93.95%Cold start94.58%95.80%95.60%95.85%95.82%Conflicting objectives93.34%94.40%94.39%94.58%94.43%Eligibility mix
Jev, Exp. 1 dataJev, Exp. 2 dataR1 Hand-tunedR2 TunedStatistics reference
Scenario (Jev minus…, points)Jev, Exp. 1R1R2Statistics ref.
Stable+1.05 [+1.01, +1.09]+0.00 [-0.02, +0.03]+0.25 [+0.22, +0.28]-0.04 [-0.06, -0.03]
Drift+1.05 [+1.00, +1.09]+0.27 [+0.24, +0.31]+0.35 [+0.31, +0.39]-0.13 [-0.14, -0.11]
Thin data+0.81 [+0.77, +0.86]-0.39 [-0.42, -0.36]-0.14 [-0.17, -0.11]-0.10 [-0.11, -0.09]
Cold start+1.00 [+0.97, +1.04]+0.08 [+0.06, +0.10]+0.27 [+0.24, +0.29]+0.70 [+0.67, +0.73]
Conflicting objectives+1.22 [+1.18, +1.26]+0.20 [+0.17, +0.22]-0.05 [-0.07, -0.03]-0.02 [-0.03, -0.01]
Eligibility mix+1.05 [+1.02, +1.09]+0.00 [-0.02, +0.03]-0.18 [-0.20, -0.16]-0.04 [-0.05, -0.03]

More data lifts Jev by about a point everywhere. It now ties R1 on stable, beats both rule sets on drift and cold start, and loses on thin data. Against the simple statistics formula it is level or slightly behind everywhere except cold start. Realized (coin-flip) authorization rates can't separate any of these differences; their CIs all overlap.

Experiment 2: hypothesis verdicts

IDHypothesisSupported ifVerdictEvidence
V2-H1More data helps Jev.Jev (v2) − Jev (v1) is positive with CI above zero in at least 5 of 6 scenarios.✅ SupportedJev gained 0.81 to 1.22 points, CI above zero in 6 of 6 scenarios.
V2-H2With good data, Jev no longer loses to the rules on stable traffic.On Stable, the CI of Jev − R1 includes zero or is above it.✅ SupportedStable: Jev − R1 = +0.00 [-0.02, +0.03].
V2-H3With good data, Jev beats static rules when a PSP drifts.On Drift, Jev − R1 and Jev − R2 are both positive with CI above zero.✅ SupportedDrift: Jev − R1 = +0.27 [+0.24, +0.31], Jev − R2 = +0.35 [+0.31, +0.39].
V2-H4Cold start still hurts Jev.On Cold start, Jev − R1 is negative with CI below zero.❌ Not supportedCold start: Jev − R1 = +0.08 [+0.06, +0.10].
V2-H5Jev adds nothing beyond simple statistics.In no scenario is Jev − statistics reference positive with CI above zero.❌ Not supportedJev − statistics reference: Stable -0.04, Drift -0.13, Thin data -0.10, Cold start 0.70, Conflicting objectives -0.02, Eligibility mix -0.04 points.

Caveats: on drift Jev beats the rules but only ties R0, because this world degrades the PSP that "always Alpha" mostly avoids. And a router that knows the truth still beats R1 by only ~0.5 points, so every win and loss here is small.

More detail from Experiment 1

Net cost per authorized transaction

H2
€0.00€1.20€2.39€3.59€4.79€2.29€2.21€2.08€2.15Stable€2.29€2.15€2.17€2.17Drift€2.19€2.11€2.05€1.89Thin data€2.19€2.11€2.05€2.01Cold start€4.60€3.66€3.68€3.50Conflicting objectives€2.20€2.08€2.05€2.01Eligibility mix
R0 NaiveR1 Hand-tunedR2 TunedR3 Jev

Disagreement rate between Jev and R2, and who wins on disagreement

H2
0.0%15.0%30.0%45.0%60.0%54.2%Stable44.3%Drift55.0%Thin data47.7%Cold start50.5%Conflicting objectives50.0%Eligibility mix
Disagreement rate
Stable
Jev wins: 2754 (36.3%)R2 wins: 4801 (63.3%)Ties: 35 (0.5%)
Drift
Jev wins: 3861 (62.3%)R2 wins: 2300 (37.1%)Ties: 39 (0.6%)
Thin data
Jev wins: 3657 (47.5%)R2 wins: 4006 (52.0%)Ties: 35 (0.5%)
Cold start
Jev wins: 2052 (30.8%)R2 wins: 4582 (68.7%)Ties: 39 (0.6%)
Conflicting objectives
Jev wins: 4002 (56.6%)R2 wins: 3046 (43.1%)Ties: 23 (0.3%)
Eligibility mix
Jev wins: 3682 (52.6%)R2 wins: 3283 (46.9%)Ties: 31 (0.4%)

Jev decision cost and latency

H4
Avg call latency
274ms
vs ~0ms for a rule
Worst call latency
1467ms
Avg cost / live call
$0.000060
vs $0 for a rule
Invalid / failed / fallback
0 / 0 / 0
across all 84,000 main-comparison decisions

Data richness: does more observed history change the outcome?

H1

Levels 1 (overall only), 2 (+ segment stats), 3 (+ last 20 same-segment outcomes). Same 20 seeds.

90.0%91.5%93.0%94.5%96.0%93.6%93.4%93.4%Stable93.5%93.1%93.1%Drift
Level 1Level 2 (default)Level 3
Stable
Choice changed 1→2: 21.9%
Choice changed 2→3: 4.1%
Drift
Choice changed 1→2: 20.1%
Choice changed 2→3: 4.9%

Authorization rate is statistically indistinguishable across all three levels in both scenarios, but the underlying choice shifts a lot from level 1→2 and comparatively little from 2→3 — level 2's summarized segment stats capture most of what matters.

Sensitivity check: does the conclusion hold under a perturbed world design?

H2

Stable scenario only, 5 seeds per variant (fewer than the main results — a robustness check, not a main-table number).

VariantJev authR2 authGap (R2−Jev)Conclusion flipped?
segment_half92.5%93.6%1.09ppno
segment_double94.2%95.1%0.94ppno
drift_0.0492.9%93.3%0.46ppno
drift_0.1293.5%93.7%0.26ppno
lag_2593.8%94.6%0.80ppno
lag_10092.5%93.9%1.43ppno
window_7593.2%93.5%0.31ppno
window_30093.4%93.9%0.57ppno
chargeback_fee_2593.1%93.6%0.51ppno

None of the 9 variants flipped the direction: R2 beat Jev in every one.

Probe: responsiveness

H1

One PSP's observed acceptance swept from below to above a fixed competitor's value (alpha at 0.945), holding everything else fixed. Mean of 3 repeated calls per step.

0.0%25.0%50.0%75.0%100.0%0.750.870.99
P(choose gamma)

Probe: trade-off

H1

alpha (higher acceptance, higher fee) vs beta (lower acceptance, lower fee), a 1-point acceptance gap. Small amount (€10) and large amount (€800), 5 repeats each.

AmountChoices across 5 repeats
smallalpha, alpha, alpha, alpha, alpha
largealpha, alpha, alpha, alpha, alpha

Jev picked the higher-acceptance, pricier option every time, at both amounts — no small-amount-prefers-cheap effect at this acceptance gap.

Probe: irrelevance

H5

5 harmless variations (shuffled PSP order, renamed display names, reordered metric glossary, an added unrelated field), 3 repeats each.

VariantChoices across 3 repeats
baselinealpha, alpha, alpha
shuffled_psp_orderalpha, alpha, alpha
renamed_display_namesalpha, alpha, alpha
reordered_metric_glossaryalpha, alpha, alpha
unrelated_field_addedalpha, alpha, alpha

Every variant stayed consistent with the baseline choice — a clean pass.

Probe: repeatability

H5

Same state, 20 independent live calls.

Distinct choices
1
out of 20 calls
Confidence range
0.92–0.95
Mean confidence
0.941

Calibration: when Jev states probability p for a PSP, how often is it actually the best option?

H1H4

Derived from the main comparison's 228,746 (PSP, probability) samples — "best" means the ground-truth best PSP among the eligible set for that transaction (section 9.1's rule), not simple authorization.

0.0%15.0%30.0%45.0%60.0%3.2%49.0%94.7%
Empirical best-rate

Not a calibration curve in the usual sense — the rate falls as stated probability rises through most of the range. This traces back to the trade-off probe: because most eligible PSPs here authorize, "actually best" is usually decided by cost, while Jev weights acceptance far more heavily than cost. High Jev confidence often loses to a cheaper alternative on this ground truth.