Payment verification on server

If we received a payment in the X-PAYMENT header, the server should now checked if it fulfills the corresponding requirement. The server can verify if the Payment Payload is valid either via local verification or by posting the Payment Payload and Payment Requirements to the /verify endpoint of a facilitator like https://www.x402.org/facilitator/verify

The documentation explaining how to interact with the /verify endpoint is here: https://github.com/coinbase/x402?tab=readme-ov-file#facilitator-types--interface. This is what we have to send:

{
  "x402Version": 1,
  "paymentPayload": {
    "x402Version": 1,
    "scheme": "exact",
    "network": "base-sepolia",
    "payload": {
      "signature": "0xc2c261db2f352e47049c68a9f96be3a46f0dda5138ec04fc9a0462f0d32c531d31a31b26c1b7852978b9db3ccc5ea4839de25ca4c17fee47f7344d420128ceb11b",
      "authorization": {
        "from": "0x2980bc24bBFB34DE1BBC91479Cb712ffbCE02F73",
        "to": "0x2980bc24bBFB34DE1BBC91479Cb712ffbCE02F73",
        "value": "1000",
        "validAfter": "1747601321",
        "validBefore": "1747601441",
        "nonce": "0xa5f2264bcb079c96f07d9fe1378f5f846e3acd5ea29024d740cec881e2e85fe6"
      }
    }
  },
  "paymentRequirements": {
    "scheme": "exact",
    "network": "base-sepolia",
    "maxAmountRequired": "1000",
    "resource": "http://localhost:4021/weather",
    "description": "",
    "mimeType": "",
    "payTo": "0x2980bc24bBFB34DE1BBC91479Cb712ffbCE02F73",
    "maxTimeoutSeconds": 60,
    "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
    "extra": {
      "name": "USDC",
      "version": "2"
    }
  }
}

And this is the kind of result we expect:

{
  "isValid": false,
  "invalidReason": "invalid_scheme",
  "payer": "0x2980bc24bBFB34DE1BBC91479Cb712ffbCE02F73"
}

You can test it with curl:

curl -X POST https://www.x402.org/facilitator/verify \
  -H "Accept: application/json, text/plain, */*" \
  -H "Content-Type: application/json" \
  -H "User-Agent: axios/1.8.4" \
  -H "Accept-Encoding: identity" \
  -d '{
  "x402Version": 1,
  "paymentPayload": {
    "x402Version": 1,
    "scheme": "exact",
    "network": "base-sepolia",
    "payload": {
      "signature": "0xc2c261db2f352e47049c68a9f96be3a46f0dda5138ec04fc9a0462f0d32c531d31a31b26c1b7852978b9db3ccc5ea4839de25ca4c17fee47f7344d420128ceb11b",
      "authorization": {
        "from": "0x2980bc24bBFB34DE1BBC91479Cb712ffbCE02F73",
        "to": "0x2980bc24bBFB34DE1BBC91479Cb712ffbCE02F73",
        "value": "1000",
        "validAfter": "1747601321",
        "validBefore": "1747601441",
        "nonce": "0xa5f2264bcb079c96f07d9fe1378f5f846e3acd5ea29024d740cec881e2e85fe6"
      }
    }
  },
  "paymentRequirements": {
    "scheme": "exact",
    "network": "base-sepolia",
    "maxAmountRequired": "1000",
    "resource": "http://localhost:4021/weather",
    "description": "",
    "mimeType": "",
    "payTo": "0x2980bc24bBFB34DE1BBC91479Cb712ffbCE02F73",
    "maxTimeoutSeconds": 60,
    "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
    "extra": {
      "name": "USDC",
      "version": "2"
    }
  }
}'

Last updated