---
title: "AgentCore Payments — x402, embedded wallets, and a budget the agent can't blow past"
date: 2026-06-08
service: "Amazon Bedrock AgentCore"
component: "Payments"
tags: [agentcore, payments, x402, microtransactions, stablecoin, usdc, embedded-wallet, coinbase-cdp, stripe-privy, payment-manager, payment-session, payment-instrument, process-payment, strands, preview]
source: https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/payments.html
verified_on: 2026-06-08
url: https://vanemmerik.ai/aws-ai/2026-06-08.html
---

# AWS Bedrock & AgentCore · Tip of the Day · 2026-06-08

## AgentCore Payments — when the agent has to pay the merchant itself

The whole AgentCore surface so far has been about an agent *doing* things — running, remembering, calling tools, browsing. **AgentCore Payments** (preview) is about an agent *buying* things: paying a merchant, per call, for a paid API, an MCP tool, or a paywalled page — in fractions of a cent, autonomously, without a credit card and without you wiring up a wallet by hand.

    aws bedrock-agentcore process-payment \
        --payment-type "CRYPTO_X402" \
        --payment-session-id "payment-session-abc123" \
        --payment-instrument-id "payment-instrument-xyz789" ...

≈ 8 min read · Amazon Bedrock AgentCore · Payments

## 01 · The problem it actually solves

As services start charging agents per request, the bill is the awkward part. Individual API calls and content fetches are often worth cents — sometimes fractions of a cent — and traditional rails make that uneconomic: credit cards carry minimum transaction fees and geographic restrictions, so a $0.004 charge per call simply doesn't work. On top of that, wiring payments into an agent has meant *months* of engineering — third-party wallets, payment orchestration, support for emerging agent protocols, budget guardrails, and end-to-end observability, all built from scratch.

AgentCore Payments is a fully managed service that collapses that to "a few lines of code." It orchestrates payments over the **x402 protocol**, settles in **stablecoins** so microtransactions are viable, and ships budget controls and CloudWatch observability in the box. AWS frames it as turning months of effort into days.

> **The shift:** the agent stops asking *you* to pay and starts paying the merchant directly — one signed transaction per 402, inside a budget you set, with an audit trail you didn't have to build.

## 02 · x402, in one paragraph

x402 is an open, HTTP-native payment standard that repurposes the **HTTP 402 Payment Required** status code for programmatic payments. The flow is small: the agent requests a paid resource; the merchant answers `402` with a payload naming the **amount, recipient, asset, and network**; the agent signs the payment and retries the same request with the signed proof in an **`X-PAYMENT`** header; the merchant verifies, settles on-chain, and returns the content. AgentCore Payments runs the agent's half of that exchange — for both x402 **v1 and v2** — so your code only sees "I asked, I got the content."

## 03 · Five resources, two control planes

The model is small once the names click. Three resources live on the **control plane** (`bedrock-agentcore-control`); two are created per-interaction on the **data plane** (`bedrock-agentcore`).

| Resource | What it is |
| --- | --- |
| **PaymentManager** | Top-level resource. Has an `authorizerType` of `AWS_IAM` or `CUSTOM_JWT`, an IAM role, and provisions a workload identity in AgentCore Identity. Lifecycle: `CREATING → READY`, plus `UPDATING` / `CREATE_FAILED` / `UPDATE_FAILED`. |
| **PaymentConnector** | Binds a manager to a provider. Two types: `CoinbaseCDP` and `StripePrivy`. References a credential provider by ARN; one manager can hold several connectors. |
| **PaymentCredentialProvider** | A specialised credential provider in AgentCore Identity that keeps Coinbase/Privy keys and wallet secrets in **AWS Secrets Manager**. 1:1 with a connector; tokens are fetched at runtime via `GetResourcePaymentToken`. |
| **PaymentInstrument** | An embedded crypto wallet, type `EMBEDDED_CRYPTO_WALLET`, bound to one blockchain network. Status `INITIATED → ACTIVE`, plus `FAILED` / `DELETED`. |
| **PaymentSession** | A scoped, time-boxed spend context for a single interaction, with an optional `maxSpendAmount` budget. |

Credentials are **never** passed to the Payments API directly — the connector references them in Identity, and Secrets Manager holds the actual secrets.

## 04 · The budget that rolls itself back

A `PaymentSession` is the spend guardrail. You create it with an expiry and an optional limit:

    session = dp_client.create_payment_session(
        userId="test-user-123",
        paymentManagerArn=PAYMENT_MANAGER_ARN,
        expiryTimeInMinutes=60,
        limits={"maxSpendAmount": {"value": "5.00", "currency": "USD"}},
        clientToken=str(uuid.uuid4()),
    )

When the session expires **or** the budget is reached, further payment requests in that session are denied. The detail worth memorising: if a payment **signing fails after the budget was deducted, the amount is automatically rolled back** — a failed call never silently eats your remaining budget. The merchant's reservation is released and the transaction is recorded as `FAILED`.

## 05 · Funding is the user's job, by design

A freshly created instrument starts with **0 USDC**, and the agent **cannot transact through it until the end user funds the wallet and explicitly grants the agent signing permission**. `CreatePaymentInstrument` returns a `paymentInstrumentDetails.redirectUrl` pointing at the provider's wallet hub (Coinbase's WalletHub or Privy's); there the user tops up — crypto transfer, credit/debit card, Apple Pay, Google Pay, or ACH — and grants (or later revokes) the agent's permission. Only then does the instrument poll its way to `ACTIVE`. Because a wallet address can't be reused across chains, you maintain a **separate instrument per network** (one for Ethereum, one for Solana, and so on).

## 06 · Calling ProcessPayment

Once an instrument is `ACTIVE` and a session exists, `ProcessPayment` does the work — budget check, credential fetch, on-chain signing, proof back:

    payment = dp_client.process_payment(
        userId="test-user-123",
        paymentManagerArn=PAYMENT_MANAGER_ARN,
        paymentSessionId=SESSION_ID,
        paymentInstrumentId=INSTRUMENT_ID,
        paymentType="CRYPTO_X402",
        paymentInput={"cryptoX402": {"version": "2", "payload": {
            "scheme": "exact", "network": "eip155:84532",
            "amount": "100000", "asset": "0x036CbD…",
            "payTo": "0x99935f…", "maxTimeoutSeconds": 300,
            "extra": {"name": "USDC", "version": "2"}}}},
        clientToken=str(uuid.uuid4()),
    )

A status of `PROOF_GENERATED` means the transaction was signed and the proof is in `paymentOutput`. There are four ways to reach it: the **AWS CLI**, the **AWS SDK** (`process_payment`), the **AgentCore SDK** (`PaymentManager.generate_payment_header` when you want to handle the 402 yourself), and the **Strands plugin**, which intercepts 402s and retries automatically:

    pip install 'bedrock-agentcore[strands-agents]'

    plugin = AgentCorePaymentsPlugin(config=AgentCorePaymentsPluginConfig(
        payment_manager_arn=PAYMENT_MANAGER_ARN,
        user_id="test-user-123",
        payment_instrument_id=INSTRUMENT_ID,
        payment_session_id=SESSION_ID,
        region="us-west-2"))
    agent = Agent(tools=[http_request], plugins=[plugin])
    agent("Access the premium endpoint at https://example-x402-merchant.com/paid-api")

Set `auto_payment=False` to keep a human in the loop, or pass `network_preferences_config` (e.g. `["eip155:8453", "base-sepolia", "solana-mainnet"]`) — by default the plugin prefers Solana mainnet and Base for low fees.

## 07 · Four roles, on purpose

Payments uses a **four-role IAM model** that splits administration from execution: `ControlPlaneRole` (manages managers, connectors, credential providers), `ManagementRole` (agent developer — creates instruments and sessions but carries an explicit **`Deny` on `ProcessPayment`**), `ProcessPaymentRole` (the only role that can execute a payment), and `ResourceRetrievalRole` (the service role AgentCore assumes at runtime to fetch credentials). The point of the split is concrete: no single compromised identity can both mint an unlimited-budget session *and* spend against it, and the audit trail cleanly separates who configured payments from who executed them.

For discovery, AgentCore ships a ready-made **Coinbase x402 Bazaar** MCP server that surfaces **10,000+ pay-per-use x402 endpoints** through AgentCore Gateway, and every data-plane call emits **vended logs** to CloudWatch and **vended spans** to X-Ray.

## Limits worth knowing

- **Preview.** Features and APIs may change before GA — treat ARNs, fields, and shapes as snapshots.
- **Two providers only:** `CoinbaseCDP` and `StripePrivy`. The only instrument type is `EMBEDDED_CRYPTO_WALLET`.
- **No funds, no permission, no payment.** Instruments start at 0 USDC and the agent can't sign until the user funds and grants — there is no way to bypass the human at funding time.
- **One instrument per chain.** Wallet addresses don't cross networks; maintain separate instruments for Ethereum, Solana, etc.
- **Separation of duties is enforced in IAM,** not just recommended — the management role explicitly *denies* `ProcessPayment`.
- **Two service names:** control-plane resources use `bedrock-agentcore-control`; instruments, sessions, and `ProcessPayment` use the `bedrock-agentcore` data plane.

## Try it in five minutes

You can't actually move money in five minutes — funding requires a real (or testnet) wallet and a human grant — but you can stand up the control-plane scaffolding:

- Store provider keys: `create_payment_credential_provider(credentialProviderVendor="CoinbaseCDP", coinbaseCdpConfig={…})`.
- Create the manager: `create_payment_manager(authorizerType="AWS_IAM", roleArn=…)`, then poll `get_payment_manager` until `READY`.
- Attach a connector: `create_payment_connector(paymentConnectorType="CoinbaseCDP", credentialProviderArn=…)`.
- Create an instrument, open its `redirectUrl`, fund with **testnet USDC**, grant the agent permission, and poll until `ACTIVE`.
- Create a session with a `maxSpendAmount`, then point the Strands plugin at a test x402 merchant and watch the 402 resolve itself.

Set up the four IAM roles first — the console can create them for you — or `ProcessPayment` will be denied before it ever reaches a wallet.

---

**Verified against the official AWS docs on 2026-06-08.** Sources: [AgentCore payments overview](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/payments.html), [Core concepts](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/payments-concepts.html), [How it works](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/payments-how-it-works.html), [Process a payment](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/payments-process-payment.html), [Quick start](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/payments-getting-started.html), [IAM roles](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/payments-iam-roles.html). If the docs change, this tip is a snapshot of that day — check the sources for current behaviour.

---

*This page — research, writing, verification, and deployment — was built by Claude Cowork. The tip was generated this morning, cross-checked against the official AWS docs by an independent verification pass, and published to Cloudflare R2 on a schedule. A daily experiment by Monty van Emmerik · [vanemmerik.ai](https://vanemmerik.ai/).*
