-
Notifications
You must be signed in to change notification settings - Fork 261
Description
Merchants need buyer environment signals (IP, user-agent, device fingerprints) for fraud prevention, rate limiting, bot detection, etc. UCP has no standard location for these signals and no mechanism for merchants to communicate what signals affect their authorization confidence.
We briefly explored this topic in earlier draft of the spec via risk_signals and deferred as a TODO. After a number of attempts and explorations, couple key insights:
- It's not just about "risk", many signals also apply for rate-limiting and similar operational concerns.
- Signals are dynamic and can change in response to every operation — e.g. buyer info, cart item, totals, etc.
- UCP has first-class concept of step-up via escalation &
continueUrl, and a state machine that performs validation of the checkout state, and what we need is a ~confidence layer & and mechanism to dynamically request signals from the platform.
To elaborate on last point, two distinct concerns govern checkout progression:
| Concern | Question | Mechanism | Blocks Status? |
|---|---|---|---|
| Completeness | Is checkout structurally valid? | error message |
Yes |
| Confidence | Can I authorize without friction? | hint message |
No |
A checkout can be complete but low-confidence:
ready_for_complete= "You have everything needed to ATTEMPT completion"hintmessages = "My confidence is low; expect friction unless you provide X"
Validation failures are deterministic: e.g, no email = can't complete. Confidence is probabilistic: e.g., no device_id = higher probability of step-up response, not certainty.
Request → [error?] → incomplete (hard enforcement)
↓ resolve
→ ready_for_complete + hints (confidence signals)
↓ complete()
→ POLICY EVALUATION: f(signals, context, policy)
↓
→ completed | requires_escalation (step-up) | declined
Proposal
1. Introduce new signals object
Transport-agnostic and extensible container for environment signals on checkout, cart, and catalog:
{
"checkout": {
"id": "chk_123",
"signals": {
"buyer_ip": "203.0.113.42",
"user_agent": "Mozilla/5.0...",
"device_id": "fp_abc123",
"ja4": "t13d1516h2_8daaf6152771_b186095e22b6"
}
}
}The spec would define a small set of well-known signals: buyer_ip, device_id, user_agent, ja4. New signals can be added via extensions and negotiated between platform & business as part of handshake; core signals are assumed to be ~universal and do not need negotiation.
2. Add new Message type: hint
Agent-targeted message expressing what signals affect merchant confidence:
{
"type": "hint",
"path": "$.signals.device_id",
"code": "risk",
"content": "Device fingerprint may reduce verification friction"
}Hint codes:
risk— fraud prevention, authorization decisionsabuse— rate limiting, bot detection
Examples
Hard enforcement
Platform MUST provide email. Deterministic:
{
"checkout": {
"status": "incomplete",
"messages": [{
"type": "error",
"path": "$.buyer.email",
"code": "REQUIRED_FIELD",
"content": "Email address is required"
}]
}
}Non-blocking hint signal
{
"checkout": {
"status": "ready_for_complete",
...
"messages": [{
"type": "hint",
"path": "$.signals.device_id",
"code": "risk",
"content": "Device fingerprint may reduce verification friction"
}]
}
}Platform CAN attempt to complete without signal. Probabilistic — step-up more likely without it.
{
"catalog": {
"products": [...],
"messages": [{
"type": "hint",
"path": "$.signals.buyer_ip",
"code": "abuse",
"content": "Without IP address, stricter rate limits may apply"
}]
}
}As message says, missing buyer_ip may result in stricter rate limit.
Requirements
Both parent signals object and all the signals would be marked as optional by default. This allows us to introduce this as a non-breaking change.