When teams start shipping AI agents that spend money, two questions surface quickly: how does the agent pay, and how do we control what it pays for? Stripe Agent Toolkit and xBPP answer different parts of that question. This page walks through the differences, where each fits best, and when you might use them together.
They're not mutually exclusive. A team running agents on Stripe can use the Stripe Agent Toolkit to move money and xBPP to govern which moves are allowed. We'll show how below.
If your agent's job is to interact with Stripe - create customers, issue invoices, manage subscriptions, process refunds - Stripe Agent Toolkit is the fastest way to do it. You get:
If you're already on Stripe and your agents stay inside the Stripe ecosystem, the toolkit is probably what you want. It removes glue code and gives your agents immediate access to Stripe's full payment surface.
xBPP solves a different problem: governing what an agent is allowed to do, independent of the payment rail underneath. It's the layer above whatever toolkit actually moves money.
The strengths that come from being a standard instead of an SDK:
xBPP isn't trying to be a payment SDK. It's trying to be the policy layer every payment SDK is missing.
The most interesting case isn't "xBPP or Stripe Agent Toolkit" - it's "xBPP with Stripe Agent Toolkit." xBPP sits in front of whatever SDK actually executes the payment. On the Stripe side, that means:
import { evaluate } from '@vanar/xbpp'
import { StripeAgentToolkit } from '@stripe/agent-toolkit'
import policy from './policies/stripe-agent.json'
const stripe = new StripeAgentToolkit({ secretKey: process.env.STRIPE_KEY })
async function chargeCustomer(customerId: string, amountUsd: number) {
// 1. xBPP evaluates the policy first
const verdict = evaluate(
{ amount: amountUsd, currency: 'USD', recipient: customerId, rail: 'stripe' },
policy
)
if (verdict.decision === 'BLOCK') {
throw new Error(`Policy block: ${verdict.reasons.join(', ')}`)
}
if (verdict.decision === 'ESCALATE') {
await humanApproval.request(verdict)
return
}
// 2. Stripe Agent Toolkit executes the charge
return stripe.charges.create({
customer: customerId,
amount: amountUsd * 100,
currency: 'usd'
})
}xBPP handles governance - the "should we" - once. Stripe Agent Toolkit handles Stripe-specific execution - the "how" - for the subset of transactions that actually happen on Stripe. The same policy can simultaneously govern agent activity on x402, on-chain, or any other rail you add later.
There's one more difference worth calling out explicitly: xBPP is an open standard, Stripe Agent Toolkit is a vendor SDK. Both are valid choices, and neither is inherently better - but they imply different things.
A vendor SDK is the shortest path when you're committed to a single provider. It's also a commitment in the other direction: your governance logic ends up shaped around one provider's primitives, and migrating it elsewhere means rewriting it.
An open standard trades some initial integration work for portability. Policies written for xBPP today will keep working if you switch payment rails, add new rails, or support multiple in parallel. For teams that expect to run on more than one rail over their lifetime - which, in our experience, is most of them - that portability is worth the tradeoff.
No. xBPP is a policy layer, not a payment SDK. If you're paying via Stripe, you still use Stripe Agent Toolkit (or the Stripe SDK directly) to execute the charge. xBPP decides whether the charge should happen.
Yes. xBPP operates above the payment rail, so it's independent of Stripe's account model. You can use it alongside Connect accounts, direct charges, or destination charges.
It's not a migration - they solve different problems. You can add xBPP alongside any existing payment toolkit without migrating anything else.
Yes. Apache 2.0, no accounts, no API keys, no telemetry.