Handling the outcome
Pass onResult to protect() and it’s called once for each outcome of a check or review:
The result
Outcomes
A review is followed by approved, declined or expired, or by nothing if the agent goes back to the quote.
onResult isn’t called for a step that proceeds without a check: after an approval of the same quote, or once checks have stopped after a second fail-open.
Fail-open reasons
reason comes with fail_open only:
Decline reasons
declined comes with declineReason when the customer chose one on the approval page.
Branch on code: it’s stable. declineReason is left out when the customer gave no reason. Review not_me declines: the customer says they didn’t ask for this purchase.
Monitor-only products
A press on a monitor-only product goes straight through, and onResult is called afterwards with monitored: true:
continuewith thecheckIdonce the check returns, orfail_openwith thereasonif it fails.
A page that unloads first (for example, a full navigation to your payment page) receives continue as it unloads, without a checkId. Code that only reads outcome sees the same values as for any other product.
What it doesn’t get
onResult gets no personal data: no quote details, no mobile, no userId.
How it’s called
- After the step continues or pauses, in a microtask, so it doesn’t delay the step.
- Anything it throws, or a promise it returns that rejects, is caught and logged to the console.
- If
onResultisn’t a function, it’s left out with a console warning, and the step is still protected.
Example: send outcomes to analytics
Alert on a rising share of fail_open, especially http_401, http_403 and network: they usually mean a revoked key, a missing allowed website, or a Content Security Policy that blocks the embed.