Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.b402.ai/llms.txt

Use this file to discover all available pages before exploring further.

Executes on-chain settlement by calling transferWithAuthorization() on the b402 Relayer contract. The facilitator re-verifies the payload, submits the transaction, and pays gas on behalf of the payer.
POST /settle
Settlement typically completes in ~3 seconds on supported chains. The facilitator covers all gas costs.

Request Body

The request body is identical to /verify.
FieldTypeDescription
paymentPayloadobjectSigned payment data
paymentPayload.tokenstringToken contract address
paymentPayload.payloadobjectAuthorization and signature
paymentPayload.payload.authorizationobjectEIP-712 authorization fields
paymentPayload.payload.authorization.fromstringPayer wallet address
paymentPayload.payload.authorization.tostringRecipient wallet address
paymentPayload.payload.authorization.valuestringAmount in wei (uint256)
paymentPayload.payload.authorization.validAfternumberUnix timestamp, signature valid after
paymentPayload.payload.authorization.validBeforenumberUnix timestamp, signature valid before
paymentPayload.payload.authorization.noncestringRandom bytes32 nonce
paymentPayload.payload.signaturestringEIP-712 signature
paymentRequirementsobjectNetwork and contract details
paymentRequirements.networkstringTarget network ("bsc" or "base")
paymentRequirements.relayerContractstringb402 Relayer contract address

Response

Successful Settlement (200)

FieldTypeDescription
successbooleantrue
transactionstringOn-chain transaction hash
networkstringNetwork where the transaction was settled
payerstringPayer wallet address
blockNumbernumberBlock number containing the transaction

Failed Settlement (200)

FieldTypeDescription
successbooleanfalse
networkstringTarget network
errorReasonstringWhy settlement failed

What Happens On-Chain

  1. The facilitator re-runs all verification checks
  2. The facilitator calls transferWithAuthorization() on the Relayer contract with the signed authorization
  3. The Relayer contract verifies the EIP-712 signature, checks the nonce, and executes transferFrom() on the token contract
  4. The nonce is marked as used on-chain, preventing replay
  5. An AuthorizationUsed event is emitted for on-chain auditability
Always call /verify before /settle. While /settle re-verifies internally, calling /verify first lets you catch issues without consuming gas.

Examples

cURL

curl -X POST https://facilitatorv3.b402.ai/settle \
  -H "Content-Type: application/json" \
  -d '{
    "paymentPayload": {
      "token": "0x55d398326f99059fF775485246999027B3197955",
      "payload": {
        "authorization": {
          "from": "0xAbC1234567890aBcDeF1234567890AbCdEf123456",
          "to": "0x9876543210FeDcBa9876543210FeDcBa98765432",
          "value": "10000000000000000",
          "validAfter": 1709251200,
          "validBefore": 1709254800,
          "nonce": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
        },
        "signature": "0xabc123...eip712_signature"
      }
    },
    "paymentRequirements": {
      "network": "bsc",
      "relayerContract": "0xE91b564EB8DFF305Ff8efA332f84c487b9da5171"
    }
  }'

TypeScript

const response = await fetch("https://facilitatorv3.b402.ai/settle", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    paymentPayload: {
      token: "0x55d398326f99059fF775485246999027B3197955",
      payload: {
        authorization: {
          from: wallet.address,
          to: recipientAddress,
          value: "10000000000000000",
          validAfter: Math.floor(Date.now() / 1000),
          validBefore: Math.floor(Date.now() / 1000) + 3600,
          nonce: crypto.randomBytes(32).toString("hex"),
        },
        signature: eip712Signature,
      },
    },
    paymentRequirements: {
      network: "bsc", // or "base"
      relayerContract: "0xE91b564EB8DFF305Ff8efA332f84c487b9da5171",
    },
  }),
});

const result = await response.json();

if (result.success) {
  console.log("Settlement complete");
  console.log("TX:", result.transaction);
  console.log("Block:", result.blockNumber);
  console.log(`View on BscScan: https://bscscan.com/tx/${result.transaction}`);
  // For Base: https://basescan.org/tx/
} else {
  console.error("Settlement failed:", result.errorReason);
}

Verify then Settle (Full Flow)

async function verifyAndSettle(paymentPayload: object, paymentRequirements: object) {
  const body = JSON.stringify({ paymentPayload, paymentRequirements });
  const headers = { "Content-Type": "application/json" };

  // Step 1: Verify
  const verifyRes = await fetch("https://facilitatorv3.b402.ai/verify", {
    method: "POST",
    headers,
    body,
  });
  const verification = await verifyRes.json();

  if (!verification.isValid) {
    throw new Error(`Verification failed: ${verification.invalidReason}`);
  }

  // Step 2: Settle
  const settleRes = await fetch("https://facilitatorv3.b402.ai/settle", {
    method: "POST",
    headers,
    body,
  });
  const settlement = await settleRes.json();

  if (!settlement.success) {
    throw new Error(`Settlement failed: ${settlement.errorReason}`);
  }

  return settlement;
}

Error Codes

CodeHTTP StatusDescription
payment_settlement_error500Transaction submitted but reverted on-chain
blockchain_error500RPC or network-level failure (timeout, node unavailable)
signature_error400EIP-712 signature is malformed or recovery failed during re-verification
If you receive a blockchain_error, wait a few seconds and retry. Transient RPC issues typically resolve quickly.