Skip to content

feat: add x402 payment agent sample#4937

Open
up2itnow0822 wants to merge 3 commits intogoogle:mainfrom
up2itnow0822:feat/x402-payment-agent
Open

feat: add x402 payment agent sample#4937
up2itnow0822 wants to merge 3 commits intogoogle:mainfrom
up2itnow0822:feat/x402-payment-agent

Conversation

@up2itnow0822
Copy link

Summary

Adds a sample agent that demonstrates autonomous API payment handling using the x402 protocol.

What it does

When fetching from a premium API, the agent:

  1. Receives HTTP 402 (Payment Required) with x402 payment requirements
  2. Evaluates the cost against a configurable spending policy (per-transaction cap, daily limit, recipient allowlist)
  3. Signs a USDC payment proof
  4. Retries the request with the payment header attached

Tools

  • fetch_paid_api — handles the full 402 → evaluate policy → pay → retry cycle
  • get_spending_status — reports daily spend, remaining budget, and recent payments

Testing

Includes mock_server.py for local e2e testing:

# Terminal 1: start mock server
python contributing/samples/x402_payment_agent/mock_server.py

# Terminal 2: run agent
adk web
# Then ask: "Fetch market data from http://localhost:8402/v1/market-data"

The mock server returns HTTP 402 for unauthenticated requests and HTTP 200 with sample market data when a valid X-PAYMENT header is present.

Testing plan

  • Mock server verified: 402 without payment, 200 with valid payment header
  • Agent syntax verified (ast.parse + py_compile)
  • Formatted with pyink + isort per project config

Why this matters

Four major agent toolkits hit trending this week with zero payment infrastructure. As agents start accessing premium APIs and services, they need a standard way to handle paywalled endpoints. The x402 protocol (by Coinbase) provides this — HTTP 402 as the native payment negotiation mechanism.

This pattern was recently merged into NVIDIA's NeMo Agent Toolkit and is adapted here for the ADK framework.

Files

contributing/samples/x402_payment_agent/
├── __init__.py       # Package init
├── agent.py          # Agent definition + tools
└── mock_server.py    # Mock x402 server for testing

Adds a sample agent that handles HTTP 402 (Payment Required) responses
using the x402 protocol. When fetching from a paid API, the agent:

1. Receives HTTP 402 with payment requirements
2. Evaluates cost against configurable spending policy (per-tx cap,
   daily limit, recipient allowlist)
3. Signs a USDC payment proof
4. Retries the request with the payment header

Two tools:
- fetch_paid_api: handles the full 402→pay→retry cycle
- get_spending_status: reports daily spend and recent payments

Includes mock_server.py for local testing (402 without payment,
200 with valid X-PAYMENT header).

This pattern was recently merged into NVIDIA's NeMo Agent Toolkit
Examples (NVIDIA/NeMo-Agent-Toolkit-Examples#17) and is adapted
here for the Google ADK agent framework.
@google-cla
Copy link

google-cla bot commented Mar 21, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@adk-bot
Copy link
Collaborator

adk-bot commented Mar 21, 2026

Response from ADK Triaging Agent

Hello @up2itnow0822, thank you for your contribution!

Before we can review this PR, please address the following points from our contribution guidelines:

  • Sign the Contributor License Agreement (CLA): It appears you haven't signed the CLA yet. You can do so at https://cla.developers.google.com/.
  • Associate an Issue: For new features, please create an issue that describes the feature and associate it with this PR.
  • Provide Testing Evidence: Could you please provide logs or screenshots from running the mock_server.py and the agent to demonstrate the functionality?

This information will help us to review your PR more efficiently. Thanks!

@up2itnow0822
Copy link
Author

Testing Evidence

Associated issue: #4938

Mock server output

$ python contributing/samples/x402_payment_agent/mock_server.py
INFO:__main__:Mock x402 server on http://localhost:8402
INFO:__main__:  GET /v1/market-data → 402 (no payment) or 200 (with payment)

Without payment (HTTP 402):

$ curl -s http://localhost:8402/v1/market-data
{
  "amount": "0.05",
  "payTo": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18",
  "asset": "USDC",
  "network": "base",
  "description": "Premium market data — single query"
}

With payment (HTTP 200):

$ curl -s http://localhost:8402/v1/market-data -H 'X-PAYMENT: {"amount":"0.05","recipient":"0x742d","asset":"USDC","proof":"abc123"}'
INFO:__main__:Payment accepted: 0.05 USDC
{
  "symbol": "NVDA",
  "price": 142.5,
  "volume": 45000000,
  "change_pct": 3.2,
  "timestamp": "2026-03-21T00:00:00Z",
  "source": "mock-x402-server"
}

Code verification:

$ python -m py_compile contributing/samples/x402_payment_agent/__init__.py  # OK
$ python -m py_compile contributing/samples/x402_payment_agent/mock_server.py  # OK
$ python -c "import ast; ast.parse(open('contributing/samples/x402_payment_agent/agent.py').read())"  # OK

Formatting:

$ pyink --config pyproject.toml contributing/samples/x402_payment_agent/*.py
All done! ✨ 🍰 ✨
$ isort --check contributing/samples/x402_payment_agent/*.py
# No changes needed

Improvements based on community feedback (google#4938):

1. Structured payment events — every payment decision emits a typed
   event (payment_required, payment_receipt, payment_denied,
   payment_approval_required) with request_id for end-to-end
   correlation and operator audit.

2. Human-in-the-loop for above-cap payments — instead of silently
   denying payments that exceed the per-transaction cap, hold them
   for explicit approval via the new approve_payment tool. Hard
   denials (daily limit, bad recipient) remain automatic.

3. Request ID tracking — unique request_id flows through all events
   and the spending log for reconciliation.

4. Pending approvals in status — get_spending_status now shows
   held payments awaiting approval and session audit event count.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants