A handoff is an exclusive lease on human control, not a credential handoff. One row per purchase records the holder, allowed merchant origin, expiry, and revision.
Claim the lease
POST /v1/applications/{appId}/purchases/{purchaseId}/handoffs accepts an empty JSON object. A claim is refused while another holder’s lease is live.
Read the allowed origin and expiry
GET /v1/applications/{appId}/purchases/{purchaseId}/handoffs/{handoffId} returns the redacted lease.
Release it
The holder calls /complete after finishing the human step, or /cancel to return control without completing it. Both writes echo expectedRevision.
Verify
A non-holder cannot release the lease. Claims are blocked after the payment commit boundary, and an active lease is revoked when the purchase is cancelled or begins its single payment attempt.