feat: Payment Identifier Extension SDK - Python#1111
Merged
CarsonRoscoe merged 23 commits intomainfrom Feb 11, 2026
Merged
Conversation
- Add PaymentIdentifierInfo and PaymentIdentifierExtension Pydantic models - Add constants: PAYMENT_IDENTIFIER, PAYMENT_ID_MIN_LENGTH, PAYMENT_ID_MAX_LENGTH, PAYMENT_ID_PATTERN - Define PaymentIdentifierSchema type alias
- Add generate_payment_id() to create UUID v4-based payment IDs - Add is_valid_payment_id() to validate ID format (16-128 chars, alphanumeric + hyphens/underscores)
- Add payment_identifier_schema compliant with JSON Schema Draft 2020-12 - Schema validates required boolean and optional id string field
- Add ValidationResult dataclass for validation results - Add is_payment_identifier_extension() type guard - Add validate_payment_identifier() for full extension validation - Add extract_payment_identifier() to extract ID from PaymentPayload - Add extract_and_validate_payment_identifier() combined function - Add has_payment_identifier() to check extension presence - Add is_payment_identifier_required() to check requirement flag - Add validate_payment_identifier_requirement() for requirement compliance
- Add append_payment_identifier_to_extensions() to append payment ID to extensions dict - Only appends if server declared the extension - Generates new ID if not provided
- Add declare_payment_identifier_extension() to create extension declaration - Add PaymentIdentifierResourceServerExtension class implementing ResourceServerExtension protocol - Add payment_identifier_resource_server_extension singleton instance
- Export all public APIs from payment-identifier extension - Add comprehensive usage documentation with examples for servers, clients, and idempotency
- Add payment-identifier imports and exports to main extensions __init__.py - Export all constants, types, functions, and classes for public API
- Export payment_identifier.ValidationResult as ValidationResult (matches payment_identifier function return types) - Export bazaar.ValidationResult as BazaarValidationResult for explicit bazaar usage - Both ValidationResult classes are structurally equivalent (same dataclass fields) - Fixes type mismatch where payment_identifier functions returned payment_identifier.ValidationResult but ValidationResult imported from x402.extensions was bazaar.ValidationResult
…ntIdentifierValidationResult - Rename ValidationResult class to PaymentIdentifierValidationResult in payment_identifier/validation.py - Update all function return types and usages throughout validation.py - Update exports in payment_identifier/__init__.py - Update imports/exports in extensions/__init__.py - Keep ValidationResult from bazaar as default export for backward compatibility - Export PaymentIdentifierValidationResult separately for explicit payment_identifier usage - Makes naming consistent with BazaarValidationResult pattern
…ension - Add test_types.py: Test constants and Pydantic models - Add test_utils.py: Test ID generation and validation functions - Add test_validation.py: Test all validation and extraction functions - Add test_client.py: Test client-side utilities - Add test_server.py: Test server-side utilities - Tests cover all major functionality including edge cases and error handling - Follows same structure as bazaar extension tests
- Fix create_extension_with_id helper to handle invalid IDs for testing - Update test assertion to check for 'identifier' in error message - All 67 tests now passing
- Add ValidationResult = BazaarValidationResult alias after bazaar import - Fixes AttributeError when importing ValidationResult from x402.extensions - ValidationResult was imported as BazaarValidationResult but exported in __all__ - Now both ValidationResult and BazaarValidationResult are available
- Add test_exports.py to verify all items in __all__ can be imported - Tests that ValidationResult alias works correctly - Tests that 'import *' works as expected - This would have caught the ValidationResult AttributeError bug
✅ Heimdall Review Status
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…tion - Remove module-level jsonschema import that raised ImportError - Import jsonschema lazily only when schema validation is needed - Return validation error instead of raising ImportError at module level - Allows payment_identifier extension to be imported without jsonschema - Users can still use non-validation functions without optional dependency
- Remove unused variable in test_types.py - Fix import sorting in extensions/__init__.py - Add noqa comment for intentional E402 (import after alias)
Add client and server examples demonstrating how to use the payment-identifier extension for idempotent payment processing. Client example shows: - Generating payment IDs with generate_payment_id() - Using on_before_payment_creation hook to inject the ID - Making duplicate requests to demonstrate cache behavior Server example shows: - Declaring extension support with declare_payment_identifier_extension() - Extracting payment IDs with extract_payment_identifier() - Caching responses after settlement for idempotency
Contributor
|
@apmcdermott Please add a changelog fragment |
CarsonRoscoe
approved these changes
Feb 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds Python implementation of
payment-identifierextension for idempotency keys in payment requests. Followsbazaarextension patterns and matches TypeScript implementation.Structure
Key Implementation Decisions
jsonschemaimport: Only imported when schema validation is needed, allowing module import without optional dependencyPaymentIdentifierValidationResultavoids conflict withbazaar.ValidationResult;ValidationResultalias maintained for backward compatibility__all__exports are importableFiles Changed
New:
python/x402/extensions/payment_identifier/(6 modules)python/x402/tests/unit/extensions/payment_identifier/(6 test files)Modified:
python/x402/extensions/__init__.py- Added exportspython/x402/tests/unit/extensions/test_exports.py- Export verificationRelated
specs/extensions/payment_identifier.mdtypescript/packages/extensions/src/payment-identifier/Checklist