Skip to main content
POST
/
v1
/
settle
Settle x402 payment
curl --request POST \
  --url https://api.mrdn.finance/v1/settle \
  --header 'Authorization: <api-key>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "paymentPayload": {
    "x402Version": 1,
    "scheme": "exact",
    "network": "base-sepolia",
    "payload": {
      "signature": "<string>",
      "authorization": {
        "from": "<string>",
        "to": "<string>",
        "value": "<string>",
        "validAfter": "<string>",
        "validBefore": "<string>",
        "nonce": "<string>"
      }
    }
  },
  "paymentRequirements": {
    "scheme": "exact",
    "network": "<string>",
    "maxAmountRequired": "<string>",
    "resource": "<string>",
    "description": "<string>",
    "mimeType": "<string>",
    "payTo": "<string>",
    "maxTimeoutSeconds": 123,
    "asset": "<string>",
    "extra": {}
  }
}
'
{
  "success": true,
  "transaction": "<string>",
  "network": "<string>",
  "payer": "<string>",
  "errorReason": "<string>",
  "authContext": {}
}
Settle a Nanopayments Gateway (Circle Gateway batched) payment. This is the same POST /v1/settle endpoint used by the default x402 path. The facilitator inspects paymentRequirements.extra and forwards batched requests to Circle’s Gateway API instead of settling on-chain.
See Nanopayments Gateway Overview for the end-to-end flow, supported networks, and Gateway Wallet contract addresses.

Routing

A request is routed to Circle Gateway when all of the following are true:
  • paymentRequirements.extra.name === "GatewayWalletBatched"
  • paymentRequirements.extra.version === "1"
  • The network is Gateway-enabled (testnets always; mainnets gated by the facilitator’s GATEWAY_MAINNET_ENABLED flag, currently true)
If extra indicates batched but the network is not Gateway-enabled, the facilitator returns HTTP 403 with errorReason: "gateway_not_enabled".

Authentication

Requires Authorization: Bearer <api-key>. Recipient is taken from your organization settings or from paymentRequirements.extra.creditedRecipient.

Request Body

{
  "paymentPayload": {
    "x402Version": 1,
    "scheme": "exact",
    "network": "base",
    "payload": {
      "signature": "0x...",
      "authorization": {
        "from": "0x742d35Cc6634C0532925a3b8D0c4E5e6C2aE7A3e",
        "to": "0x77777777Dcc4d5A8B6E418Fd04D8997ef11000eE",
        "value": "10000",
        "validAfter": "1735689600",
        "validBefore": "1736035200",
        "nonce": "0x..."
      }
    }
  },
  "paymentRequirements": {
    "scheme": "exact",
    "network": "base",
    "maxAmountRequired": "10000",
    "amount": "10000",
    "resource": "https://example.com/api/sample",
    "description": "Batched payment for 0.01 USDC",
    "mimeType": "application/json",
    "payTo": "0xRecipient...",
    "maxTimeoutSeconds": 345600,
    "asset": "0x77777777Dcc4d5A8B6E418Fd04D8997ef11000eE",
    "extra": {
      "name": "GatewayWalletBatched",
      "version": "1",
      "verifyingContract": "0x77777777Dcc4d5A8B6E418Fd04D8997ef11000eE",
      "creditedRecipient": "0xRecipient...",
      "platform": "0x0000000000000000000000000000000000000000",
      "platformFeeBps": 0,
      "destinationChainId": 8453
    }
  }
}

Field notes

FieldNotes
paymentRequirements.assetSet to the Gateway Wallet contract for this network (used as verifyingContract in EIP-712 signing). The facilitator swaps it back to USDC before forwarding to Circle.
paymentRequirements.maxTimeoutSeconds345600 (4 days) is the recommended Circle Gateway nanopayment validity window.
payload.authorization.valueUSDC base units (6 decimals). 10000 = 0.01 USDC.
extra.name + extra.versionRequired exactly as "GatewayWalletBatched" and "1". This is the routing trigger.

Response

200: Success

The facilitator spreads Circle’s response and adds Meridian-specific fields. The exact shape is { ...gatewayResponse, settlementMethod, network, testnet, authContext } after toJsonSafe():
{
  "success": true,
  "transaction": "0xCircleSettlementTxHash...",
  "network": "base",
  "settlementMethod": "batched",
  "testnet": false,
  "authContext": {
    "authMethod": "middleware_handled",
    "timestamp": "2026-04-30T18:24:11.502Z"
  }
}
  • success and transaction (and any other fields) are forwarded from Circle.
  • settlementMethod: "batched" confirms the Circle Gateway path was taken.
  • testnet is true when network is one of arc-testnet, base-sepolia, optimism-sepolia, or fluent-testnet.
  • authContext.authMethod is the literal string "middleware_handled".
  • The settle path’s authContext does not include organizationId (unlike verify).

400: Error from Circle Gateway

When Circle’s response has success: false, the facilitator forwards it with HTTP 400. The shape is { ...gatewayResponse, settlementMethod, network, testnet } (no authContext):
{
  "success": false,
  "settlementMethod": "batched",
  "network": "base",
  "testnet": false,
  "...": "all other fields are forwarded from Circle (errorReason, message, etc.)"
}

403: Network not enabled

{
  "success": false,
  "errorReason": "gateway_not_enabled",
  "error": "Circle Gateway is not supported for network \"<network>\".",
  "transaction": "",
  "network": "<network>"
}

500: Facilitator-side failure forwarding to Circle

{
  "success": false,
  "errorReason": "batched_settle_error",
  "error": "<error.message or 'Unknown batched settlement error'>",
  "transaction": "",
  "network": "<network>"
}

Error Codes

  • gateway_not_enabled: paymentRequirements.extra matched batched but isGatewayEnabledForNetwork(network) returned false.
  • batched_settle_error: forwarding to Circle threw before a response could be parsed (network error, SDK exception, etc.).
  • Any errorReason Circle returns: passed through verbatim alongside settlementMethod: "batched".

Authorizations

Authorization
string
header
required

Body

application/json
paymentPayload
object
required

Payload accepted by POST /v1/settle. Permit2 is currently settle-only; the deprecated POST /v1/verify endpoint still uses the legacy PaymentPayload schema.

paymentRequirements
object
required

Response

Payment settlement result

success
boolean
required
transaction
string
required

Transaction hash on success. Empty string on failure.

network
string
required
payer
string
errorReason
string
authContext
object