noulDemo available

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
target

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

  1. nowThe decision is logged with the refund id.proxy
  2. hoursThe risk team’s verdict on escalated and audited refunds.human_review
  3. 30–90 daysA chargeback or a confirmed fraud case.downstream
  4. 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