Skip to main content
Base settlement uses EIP-3009 transferWithAuthorization — a gasless USDC transfer signed by the payer and submitted by the facilitator. Endpoint: GET and POST /v1/invoices/{id}/x402/base Asset: USDC on Base (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) Network (CAIP-2): eip155:8453

1. Discovery

GET /v1/invoices/{id}/x402/base
Returns HTTP 402 with the PAYMENT-REQUIRED header (base64-encoded JSON):
{
  "x402Version": 2,
  "error": "Payment required",
  "resource": {
    "method": "POST",
    "url": "https://agents.gwop.io/v1/invoices/{id}/x402/base"
  },
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:8453",
      "amount": "5000000",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "payTo": "0x...",
      "maxTimeoutSeconds": 900,
      "extra": {
        "invoiceId": "inv_...",
        "settlementId": "req_...",
        "assetSymbol": "USDC",
        "assetDecimals": 6,
        "chain": "base",
        "name": "USD Coin",
        "version": "2",
        "assetTransferMethod": "eip3009"
      }
    }
  ]
}

Key fields

FieldDescription
amountUSDC minor units (6 decimals). "5000000" = $5.00.
assetUSDC contract address on Base.
payToMerchant’s Base receive address.
maxTimeoutSecondsTime remaining before the settlement challenge expires.
extra.settlementIdRequired in the PAYMENT-SIGNATURE. Also used for recovery.
extra.name / extra.versionEIP-712 domain fields for USDC on Base.
extra.assetTransferMethodAlways "eip3009" — signals to use transferWithAuthorization.

2. Payment signature

After reading the terms, the client constructs an EIP-3009 transferWithAuthorization and signs it with the payer’s private key. The signed authorization is sent as a base64-encoded PAYMENT-SIGNATURE header:
POST /v1/invoices/{id}/x402/base
PAYMENT-SIGNATURE: <base64>
The decoded PAYMENT-SIGNATURE JSON:
{
  "x402Version": 2,
  "resource": {
    "method": "POST",
    "url": "https://agents.gwop.io/v1/invoices/{id}/x402/base"
  },
  "accepted": {
    "scheme": "exact",
    "network": "eip155:8453",
    "extra": {
      "settlementId": "req_..."
    }
  },
  "payload": {
    "authorization": {
      "from": "0x<payer>",
      "to": "0x<merchant>",
      "value": "5000000",
      "validAfter": "0",
      "validBefore": "1735689600",
      "nonce": "0x..."
    },
    "signature": {
      "v": 27,
      "r": "0x...",
      "s": "0x..."
    }
  }
}

Required payload fields

FieldTypeDescription
payload.authorization.fromstringPayer’s address.
payload.authorization.tostringMust match payTo from discovery.
payload.authorization.valuestringMust match amount from discovery.
payload.authorization.validAfterstringUnix timestamp (usually "0").
payload.authorization.validBeforestringUnix timestamp. Must be in the future.
payload.authorization.noncestringUnique nonce (bytes32 hex).
payload.signature.vnumberECDSA v value.
payload.signature.rstringECDSA r value.
payload.signature.sstringECDSA s value.
accepted.extra.settlementIdstringThe settlementId from discovery.

3. Settlement response

On success, the server returns HTTP 200 with the PAYMENT-RESPONSE header (base64-encoded JSON):
{
  "x402Version": 2,
  "status": "settled",
  "network": "eip155:8453",
  "txHash": "0x...",
  "settlementId": "req_..."
}
The response body includes the full paid invoice details: paid_at, paid_tx_hash, payer_address, paid_amount, and tx_url (Basescan link).

Error diagnostics

Settlement errors return x402_diagnostics with a reason field:
ReasonMeaning
base_authorization_invalidAuthorization payload is malformed.
base_authorization_replayedThis authorization nonce was already used.
base_authorization_expiredvalidBefore is in the past.
resource_mismatchresource.url doesn’t match the endpoint.
chain_mismatchNetwork in signature doesn’t match /x402/base.
verification_failedOn-chain verification failed.
settlement_failedFacilitator could not settle the transaction.

Support

Having trouble with Base x402 integration? Contact support@gwop.io with your invoice ID and we’ll help debug.