View a markdown version of this page

Process a payment - Amazon Bedrock AgentCore

Process a payment

To process a payment, you need two resources:

After both exist, call ProcessPayment with the payment session ID, payment instrument ID, and a payment payload. The service validates the request, checks the budget, signs the transaction on the appropriate blockchain, and returns a signed payment result. For the complete request and response schema, see ProcessPayment in the API Reference.

AgentCore payments supports two payment protocols, which you select with the paymentType parameter:

  • CRYPTO_X402 — The x402 protocol. Provide the merchant’s x402 payment payload in paymentInput.cryptoX402, and the agent retries the request with the signed proof in the X-PAYMENT header.

  • MPP — The Machine Payments Protocol (MPP). Forward the merchant’s WWW-Authenticate: Payment challenge in paymentInput.mpp, and the agent retries the request with the returned credential in the Authorization header.

Choose the paymentType that matches the protocol the merchant used in its 402 Payment Required response. For x402 request and response details, see Pay an x402 payment request. For MPP request and response details, see Pay an MPP challenge.

Tip

You can automate the steps on this page with the AgentCore Payments skill in the AWS agent toolkit. The skill is part of the aws-agents plugin and lets an AI coding agent create your Payment Manager, connector, credential provider, payment instrument, and session using the agentcore CLI, and add a process payment tool to your agent. For details, see the quickstart and the AWS agent toolkit on GitHub.

There are five ways to invoke the ProcessPayment API:

Example
AgentCore CLI

If your agent is deployed with payment capabilities configured, invoke it with payment context and the x402 interceptor handles payment processing automatically:

agentcore invoke \ --prompt "Access the premium endpoint at https://example-x402-merchant.com/paid-api" \ --payment-instrument-id <INSTRUMENT_ID> \ --auto-session \ --payment-user-id user@example.com

To use an explicit session instead of auto-creating one:

agentcore invoke \ --prompt "Access the premium endpoint at https://example-x402-merchant.com/paid-api" \ --payment-instrument-id <INSTRUMENT_ID> \ --payment-session-id <SESSION_ID> \ --payment-user-id user@example.com

The deployed agent’s x402 plugin intercepts HTTP 402 responses, calls ProcessPayment, and retries the request with proof. Requires AgentCore CLI v0.19.0 or later.

AgentCore SDK

Use the PaymentManager class to generate payment headers manually within any agent framework:

import uuid from bedrock_agentcore.payments import PaymentManager manager = PaymentManager( payment_manager_arn=mgr["paymentManagerArn"], region_name="us-west-2" ) # When you receive a 402 response, generate payment proof payment_required_request = { "statusCode": 402, "headers": payment_required["headers"], "body": payment_required["body"], } payment_proof_headers = manager.generate_payment_header( user_id="test-user-123", payment_instrument_id=instrument["paymentInstrumentId"], payment_session_id=session["paymentSessionId"], payment_required_request=payment_required_request, client_token=str(uuid.uuid4()), )

payment_proof_headers contains the payment proof header. Include this header when retrying the request to the paid endpoint. You can also call the process_payment method of PaymentManager for more control over inputs.

AWS CLI

The following example processes an x402 payment by passing the merchant’s payload in paymentInput.cryptoX402:

aws bedrock-agentcore process-payment \ --payment-manager-arn "arn:aws:bedrock-agentcore:us-west-2:123456789012:payment-manager/my-manager" \ --payment-session-id "payment-session-abc123" \ --payment-instrument-id "payment-instrument-xyz789" \ --payment-type "CRYPTO_X402" \ --payment-input '{ "cryptoX402": { "version": "2", "payload": { "scheme": "exact", "network": "eip155:84532", "amount": "100000", "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e", "payTo": "0x99935f281d3ED1E804bF1413b76E0B03e1fed4F9", "maxTimeoutSeconds": 300, "extra": {"name": "USDC", "version": "2"} } } }' \ --client-token "$(uuidgen)" \ --region us-west-2

To learn how to build the paymentInput for each protocol, including the MPP AWS CLI example, see Pay an x402 payment request and Pay an MPP challenge.

AWS SDK

The following example processes an x402 payment by calling process_payment with the merchant’s payload in paymentInput.cryptoX402:

import uuid 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": "0x036CbD53842c5426634e7929541eC2318f3dCF7e", "payTo": "0x99935f281d3ED1E804bF1413b76E0B03e1fed4F9", "maxTimeoutSeconds": 300, "extra": {"name": "USDC", "version": "2"}, }, } }, clientToken=str(uuid.uuid4()), )

Response:

{ "processPaymentId": "12345678-1234-1234-1234-123456789012", "paymentManagerArn": "arn:aws:bedrock-agentcore:us-west-2:123456789012:payment-manager/my-manager-a1b2c3d4e5", "paymentSessionId": "payment-session-abc123def4567", "paymentInstrumentId": "payment-instrument-xyz789abc1234", "paymentType": "CRYPTO_X402", "status": "PROOF_GENERATED", "paymentOutput": { "cryptoX402": { "version": "2", "payload": { "...signed transaction proof..." } } }, "createdAt": "2025-07-15T10:35:00Z", "updatedAt": "2025-07-15T10:35:02Z" }

A status of PROOF_GENERATED indicates the transaction was signed and the payment proof is included in paymentOutput.

To learn how to build the paymentInput for each protocol, including the MPP AWS SDK example and its response, see Pay an x402 payment request and Pay an MPP challenge.

Strands SDK

The AgentCore payments plugin provides automated payment processing for Strands Agents. It supports the x402 Payment Required protocol, enabling agents to automatically handle HTTP 402 responses.

Installation:

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

Configure and use the plugin:

from strands import Agent from strands_tools import http_request from bedrock_agentcore.payments.integrations.config import AgentCorePaymentsPluginConfig from bedrock_agentcore.payments.integrations.strands.plugin import AgentCorePaymentsPlugin # Configure the plugin config = AgentCorePaymentsPluginConfig( payment_manager_arn="arn:aws:bedrock-agentcore:us-west-2:123456789012:payment-manager/pm-abc123", user_id="test-user-123", payment_instrument_id="payment-instrument-XJU4RSQP9VO0ler", payment_session_id="payment-session-xuzrnUCd7RT725G", region="us-west-2", ) # Create the plugin plugin = AgentCorePaymentsPlugin(config=config) # Create agent with the plugin agent = Agent( system_prompt="You are a helpful assistant that can access paid APIs.", tools=[http_request], plugins=[plugin], ) # Use the agent -- 402 responses are automatically handled agent("access https://drvd12nxpcyd5.cloudfront.net/market-recap")

The AgentCore payments plugin intercepts x402 payment requests automatically, processes the payment, and retries the request with payment proof for the agent.

LangGraph

The AgentCore payments middleware provides automated payment processing for LangGraph agents. It supports the x402 Payment Required protocol, enabling agents to automatically handle HTTP 402 responses.

Installation:

pip install 'bedrock-agentcore[langgraph]'

Configure and use the middleware:

from langchain.agents import create_agent from bedrock_agentcore.payments.integrations.langgraph import ( AgentCorePaymentsConfig, AgentCorePaymentsMiddleware, ) config = AgentCorePaymentsConfig( payment_manager_arn="arn:aws:bedrock-agentcore:us-west-2:123456789012:payment-manager/pm-abc123", user_id="test-user-123", payment_instrument_id="payment-instrument-XJU4RSQP9VO0ler", region="us-west-2", auto_session=True, ) payments = AgentCorePaymentsMiddleware(config) agent = create_agent( model="us.anthropic.claude-sonnet-4-20250514-v1:0", tools=[], middleware=[payments], ) result = agent.invoke({"messages": [{"role": "user", "content": "access https://drvd12nxpcyd5.cloudfront.net/market-recap"}]}) print(result)

The AgentCore payments middleware intercepts x402 payment requests automatically, processes the payment, and retries the request with payment proof for the agent.

Pay an x402 payment request

When a merchant responds with an x402 payment payload in its 402 Payment Required response, you forward that payload to AgentCore payments, and AgentCore payments returns a signed proof. You copy the merchant’s payload into paymentInput.cryptoX402, and AgentCore payments checks the budget, signs the transaction with the wallet, and returns the signed proof. You attach the proof to the X-PAYMENT header and retry the original request.

Request and response

Provide the following fields in paymentInput.cryptoX402:

  • version — The x402 protocol version (for example, 1 or 2). Required.

  • payload — The merchant’s x402 payment requirements, passed as a JSON object. This specifies the scheme, network, maxAmountRequired, asset, payTo, and other fields from the merchant’s 402 response. Required.

  • permit2AllowanceLimit — The maximum on-chain Permit2 allowance to grant, in the asset’s smallest denomination. Optional. Set this only for the upto (metered) scheme, which settles through the Permit2 contract; supplying it for the exact scheme is a validation error. See Permit2 allowance for upto payments.

The response returns the following fields in paymentOutput.cryptoX402:

  • version — The x402 protocol version.

  • payload — The signed transaction proof, as a JSON object. Attach it to the X-PAYMENT header and retry the original request.

A status of PROOF_GENERATED indicates that the transaction was signed and the payment proof is included in paymentOutput.

Schemes

An x402 payload names a scheme. AgentCore payments supports the following schemes:

  • exact — Pays a fixed amount specified in the merchant’s payload. This is the default scheme, and it requires no allowance handling.

  • upto — Pays a metered amount up to a ceiling. This scheme settles through the Permit2 contract, so the payer wallet must have granted a Permit2 allowance. See Permit2 allowance for upto payments.

Permit2 allowance for upto payments

The upto scheme settles through the Permit2 contract, which moves funds with transferFrom. The payer wallet must first grant Permit2 an ERC-20 allowance, or settlement fails with a Permit2-allowance precondition error. This grant follows the same on-chain approval model as any direct Permit2 approval. For more information, see Uniswap Permit2 on the Uniswap website and the x402 upto scheme specification on the GitHub website.

To handle this, set permit2AllowanceLimit to the maximum allowance in the asset’s smallest denomination (for example, 1000000 = 1 USDC at 6 decimals). To grant an unlimited allowance, pass the maximum uint256 value as a string: 115792089237316195423570985008687907853269984665640564039457584007913129639935. When you set this field, AgentCore payments submits an on-chain approve transaction before signing. This transaction incurs blockchain network (gas) fees paid from the wallet’s native token balance.

Because approve sets, rather than adds to, the wallet’s allowance, set permit2AllowanceLimit only when the wallet needs approving (for example, its first upto payment) to avoid a redundant on-chain transaction. Omit the field to skip allowance handling entirely. This field applies only to the upto scheme; supplying it for the exact scheme is a validation error.

The following example processes an upto payment and grants an allowance of 1 USDC to Permit2. For upto, maxAmountRequired carries the ceiling the merchant advertises in its 402 response, and extra.facilitatorAddress is the settlement facilitator from that same response.

Example
AWS CLI
aws bedrock-agentcore process-payment \ --payment-manager-arn "arn:aws:bedrock-agentcore:us-west-2:123456789012:payment-manager/my-manager" \ --payment-session-id "payment-session-abc123" \ --payment-instrument-id "payment-instrument-xyz789" \ --payment-type "CRYPTO_X402" \ --payment-input '{ "cryptoX402": { "version": "2", "payload": { "scheme": "upto", "network": "eip155:8453", "maxAmountRequired": "3495", "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "payTo": "0x99935f281d3ED1E804bF1413b76E0B03e1fed4F9", "maxTimeoutSeconds": 300, "extra": {"name": "USDC", "version": "2", "facilitatorAddress": "0x8581784D3E598cCa3482375CFF2409Ac9DD8c402"} }, "permit2AllowanceLimit": "1000000" } }' \ --client-token "$(uuidgen)" \ --region us-west-2
AWS SDK
import uuid 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": "upto", "network": "eip155:8453", "maxAmountRequired": "3495", "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "payTo": "0x99935f281d3ED1E804bF1413b76E0B03e1fed4F9", "maxTimeoutSeconds": 300, "extra": {"name": "USDC", "version": "2", "facilitatorAddress": "0x8581784D3E598cCa3482375CFF2409Ac9DD8c402"}, }, "permit2AllowanceLimit": "1000000", } }, clientToken=str(uuid.uuid4()), )

Limitations

  • The permit2AllowanceLimit field is valid only for the upto scheme. Supplying it for the exact scheme returns a ValidationException.

For x402 payment request validation errors and their resolutions, see x402 payment request errors. For payment processing errors and their resolutions, see Payment processing errors.

Pay an MPP challenge

When a merchant returns a WWW-Authenticate: Payment challenge in its 402 Payment Required response, forward the challenge verbatim in paymentInput.mpp. AgentCore payments parses the challenge, checks the budget, signs with the wallet, and returns a ready-to-send Authorization header value. AgentCore payments handles the header parsing, base64url decoding, and signing, so you do not need to perform these operations.

Request and response

Provide the following fields in paymentInput.mpp:

  • version — The MPP protocol version (for example, 1). Required.

  • wwwAuthenticateHeaders — The raw WWW-Authenticate: Payment header value from the merchant’s 402 response, passed verbatim. Provide exactly one header. Required.

  • buyerPaysGasFees — Whether to authorize paying blockchain network (gas) fees from the buyer’s wallet when the seller does not sponsor them. Optional. Omitted or false means the buyer declines. See Network fee consent.

The response returns the following fields in paymentOutput.mpp:

  • version — The MPP protocol version.

  • selectedPaymentId — The id of the challenge that AgentCore payments paid, echoed from the input challenge so that you can correlate the result without decoding the credential.

  • paymentCredential — The ready-to-send Authorization header value, in the form Payment <base64url-token>. Attach it as the Authorization header and retry the original request.

Important

Do not decode or modify paymentCredential. It embeds the original challenge and the signed payload, and the merchant’s HMAC binds to those exact bytes. Attach the value as returned.

The following example processes an MPP challenge. Set --payment-type "MPP" and forward the merchant’s WWW-Authenticate: Payment challenge verbatim in paymentInput.mpp.wwwAuthenticateHeaders (exactly one header).

Example
AWS CLI
aws bedrock-agentcore process-payment \ --payment-manager-arn "arn:aws:bedrock-agentcore:us-west-2:123456789012:payment-manager/my-manager" \ --payment-session-id "payment-session-abc123" \ --payment-instrument-id "payment-instrument-xyz789" \ --payment-type "MPP" \ --payment-input '{ "mpp": { "version": "1", "wwwAuthenticateHeaders": [ "Payment id=\"c1\", realm=\"seller.example.com\", method=\"evm\", intent=\"charge\", request=\"eyJhbW91bnQiOiIxMDAwMDAifQ\"" ] } }' \ --client-token "$(uuidgen)" \ --region us-west-2
AWS SDK
import uuid payment = dp_client.process_payment( userId="test-user-123", paymentManagerArn=PAYMENT_MANAGER_ARN, paymentSessionId=SESSION_ID, paymentInstrumentId=INSTRUMENT_ID, paymentType="MPP", paymentInput={ "mpp": { "version": "1", "wwwAuthenticateHeaders": [ 'Payment id="c1", realm="seller.example.com", method="evm", ' 'intent="charge", request="eyJhbW91bnQiOiIxMDAwMDAifQ"' ], } }, clientToken=str(uuid.uuid4()), )

Response:

{ "processPaymentId": "12345678-1234-1234-1234-123456789012", "paymentManagerArn": "arn:aws:bedrock-agentcore:us-west-2:123456789012:payment-manager/my-manager-a1b2c3d4e5", "paymentSessionId": "payment-session-abc123def4567", "paymentInstrumentId": "payment-instrument-xyz789abc1234", "paymentType": "MPP", "status": "PROOF_GENERATED", "paymentOutput": { "mpp": { "version": "1", "selectedPaymentId": "c1", "paymentCredential": "Payment <base64url-token>" } }, "createdAt": "2025-07-15T10:35:00Z", "updatedAt": "2025-07-15T10:35:02Z" }

A status of PROOF_GENERATED indicates the credential was signed and is included in paymentOutput.mpp.paymentCredential.

Methods and tokens

An MPP challenge names a payment method. AgentCore payments supports the following methods for the charge intent:

  • evm — Canonical USDC only. The challenge must include methodDetails.chainId and realm.

  • tempo — Any Tempo chain, selected by methodDetails.chainId, using the network’s recognized USDC-equivalent token.

  • solana — The mainnet and devnet networks, with server-sponsored fees only.

The payment instrument’s blockchain network must match the challenge method. Provider support depends on the connector type:

Method Coinbase CDP Stripe (Privy)

evm

Supported

Supported

tempo

Supported

Supported

solana

Not supported

Supported

Network fee consent

Blockchain network (gas) fees are separate from the challenge amount. A challenge advertises who sponsors them through its methodDetails.feePayer flag:

  • methodDetails.feePayer=true — The seller sponsors the network fees. buyerPaysGasFees has no effect.

  • methodDetails.feePayer=false or absent — The buyer pays the network fees from the paying wallet, in addition to the payment amount. Because that cost is not visible in the challenge amount, AgentCore payments signs only if you set buyerPaysGasFees=true; otherwise it returns a ValidationException. For the tempo method, this consent is required whenever the seller does not sponsor fees.

The evm method needs no fee consent, because the facilitator broadcasts the transaction and pays the gas. The solana method supports only server-sponsored fees today.

Limitations

  • AgentCore payments fulfills exactly one challenge per ProcessPayment call. Provide a single header in wwwAuthenticateHeaders.

  • Only the charge intent and pull mode are supported.

  • MPP challenges are short-lived. If the challenge has expired, AgentCore payments returns a ValidationException and consumes no budget. Request the paid resource again to obtain a fresh challenge, then retry.

For MPP challenge validation errors and their resolutions, see MPP challenge errors.

Framework integrations

For full reference documentation including error handling, configuration options, and built-in tools, see Framework integrations.

Framework Integration type Reference

Strands Agents

Plugin (hook-based)

Interrupt handling, config options, built-in tools

LangGraph

Middleware (wraps tool calls)

Error callbacks, allowlists, async support, config options