> ## Documentation Index
> Fetch the complete documentation index at: https://docs.x84.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Verify an x402 v2 payment payload

> Deserializes and validates a Solana VersionedTransaction against the payment requirements.

**Standard x402 flow:**
1. Deserializes the base64-encoded transaction from `payload.transaction`
2. Validates only allowed program IDs (SPL Token, ComputeBudget, Memo)
3. Finds the SPL Token TransferChecked instruction and validates amount, mint, and destination
4. Confirms the fee payer matches the facilitator public key
5. Rejects already-signed transactions (replay prevention)

**x84 extensions (optional):**
If `extensions.mode` is present, additional verification runs:
- **atomic**: Confirms on-chain tx signature + receipt PDA exists
- **attestation**: Confirms tx signature + receipt PDA on-chain
- **delegated**: Validates delegation PDA (client-side) or ed25519 signature with 60s timestamp window (server-side)

**v1 backward compatibility:** Accepts a base64-encoded JSON string in `paymentPayload` for legacy clients.



## OpenAPI

````yaml https://facilitator.x84.ai/openapi.yaml post /verify
openapi: 3.0.0
info:
  title: x84 Facilitator
  description: >-
    ## x402 v2 Payment Facilitator


    The x84 Facilitator verifies and settles USDC payments on Solana following
    the [Coinbase x402 v2 protocol](https://github.com/coinbase/x402).


    ### Endpoints


    | Method | Path | Description |

    |--------|------|-------------|

    | `GET` | `/supported` | Discover supported payment kinds, extensions, and
    signer keys |

    | `POST` | `/verify` | Verify a payment payload (deserialize tx, validate
    instructions) |

    | `POST` | `/settle` | Co-sign as fee payer and submit to Solana |


    ### x84 Extensions


    On top of standard x402 SVM exact payments, the facilitator supports
    x84-specific settlement modes via the `extensions` field:


    - **x84-atomic** — CPI receipt on-chain (tx already submitted by client)

    - **x84-attestation** — Attestation receipt on-chain

    - **x84-delegated** — Delegation-based vault settlement (client-side or
    server-side with ed25519 proof)


    ### v1 Backward Compatibility


    The `paymentPayload` field accepts both:

    - **v2 (recommended)**: Structured `PaymentPayload` object with
    `x402Version`, `accepted`, `payload`, and optional `extensions`

    - **v1 (legacy)**: Base64-encoded JSON string (automatically normalized to
    v2 internally)
  version: 0.2.0
  contact: {}
servers:
  - url: https://facilitator.x84.ai
    description: Endpoint
security: []
tags:
  - name: x402
    description: x402 v2 payment verification and settlement
externalDocs:
  description: x402 Protocol Specification
  url: https://github.com/coinbase/x402
paths:
  /verify:
    post:
      tags:
        - x402
      summary: Verify an x402 v2 payment payload
      description: >-
        Deserializes and validates a Solana VersionedTransaction against the
        payment requirements.


        **Standard x402 flow:**

        1. Deserializes the base64-encoded transaction from
        `payload.transaction`

        2. Validates only allowed program IDs (SPL Token, ComputeBudget, Memo)

        3. Finds the SPL Token TransferChecked instruction and validates amount,
        mint, and destination

        4. Confirms the fee payer matches the facilitator public key

        5. Rejects already-signed transactions (replay prevention)


        **x84 extensions (optional):**

        If `extensions.mode` is present, additional verification runs:

        - **atomic**: Confirms on-chain tx signature + receipt PDA exists

        - **attestation**: Confirms tx signature + receipt PDA on-chain

        - **delegated**: Validates delegation PDA (client-side) or ed25519
        signature with 60s timestamp window (server-side)


        **v1 backward compatibility:** Accepts a base64-encoded JSON string in
        `paymentPayload` for legacy clients.
      operationId: SettlementsController_verify
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifyPaymentDto'
      responses:
        '200':
          description: Verification result — check `isValid` to determine success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VerifyResponseDto'
              examples:
                valid:
                  summary: Valid payment
                  value:
                    isValid: true
                    payer: D6j5dis544qzYmSNixwYwBXqcDqgWiFHpi6hebPEQNVu
                invalid-amount:
                  summary: Amount mismatch
                  value:
                    isValid: false
                    invalidReason: AMOUNT_MISMATCH
                    invalidMessage: Expected amount 1000000, got 500000
                invalid-program:
                  summary: Disallowed program in transaction
                  value:
                    isValid: false
                    invalidReason: DISALLOWED_PROGRAM
                    invalidMessage: 'Disallowed program: 11111111111111111111111111111111'
                invalid-deserialize:
                  summary: Malformed transaction
                  value:
                    isValid: false
                    invalidReason: INVALID_TRANSACTION
                    invalidMessage: >-
                      Failed to deserialize transaction: Unexpected end of
                      buffer
                invalid-feepayer:
                  summary: Fee payer mismatch
                  value:
                    isValid: false
                    invalidReason: FEE_PAYER_MISMATCH
                    invalidMessage: Expected fee payer 7iRiHRnj..., got D6j5dis5...
        '400':
          description: Malformed request body
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResponseDto'
              examples:
                missing-payload:
                  summary: Missing paymentPayload
                  value:
                    statusCode: 400
                    message: >-
                      paymentPayload must be a v2 PaymentPayload object or a
                      base64-encoded v1 proof string
                    error: Bad Request
components:
  schemas:
    VerifyPaymentDto:
      type: object
      properties:
        paymentPayload:
          description: >-
            x402 v2 structured PaymentPayload object. For backward
            compatibility, a base64-encoded v1 proof string is also accepted.
          allOf:
            - $ref: '#/components/schemas/PaymentPayloadDto'
        paymentRequirements:
          description: >-
            The payment requirements issued by the resource server in the 402
            response
          allOf:
            - $ref: '#/components/schemas/PaymentRequirementsDto'
      required:
        - paymentPayload
        - paymentRequirements
    VerifyResponseDto:
      type: object
      properties:
        isValid:
          type: boolean
          description: Whether the payment payload passed verification
          example: true
        invalidReason:
          type: string
          description: Machine-readable reason code for invalid payments
          example: AMOUNT_MISMATCH
        invalidMessage:
          type: string
          description: Human-readable explanation of why verification failed
          example: Expected amount 1000000, got 500000
        payer:
          type: string
          description: Wallet address of the payer (extracted from transaction)
          example: D6j5dis544qzYmSNixwYwBXqcDqgWiFHpi6hebPEQNVu
        extensions:
          type: object
          description: Additional extension data (e.g. x84 settlement mode)
          example:
            mode: atomic
      required:
        - isValid
    BadRequestResponseDto:
      type: object
      properties:
        statusCode:
          type: number
          example: 400
        message:
          type: object
          description: Error message or array of validation messages
          example: >-
            paymentPayload must be a v2 PaymentPayload object or a
            base64-encoded v1 proof string
        error:
          type: string
          example: Bad Request
      required:
        - statusCode
        - message
        - error
    PaymentPayloadDto:
      type: object
      properties:
        x402Version:
          type: number
          description: x402 protocol version
          example: 1
        resource:
          type: string
          description: Resource URL being paid for
          example: https://api.x84.ai/a2a/agent-abc/tasks/send
        accepted:
          description: The payment requirements that were accepted by the client
          allOf:
            - $ref: '#/components/schemas/PaymentRequirementsDto'
        payload:
          description: SVM exact scheme payload containing the partially-signed transaction
          allOf:
            - $ref: '#/components/schemas/SvmExactPayloadDto'
        extensions:
          description: x84-specific payment extensions (settlement mode, receipt PDA, etc.)
          allOf:
            - $ref: '#/components/schemas/X84PaymentExtensionsDto'
      required:
        - x402Version
        - accepted
        - payload
    PaymentRequirementsDto:
      type: object
      properties:
        scheme:
          type: string
          description: Payment scheme identifier
          example: exact
          enum:
            - exact
        network:
          type: string
          description: CAIP-2 network identifier
          example: solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1
        asset:
          type: string
          description: Token mint address (e.g. USDC)
          example: Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr
        amount:
          type: string
          description: Amount in token base units (e.g. 1000000 = 1 USDC)
          example: '1000000'
        payTo:
          type: string
          description: Recipient wallet address (base58)
          example: 8VF2ZAp9C1RKeV2XmKBnCQdbhGuNZaLZ1x7mTCSGsMH9
        maxTimeoutSeconds:
          type: number
          description: Maximum time in seconds before the payment expires
          example: 60
        resource:
          type: string
          description: Resource URL being paid for
          example: https://api.x84.ai/a2a/agent-abc/tasks/send
        description:
          type: string
          description: Human-readable description of the payment
          example: Query agent-abc for market analysis
        extra:
          description: Scheme-specific extra fields and x84 extensions
          allOf:
            - $ref: '#/components/schemas/PaymentRequirementsExtraDto'
      required:
        - scheme
        - network
        - asset
        - amount
        - payTo
    SvmExactPayloadDto:
      type: object
      properties:
        transaction:
          type: string
          description: >-
            Base64-encoded Solana VersionedTransaction (partially signed by
            payer)
          example: >-
            AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjwuBdojnm...
      required:
        - transaction
    X84PaymentExtensionsDto:
      type: object
      properties:
        mode:
          type: string
          description: x84 settlement mode
          enum:
            - atomic
            - attestation
            - delegated
          example: atomic
        receiptPda:
          type: string
          description: On-chain receipt PDA address
          example: 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU
        delegationPda:
          type: string
          description: On-chain delegation PDA address
          example: 9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin
        delegate:
          type: string
          description: Delegate wallet address (for delegated mode)
          example: D6j5dis544qzYmSNixwYwBXqcDqgWiFHpi6hebPEQNVu
        signature:
          type: string
          description: Base64-encoded ed25519 signature (for server-side delegated mode)
        timestamp:
          type: number
          description: Unix timestamp of delegation proof (must be within 60s)
          example: 1708700000
        paymentId:
          type: string
          description: Unique payment identifier (hex-encoded)
          example: a1b2c3d4e5f6
        txSignature:
          type: string
          description: On-chain transaction signature (for atomic/attestation modes)
          example: >-
            5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW
        payer:
          type: string
          description: Payer wallet address
          example: D6j5dis544qzYmSNixwYwBXqcDqgWiFHpi6hebPEQNVu
        amount:
          type: string
          description: Payment amount in base units
          example: '1000000'
    PaymentRequirementsExtraDto:
      type: object
      properties:
        feePayer:
          type: string
          description: Facilitator public key that will co-sign as fee payer
          example: 7iRiHRnj1NofyEZVuj86Z4s5MJwVFZVR71XuAsLnwLYX
        name:
          type: string
          description: Human-readable name for the payment requirement
          example: Agent Query Fee
        agentMint:
          type: string
          description: x84 agent NFT mint address
          example: 6s1irFAQHoiK7VLwrUQEGpN5E1MrLoo5dZVWZCAwsDZS
        programId:
          type: string
          description: x84 program ID
          example: X84XHMKT7xvjgVUXFNQLZLSdCEEZu2wAPrAeP4M9Hhi
        settlementModes:
          description: Supported x84 settlement modes
          example:
            - atomic
            - attestation
            - delegated
          type: array
          items:
            type: string

````