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

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