Subchapter 23.6
references/agentcore-payments-wiring.mdMarkdown12 KBView on GitHub
Once the developer confirms delegation and funding are done, modify their existing agent code to add a custom x402-aware fetch tool.
Find the agent’s entrypoint file (e.g., main.py, app.py, or the file containing the constructor). Based on the framework detected in Step 1, use the appropriate pattern below.
Assets
Kb Shim PyAgent(...)Why a custom tool instead of the AgentCorePaymentsPlugin? The
AgentCorePaymentsPluginworks by intercepting tool results via anafter_tool_callhook. It only works when the tool surfaces the full HTTP response. Many tools do not expose response headers where the x402 challenge often lives.The custom
x402_fetchtool handles the full flow internally: request → detect 402 → extract challenge (body OR header) → ProcessPayment → build proof → retry with fresh client → return content.Critical: Use a fresh httpx client for the retry. Some merchants set cookies on the 402 response that cause the retry to fail if sent back.
Version-aware proof. The tool reads
x402Versionfrom the challenge and builds the matching proof: v1 sends anX-PAYMENTheader with a flat proof (top-levelscheme/network), v2 sends aPAYMENT-SIGNATUREheader whereacceptedis a top-level sibling ofpayloadandpayloadholds onlysignature+authorization(no top-levelscheme/network). TheProcessPaymentinput is the same for both (always CAIP-2 network); only the proof presented to the merchant differs.
import os
import json
import base64
import httpx
import boto3
# Payment configuration from environment
PAYMENT_MANAGER_ARN = os.getenv("PAYMENT_MANAGER_ARN")
PAYMENT_INSTRUMENT_ID = os.getenv("PAYMENT_INSTRUMENT_ID")
PAYMENT_SESSION_ID = os.getenv("PAYMENT_SESSION_ID")
PAYMENT_USER_ID = os.environ.get("PAYMENT_USER_ID") # Required — no insecure default
REGION = os.getenv(
from strands import Agent, tool
@tool
def x402_fetch(url: str, method: str = "GET") -> str:
"""Fetch a URL with automatic x402 payment handling.
If the endpoint returns 402 Payment Required with an x402 challenge,
this tool automatically processes the payment and retries with proof.
Args:
url: The URL to fetch
method: HTTP method (GET, POST, etc.)
"""
return _x402_fetch_impl(url, method)
agent = Agent(
model="<model_id>",
tools=[x402_fetch],
system_prompt=(
"You are a helpful assistant that can access paid APIs and content. "
"Use the x402_fetch tool to access URLs that may require payment — "
"it handles x402 payments automatically."
),
)from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent
from langchain_aws import ChatBedrock
@tool
def x402_fetch(url: str, method: str = "GET") -> str:
"""Fetch a URL with automatic x402 payment handling.
If the endpoint returns 402 Payment Required with an x402 challenge,
this tool automatically processes the payment and retries with proof.
Args:
url: The URL to fetch
method: HTTP method (GET, POST, etc.)
"""
return _x402_fetch_impl(url, method)
model = ChatBedrock(model_id="<model_id>", region_name=REGION)
graph = create_react_agent(model, tools=[x402_fetch])
# Invoke:
result = graph.invoke({"messages": [("human", "Fetch https://paid-api.example.com/data")]})
print(result["messages"][-1].content)from agents import Agent, Runner, function_tool
@function_tool
def x402_fetch(url: str, method: str = "GET") -> str:
"""Fetch a URL with automatic x402 payment handling.
If the endpoint returns 402 Payment Required with an x402 challenge,
this tool automatically processes the payment and retries with proof.
Args:
url: The URL to fetch
method: HTTP method (GET, POST, etc.)
"""
return _x402_fetch_impl(url, method)
agent = Agent(
name="PaymentAgent",
instructions=(
"You are a helpful assistant that can access paid APIs and content. "
"Use the x402_fetch tool to access URLs that may require payment — "
"it handles x402 payments automatically."
),
tools=[x402_fetch],
)
# Invoke:
import asyncio
result = asyncio.run(Runner.run(agent, "Fetch https://paid-api.example.com/data"))
print(result.final_output)If the developer’s framework is not listed above, they can call _x402_fetch_impl() directly from whatever tool/function mechanism their framework provides. The core logic is pure Python with no framework dependencies.