Vibe Engines
YouTube

Vibe Engines is free, interactive AI engineering & system design — runs in your browser. Pick a learning path

AI System Design

Design an Agent Payment Gateway

Step 1 / 9

Learn AI system design by building the platform that lets autonomous agents pay for things mid-task without draining an account.

The whole design, in writing

Every step of the build above, written out: the problem each piece solves, the option that was taken and the ones that were not, the numbers, and how it fails in production.

The big idea

A gateway, not a corporate card

An autonomous agent will eventually hit a paywall mid-task — an API that costs a cent a call, a dataset behind a charge. Stopping to ask a human defeats the point of autonomy; handing the agent a shared API key or card defeats your bank balance. How do you let an agent pay without letting it — or whatever hijacks it — spend without limit?

Agentwants to pay mid-task
New in this step: Agent.

We'll build the agent-rails layer: a gateway every payment flows through, a signed mandate that scopes what the agent may spend, spend caps enforced before any money moves, machine-native x402 settlement, and an immutable audit trail. This is not the human card-rails system — see Payment System and Digital Wallet for those; this is the layer built for an autonomous spender.

What the new pieces do

Agentclient
An autonomous agent that hits a paywall mid-task — an API that charges per call, a dataset behind a fee, a compute job to rent. It needs to pay without a human checkout, and without holding unlimited spending power.

Step 1 · The baseline

The agent pays the merchant directly

The naive starting point: give the agent an API key or card credential and let it call the merchant's pay endpoint itself. It works in the demo. What's the actual risk the moment this agent is autonomous and reads untrusted content?

AgentMerchant / API
New in this step: Merchant / API. · swipe to pan the diagram

An autonomous agent holds a payment credential and pays merchants directly. What's the core risk?

  1. "Only when it legitimately needs to" assumes the agent always behaves. An agent reads untrusted web content and tool output; one prompt injection, or one looping bug, turns a credential with no spending limit into an unbounded liability.

  2. Exactly the problem: authority is ambient and unbounded. A runaway loop or a hijacked agent can drain the account, and the only blunt fix is killing a shared credential that other legitimate agents also depend on. There's no per-agent scope, no cap, and no record of why any payment happened.

  3. Latency is a secondary concern. The immediate danger is that an autonomous process holds unlimited, unscoped spending authority — a correctness and security problem, not a performance one.

A direct credential gives the agent unlimited, unscoped spending power. A looping bug or a prompt-injected instruction can spend arbitrarily, and there's no per-agent limit, no record of why a payment happened, and no way to stop one agent without revoking a credential others share.

Why this piece earns its place

Worth naming when this baseline is genuinely fine, because sometimes it is: one internal agent, one merchant, a prepaid card with a hard balance the issuer enforces. A ceiling exists there too — it just lives at the card issuer, resets on the issuer's calendar rather than your task's, and moves only when a human calls the bank. The invoice is then your only record, and it is the wrong shape. Spend arrives aggregated by credential, so a charge cannot be tied back to a run, a tenant or a job: you can't pass it through to the customer who caused it, can't dispute the single line that was wrong, and can't say what the money bought. The operational sting is how you discover the ceiling at all. The issuer announces it with a decline, and a decline reaches the agent as an ordinary HTTP error — which an agent written to retry on errors will cheerfully treat as something to try again. That same credential is usually sitting in a test harness as well, spending real money on runs nobody meant to pay for.

What the new pieces do

Merchant / APIcontrol
The external service the agent is paying — an API, a data provider, a compute host. Speaks the x402 flow: responds with a price, accepts proof of payment, then delivers the resource.

Step 2 · The front door

Route every payment through a gateway

First move: the agent never touches a raw credential. Every payment request goes to a Payment Gateway API instead of the merchant. Why is a mediating front door the prerequisite for everything else?

Agentpays via the gatewayPayment Gateway APIverify, cap, settle
New in this step: Payment Gateway API.

Why route all agent payments through a gateway instead of letting the agent pay merchants directly?

  1. Caching isn't the point. The gateway exists to be a control point — a single place where every payment can be verified, capped, recorded, and refused before money moves.

  2. The gateway is the enforcement point. By making every payment flow through one mediated API, you get one place to check "is this allowed?" before anything happens — and the agent holds no spendable credential of its own, so there's nothing to steal or misuse directly.

  3. Convenience isn't the driver — and in fact the gateway deliberately restricts which merchants are in scope. The reason for the front door is control: a single point to enforce policy and record decisions.

All payments flow through the gateway, and the agent holds no spendable credential of its own. This single mediated choke point is what makes every downstream control — mandate checks, spend caps, safe settlement, audit — possible; without it, there's nowhere to enforce policy before money moves.

Why this piece earns its place

The front door earns its keep the moment you notice how often an agent retries. A planner that times out on a tool call re-issues it, and a re-issued payment is not a re-issued read — it moves money twice. So a payment request carries an idempotency key, and that key has to be minted by the caller as part of the payment intent rather than generated at the gateway, because a gateway-minted key is fresh on every retry and therefore never matches the attempt it was meant to deduplicate. That is the general rule for this API. Anything only the caller can know — which intent this is, which mandate it is acting under, what the spend is for — belongs in the request. Anything policy decides — which merchants are reachable, what the ceilings are, how long a held payment waits before it is abandoned — belongs in configuration the agent cannot set. The other half of that contract is the response. A policy refusal and a transport failure must not look alike to the caller: a denial is final, and a planner that retries it burns its entire loop arguing with a decision that will never change, while a timeout is the one case where retrying under the same key is exactly right. Give them different shapes and the agent can tell them apart.

What the new pieces do

Payment Gateway APIgateway
The single front door for every agent payment — mandate verification, spend-cap enforcement, settlement, and audit all flow through here. The agent never touches a raw credential.

Step 3 · Delegated authority

Verify a signed mandate

The gateway needs to know what THIS agent is actually allowed to spend. The answer is a mandate: a signed authorization scoping the agent's spending — a per-transaction ceiling, a total budget, allowed merchants, an expiry. What must the gateway do with it, and why can't it just trust the agent's request?

Payment Gateway APIverify, cap, settleMandate Verifiersignature · scope · expiry
New in this step: Mandate Verifier.

The agent presents a mandate describing what it may spend. How should the gateway treat it?

  1. An agent that's been prompt-injected will happily send a mandate claiming it can spend anything. A mandate is only meaningful if the gateway can prove it wasn't fabricated by the agent presenting it.

  2. A single global limit can't express per-agent scope — this agent may buy data, that one may rent compute, each with different caps and merchants. The mandate is what carries that per-agent authority.

  3. Right: the mandate is like an OAuth token for money. The gateway checks it was validly signed by the issuer, hasn't expired, and actually covers this merchant — so a hijacked agent can't just assert broad spending power, because it can't forge a valid signature.

The Mandate Verifier checks the presented mandate's signature, scope, and expiry against the issuer's key before the gateway honors it. Authority is delegated by a signed artifact — an OAuth-scopes-for-money token — so a prompt-injected agent can't simply claim broad spending power it was never granted.

Why this piece earns its place

A signature proves a mandate was issued. It cannot prove anyone still wants it honored, and that gap is the whole operational story. Expiry is the only revocation the artifact carries by itself, which makes picking it a scheduling decision as much as a security one. Set it short and the issuer becomes a runtime dependency: agents reissue mid-task, the signing service lands on the payment path, and its availability becomes yours. Short expiries also strand work — a mandate that lapses partway through a long task leaves spend already made with nothing delivered for it, and the agent cannot finish or refund its way out. Anything faster than expiry means a revocation check, a lookup on every payment, and because the gateway refuses what it cannot check, an outage in that lookup is an outage in paying at all. Then there is key handling, which is the part that gets skipped in a design round. The gateway verifies against the issuer's key, so the mandate has to name which key signed it — a kid — and rotation means publishing the new key, honoring both through an overlap, then retiring the old one. Rotate without that overlap and every unexpired mandate fails verification at once — an incident that looks like an attack and is really a deploy.

What the new pieces do

Mandate Verifierservice
Checks the signed mandate the agent presents — is the signature valid, is the merchant in scope, is it unexpired? Authority is a signed artifact, not a claim in the request.

Step 4 · The hard limit

Enforce spend caps before settlement

A valid mandate says the agent may spend up to a cap. Now the gateway has to actually enforce it on each payment. When should the cap be checked — and against what?

Payment Gateway APIverify, cap, settleSpend-Cap Enforcerper-txn + cumulative
New in this step: Spend-Cap Enforcer.

The mandate allows up to $50 total, $20 per transaction. When and how should the cap be enforced?

  1. Correct: the check must run before money moves, on every payment, against both the single-payment limit and the accumulated total. A looping agent that tries ten $20 payments is refused the moment cumulative spend would cross $50 — the cap bounds the damage no matter how many times it loops.

  2. A cap checked only after the fact doesn't bound anything — the money has already left. By the time you total it up, a runaway agent has already overspent. Enforcement has to run alongside consumption, before each payment.

  3. Then an agent making a hundred small in-limit payments blows far past its total budget while never tripping the per-transaction check. You need BOTH ceilings — the single-payment limit and the running total.

Before every settlement, the Spend-Cap Enforcer checks the amount against the per-transaction ceiling and the running cumulative spend against the mandate total, refusing anything that would breach either. Enforcement runs in the payment layer, before money moves — not as an after-the-fact report — so a runaway loop is bounded to the cap you chose.

Why this piece earns its place

Check-then-settle is two operations over shared mutable state, so the interesting failure here is a race rather than a breach. Two payments under the same mandate can both read a cumulative total that is under the cap and both proceed, and the mandate ends up overspent by exactly the amount you were enforcing. The fix is to treat the budget as something you reserve rather than something you read: hold the amount atomically before settlement, release the hold if the payment fails, convert it to a spend when proof comes back. That also covers the uglier case where settlement succeeds and the counter write does not, which a record-afterwards design turns into money that left without ever being counted. Be careful what the counter is keyed on, too. The obvious key is the mandate id, because the total belongs to the mandate — but then a reissue starts the count from zero, and a looping agent only has to obtain a fresh mandate to have its budget back. Carry a budget identity for the agent across reissues and count against that as well. Units, last: a $20 ceiling has to mean the amount that actually leaves, network fees included, and when the mandate is denominated in dollars while settlement moves a stablecoin, that conversion belongs inside the cap check. A cap enforced on the pre-fee number is not the cap you promised.

What the new pieces do

Spend-Cap Enforcerservice
Before any settlement, checks the amount against the per-transaction ceiling and the running cumulative spend against the mandate total. Refuses anything that would breach either.

Step 5 · Settlement

Pay via x402 and return proof

The mandate is valid and the payment is within cap. Now actually pay the merchant. The merchant speaks x402 — it responds to a request with HTTP 402 and payment terms. How does settlement work, and why is this a clean fit for an agent?

Merchant / APIPayment Gateway APISpend-Cap Enforcerx402 Settlement
New in this step: x402 Settlement. · swipe to pan the diagram

The merchant returns HTTP 402 with a price. How does x402 settlement complete the payment?

  1. That reintroduces a human in the loop and defeats the point of an autonomous agent paying mid-task. x402 is designed to settle inside the request/response cycle, no human checkout.

  2. Right: x402 revives the dormant HTTP 402 status as a machine-native checkout. Server says "402, here's the price," the gateway pays and retries with proof, gets the resource. Payment becomes just another part of the protocol — which is exactly what an autonomous agent needs.

  3. Handing the agent a credential at settlement time recreates the original ambient-authority problem. The gateway settles on the agent's behalf; the agent never holds a spendable credential.

On the merchant's 402 + price, the x402 Settlement service performs the payment, retries with proof, receives the resource, and returns it to the agent — all inside the request/response cycle, no human checkout. The agent never holds a credential; the gateway settles on its behalf, only after mandate and cap checks have passed.

Why this piece earns its place

Two things about this flow only show up once you have run it. First, the price belongs to the merchant and arrives in the 402, so the number the enforcer judges does not exist until the merchant has been asked. That does not move the cap check after settlement — the 402 exchange is a quote and moves no money, and the decision still completes before any transfer — but it does mean the merchant is contacted before the gateway knows whether it will pay at all. So the opening request has to be safe to repeat and free to abandon. The gateway will routinely fetch a price, refuse it on the cap, and never come back; if a merchant treats that first call as a reservation, your refusals quietly consume its stock. Second, there is a window between paying and holding the resource. The transfer lands, the retry carrying proof goes out, and the merchant times out. Money has moved, nothing has been delivered, and a gateway that simply starts over pays twice. So the proof is persisted against the payment intent the moment it exists, and a retry re-presents the stored proof instead of settling again — the proof is the receipt. Finality is not yours to set either: the merchant decides how much confirmation counts as proof, so settlement latency is a merchant policy you inherit.

What the new pieces do

x402 Settlementservice
Executes the HTTP 402 flow: on the merchant's 402 + price, performs the payment (typically a small stablecoin transfer) and retries with proof, then hands the resource back to the agent.

Step 6 · Accountability

Log every decision, immutably

Money moved. Whether a payment was allowed or refused, the platform needs a record of why. What has to be captured, and why is an append-only audit trail non-negotiable for a spending system?

Payment Gateway APISpend-Cap EnforcerAudit Trail
New in this step: Audit Trail. · swipe to pan the diagram

What should the audit trail record, and why does it matter for a payment gateway?

  1. Refusals are often the most important events: a spike in denied payments is how you detect a runaway or hijacked agent. An audit trail that drops refusals is blind to exactly the incidents it exists to catch.

  2. A daily total can't answer "why did this agent pay this merchant?" or reconstruct an incident. You need the per-decision detail — mandate, cap state, amount, merchant, allow/deny — not just an aggregate.

  3. Right: a spending system you can't reconstruct after the fact is one you can't trust. An append-only log of every decision (including refusals) is what lets you audit spend, prove compliance, and investigate a compromised agent — and immutability means a hijacked agent can't erase its own tracks.

The Audit Trail appends every payment decision immutably — mandate checked, cap state, amount, merchant, allow or deny — including refusals. A spending system you can't reconstruct is one you can't trust; the immutable log is what makes spend auditable, incidents investigable, and a compromised agent's tracks impossible to erase.

Why this piece earns its place

The trail earns its keep after the incident rather than during it, and that changes what you build it for. Every check upstream asks a single-payment question: is this one inside this mandate? Nothing in that path can see a crowd of unrelated agents converging on a merchant none of them had ever paid, or one mandate consuming its whole budget in a single burst while every individual payment sits comfortably under its ceiling. Those are shapes in the record, which makes the trail where detection actually lives — so it has to be queryable, not merely durable, and written where you can join across agents instead of one file per service. Immutability then costs you something, and it is better to pay that deliberately. Nothing can be edited, so a mistake is corrected by appending a compensating entry, and anything you write you have agreed to keep for the life of the log — a good reason to record identifiers and decisions rather than payloads someone may later be entitled to have erased. And append-only is a property you buy, not a word you write. On ordinary storage it is an access-control claim that anyone who can deploy the gateway can undo, so revoke UPDATE and DELETE at the database role, or chain each entry to a hash of its predecessor so a removal is at least detectable.

What the new pieces do

Audit Traildata
An append-only record of every payment decision — mandate checked, cap state, amount, merchant, allow/deny — because a spending system you can't reconstruct after the fact is a spending system you can't trust.

The payoff

A spender you can actually trust

Put it together: an agent can pay for what its task needs, autonomously — and a runaway loop, a bug, or a full hijack is bounded to a number you chose in advance, with a complete record of every decision.

AgentMerchant / APIPayment Gateway APIMandate VerifierSpend-Cap Enforcerx402 SettlementAudit Trail
The finished design, end to end. · swipe to pan the diagram

That's the agent-payment gateway. Delegated, bounded, revocable authority, verified and capped before money moves, settled machine-natively, and logged immutably — the same least-privilege discipline that governs an agent's tools, applied to its wallet.

Everything you assembled, in order

  • The agent holds no spendable credential — every payment flows through one mediated gateway.
  • A signed mandate scopes spending (per-txn, total, merchants, expiry); the gateway verifies signature/scope/expiry, never trusting the agent's claim.
  • Spend caps are enforced BEFORE every settlement, against both the per-transaction and cumulative limits — a runaway loop is bounded to the cap.
  • Settlement uses the x402 (HTTP 402) machine-native flow: pay, retry with proof, deliver — no human checkout, no credential in the agent's hands.
  • Every decision, allow or deny, is appended to an immutable audit trail so incidents can be reconstructed and a compromised agent can't erase its tracks.

Where an interviewer pokes next

Getting the boxes right is the easy half. These are the questions that separate a candidate who drew the diagram from one who has run the thing. Answer each one out loud before you open it.

  1. How is this different from the Payment System / Digital Wallet designs?

    Those are the HUMAN rails — a person authorizes a charge, disputes a transaction, and the system optimizes for consumer protection, double-entry ledgers, and settlement across banks/card networks. This design is the AGENT rails: the payer is autonomous software with no human in the loop per transaction, so the central problems become delegated-but-bounded authority (the signed mandate), pre-settlement cap enforcement (bounding a runaway process), and machine-native settlement (x402). It composes ON TOP of human rails — the gateway itself ultimately settles through real payment infrastructure — but the control model is fundamentally about safely delegating spending power to a non-human agent.

  2. Why enforce the cap in the gateway instead of just instructing the agent to respect its budget in the prompt?

    A prompt instruction shifts the PROBABILITY the agent stays in budget, but provides no guarantee — an unusual input, a prompt injection in retrieved content, or simple model variance can produce an over-budget payment attempt. Gateway enforcement doesn't depend on the model behaving: even if the agent DOES attempt an over-cap payment, the platform refuses it before settlement. Prompt-level budget guidance is still useful as a first line that reduces how often a violation is even attempted, but it can't be the actual security boundary for something as consequential as spending money.

  3. What stops the mandate itself from being stolen and replayed by an attacker?

    Several standard controls compose here: mandates are short-lived (a tight expiry limits the replay window), scoped narrowly (a stolen mandate can still only spend its capped amount at its listed merchants, not anything), and typically bound to a specific agent identity and/or nonce so the same mandate can't be reused arbitrarily. The immutable audit trail also makes replay detectable after the fact. The design assumption is that a mandate WILL occasionally leak, so its blast radius is deliberately bounded by scope and expiry — the same defense-in-depth logic as short-lived, narrowly-scoped access tokens.

  4. How would you extend this to require human approval for larger payments?

    Add an approval tier keyed on amount: the Spend-Cap Enforcer already sees every payment before settlement, so it's the natural place to branch — payments under a threshold settle autonomously, payments over it are held and routed to a human-approval queue (with the full context: agent, merchant, amount, mandate). This is the same human-in-the-loop-for-irreversible-actions pattern used for agent tool use generally, applied to spending: cheap, routine payments stay fully autonomous for speed, while a small number of high-value ones get a human checkpoint without reintroducing a human into every transaction.

  5. Could the gateway itself become a bottleneck or single point of failure for all agent payments?

    It's a control point, so it does need to be highly available — but the operations it performs (verify a signature, compare counters against caps, append a log entry) are cheap and horizontally scalable, and the cap/mandate state is per-agent, so it shards naturally. The real availability concern is that the gateway sits in the critical path of every payment; you mitigate that with the usual stateless-service + replicated-state patterns, and you make failure SAFE rather than merely rare — if the gateway can't verify a mandate or check a cap, it must FAIL CLOSED (refuse the payment) rather than fail open, because an unenforced payment is exactly the risk the whole system exists to prevent.

Check yourself — the answers, and why

Seven steps in, these are the calls you should be able to make cold. Pick one, then read why.

  1. An agent payment gateway exists primarily to…

    The whole point is safe delegation of spending power to a non-human agent — bounded, verified, and revocable — not speed.

  2. A signed mandate is verified rather than trusted because…

    Authority is a signed artifact (like an OAuth token for money), not whatever the agent asserts — that's what survives a hijacked agent.

  3. Spend caps must be checked…

    A cap checked after the fact doesn't bound anything — the money already left. Enforcement runs before each payment.

  4. x402 settlement is a good fit for agents because…

    x402 makes payment a normal step of the protocol — exactly what an autonomous agent needs, with the gateway settling on its behalf.

  5. If the gateway can't verify a mandate or check a cap, it should…

    An unenforced payment is the exact risk the system exists to prevent — failure must be safe (refuse), not convenient (allow).

How you’d open this design in an interview

Before any boxes: agree what it must do, pin the qualities that shape everything, then build — naming each trade-off as you make it. The walkthrough above is that exact order.

What it must do

Agree on these before drawing a single box.

  • Pay mid-task: let an autonomous agent settle a paywall (an API fee, a dataset charge) without a human checkout.
  • Scope authority: a signed mandate caps per-transaction and total spend, allowed merchants, and an expiry.
  • Cap spend: refuse any payment that would breach the per-transaction ceiling or the cumulative total.
  • Settle machine-natively: complete the x402 (HTTP 402) flow — pay, retry with proof, deliver.
  • Audit: append every payment decision, allow or deny, to an immutable record.

The qualities that shape everything

Each one names the mechanism that buys it.

The agent holds nothing worth stealing
Route every payment through one mediated gateway; the agent holds no spendable credential of its own.
A hijacked agent can’t assert broad spending power
The Mandate Verifier checks the mandate’s signature, scope and expiry against the issuer’s key before honoring it — authority is a signed artifact, not a claim.
A runaway loop is bounded to a number you chose
The Spend-Cap Enforcer checks each payment against the per-transaction ceiling and the cumulative total before settlement, refusing anything that would breach either.
Autonomous payment with no human in the loop
x402 settlement pays, retries with proof, and delivers the resource inside the HTTP request/response cycle — no human checkout.
Every incident is reconstructable
An append-only Audit Trail records every decision including refusals, so a compromised agent can’t erase its own tracks.

The trade-offs you say out loud

Senior signal isn’t the boxes — it’s naming what you gave up and why it was the right price.

A mediating gateway over the agent paying merchants directly

A direct credential gives unlimited, unscoped spending power a bug or injection can drain. The gateway is the one place to verify, cap, and log before money moves.

A signed mandate, verified over trusting the agent’s claim

A prompt-injected agent will happily claim it can spend anything. Authority must come from a signature it can’t forge, checked for scope and expiry.

Cap checks before every settlement over a post-run overspend report

A cap checked after the fact doesn’t bound anything — the money already left. Enforce both the per-transaction and cumulative limits before each payment.

x402 machine-native settlement over a human purchase-order approval

Emailing a PO and waiting for a human defeats autonomous mid-task payment. x402 settles inside the request/response cycle, on the agent’s behalf.

Fail closed on the gateway over failing open when it can’t verify

An unenforced payment is the exact risk the system exists to prevent. If a mandate or cap can’t be checked, refuse rather than allow.

The answer, out loud

What a strong answer to “Design an Agent Payment Gateway” sounds like, first question to last trade-off. It is about 7 minutes of talking; the whiteboard and the interviewer fill the rest of the 45. Read it aloud once, then close the page and give it yourself.

  1. 0–3 min

    Agent rails, not human rails

    First I want to say what this is and what it isn't, because the name misleads. This isn't the human payment rails — a person authorizing a charge, disputing it later, settlement across card networks. The payer here is autonomous software, and there's no human in the loop per transaction. So the problem I'd actually solve is delegation: how does an agent pay for what its task needs — an API that charges a cent a call, a dataset behind a fee — without me handing it something that can spend without limit? That reframing is most of the design. It turns into three questions: who says it may spend, how much, and what happened.

  2. 3–8 min

    The version I would not ship

    I'd start from the obvious version so the risk is on the table. Give the agent an API key or a card credential and let it call the merchant's pay endpoint itself. It works in the demo. The trouble is what that agent does all day — it reads web pages and tool output nobody on my team wrote, and then decides what to do next. So that credential is only as bounded as the least trustworthy thing it read this morning. And it doesn't even take an attacker: a planner stuck in a loop will just keep paying. The authority here is ambient — the agent can spend because it happens to be holding the key — and nothing narrows that to this agent, this merchant, or this task.

    Built in step 1: The agent pays the merchant directly
  3. 8–13 min

    One front door

    So the first real move is a Payment Gateway API that every payment goes through, and an agent that holds no spendable credential at all. That isn't a performance decision — I'm not caching merchant responses — it's about having a choke point: one mediated place to ask "is this allowed?" before anything moves, and to refuse if it isn't. Everything after this hangs off it. Mandate checks, spend caps, settlement, the audit record: if the agent can pay merchants directly, there is simply nowhere to put any of them.

    Built in step 2: Route every payment through a gateway
  4. 13–20 min

    Authority is a signed artifact

    Next the gateway has to know what this agent may spend, and I'd carry that in a mandate — a signed authorization with a per-transaction ceiling, a total, the merchants in scope, and an expiry. The important part is that the gateway verifies it rather than trusting it: signature against the issuer's key, not expired, and this merchant actually covered. The reason is blunt. A hijacked agent will happily send a request claiming it can spend $10,000 anywhere; the one thing it cannot manufacture is a valid signature saying so. If the interviewer wants a comparison, I'd reach for an OAuth token — same idea, except the scopes are amounts and merchants rather than API permissions, and it's the treasury doing the signing.

    Built in step 3: Verify a signed mandate
  5. 20–27 min

    Two ceilings, before the money moves

    Then enforcement, and I'd be specific about when and against what. Before every settlement, and against both ceilings: the amount against the per-transaction limit, and the running cumulative spend against the mandate total. Both, because either one alone leaks. Per-transaction only, and a hundred small in-limit payments blow past the budget without ever tripping the check. After the run, and it's a report rather than a cap — the money has already left. With fifty total and twenty per transaction, an agent stuck in a loop gets refused on its third payment, mid-loop, rather than at the invoice.

    Built in step 4: Enforce spend caps before settlement
  6. 27–34 min

    Settle inside the request

    Settlement is where x402 earns its place. The merchant answers with HTTP 402 and a price. The gateway performs the payment — typically a small stablecoin transfer — retries the request carrying proof, gets a 200 and the resource, and hands that back to the agent. The whole exchange closes inside the request/response cycle. The alternative is emailing a purchase order and waiting for a human to approve it, which puts a person back in the loop and defeats mid-task autonomy entirely. And I'd stress that the agent still never touches a credential here: the gateway settles on its behalf, only once the mandate and cap checks have passed.

    Built in step 5: Pay via x402 and return proof
  7. 34–40 min

    Write down every decision

    The last piece is an audit trail, appended immutably, recording refusals as well as payments. The refusals are often the more useful half — a spike in denied payments is how you notice a runaway or a hijacked agent at all. Each entry carries the mandate that was checked, the cap state, the amount, the merchant, and the decision, because a daily spend total can't answer why this agent paid this merchant. And immutability matters specifically because the thing you're investigating may be a compromised agent, which would otherwise be in a position to tidy up after itself.

    Built in step 6: Log every decision, immutably
  8. 40–45 min

    The trade-off, and what I would do next

    To close on the trade-off: every control here sits in the critical path of every payment, and when the gateway can't verify a mandate or check a cap, it refuses. I'd say plainly what that costs — the gateway's uptime becomes the company's ability to spend at all, and an outage blocks payments that were perfectly legitimate. I take that deal because a refusal is something you can retry, and a payment nobody checked is already gone by the time anyone reads about it. With more time, the piece I'd want to work through is revocation. Right now a mandate stops mattering when it expires, so the expiry I pick is the fastest I can take authority back. Anything quicker means checking a revocation list on every payment — which buys that speed by adding one more thing that has to be up before anyone can pay.

What this teaches

Learn AI system design by building the platform that lets autonomous agents pay for things mid-task without draining an account. Not the human card rails (see Payment System and Digital Wallet for those) — this is the agent-rails layer: a gateway that verifies a signed spending mandate, enforces per-transaction and cumulative spend caps BEFORE any money moves, settles via the x402 (HTTP 402) machine-native checkout, and keeps an immutable audit trail — so a runaway or hijacked agent is stopped by the platform, not by someone noticing the bill.

Key takeaways

  • The agent holds no spendable credential — every payment flows through one mediated gateway.
  • A signed mandate scopes spending (per-txn, total, merchants, expiry); the gateway verifies signature/scope/expiry, never trusting the agent's claim.
  • Spend caps are enforced BEFORE every settlement, against both the per-transaction and cumulative limits — a runaway loop is bounded to the cap.
  • Settlement uses the x402 (HTTP 402) machine-native flow: pay, retry with proof, deliver — no human checkout, no credential in the agent's hands.
  • Every decision, allow or deny, is appended to an immutable audit trail so incidents can be reconstructed and a compromised agent can't erase its tracks.

Concepts covered

  • A gateway, not a corporate card
  • The agent pays the merchant directly
  • Route every payment through a gateway
  • Verify a signed mandate
  • Enforce spend caps before settlement
  • Pay via x402 and return proof
  • Log every decision, immutably
RUN IT YOURSELF

The idempotency key that is checked instead of claimed

An agent hits four paywalls worth $47.50, two responses go missing, and it retries — once after a timeout, once while the first request is still in flight. The same workload runs against three gateways that differ only in how they treat the key, and the file prints what each one charged. Change RETRIES at the top, hit Run, and watch two rows climb while the third refuses to move.

HOW TO READ THE CODE — 5 IDEAS
  1. The key is minted by the caller, from the payment intent, so every retry carries the same one — a gateway-minted key is fresh on each retry and deduplicates nothing (step 2).
  2. With no key at all, 6 requests become 6 charges: $79.50 spent for $47.50 of resources, and 159% of a $50 mandate consumed (step 4).
  3. The middle row is the dangerous one. check-then-write deduplicates every sequential retry — so it passes any test written without concurrency — and still pays twice for the double submit, because both attempts read a miss before either wrote.
  4. claim-then-settle takes the key in one store operation (INSERT … ON CONFLICT DO NOTHING); the loser waits and gets back the original pay_0003, not a second charge. That is the page's "the proof is the receipt" (step 5).
  5. All three delivered 4 of 4 resources — the agent's transcript is identical. Only the ledger knows the difference, which is why the audit trail is where this gets caught (step 6).
CPython · WebAssembly
built so a runaway agent is capped at the mandate, not at the credit limit — make the calls, forge a mandate, blow the budget, and watch the gateway refuse.
Finished this one? 0 / 65 AI System Designs done
NextDesign a Conversational AI Closest AI system design to this one

Explore the topic

See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.

More AI System Designs