Skip to main content
POST
/
v1
/
settle
Settle Payment
curl --request POST \
  --url https://api.example.com/v1/settle
{
  "success": true,
  "transaction": null,
  "message": "Settlement completed successfully",
  "details": {
    "settlement_id": "stl_xyz789",
    "verification_id": "vrf_abc123",
    "settled_amount": "20000",
    "merchant_received": 20000,
    "fee_amount_wei": 10000,
    "fee_collection_status": "collected",
    "fee_tx_hash": "0x8f3e7d2a1b9c4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f",
    "settlement_tx_hash": "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b",
    "fee_collected_first": true,
    "pricing_model": "flat_rate",
    "description": "$0.01 USDC fee collected from merchant's approved balance before settlement"
  }
}

Endpoint

Initiate settlement of a verified payment. The facilitator will:
  1. Collect $0.01 fee from merchant’s approved USDC balance
  2. Execute customer → merchant payment via 1Shot API
Fee Collection: The $0.01 fee is collected from the merchant’s pre-approved USDC balance BEFORE settlement execution.

Request Parameters

payment
object
required
Same payment payload used in verification
requirements
object
required
Same payment requirements used in verification

Request Examples

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

Response Examples

{
  "success": true,
  "transaction": null,
  "message": "Settlement completed successfully",
  "details": {
    "settlement_id": "stl_xyz789",
    "verification_id": "vrf_abc123",
    "settled_amount": "20000",
    "merchant_received": 20000,
    "fee_amount_wei": 10000,
    "fee_collection_status": "collected",
    "fee_tx_hash": "0x8f3e7d2a1b9c4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f",
    "settlement_tx_hash": "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b",
    "fee_collected_first": true,
    "pricing_model": "flat_rate",
    "description": "$0.01 USDC fee collected from merchant's approved balance before settlement"
  }
}

Response Fields

success
boolean
required
Whether settlement completed successfully
transaction
null
required
Always null (maintained for x402 compatibility)
message
string
required
Human-readable settlement result
details
object
details.settlement_id: Unique settlement identifierdetails.verification_id: Associated verification IDdetails.settled_amount: Amount settled (customer payment)details.merchant_received: Amount merchant received (same as settled_amount)details.fee_amount_wei: Fee collected from merchant (10000 = $0.01)details.fee_collection_status: “collected” | “failed”details.fee_tx_hash: On-chain transaction hash of fee collectiondetails.settlement_tx_hash: On-chain transaction hash of settlementdetails.fee_collected_first: Always true (guarantees no free service)details.pricing_model: “flat_rate”details.description: Explanation of fee collection method

Settlement Process


Settlement States


Fee Collection Details

Pre-Settlement Fee Collection

Why collect fee first? Prevents free service exploitation. If settlement executed before fee collection, merchants could intentionally cause settlement failures to get free verification service. Process:
// 1. Check merchant approval
allowance = USDC.allowance(merchant, treasury);
require(allowance >= 10000, "Insufficient allowance");

// 2. Collect fee FIRST
USDC.transferFrom(merchant, treasury, 10000);  // $0.01

// 3. THEN execute settlement
executeSettlement(authorization, signature);
If fee collection fails:
  • Settlement is blocked
  • Customer is NOT charged
  • Merchant receives error: insufficient_allowance or fee_collection_failed
If settlement fails after fee:
  • Merchant paid $0.01 for the attempt
  • This is intentional (prevents exploitation)

Handling Settlement Status

Polling for Completion

async function waitForSettlement(settlementId) {
  const maxAttempts = 60;  // 5 minutes

  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    const response = await fetch(
      `https://facilitator.0xmeta.ai/v1/settlements/${settlementId}`
    );

    const settlement = await response.json();

    if (settlement.success && settlement.details.settlement_tx_hash) {
      console.log("✅ Settlement complete:", settlement.details.settlement_tx_hash);
      return settlement;
    }

    // Wait 5 seconds before next check
    await new Promise(resolve => setTimeout(resolve, 5000));
  }

  throw new Error("Settlement timeout");
}

Common Issues

Error: fee_collection_status: insufficient_allowanceSolution: Merchant must approve facilitator:
node approve-facilitator.mjs
Error: fee_collection_failed: Insufficient USDC balanceSolution: Merchant needs to add USDC to their addressCheck balance:
node check-allowance.mjs
# Shows: USDC Balance: 0.00 USDC ← Problem
Error: settlement_failed: authorization is expiredSolution: Customer needs to create new authorization with longer validity:
validBefore: String(Math.floor(Date.now() / 1000) + 86400)  // 24 hours
Error: settlement_failed: authorization is used or canceledSolution: Generate new unique nonce for each payment:
const nonce = "0x" + Array.from(crypto.getRandomValues(new Uint8Array(32)))
  .map(b => b.toString(16).padStart(2, "0"))
  .join("");
Normal: 35-70 secondsBreakdown:
  • Fee collection: 5-10 seconds
  • Provider submission: 5-15 seconds
  • On-chain confirmation: 15-45 seconds
If longer: Check Base network status and Provider API status

On-Chain Verification

All transactions are publicly verifiable:
# Fee collection transaction
https://basescan.org/tx/{fee_tx_hash}

# Settlement transaction
https://basescan.org/tx/{settlement_tx_hash}

# Merchant address activity
https://basescan.org/address/{merchant_address}

Settlement Timing

StageTypical Duration
Fee Collection5-10 seconds
Provider Submission5-15 seconds
On-chain Confirmation15-45 seconds
Total35-70 seconds
Settlement typically completes in 35-70 seconds on Base. Use polling or webhooks to track status.

Merchant Economics

Per settlement:
Customer pays:        $0.02 (to merchant address)
Merchant receives:    $0.02 (100% of customer payment)
Fee collected:        $0.01 (from merchant's approved balance)
Net to merchant:      $0.01
Example: 1000 settlements
Gross revenue:        $20.00 (customer payments)
Facilitator fees:     $10.00 (collected via transferFrom)
Net revenue:          $10.00

Best Practices

1

Ensure Sufficient Approval

Before going live, verify merchant has approved enough USDC:
node check-allowance.mjs
# Should show: Settlements: 10000+ ✅
2

Maintain USDC Balance

Ensure merchant address has USDC for fees:
  • Minimum: 1 USDC (100 settlements)
  • Recommended: Match approval amount
3

Handle Errors Gracefully

Catch and display user-friendly error messages:
if (error.code === "insufficient_allowance") {
  alert("Merchant setup required. Please contact support.");
}
4

Monitor Settlements

Log settlement IDs and track success rates:
logger.info({
  settlement_id: settlement.details.settlement_id,
  fee_collected: settlement.details.fee_collection_status,
  settlement_tx: settlement.details.settlement_tx_hash
});

Next Steps

Verify Payment

Verify before settling

Error Handling

Handle settlement failures

Webhooks

Get settlement notifications

Architecture

Understand fee collection
Settlement complete! Customer payment delivered to merchant, fee collected from merchant’s approved balance.