Pay with x402

Learn how to pay for x401 presentations with x402.

x401 Verifiers whose Proof account has no credit card or bank account on file pay for presentations with x402. Proof delivers their vp_token with both signature segments removed, and the Verifier fetches them from the x401 Signatures endpoint, paying in USDC. The claims stay readable, but the presentation is not cryptographically verifiable until the signatures are restored.

The Proof SDK fetches the signatures and pays with x402 automatically for you when you call verifyVPToken with an x402-capable fetch. See Pay with x402 to set it up.

User agentYour endpointProof APIGET /protected + PROOF-RESPONSE1Decode vp_token · read proof.com#sig-12POST /x401-signatures + client assertion3Only when payment is due402 + PAYMENT-REQUIRED4POST /x401-signatures + PAYMENT-SIGNATURE5Settle USDC payment6200 + signatures + PAYMENT-RESPONSE7Restore signatures · verify vp_token8200 + protected resource9x401x401 Signatures endpointSteps 2 to 8 are handled by the Proof SDK

Detached-signature presentation

The vp_token keeps the format described in SD-JWT VC Format, except that the Issuer-Signed JWT and the Key Binding JWT have an empty signature segment:

<issuer-header>.<issuer-payload>.~<Disclosure 1>~...~<Disclosure n>~<kb-header>.<kb-payload>.

The Key Binding JWT header carries a critical header parameter (RFC 7515 §4.1.11) holding the id of the signature record:

{
  "typ": "kb+jwt",
  "alg": "ES256",
  "crit": ["proof.com#sig-1"],
  "proof.com#sig-1": "<record id>"
}
  • The signatures are available for 1 hour after the presentation is created.
  • Verifiers MUST reject a Key Binding JWT whose crit lists a header parameter they do not implement.
  • Attempting to verify the vp_token without fetching the signature segments first results in failure.

Pay with x402

Proof implements x402 version 2 with the exact scheme and USDC.

EnvironmentNetworkpayTo
productionBase · eip155:84530x7f3bb9341698005d0b557550f4a3690388400a2f
sandboxBase Sepolia (testnet USDC) · eip155:845320x3b0b371ae3cb08f272b87319684f6518b3b313a0
  1. Fetch the signature segments from the x401 Signatures endpoint, documented in the API reference. The request carries the record id and a private_key_jwt client assertion (RFC 7523) signed with a key published in the jwks of your OAuth Client ID Metadata Document. The endpoint responds 402 Payment Required with the payment requirements in its PAYMENT-REQUIRED header.

    POST https://api.proof.com/verifiable-credentials/v1/x401-signatures

  2. Sign an EIP-3009 transferWithAuthorization for the accepts entry, wrap it in an x402 payment payload and resend the same request with the payload base64-encoded in the PAYMENT-SIGNATURE header.

  3. Proof settles the payment and responds 200 with the signatures and a PAYMENT-RESPONSE header. Payment is required once per presentation.

x402 client libraries such as @x402/fetch handle these steps for you. See Pay with x402 to wire one into the Proof SDK.

Restore and verify

Set issuer_signature as the third segment of the first ~ part and kb_signature as the third segment of the last ~ part:

<issuer-header>.<issuer-payload>.<issuer_signature>~<Disclosure 1>~...~<Disclosure n>~<kb-header>.<kb-payload>.<kb_signature>

Then run the checks of Validation on the complete presentation. Comparing the nonce of the Key Binding JWT with the nonce of your request remains your responsibility.


See also: x401 · Verify a Credential (OID4VP) · SD-JWT VC Format · Proof Certificate Authority


Did this page help you?