Agents can pay.
Now they can pick up.
agentPickup turns a payment into a signed pickup pass. An agent pays over x402, or a person pays by card, and the buyer gets a QR. The merchant's scan proves the right person collected the order, and only then does the payment settle. It's an open format and a drop-in library for facilitators, agent wallets and ordering platforms.
/gap
Agents can pay for physical things.
Nobody can prove they collected them.
The payment and shopping standards each stop one step short of the counter.
/how
From 402 to hand-over
What happens on the wire, start to finish.
exact today. Holds through auth-capture as facilitators add it. Cards through Stripe are held until the scan.x402 · Stripe/.well-known.pass.emailed/standards
Speaks every agent checkout
Whichever way the agent pays, the order ends in the same signed pickup pass. Every path is covered by the test suite.
pickup method, and the pickup pass as the order's link./.well-known/ucp/spec
An open pickup pass
A small, signed token that any facilitator, wallet or platform can issue and check. It carries no names, items or amounts, so a leaked screenshot gives nothing away.
- Compact JWS, EdDSA. It fits in a QR that a normal phone camera opens.
- Checkable offline. Keys come from the merchant's JWKS, so a locker or kiosk can verify one with no network.
- Built for x402. It's designed to sit next to x402's offer-and-receipt extension: the receipt proves payment, and the pass proves collection.
- Maps to UCP. The pass fills in the proof of collection that UCP's
pickupfulfilment method leaves open.
format v1 · draft · feedback welcome
// header
{ "alg": "EdDSA", "kid": "_Gmp2PH4" }
// payload
{
"v": 1,
"oid": "ord_7HkQ2mXc9aRt", // order
"pid": "Ya7qVHjkKI7bn4gU", // pass id, single use
"exp": 1793666330 // collect by
}
// QR content
https://shop.example/c/<header>.<payload>.<sig>
// keys
GET /.well-known/collect-keys.json → JWKS (Ed25519)
/demo
Run an order end to end
A pretend café running the library. Pay with the test button, or hit the x402 link and see the real 402 quote. Then scan the pass the way staff would. No real money moves.
$ waiting for an order▍
Add something on the left and pay. The events, the email and the scan will show up here.
Or open the staff scanner on another phone and point it at the QR in the email.
/who
Built for the companies that move agent payments
A real-world use case for agent money
Your agents can already buy API calls. Add physical goods that someone collects in person, with a signed proof of hand-over for disputes and spending policies.
- Issue and check passes in your stack
- Settle when the scan happens, not before
Agent-ready pickup for every merchant
Accept orders from any agent, not just the ones on your app, and give every merchant on your platform the same signed hand-over under your brand.
- White-label scanner and emails
- Courier hand-over doubles as proof of delivery
Click and collect in an afternoon
Mount one Hono app and get checkout, passes, a scanner and webhooks. SQLite out of the box, or bring your own store.
- Free to self-host, no tracking
- TypeScript on Node 22; swap the store for other runtimes
/developers
One mount, the whole flow
Checkout, passes, scanner, emails and webhooks, on your domain and under your brand.
- Every way agents pay. x402, MPP, UCP and ACP for agents, and Stripe Checkout with the card held until pickup.
- An MCP server.
@agentpickup/mcplets any agent order, pay and fetch the pass. Try ours at/mcp. - Your brand only. Emails, pass pages and the scanner carry the merchant's name and colours, never ours.
- Events you can act on. Signed webhooks for paid, ready, collected and expired orders.
- Safe by default. Prices come from the catalog, claims are atomic so two scanners can't both hand over, and staff routes sit behind a key.
import { createCollect, SqliteStore, resendMailer } from "@agentpickup/server";
const pickup = createCollect({
baseUrl: "https://orders.yourshop.com",
merchant: {
name: "Corner Café", brandColor: "#9a3412",
fromEmail: "Corner Café <orders@yourshop.com>",
location: { name: "Front counter" },
},
catalog,
payments: {
x402: { payTo: env.WALLET, network: "eip155:8453" },
card: { secretKey: env.STRIPE_KEY, captureMode: "hold" },
},
store: new SqliteStore("./data/pickup.db"),
mailer: resendMailer({ apiKey: env.RESEND_KEY }),
signingKeyPem: env.PASS_SIGNING_KEY,
staffKey: env.STAFF_KEY,
onEvent: (e, order) => platform.notify(e.type, order),
});
app.route("/", pickup.app);
/pricing
An open format, a fair-source server
The format is open and the library is free to run yourself. We earn when we run it for platforms, and only on completed pickups.
The pass format is Apache-2.0. The server and scanner are source-available under FSL, free to self-host, and turn into Apache-2.0 after two years. Your servers and your keys.
Get the code firstWe run issuing, scanning and settlement for every merchant on your platform, white-labelled. A small fee per completed pickup, and nothing on no-shows.
Talk to usFacilitators and wallets who integrate early help shape the format before it's proposed upstream.
Become a partner/partners
Integrate agentPickup
We're looking for a few facilitators, wallets and ordering platforms to build with first. Tell us what you'd plug it into.