Skip to content

Conversation

@Darjiro
Copy link

@Darjiro Darjiro commented Dec 18, 2025

Python SDK V2 Upgrade

Description

Note

The large diff size (+20k lines) is primarily due to newly generated uv.lock files for the added examples and metadata updates (upload-time) in the main SDK lockfile.

Python SDK Changes

src/x402/clients/base.py

  • fix: Include 'accepted' field in PaymentPayload during header creation to comply with V2 spec.
  • refactor: Update field access to use 'amount' instead of legacy 'maxAmountRequired'.

src/x402/clients/ (requests.py & httpx.py)

  • feat: Prioritize PAYMENT-REQUIRED header for 402 responses.
  • fix: Send PAYMENT-SIGNATURE header instead of legacy X-Payment.
  • fix: Expose PAYMENT-RESPONSE header (requests only).
  • refactor: Use safe_base64_decode for robust parsing.

src/x402/exact.py

  • refactor: Update field access to use 'amount' instead of legacy 'maxAmountRequired'.

src/x402/facilitator.py

  • fix: Add exclude_none=True to model_dump() in verify() and settle() to match TypeScript SDK behavior and ensure clean payloads.

src/x402/paywall.py

  • docs: Update comments to clarify that chainId, tokenAddress, and recipient injections are required for EVM_PAYWALL_TEMPLATE compatibility.
  • fix: Inject legacy fields (chainId, tokenAddress) to adapt V2 data for the Template's internal clients (which expect V1-style inputs).

src/x402/types.py

  • refactor: Remove legacy 'scheme' and 'network' fields from PaymentPayload root.
  • refactor: Remove V1 fields (resource, description, mimeType, outputSchema) from PaymentRequirements.
  • refactor: Rename 'maxAmountRequired' to 'amount' in PaymentRequirements.
  • feat: Add ResourceInfo type.
  • fix: Update X402Headers mapping to V2 standards.

src/x402/common.py

  • fix: Update find_matching_payment_requirements to exclusively check 'accepted' field logic (V2).

src/x402/networks.py & src/x402/chains.py

  • refactor: Remove legacy network slugs (e.g., 'base-sepolia'), enforcing CAIP-2 identifiers (e.g., 'eip155:84532').

src/x402/fastapi/middleware.py & src/x402/flask/middleware.py

  • fix: Enforce PAYMENT-REQUIRED (base64) and PAYMENT-RESPONSE headers.
  • fix: Remove legacy X-PAYMENT headers.
  • fix: Raise ValueError if configured for Mainnet without a Facilitator URL.
  • fix: Correct PAYMENT-REQUIRED header serialization to return full object instead of list (Flask).

New Examples

examples/python/v2/clients/

  • requests: Added simple client example using Requests library.
  • httpx: Added simple client example using HTTPX library.

examples/python/v2/servers/

  • fastapi: Added simple FastAPI server example.
  • flask: Added simple Flask server example.
  • mainnet: Added FastAPI example configured for Mainnet.
  • advanced: Added advanced server example featuring dynamic pricing, multiple payments, and delayed settlement.

Tests

Running uv run pytest - All 90 tests passed.

Test Changes:

tests/clients/test_v2_strict.py

  • test: Add new tests verifying V2 header priority.

tests/clients/test_base.py

  • test: Update assertions for PaymentPayload structure (accepted/amount fields).

tests/clients/test_requests.py

  • test: Update header assertions to PAYMENT-SIGNATURE/RESPONSE.
  • test: Update mock 402 responses to include mandatory PAYMENT-REQUIRED header.

tests/clients/test_httpx.py

  • test: Update header assertions to PAYMENT-SIGNATURE/RESPONSE.
  • test: Update mock 402 responses to include mandatory PAYMENT-REQUIRED header.

tests/test_exact.py

  • test: Update assertions for field renaming (amount).

tests/fastapi_tests/test_middleware.py

  • test: Update header assertions to PAYMENT-SIGNATURE/RESPONSE.
  • test: Add test case for Mainnet facilitator requirement.

tests/flask_tests/test_middleware.py

  • test: Update header assertions to PAYMENT-SIGNATURE/RESPONSE.
  • test: Add test case for Mainnet facilitator requirement.

tests/test_types.py

  • test: Remove assertions for legacy V1 fields.

tests/test_common.py

  • test: Update matching logic tests to use 'accepted' field structure.

tests/test_paywall.py

  • test: Verify V2 payload structure in generated configurations.

Checklist

  • I have formatted and linted my code
  • All new and existing tests pass
  • My commits are signed (required for merge) -- you may need to rebase if you initially pushed unsigned commits

SDK Changes:
src/x402/clients/base.py
- fix: Include 'accepted' field in PaymentPayload during header creation to comply with V2 spec.
- refactor: Update field access to use 'amount' instead of legacy 'maxAmountRequired'.

src/x402/clients/requests.py
- feat: Prioritize PAYMENT-REQUIRED header for 402 responses.
- fix: Send PAYMENT-SIGNATURE header instead of X-Payment.
- fix: Expose PAYMENT-RESPONSE header in Access-Control-Expose-Headers.
- refactor: Import and use safe_base64_decode for robust header parsing.

src/x402/clients/httpx.py
- feat: Prioritize PAYMENT-REQUIRED header for 402 responses.
- fix: Send PAYMENT-SIGNATURE header instead of X-Payment.
- refactor: Import and use safe_base64_decode for robust header parsing.

src/x402/exact.py
- refactor: Update field access to use 'amount' instead of legacy 'maxAmountRequired'.

src/x402/facilitator.py
- fix: Add exclude_none=True to model_dump() in verify() and settle() to match TypeScript SDK behavior and ensure clean payloads.

src/x402/paywall.py
- docs: Update comments to clarify that chainId, tokenAddress, and recipient injections are required for EVM_PAYWALL_TEMPLATE compatibility.
- fix: Inject legacy fields (chainId, tokenAddress) to adapt V2 data for the Template's internal clients (which expect V1-style inputs).

src/x402/types.py
- refactor: Remove legacy 'scheme' and 'network' fields from PaymentPayload root.
- refactor: Remove V1 fields (resource, description, mimeType, outputSchema) from PaymentRequirements.
- refactor: Rename 'maxAmountRequired' to 'amount' in PaymentRequirements.
- feat: Add ResourceInfo type.
- fix: Update X402Headers mapping to V2 standards.

src/x402/common.py
- fix: Update find_matching_payment_requirements to exclusively check 'accepted' field logic (V2).

src/x402/networks.py & src/x402/chains.py
- refactor: Remove legacy network slugs (e.g., 'base-sepolia'), enforcing CAIP-2 identifiers (e.g., 'eip155:84532').

src/x402/fastapi/middleware.py & src/x402/flask/middleware.py
- fix: Enforce PAYMENT-REQUIRED (base64) and PAYMENT-RESPONSE headers.
- fix: Remove legacy X-PAYMENT headers.
- fix: Raise ValueError if configured for Mainnet without a Facilitator URL.
- fix: Correct PAYMENT-REQUIRED header serialization to return full object instead of list (Flask).

Test Changes:
tests/clients/test_v2_strict.py
- test: Add new tests verifying V2 header priority.

tests/clients/test_base.py
- test: Update assertions for PaymentPayload structure (accepted/amount fields).

tests/clients/test_requests.py
- test: Update header assertions to PAYMENT-SIGNATURE/RESPONSE.
- test: Update mock 402 responses to include mandatory PAYMENT-REQUIRED header.

tests/clients/test_httpx.py
- test: Update header assertions to PAYMENT-SIGNATURE/RESPONSE.
- test: Update mock 402 responses to include mandatory PAYMENT-REQUIRED header.

tests/test_exact.py
- test: Update assertions for field renaming (amount).

tests/fastapi_tests/test_middleware.py
- test: Update header assertions to PAYMENT-SIGNATURE/RESPONSE.
- test: Add test case for Mainnet facilitator requirement.

tests/flask_tests/test_middleware.py
- test: Update header assertions to PAYMENT-SIGNATURE/RESPONSE.
- test: Add test case for Mainnet facilitator requirement.

tests/test_types.py
- test: Remove assertions for legacy V1 fields.

tests/test_common.py
- test: Update matching logic tests to use 'accepted' field structure.

tests/test_paywall.py
- test: Verify V2 payload structure in generated configurations.

Example Changes:
examples/python/v2/clients/
- requests: Added simple client example using Requests library.
- httpx: Added simple client example using HTTPX library.

examples/python/v2/servers/
- fastapi: Added simple FastAPI server example.
- flask: Added simple Flask server example.
- mainnet: Added FastAPI example configured for Mainnet.
- advanced: Added advanced server example featuring dynamic pricing, multiple payments, and delayed settlement.
@vercel
Copy link

vercel bot commented Dec 18, 2025

@Darjiro is attempting to deploy a commit to the Coinbase Team on Vercel.

A member of the Team first needs to authorize it.

@cb-heimdall
Copy link

cb-heimdall commented Dec 18, 2025

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 1
Sum 2

@phdargen
Copy link
Contributor

Hi @Darjiro, thanks for your contribution!

We are currently developing the v2 implementation of the core python x402 package. Once this is in place, we will coordinate with the community for the client/middleware packages, see for example
#805

@phdargen phdargen self-assigned this Dec 22, 2025
@Darjiro
Copy link
Author

Darjiro commented Dec 22, 2025

Okay, thanks. I'll take a look.

@phdargen
Copy link
Contributor

Hi @Darjiro, thanks again for your initiative!

We have a development branch for python v2 up now with the core building blocks but there is still a lot missing.
Please have a look at this PR: #841 and let me know if you are interested in working on any of the TODO items. Your contribution would be much appreciated!

Closing this now, please target the feat/python-v2-sdk branch if you open a new PR

@phdargen phdargen closed this Dec 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants