Refund fraud
An online shop pays refunds automatically. Paying a fraudulent one loses money; holding an honest one loses a customer. The truth comes as a chargeback one to three months later, and a refund that was held almost never learns it.
“Is this refund request fraudulent?”
The request · POST /v1/systemone
{
"model": "jev-latest",
"state": {
"refund_id": "rf-1001",
"amount": 129.5,
"reason": "item not received"
},
"questions": {
"refund_fraud": {
"type": "noul",
"instructions": "Is this refund request fraudulent?"
}
}
}
The policy
- p < 0.26ACCEPTpay out
- otherwiseESCALATEthe risk team decides
False passes ≤ 2% with 95% confidence, and at most 15% escalated.
0.26 in one run of the demo, on generated data, proposed from 2,131 tuning refunds. On 1,127 refunds it never saw, 96.3% were paid out without a look and 1.66% of those were fraud (95% interval 0.99% to 2.61%). There is no block rule: a held refund almost never gets a chargeback, so its errors can't be measured, and trimset won't certify what it can't measure. 1% of accepted refunds are reviewed anyway, so the refits stay honest.
When the truth arrives
- nowThe decision is logged with the refund id.proxy
- hoursThe risk team’s verdict on escalated and audited refunds.human_review
- 30–90 daysA chargeback or a confirmed fraud case.downstream
- 120 daysNo chargeback: recorded as not fraud.rule
In your app · Python SDK, gate() from M3
d = ts.gate("refund_fraud", answer=resp["answers"]["refund_fraud"],
model_served=resp["model"], decision_id=ids[0])
if d.action == "ACCEPT":
pay_out(refund)
elif d.action == "ESCALATE":
risk_queue.add(refund)
else:
hold(refund)
Run the demo from a clean checkout: seven months of refunds from a badly calibrated model, with chargebacks 30 to 90 days late, end in a draft policy with its guarantee in words. Approving it, and applying it in your app with gate(), are in the ticket triage demo.
Run the demo