Agent payments: mandates, pay-per-use, receipts

Status: draft 0.1. Covers friction #7 (no scoped spending limits), #17 (checkout assumes a human with a card), #24 (micropayments are impractical) and #28 (no refund and receipt trail). Reference implementation: agent_index/payments.py, built on agent identity.

Spending mandate

A mandate is an agent grant with the pay scope and limits in constraints:

"constraints": {
  "max_per_purchase": 5000,
  "max_total": 8000,
  "currency": "USD",
  "categories": ["office-supplies"]
}

Amounts are in minor units (cents). The mandate names one merchant (aud) and expires (exp, default 7 days). "This merchant, this amount, this week" is one token the person signs once.

The merchant checks, on every charge: the signatures, the pay scope, currency, per-purchase limit, running total under this mandate (charges minus refunds), and category. A charge that breaks a limit fails with a code: over_purchase_limit, over_total_limit, wrong_currency, category_not_allowed.

Because the mandate itself is the person's authorization, the merchant has no reason to demand 3-D Secure, an OTP or a CAPTCHA for charges inside it. How the merchant then collects money (card on file, network token, account balance) is unchanged and out of scope.

Receipt trail

Every charge and refund is appended to a hash-chained ledger. Each entry carries:

type (charge or refund), id, mandate, principal, agent, purpose, merchant, item, amount, currency, refund_of (refunds), reason, at, prev, hash.

prev is the previous entry's hash, so editing or deleting any past entry breaks the chain and verify() fails. Any purchase traces back to the mandate, and the mandate to the person who signed it. Refunds can't exceed the charge they reference.

Pay-per-use (HTTP 402)

For content and API calls priced in cents:

  1. The agent requests a page. The server answers 402 Payment Required with Agent-Price: amount=25, currency="USD", payee="news.example".
  2. The agent checks the price against its approval policy and mandate, then retries the same request signed under its mandate, with Agent-Payment: {"accept_price": {...}} in the signed body.
  3. The server verifies, charges exactly the advertised price, records a receipt, and serves the content.

A site's agent policy can publish prices up front, so agents know the cost before the first request. Settlement between the merchant and the person's payment provider can be batched, which is what makes 25-cent charges practical.

Running it

Site. AgentFriendly(merchant=payments.Merchant(host, trusted, state=SiteState("agents.db"))). Priced paths answer 402 and charge on the signed retry; action handlers charge with ctx.charge(amount, currency, item, category). Every charge's receipt goes back to the agent in an Agent-Receipts header (base64url JSON). The ledger lives in the site's SQLite state, so it survives restarts and is shared by workers.

Endpoint What it does
GET /.well-known/agent-receipts Signed under the person's mandate: every receipt for that person, the chain head and length, and whether the chain verifies.
POST /.well-known/agent-refunds {"charge_id", "amount"?, "reason"} Refund to the buyer. Automatic inside the merchant's refund window (30 days by default); after it, needs_human.

Agent. The wallet holds mandates and a copy of every receipt it was handed, after checking its hash. Before paying it checks the mandate's currency, per-purchase and remaining limits itself, so a doomed charge is never sent. The person's approval policy decides each spend: small ones go through (by default up to $20), larger ones come back as needs_human with the amount, and go through when the agent calls again with confirm=true after asking. fetch pays 402 prices the policy allows on its own, and keeps paid pages out of the shared cache. receipts(check_with_merchant=true) compares the agent's copies with the merchant's ledger and lists any receipt the merchant dropped or changed.

What still needs outside parties. Moving real money: the merchant settles charges with its payment provider (card on file, network token or balance) in batches. Card networks' own agent programs can carry the mandate token as the authorization evidence; until they do, the mandate is the merchant's record of consent.