Extensions

extensions/paymentidentifier

Package paymentidentifier implements the payment-identifier extension for x402.

import "github.com/x402-foundation/x402/go/v2/extensions/paymentidentifier"

Package paymentidentifier implements the payment-identifier extension for x402.

The payment-identifier extension enables clients to provide an idempotency key that resource servers can use for deduplication of payment requests.

Usage

Server-side (declaring the extension):

extensions := map[string]interface{}{
    paymentidentifier.PAYMENT_IDENTIFIER: paymentidentifier.DeclarePaymentIdentifierExtension(true),
}

Client-side (appending the identifier):

err := paymentidentifier.AppendPaymentIdentifierToExtensions(extensions, "")
// A new ID is generated if empty string is passed

Facilitator-side (extracting and validating):

id, err := paymentidentifier.ExtractPaymentIdentifier(payload, true)
if err != nil {
    // Handle error
}

Constants

Re-export constants and patterns from shared types for convenience

Source: extensions/paymentidentifier/types.go:9

const (
	PAYMENT_IDENTIFIER    = types.PAYMENT_IDENTIFIER
	PAYMENT_ID_MIN_LENGTH = types.PAYMENT_ID_MIN_LENGTH
	PAYMENT_ID_MAX_LENGTH = types.PAYMENT_ID_MAX_LENGTH
)

Variables

PAYMENT_ID_PATTERN is re-exported for convenience

Source: extensions/paymentidentifier/types.go:15

var PAYMENT_ID_PATTERN = types.PAYMENT_ID_PATTERN

PaymentIdentifierResourceServerExtension is the singleton instance of the payment-identifier resource server extension.

Source: extensions/paymentidentifier/server.go:25

var PaymentIdentifierResourceServerExtension = &paymentIdentifierResourceServerExtension{}

Functions

func AppendPaymentIdentifierToExtensions(extensions map[string]interface{}, id string) error

Source: extensions/paymentidentifier/client.go:35

AppendPaymentIdentifierToExtensions appends a payment identifier to the extensions object if the server declared support for the payment-identifier extension.

This function reads the server's payment-identifier declaration from the extensions, and appends the client's ID to it. If the extension is not present (server didn't declare it), the extensions are returned unchanged.

Args:

  • extensions: The extensions object from PaymentRequired (will be modified in place)
  • id: Optional custom payment ID. If empty, a new ID will be generated.

Returns:

  • Error if the provided ID is invalid

Example:

// Get extensions from server's PaymentRequired response
extensions := paymentRequired.Extensions
if extensions == nil {
    extensions = make(map[string]interface{})
}

// Append a generated ID (only if server declared payment-identifier)
err := paymentidentifier.AppendPaymentIdentifierToExtensions(extensions, "")

// Or use a custom ID
err := paymentidentifier.AppendPaymentIdentifierToExtensions(extensions, "pay_my_custom_id_12345")

func DeclarePaymentIdentifierExtension(required bool) PaymentIdentifierExtension

Source: extensions/paymentidentifier/resource_service.go:28

DeclarePaymentIdentifierExtension creates a payment-identifier extension declaration for inclusion in PaymentRequired.extensions.

Resource servers call this function to advertise support for payment identifiers. The declaration indicates whether a payment identifier is required and includes the schema that clients must follow.

Args:

  • required: Whether clients must provide a payment identifier. When true, clients must provide an id or receive a 400 Bad Request.

Returns:

  • A PaymentIdentifierExtension object ready for PaymentRequired.extensions

Example:

// Include in PaymentRequired response (optional identifier)
extensions := map[string]interface{}{
    paymentidentifier.PAYMENT_IDENTIFIER: paymentidentifier.DeclarePaymentIdentifierExtension(false),
}

// Require payment identifier
extensions := map[string]interface{}{
    paymentidentifier.PAYMENT_IDENTIFIER: paymentidentifier.DeclarePaymentIdentifierExtension(true),
}

func ExtractAndValidatePaymentIdentifier(payload x402.PaymentPayload) (string, ValidationResult)

Source: extensions/paymentidentifier/facilitator.go:187

ExtractAndValidatePaymentIdentifier extracts and validates the payment identifier from a PaymentPayload.

Args:

  • payload: The payment payload to extract from

Returns:

  • The ID (or empty string if not present)
  • ValidationResult with any errors

func ExtractPaymentIdentifier(payload x402.PaymentPayload, validate bool) (string, error)

Source: extensions/paymentidentifier/facilitator.go:124

ExtractPaymentIdentifier extracts the payment identifier from a PaymentPayload.

Args:

  • payload: The payment payload to extract from
  • validate: Whether to validate the ID before returning

Returns:

  • The payment ID string, or empty string if not present
  • Error if extraction fails or validation fails (when validate is true)

func ExtractPaymentIdentifierFromBytes(payloadBytes []byte, validate bool) (string, error)

Source: extensions/paymentidentifier/facilitator.go:158

ExtractPaymentIdentifierFromBytes extracts the payment identifier from raw PaymentPayload bytes.

This is useful for facilitators that receive the payload as raw bytes. Returns empty string for V1 payloads (which don't support extensions).

Args:

  • payloadBytes: Raw JSON bytes of the payment payload
  • validate: Whether to validate the ID before returning

Returns:

  • The payment ID string, or empty string if not present or V1 payload
  • Error if extraction fails

func ExtractPaymentIdentifierFromPaymentRequired(paymentRequiredBytes []byte) (bool, error)

Source: extensions/paymentidentifier/facilitator.go:296

ExtractPaymentIdentifierFromPaymentRequired extracts the required flag from a PaymentRequired response.

This is useful for clients to determine if they need to provide a payment identifier.

Args:

  • paymentRequiredBytes: Raw JSON bytes of the 402 PaymentRequired response

Returns:

  • Whether the server requires a payment identifier
  • Error if extraction fails

func GeneratePaymentID(prefix string) string

Source: extensions/paymentidentifier/utils.go:14

GeneratePaymentID generates a unique payment identifier with the given prefix. If prefix is empty, "pay_" is used as the default prefix.

The generated ID format is: prefix + UUID v4 without hyphens (32 hex chars) Example: "pay_7d5d747be160e280504c099d984bcfe0"

func HasPaymentIdentifier(payload x402.PaymentPayload) bool

Source: extensions/paymentidentifier/facilitator.go:216

HasPaymentIdentifier checks if a PaymentPayload contains a payment-identifier extension.

Args:

  • payload: The payment payload to check

Returns:

  • True if the extension is present

func IsPaymentIdentifierExtension(extension interface{}) bool

Source: extensions/paymentidentifier/facilitator.go:47

IsPaymentIdentifierExtension checks if an object is a valid payment-identifier extension structure.

This checks for the basic structure (info object with required boolean), but does not validate the id format if present.

Args:

  • extension: The object to check

Returns:

  • True if the object has the expected payment-identifier extension structure

func IsPaymentIdentifierRequired(extension interface{}) bool

Source: extensions/paymentidentifier/facilitator.go:229

IsPaymentIdentifierRequired checks if the server requires a payment identifier based on the extension info.

Args:

  • extension: The payment-identifier extension from PaymentRequired or PaymentPayload

Returns:

  • True if the server requires a payment identifier

func IsValidPaymentID(id string) bool

Source: extensions/paymentidentifier/utils.go:29

IsValidPaymentID validates that a payment ID meets the format requirements. Returns true if the ID is valid, false otherwise.

Validation rules:

  • Length must be between 16 and 128 characters (inclusive)
  • Must contain only alphanumeric characters, hyphens, and underscores

func PaymentIdentifierSchema() types.JSONSchema

Source: extensions/paymentidentifier/schema.go:9

PaymentIdentifierSchema returns the JSON Schema for validating payment identifier info. The schema is compliant with JSON Schema Draft 2020-12.

func ValidatePaymentIdentifier(extension interface{}) ValidationResult

Source: extensions/paymentidentifier/facilitator.go:85

ValidatePaymentIdentifier validates a payment-identifier extension object.

Checks both the structure (using JSON Schema) and the ID format.

Args:

  • extension: The extension object to validate

Returns:

  • ValidationResult with errors if invalid

func ValidatePaymentIdentifierRequirement(payload x402.PaymentPayload, serverRequired bool) ValidationResult

Source: extensions/paymentidentifier/facilitator.go:252

ValidatePaymentIdentifierRequirement validates that a payment identifier is provided when required.

Use this to check if a client's PaymentPayload satisfies the server's requirement.

Args:

  • payload: The client's payment payload
  • serverRequired: Whether the server requires a payment identifier (from PaymentRequired)

Returns:

  • ValidationResult - invalid if required but not provided

Types

type PaymentIdentifierExtension

Source: extensions/paymentidentifier/types.go:24

PaymentIdentifierExtension represents the full extension structure

type PaymentIdentifierExtension struct {
	Info   PaymentIdentifierInfo `json:"info"`
	Schema types.JSONSchema      `json:"schema"`
}
Fields
  • Info PaymentIdentifierInfo `json:"info"`
  • Schema types.JSONSchema `json:"schema"`

type PaymentIdentifierInfo

Source: extensions/paymentidentifier/types.go:18

PaymentIdentifierInfo contains the required flag and client-provided ID

type PaymentIdentifierInfo struct {
	Required bool   `json:"required"`
	ID       string `json:"id,omitempty"`
}
Fields
  • Required bool `json:"required"`
  • ID string `json:"id,omitempty"`

type ValidationResult

Source: extensions/paymentidentifier/types.go:30

ValidationResult represents the result of validating a payment identifier

type ValidationResult struct {
	Valid  bool
	Errors []string
}
Fields
  • Valid bool
  • Errors []string