{"slug": "show-hn-my-ai-spent-15-on-a-test-order-so-i-built-a-payment-guardrail", "title": "Show HN: My AI spent $15 on a test order, so I built a payment guardrail", "summary": "Developer built SpendShield, an open-source payment safety layer for Python and MCP, after his AI automation system charged 4 orders of ¥99 ($15 total) on a test order that was meant to be a dry run. SpendShield provides spend-capped digital identities, four deterministic gates (dry_run, budget, max_amount, approval), and an encrypted secret vault to prevent AI agents from spending money recklessly. The tool integrates with x402, the open payment protocol for AI agents, and is available via pip or Docker.", "body_md": "Before your AI spends real money, it passes through SpendShield.\n\nAn open-source payment safety layer for Python and MCP. Give your AI agent a **spend-capped digital identity (KYA)**, run every payment through four deterministic gates, defend against prompt injection, and keep secrets in an encrypted vault.\n\nOn August 9, 2026, my automation system ran a test order. I sent `dry: true`\n\n, expecting a price preview. The server only honored `?dry=1`\n\n— **4 orders of ¥99 were charged for real, and the money was gone.**\n\nThis is not just my problem. AI agents are about to order food, top up accounts, and call paid APIs on your behalf. **When AI starts spending real money, who puts a gate in front of it?**\n\nI turned my scar into a library.\n\n| Pillar | What it does |\n|---|---|\n🔑 Identity (KYA) |\nEvery agent gets a digital identity with its own budget/blacklist/limits. Unregistered agents are denied by default. |\n🎯 Intent alignment |\nNew recipients and large amounts always require human sign-off — stops prompt-injected agents from spending without you. |\n🔐 Secret vault |\nKeys encrypted at rest (AES-256), master key never on disk. Key access passes the gates and is fully audited. |\n\nEvery spend passes all of them. Rules are code, not AI opinion — agents cannot argue, trick, or inject their way past.\n\n| Gate | Default | Effect |\n|---|---|---|\n🧪 dry_run |\nOn | Preview only. Nothing executes until you say so. |\n💰 budget |\nUnlimited | Hard ceiling. Over budget means denied. |\n🚧 max_amount |\nUnlimited | Per-transaction cap. |\n🙋 approval |\nOff | Human sign-off — console, Telegram, or webhook. |\n📜 audit |\nOn | Every attempt recorded, exportable JSON. |\n\n```\npip install spendshield\n```\n\nOr run it with Docker (MCP server):\n\n```\ndocker build -t spendshield .\ndocker run -it spendshield\n```\n\n💡 Pre-built image on GHCR is coming soon (requires a workflow-scoped GitHub token to publish the CI pipeline).\n\n``` python\nfrom spendshield import SpendShield, KeyVault\n\nguard = SpendShield(budget=200, dry_run=True, whitelist=[\"McDonald's\"])\n\n@guard.protect(\"order\")\ndef place_order(amount, to):\n    return call_real_api(amount, to)\n\nplace_order(amount=99, to=\"McDonald's\")\n# => DryRunBlocked: dry_run mode, nothing executed\n\nguard.dry_run = False\nfor i in range(4):\n    place_order(amount=99, to=\"McDonald's\")   # 3rd order blocked by BudgetExceeded\nguard = SpendShield(dry_run=False)\nguard.register_agent(\"mcd_bot\", budget=50, max_amount=30,\n                     blacklist=[\"unknown_vendor\"], whitelist=[\"McDonald's\"],\n                     rate_limit={\"window_s\": 60, \"max_calls\": 3})\n\n@guard.protect(\"order\", agent=\"mcd_bot\")\ndef place_order(amount, to):\n    return call_real_api(amount, to)\npython\npython -c \"from spendshield import KeyVault; print(KeyVault.generate_key())\"\nexport SPENDGUARD_MASTER_KEY=***   # never commit this\nvault = KeyVault(\"vault.json\")\nvault.store(\"mcd_sk\", \"sk_live_xxx\")\n\nguard = SpendShield(key_vault=vault)\nguard.register_agent(\"mcd_bot\", whitelist=[\"mcd_sk\"])\nsk = guard.get_secret(\"mcd_sk\", agent=\"mcd_bot\")   # passes identity + intent gates\n```\n\nClaude Code, OpenClaw and any MCP-compatible agent can call the guard directly:\n\n```\nspendshield-mcp --policy spendshield.yaml\n```\n\nTools: `spend_protect`\n\n/ `spend_status`\n\n/ `spend_audit`\n\n/ `spend_reset`\n\n/ `secret_get`\n\n[x402](https://x402.org) is the open payment protocol for the internet (HTTP 402) — how AI agents pay for APIs. SpendShield is the guardrail in front of it: **x402 lets agents pay, SpendShield stops them paying recklessly.**\n\n``` python\nfrom spendshield import SpendShield\nfrom spendshield.adapters.x402 import X402PaywallGuard, protect_x402_payment\n\nguard = SpendShield(budget=50, dry_run=True)\npw = X402PaywallGuard(guard)\n\n# Server side: every paid resource passes the gates before settlement\npw.authorize_resource(\"weather-api\", price=\"0.01\", asset=\"USDC\", pay_to=\"0x...\")\npw.confirm_payment(\"weather-api\", price=\"0.01\", pay_to=\"0x...\")   # after settlement\n\n# Client side: gate the payment before your agent pays\nprotect_x402_payment(guard, amount=0.01, to=\"weather.example.com\", agent=\"research_bot\")\n```\n\nBudget, blacklist, rate limits, human approval, identity (KYA) and audit all apply to x402 payments — new recipients require human sign-off, unregistered agents are denied.\n\n30 tests covering gates, identity, intent alignment, vault, and edge cases.\n\n```\npython3 -m pytest tests/\n```\n\n- 🐛 Found a bug?\n[Open an issue](https://github.com/felixpg13-glitch/spendshield/issues/new?template=bug_report.md) - 💡 Have an idea?\n[Suggest a feature](https://github.com/felixpg13-glitch/spendshield/issues/new?template=feature_request.md) - 🔒 Security vulnerability? See\n[SECURITY.md](/felixpg13-glitch/spendshield/blob/main/SECURITY.md)— report privately, not in a public issue. - ⭐ Found it useful? Star the repo so other people who got burned by \"test orders\" find it.\n\nMIT — take it. May no one get burned by a \"test order\" twice in the AI era.", "url": "https://wpnews.pro/news/show-hn-my-ai-spent-15-on-a-test-order-so-i-built-a-payment-guardrail", "canonical_source": "https://github.com/felixpg13-glitch/spendshield", "published_at": "2026-08-31 15:37:00+00:00", "updated_at": "2026-08-31 15:52:56.574640+00:00", "lang": "en", "topics": ["ai-safety", "ai-agents", "ai-tools", "developer-tools"], "entities": ["SpendShield", "x402", "Claude Code", "OpenClaw", "McDonald's", "GitHub"], "alternates": {"html": "https://wpnews.pro/news/show-hn-my-ai-spent-15-on-a-test-order-so-i-built-a-payment-guardrail", "markdown": "https://wpnews.pro/news/show-hn-my-ai-spent-15-on-a-test-order-so-i-built-a-payment-guardrail.md", "text": "https://wpnews.pro/news/show-hn-my-ai-spent-15-on-a-test-order-so-i-built-a-payment-guardrail.txt", "jsonld": "https://wpnews.pro/news/show-hn-my-ai-spent-15-on-a-test-order-so-i-built-a-payment-guardrail.jsonld"}}