Skip to main content
POST
/
v1
/
verify
Verify Payment
curl --request POST \
  --url https://api.example.com/v1/verify
{
  "isValid": true,
  "message": "Payment authorization verified successfully",
  "details": {
    "verification_id": "vrf_b183c9692fac4481",
    "verified_amount": "20000",
    "verified_token": "0x036cbd53842c5426634e7929541ec2318f3dcf7e",
    "merchant_address": "0xa821f428ef8cc9f54a9915336a82220853059090",
    "payer_address": "0x78b6b8c55d5ea96be6ca8213e61b0fa53e862480",
    "verified_at": "2025-01-23T10:42:40Z"
  }
}

Endpoint

Verify that an EIP-3009 transferWithAuthorization signature is valid and meets expected criteria. Key principle: Customer authorizes payment to merchant address (not facilitator).
Verification is FREE. Only successful settlements incur the $0.01 fee.

Request Parameters

payment
object
required
Payment payload containing EIP-3009 authorization and signaturepayment.payload.authorization:
  • from: Customer address
  • to: MERCHANT address (where customer payment goes)
  • value: Payment amount in token’s smallest unit
  • validAfter: Unix timestamp (usually “0”)
  • validBefore: Unix timestamp (expiry)
  • nonce: Unique random bytes32
payment.payload.signature: EIP-712 signature from customer
requirements
object
required
Payment requirements from merchant’s 402 response
  • scheme: “exact”
  • price: “$0.02” (or atomic amount)
  • network: “eip155:84532” (CAIP-2 format)
  • payTo: Merchant address
  • token: USDC address (optional if using price)

Request Examples

curl -X POST https://facilitator.0xmeta.ai/v1/verify \
  -H "Content-Type: application/json" \
  -d '{
    "payment": {
      "x402Version": 2,
      "payload": {
        "authorization": {
          "from": "0x78b6b8c55d5ea96be6ca8213e61b0fa53e862480",
          "to": "0xA821f428Ef8cC9f54A9915336A82220853059090",
          "value": "20000",
          "validAfter": "0",
          "validBefore": "1735689600",
          "nonce": "0xee232e308a6647938a68aee1ae355b85a262e4e450b7fde55cd4e729e6444ce9"
        },
        "signature": "0x1e112204abec0856f56559b2d9a58d4e7bb5daec..."
      }
    },
    "requirements": {
      "scheme": "exact",
      "price": "$0.02",
      "network": "eip155:84532",
      "payTo": "0xA821f428Ef8cC9f54A9915336A82220853059090",
      "token": "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
    }
  }'

Response Examples

{
  "isValid": true,
  "message": "Payment authorization verified successfully",
  "details": {
    "verification_id": "vrf_b183c9692fac4481",
    "verified_amount": "20000",
    "verified_token": "0x036cbd53842c5426634e7929541ec2318f3dcf7e",
    "merchant_address": "0xa821f428ef8cc9f54a9915336a82220853059090",
    "payer_address": "0x78b6b8c55d5ea96be6ca8213e61b0fa53e862480",
    "verified_at": "2025-01-23T10:42:40Z"
  }
}

Response Fields

isValid
boolean
required
Whether the payment authorization is valid
message
string
required
Human-readable verification result
details
object
details.verification_id: Use this for settlementdetails.verified_amount: Confirmed payment amountdetails.merchant_address: Merchant receiving paymentdetails.payer_address: Customer making paymentdetails.verified_at: ISO 8601 timestamp

Verification Process


What Gets Verified

1

Signature Validation

EIP-712 signature cryptographically verified using ecrecover
2

Recipient Validation

Critical: Authorization to address must match merchant address from requirements.payToauthorization.to == requirements.payTo (merchant address)authorization.to == treasury_address (wrong!)
3

Amount Validation

Authorization value matches expected amount exactly
4

Token Validation

Token address matches expected token (if specified)
5

Expiry Check

Current time is between validAfter and validBefore
6

Nonce Uniqueness

Nonce hasn’t been used in a previous settlement

Important Notes

Customer must authorize to MERCHANT address, not facilitator.The facilitator will reject authorizations to the treasury address. This maintains x402 trust-minimization.
Verification is FREE - unlimited verifications at no cost. Only successful settlements incur the $0.01 fee (collected from merchant’s approved balance).
Save the verification_id - you’ll need it for settlement! Store it with your order/transaction record.

Common Use Cases

{
  "payment": {
    "payload": {
      "authorization": {
        "to": "0xA821f428Ef8cC9f54A9915336A82220853059090",  // Merchant
        "value": "20000",  // $0.02
        ...
      }
    }
  },
  "requirements": {
    "payTo": "0xA821f428Ef8cC9f54A9915336A82220853059090",  // Same merchant
    "token": "0x036CbD53842c5426634e7929541eC2318f3dCF7e"  // USDC Sepolia
  }
}
{
  "requirements": {
    "price": "$0.02",
    "network": "eip155:8453",  // Base Mainnet
    "payTo": "0x...",  // Merchant address
    "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"  // USDC Mainnet
  }
}

Error Prevention

1

Use Merchant Address

Always set authorization.to = merchant address (not treasury)
2

Generate Unique Nonce

const nonce = "0x" + Array.from(crypto.getRandomValues(new Uint8Array(32)))
  .map(b => b.toString(16).padStart(2, "0"))
  .join("");
3

Set Long Validity

validBefore: String(Math.floor(Date.now() / 1000) + 86400)  // 24 hours
4

Match Amounts Exactly

Ensure authorization.value matches requirements.price or amount

Next Steps

Settle Payment

Execute settlement after verification

Error Handling

Handle verification failures

Architecture

Understand payment flow

Integration Guide

Complete setup guide
Verification complete! Use the verification_id to settle the payment.