An AI agent tested our payment system with $3 of test funds, spent one cent and found nine flaws. We patched them the same night.
Late on a Friday night this month, an application arrived in my company’s inbox. The applicant described itself in its first line as an AI agent. It said it worked for a small team that runs its own paid service for other agents, and it offered to test mine.
My company, Kilawatt Cloud, runs an endpoint where software can rent a GPU and pay per job in USDC, a dollar-pegged digital currency, with no account to open and no person in the loop. The protocol is x402, named after the old HTTP “402 Payment Required” status code. The server replies with a price. The agent signs a payment and sends it back, and the work starts.
What we had tested ourselves
Before any outsider touched it, we ran our own public test. We attempted 329 GPU jobs from our own wallet, and 200 reached a ready state. The other 129 did not. Jobs that cannot be placed are not charged, and jobs that never become ready are refunded to the account balance.
That number needs a caveat. It was our own traffic, so it shows the system works. It does not show customer demand. After weeks of testing your own product, you also stop seeing it clearly. I wanted an external user to try to break it.
What the external user found
I sent the applicant $3 in test funding and asked for one thing: tell me everything that breaks. Inside seventy minutes it had sent two reports covering nine findings, plus one real paid job. That job cost one cent and settled on the blockchain in about ten seconds. Two of the findings could have cost buyers money.
Garbled requests became the most expensive job. If a request arrived as data the system could not read, it did not refuse it. It treated it as a default job: a top-end GPU for ten minutes, quoted at about 38 cents. The job the agent probably meant cost one cent. An agent that pays automatically would have signed it.
Repeated payments were not recognized. If an agent lost the server’s reply and sent the same signed payment again, the system returned a generic error, not “already paid.” No money moved twice, but a simple client could not tell “you paid” from “something broke,” and might pay for a duplicate job.
Errors a person could read, but a machine could not. An underfunded wallet got an unreadable contract error. A changed price came back as a sentence with no code. A mistyped GPU name returned a message that meant “no capacity,” which tells a client to retry as if there were an outage.
The rest were smaller: the endpoint answered a wrong-method call with our website’s home page, receipts lacked start and end times, and an internal payment ID appeared in buyer receipts.
The reports were unusually easy to act on. Each finding came with the exact command to reproduce it, what the tester expected, what actually happened, and who would be affected. The tester said plainly that its work was AI-assisted. It also listed what it could not test and why. It held back its first paid job because its own wallet required a human owner to approve each spending authorization, and that approval was not available at the time. It ran the paid job shortly afterward.
That detail is worth borrowing. A spending approval step between an agent and its wallet is the kind of control every team that lets software pay should consider. It is slower, but it puts a person between a bug and a payment.
The report was not all bad news. Payments to the wrong recipient or the wrong network were refused. An underpaid authorization was rejected before any money moved. The input rules were precise, and the rate limiter worked. The money-moving core held. The trouble was at the edges, where a human operator would have shrugged and a machine does not.
How fast we fixed it
We fixed the problems the same night, with eight changes live. Unreadable requests are now rejected with a clear error. Repeated payments return a clear “already used” response. Price changes carry a machine-readable code. Wallet and signature problems return stable codes with a plain hint. Mistyped GPU names return the list of valid ones. Wrong-method calls return a proper error, and there is now a discovery file for directories. Receipts include start, end and runtime. The internal payment ID is gone.
What to check in your own system
If you run, or buy from, anything that lets software pay automatically, four questions are worth an afternoon.
- What happens when a request is malformed? It should be refused, not repaired into something more expensive.
- What happens when the same payment arrives twice? The answer should match the first time.
- Can a program tell “add funds” from “fix your signature” from “try again later”?
- What internal details appear in receipts that every customer can read?
The test cost us three dollars in funding, and the tester spent one cent of it. The next buyers of compute will be machines. It makes sense to let machines tell us how they get confused.
Damian Dixon is the founder of Kilawatt Cloud, which lets software agents rent GPU capacity across multiple data centers through one API and pay per job in USDC. He is building the payment and routing layer for machine-to-machine compute.
