How to Prevent AI Agents From Spending at the Wrong Merchants
TL;DR
- Three layered controls: merchant whitelist (strict outer boundary), MCC blocklist (categorical filter), policy token (per-transaction rules). Use all three.
- Each catches a different failure mode. Whitelist blocks unknown merchants. MCC blocks blocks unwanted categories. Policy catches edge cases the other two miss.
- Decline reasons are explicit so you can debug which layer fired and adjust.
The fastest way for an AI agent to embarrass itself in production is to spend at the wrong merchant — paid an off-brand impostor, hit a category the user didn't intend, or charged a vendor the policy explicitly forbids. The fix is three layered controls evaluated at auth time: whitelist, MCC block, policy token.
What are the three layers?
Layer 1: Merchant whitelist (outer boundary).
The agent can only transact with merchants on the whitelist. Everything else: declined. See [Merchant Whitelisting for AI Agents](/blog/merchant-whitelisting-ai-agents).
Layer 2: MCC blocklist (categorical filter).
Even within whitelisted merchants, certain merchant categories are blocked. Catches edge cases like a whitelisted merchant operating in multiple categories. See [How MCC Codes Restrict Agent Spending](/blog/mcc-rules-control-agent-spending).
Layer 3: Policy token (per-transaction rules).
Amount limits, time windows, geo restrictions, velocity caps. Catches behavioral anomalies that whitelist + MCC alone wouldn't.
Shatale's engine checks all three layers on every authorization, and decline reasons identify which layer fired.
Why three layers and not just one?
Each layer has a failure mode the others cover:
Whitelist alone fails when: A whitelisted merchant operates in a category you didn't intend. (Whitelisted travel agency that also sells gambling.)
MCC alone fails when: A merchant is mis-coded. (A consumer SaaS company coded as MCC 5942 "Bookstores" because of legacy.)
Policy alone fails when: The agent is prompted by a malicious user to spend within all rules but at a merchant that's still wrong. (Whitelisted, correct MCC, within budget, but not what the agent should be doing.)
Layered defense means a failure in one rule is caught by another.
What does this look like in a production policy?
A production policy combines the three layers in one place: a merchant whitelist of specific approved merchants, an MCC blocklist for high-risk categories, and transaction rules covering per-transaction and daily caps, geo restrictions, and velocity limits.
For a travel agent: whitelisted to specific airlines + hotels, MCC blocks for gambling/crypto/tobacco, policy caps at $500/transaction and $2k/day with geo restrictions.
How do you build each layer?
Whitelist (Layer 1):
Start with research — what merchants does the agent type need? Add 5-10 vetted partners. Expand based on user-requested adds. See the patterns in [Merchant Whitelisting](/blog/merchant-whitelisting-ai-agents).
MCC blocks (Layer 2):
Default block list for high-risk categories: gambling (7995), crypto (6051), drugs/pharma (5912), tobacco (5993), adult (5967). Tune for your specific compliance posture.
Policy rules (Layer 3):
Amount caps from user budget. Time + geo from user enrollment. Velocity from agent type — research agents need higher velocity than purchase agents.
How do you debug declines?
Every decline returns a reason code identifying which layer fired:
merchant_not_whitelisted(Layer 1)mcc_blocked(Layer 2)amount_exceeded/velocity_exceeded/geo_denied/outside_business_hours(Layer 3)
Plus a human-readable explanation: "Merchant 'X' is not on agent 'travel-bot' policy whitelist."
In the dashboard, filter declines by reason code. Adjust the offending layer. Test in sandbox before re-deploying policy.
What about smart attackers?
A determined attacker with prompt-injection access to your agent will try to bypass controls. The three layers handle the common cases:
- Trying to charge a non-whitelisted merchant: Layer 1 blocks.
- Trying to charge a whitelisted merchant in a wrong category: Layer 2 blocks.
- Trying to charge within rules but suspiciously: Layer 3 (velocity, time, geo) catches.
What's NOT covered: charging within all rules but for the wrong reason. (Agent prompted to "buy these specific tickets" instead of normal travel booking.) This requires application-layer logic — what is the agent supposed to be doing right now? — that the payment platform can't fully solve.
What about novel merchants the agent legitimately needs?
Three patterns:
FAQ
What's the right starting whitelist size?
3-10 merchants for narrow-purpose agents. Anything more, and the operational toil starts to outweigh the benefit — switch to MCC + policy as primary control.
Should I block crypto MCCs by default?
For most consumer agents, yes. Crypto MCCs (6051, 6540) are high-fraud and often prohibited by issuer policy regardless. Allow only for crypto-native agent products where it's the intended behavior.
Can the agent see why it was declined?
Yes — the decline reason and explanation are part of the response. Most agent runtimes propagate this so the agent can act (retry differently, escalate to user, fall back).
What about multi-region operations?
Geo allow list per region. Same agent, multi-region delegation = multiple geo-scoped delegations under one user.
Is there an audit trail of every decline?
Yes. Every authorization request — approved or declined — is logged with the policy version evaluated and reason codes. Available in the dashboard and via API export.
Related reading
- [Merchant Whitelisting for AI Agents](/blog/merchant-whitelisting-ai-agents)
- [How MCC Codes Restrict Autonomous AI Agent Spending](/blog/mcc-rules-control-agent-spending)
External references
- [Visa Merchant Category Codes](https://developer.visa.com) — MCC reference
- [PSD2 Strong Customer Authentication](https://www.eba.europa.eu/) — regulatory framework relevant to layered controls
---
By Vlad K.. Last updated 2026-04-29.