Using Stripe Issuing for AI agent spending
Stripe Issuing gives AI agents real virtual cards. PayGraph gives those cards a policy layer. Here's how the two stack — with concrete fees, limits, and code.
Stripe Issuing is the cleanest way to give an AI agent its own card. Stripe handles the rails. PayGraph handles the policy. Together they cover the gap between "the card works" and "the card is safe."
What is Stripe Issuing for AI agents?
Stripe Issuing is an API for programmatically creating virtual and physical payment cards. For AI agents, the relevant primitive is the virtual card — a 16-digit card number created in milliseconds, scoped to a single agent, a single vendor, or a single transaction.
You provision a card with a few API parameters:
import stripe
card = stripe.issuing.Card.create(
cardholder="ich_agent_ops_01",
currency="usd",
type="virtual",
spending_controls={
"spending_limits": [
{"amount": 50000, "interval": "daily"},
],
"allowed_categories": [
"computer_software_stores",
"advertising_services",
],
},
)That card can now be used by an agent to pay any merchant that accepts Visa or Mastercard — which is most of the internet. The catch: Stripe's controls are coarse, and the agent still chooses what to buy.
Why pair Stripe Issuing with a policy layer?
Stripe Issuing's spending_controls are based on MCC codes (merchant category codes) and fixed amount intervals. They're enforced at the network level — fast, reliable, and final.
But MCC is a blunt instrument. computer_software_stores (5734) covers Adobe, JetBrains, a malware reseller, and a one-person SaaS you've never heard of. Stripe will approve all of them. The MCC also tells you nothing about what the agent is buying or why.
PayGraph adds the missing axis: semantic rules evaluated in your application before the card is even charged. Vendor allowlists, per-task budgets, time-of-day windows, approval routing for unusual purchases, and an immutable log tying every charge back to the agent run that caused it.
Stripe answers "is this card allowed to pay this merchant?" PayGraph answers "should this agent be spending this money on this thing right now?"
How do the two control layers stack?
Think of it as two filters in series. PayGraph runs first, in your code, before the card is charged. Stripe runs second, at authorization time, on the network. A transaction has to pass both.
| Control | Stripe Issuing | PayGraph |
|---|---|---|
| Per-transaction cap | Yes (MCC-based) | Yes (semantic) |
| Daily/weekly/monthly caps | Yes | Yes |
| Merchant category (MCC) | Native | Pass-through |
| Specific vendor allowlist | No | Yes |
| Per-agent-run budget | No | Yes |
| Approval workflow | No | Built-in |
| Reason-for-purchase capture | No | Yes |
| Audit log of intent + outcome | Authorization only | Full trace |
| Enforcement point | Card network | Application |
The pairing matters because each layer catches what the other misses. Stripe will block a $50,000 charge on a $5,000-cap card even if your application is compromised. PayGraph will block a $400 charge to a vendor not on your allowlist even if Stripe would have approved it.
What does the integration actually look like?
Here's a concrete pattern: a marketing agent buys ad credits. Stripe Issuing provides the card. PayGraph wraps the purchase tool.
from paygraph import PolicyEngine, Policy
import stripe
policy = Policy(
max_per_transaction_usd=500,
daily_cap_usd=2000,
allowed_vendors=["google.com", "meta.com", "linkedin.com"],
require_approval_above_usd=250,
require_reason=True,
)
engine = PolicyEngine(policy)
@engine.guarded_tool
def buy_ad_credits(vendor: str, amount_usd: float, reason: str):
return stripe.PaymentIntent.create(
amount=int(amount_usd * 100),
currency="usd",
payment_method=AGENT_CARD_ID,
confirm=True,
metadata={"vendor": vendor, "reason": reason},
)The agent's tool call goes through PayGraph's policy evaluation first. If vendor isn't on the allowlist, the call fails before Stripe sees it. If the amount exceeds $250, the call pauses for human approval. If approved, Stripe authorizes against its own MCC and amount controls. Either layer can stop the charge. Both layers log the attempt.
For more on the underlying pattern, see the three-layer architecture of policy-controlled agent spending.
What are the real fees and limits?
The numbers that matter when you're sizing this for production:
- Stripe Issuing pricing (US): $0.10 per virtual card created, plus the standard interchange the merchant pays. No monthly fee for issued cards. International transactions add a 1% cross-border fee.
- Card creation throughput: virtual cards provision in well under a second via the API. You can mint a card per agent run if your model demands ephemeral credentials.
- Spending limit intervals: Stripe supports
per_authorization,daily,weekly,monthly,yearly, andall_time. Granularity below "daily" requires PayGraph. - MCC granularity: Stripe exposes roughly 300 merchant categories. Useful for broad fences. Useless for "only this specific SaaS vendor."
- Authorization webhook latency: Stripe sends
issuing_authorization.requestevents that you can synchronously approve or decline within a 2-second window. PayGraph plugs into this webhook for last-mile checks.
Two operational notes. Cards default to inactive until you activate them, which is the right posture for agent provisioning. And issuing_authorization.request is the hook to use if you want PayGraph to make the final approve/decline call at network time, rather than just gating the upstream tool call.
Where to start
- GitHub: github.com/paygraph-ai/paygraph — MIT-licensed SDK with a Stripe Issuing adapter and example LangGraph agent.
- Docs: docs.paygraph.dev — Stripe Issuing integration guide, authorization webhook setup, vendor allowlist patterns.
- Discord: discord.gg/PPVZWSMdEm — talk to teams running Stripe Issuing in production with agents today.
If you're already issuing cards to agents, the next 30 minutes of work is the policy layer that decides which charges those cards should ever attempt.