{"slug": "i-sent-an-ai-agent-to-buy-from-real-stores-here-s-what-actually-breaks", "title": "I sent an AI agent to buy from real stores. Here's what actually breaks.", "summary": "A developer built AgentiQA, an open-source tool that sends AI agents through real e-commerce checkout funnels to test agent-readiness. Testing revealed that many stores fail at critical steps like login walls, JavaScript-heavy interactions, and non-standard form fields, even when their markup is technically correct. The tool uses a text-only DOM snapshot and a payment-field safety guard to prevent agents from entering sensitive data.", "body_md": "AI agents are starting to shop for people. ChatGPT has an operator that clicks around the web. Perplexity ships a \"buy\" button. Anthropic and others are wiring agents into real checkout flows. If you run an online store, some fraction of your future customers won't be humans clicking — they'll be agents acting on a human's behalf.\n\nWhich raised a question I couldn't answer for my own projects: **can an AI agent actually complete a purchase on this store?**\n\nEvery \"agent-readiness\" tool I found just lints your markup — does your robots.txt allow agent crawlers, do you have structured data, that kind of thing. Useful, but it answers a *different* question. Clean markup doesn't mean an agent can navigate your funnel any more than a valid HTML resume means you can do the job. The only way to know is to send an agent through and watch where it dies.\n\nSo I built [AgentiQA](https://github.com/OmkarPalika/agentiqa). It's open source (MIT). Here's how it works and — more interestingly — what I found when I pointed it at real stores.\n\n**Static checks** (stdlib only, no API key): does robots.txt allow agent user-agents (`Claude-User`\n\n, `ChatGPT-User`\n\n, `OAI-SearchBot`\n\n, `PerplexityBot`\n\n), is there JSON-LD `Product`\n\n/`Offer`\n\ndata, OpenGraph tags, a reachable sitemap. This is the cheap \"is the door unlocked\" pass.\n\n**The live shopper agent**: Claude driving a real headless Chromium browser through the actual funnel — find a product, add to cart, reach checkout — recording milestones as it goes. This is the part that answers the real question.\n\nNo screenshots, no vision model. The agent reads a **text snapshot** of the DOM: the page URL and title, every interactive element indexed by a number, and the visible text. Roughly:\n\n```\nURL: https://store.example/\nTITLE: All Products\n\nINTERACTIVE ELEMENTS:\n[0] <a href=/product/blue-top> Blue Top\n[1] <button> Add to cart\n[2] <input type=text name=search> Search\n...\n\nVISIBLE TEXT (truncated):\nBlue Top  Rs. 500  In Stock ...\n```\n\nThe agent gets a tiny toolset — `read_page`\n\n, `click(element_id)`\n\n, `type_text(element_id, text)`\n\n, `goto(url)`\n\n, `record_milestone(stage)`\n\n— and loops: read the page, decide, act, read again. Text-only is cheaper than vision, deterministic, and it's roughly what an agent shopper actually operates on anyway.\n\nAny tool that drives a browser through checkout has to *never* touch payment data. You cannot rely on a system prompt for that — prompts are suggestions, and a model under pressure to \"complete the task\" can rationalize its way past one.\n\nSo the refusal lives in the executor, not the instructions. Before any keystroke, the field is checked:\n\n```\nPAYMENT_FIELD_RE = re.compile(r\"card|cvv|cvc|cc-|expir|security.?code|pan\\b\", re.IGNORECASE)\n\ndef is_payment_field(el) -> bool:\n    for attr in (\"name\", \"id\", \"autocomplete\", \"placeholder\", \"aria-label\"):\n        v = el.get_attribute(attr)\n        if v and PAYMENT_FIELD_RE.search(v):\n            return True\n    return False\n```\n\nIf the agent tries to type into anything that looks like a payment field, the tool returns a hard `REFUSED`\n\nand tells it to stop and summarize. It also never creates accounts and never submits a final order — it stops at the checkout page. The model's judgment is a second layer, not the only one.\n\nThe obvious way to drive this is the Anthropic API, which costs ~$1–2 per full audit. But for a solo dev validating an idea, I didn't want a per-run bill. So there's a second driver that speaks to the `claude`\n\nCLI (the Claude Code subscription) over a small JSON protocol — one action per turn, resumed across steps:\n\n```\npython -m agentiqa https://your-store.com --driver cli   # subscription, no API key\npython -m agentiqa https://your-store.com --driver api   # API key, faster\n# default: api if ANTHROPIC_API_KEY is set, else cli\n```\n\nSame browser loop, same safety guards — just a different way to get the model's next move. It means you can run the whole thing on a subscription you already pay for.\n\nHere's the honest part, and it wasn't what I expected going in.\n\nI ran the benchmark against a set of real, public demo stores — the kind built to be tested against, with genuine cart and checkout flows. My assumption was that agents would faceplant everywhere. They didn't.\n\n**On clean, functional stores, the agent checked out fine.** Product → cart → checkout, no drama. One \"failure\" in my batch turned out to be a dead server throwing a Cloudflare SSL error — not an agent problem at all.\n\nThe failures that *are* real are dumber and quieter than \"the agent is dumb\":\n\nNone of these show up in a markup linter. And here's the kicker I found: a store scored **1/4 on static readiness** and the agent still checked out perfectly. Static score did **not** predict agent success. The behavioral test and the markup test measure different things — you need the behavioral one.\n\n```\npip install -r requirements.txt\nplaywright install chromium\n\n# free static check, no API key:\npython -m agentiqa https://your-store.com --no-agent\n\n# full run with the live agent:\npython -m agentiqa https://your-store.com\n```\n\nYou get an HTML report: a verdict banner (did the agent complete checkout?), a prioritized fix list, the funnel, and the full step-by-step transcript of what the agent did. There's also a batch mode that runs a list of stores and emits an aggregate leaderboard.\n\nOnly run it against stores you own or have permission to test.\n\nAgentic commerce is early. Right now the interesting finding is that the gap between \"works for humans\" and \"works for agents\" is made of small, invisible things — and nobody's funnel-testing for them yet. The tool is open source; I'd genuinely like to know what breaks on *your* store, because my sample is small and demo stores are easier than messy production ones.\n\nRepo, demo GIF, and the full report format: [https://github.com/OmkarPalika/agentiqa](https://github.com/OmkarPalika/agentiqa)\n\nIf you run an e-commerce store and want to know whether an AI agent can buy from you — or you just want to see an agent narrate its way through a checkout and give up at a broken button — point it at your site and tell me what you find.", "url": "https://wpnews.pro/news/i-sent-an-ai-agent-to-buy-from-real-stores-here-s-what-actually-breaks", "canonical_source": "https://dev.to/omkarpalika/i-sent-an-ai-agent-to-buy-from-real-stores-heres-what-actually-breaks-4g92", "published_at": "2026-07-17 17:20:28+00:00", "updated_at": "2026-07-17 17:28:55.407871+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-products"], "entities": ["AgentiQA", "Claude", "ChatGPT", "Perplexity", "Anthropic", "OmkarPalika"], "alternates": {"html": "https://wpnews.pro/news/i-sent-an-ai-agent-to-buy-from-real-stores-here-s-what-actually-breaks", "markdown": "https://wpnews.pro/news/i-sent-an-ai-agent-to-buy-from-real-stores-here-s-what-actually-breaks.md", "text": "https://wpnews.pro/news/i-sent-an-ai-agent-to-buy-from-real-stores-here-s-what-actually-breaks.txt", "jsonld": "https://wpnews.pro/news/i-sent-an-ai-agent-to-buy-from-real-stores-here-s-what-actually-breaks.jsonld"}}