Skip to content

Unify Payment Link (UPL) ​

Resolve an agent's permanent receiving endpoint and pay via the x402 protocol. No wallet address lookup required — only the target Agent ID.


Get UPL ​

Request the 402 payment requirement for a target agent. The response tells you where to send funds and how much.

bash
curl -s "https://walletapi.fluxapay.xyz/unifypaymentlink/agentid/<agentId>?amount=<atomic_units>&asset=usdc"

Path parameters ​

ParameterTypeDescription
agentIdstringThe recipient agent's agent_id (required)

Query parameters ​

ParameterTypeDescription
amountstringAmount in atomic units (required). 1 USDC = 1000000
assetstringAsset identifier (required). Only usdc is supported

Example request ​

bash
curl -s "https://walletapi.fluxapay.xyz/unifypaymentlink/agentid/bob-agent-id?amount=2000000&asset=usdc"

Response (HTTP 402) ​

The server returns HTTP 402 with a JSON body following the x402 protocol format:

json
{
  "x402Version": 1,
  "accepts": [
    {
      "scheme": "exact",
      "network": "base",
      "maxAmountRequired": "2000000",
      "resource": "https://walletapi.fluxapay.xyz/unifypaymentlink/agentid/bob-agent-id?amount=2000000&asset=usdc",
      "description": "Pay 2.00 USDC to bob-agent-id",
      "payTo": "0x1234567890abcdef1234567890abcdef12345678",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "extra": {
        "name": "USD Coin",
        "version": "2"
      }
    }
  ]
}
FieldDescription
x402VersionProtocol version (always 1)
accepts[].schemePayment scheme (exact)
accepts[].networkBlockchain network (base)
accepts[].maxAmountRequiredAmount to pay in atomic units
accepts[].resourceThe full UPL URL (use this as-is for the retry)
accepts[].descriptionHuman-readable description
accepts[].payToRecipient's current onchain wallet address
accepts[].assetUSDC contract address on Base
accepts[].extra.nameToken name (USD Coin)
accepts[].extra.versionToken version (2) — used for EIP-3009 signing

Error responses ​

StatusMeaning
400Missing amount or asset, invalid amount format, zero or negative amount, or unsupported asset
404Agent not found, agent has been deleted, or agent has no wallet linked

Error body:

json
{
  "error": "Agent not found",
  "code": "AGENT_NOT_FOUND"
}

Submit payment ​

After obtaining the 402 payload and signing the payment via POST /api/payment/x402V3Payment, retry the same UPL URL with the X-Payment header.

bash
curl -H "X-Payment: <xPaymentB64>" \
  "https://walletapi.fluxapay.xyz/unifypaymentlink/agentid/<agentId>?amount=<atomic_units>&asset=usdc"

Headers ​

HeaderDescription
X-PaymentBase64-encoded payment proof from x402V3Payment (required)

Example request ​

bash
curl -H "X-Payment: eyJ4NDAyVmVyc2lvbiI6MSwic2NoZW..." \
  "https://walletapi.fluxapay.xyz/unifypaymentlink/agentid/bob-agent-id?amount=2000000&asset=usdc"

Response (HTTP 200) ​

json
{
  "success": true,
  "txHash": "0xabc123...",
  "settledAmount": "2000000",
  "network": "base",
  "payer": "0x...",
  "payee": "0x..."
}
FieldDescription
successtrue if the onchain transfer succeeded
txHashTransaction hash on Base — use a block explorer to verify
settledAmountAmount transferred in atomic units
networkNetwork where the transfer was executed
payerSender's onchain address
payeeRecipient's onchain address

Error responses ​

StatusMeaning
400Invalid or malformed X-Payment header
402Payment proof is missing, expired, or insufficient
404Agent not found
500Onchain transfer failed (e.g., insufficient USDC balance in the sender's wallet)

End-to-end example ​

Complete flow from constructing the URL to receiving a confirmed transfer.

1. Get the 402 payload ​

bash
UPL_URL="https://walletapi.fluxapay.xyz/unifypaymentlink/agentid/bob-agent-id?amount=1000000&asset=usdc"

PAYLOAD=$(curl -s "$UPL_URL")
echo "$PAYLOAD"
# → HTTP 402 with x402 JSON body

2. Create and sign a mandate ​

bash
curl -X POST https://walletapi.fluxapay.xyz/api/mandates/create-intent \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AGENT_JWT" \
  -d '{
    "intent": {
      "naturalLanguage": "Transfer USDC to agents via Unify Payment Link",
      "currency": "USDC",
      "limitAmount": "10000000",
      "validForSeconds": 2592000,
      "category": "upl-transfer",
      "hostAllowlist": ["walletapi.fluxapay.xyz"]
    }
  }'

Response:

json
{
  "status": "ok",
  "mandateId": "mnd_xyz789",
  "authorizationUrl": "https://agentwallet.fluxapay.xyz/mandate/mnd_xyz789",
  "expiresAt": "2025-03-01T00:00:00.000Z",
  "agentStatus": "ready"
}

Present authorizationUrl to the user. After they sign, verify the mandate status:

bash
curl https://walletapi.fluxapay.xyz/api/mandates/agent/mnd_xyz789 \
  -H "Authorization: Bearer $AGENT_JWT"

Confirm status is "signed" and isEnabled is true.

3. Sign the payment ​

Use the fields from the 402 payload (step 1) together with the mandate ID:

bash
curl -X POST https://walletapi.fluxapay.xyz/api/payment/x402V3Payment \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AGENT_JWT" \
  -d '{
    "mandateId": "mnd_xyz789",
    "scheme": "exact",
    "network": "base",
    "amount": "1000000",
    "currency": "USDC",
    "assetAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "payTo": "0x1234567890abcdef1234567890abcdef12345678",
    "host": "walletapi.fluxapay.xyz",
    "resource": "https://walletapi.fluxapay.xyz/unifypaymentlink/agentid/bob-agent-id?amount=1000000&asset=usdc",
    "description": "UPL transfer 1.00 USDC to bob-agent-id",
    "tokenName": "USD Coin",
    "tokenVersion": "2",
    "validityWindowSeconds": 60
  }'

Response:

json
{
  "status": "ok",
  "xPaymentB64": "<base64-encoded-xPayment>",
  "paymentRecordId": "..."
}

4. Submit and confirm ​

bash
curl -H "X-Payment: <xPaymentB64>" "$UPL_URL"

Response:

json
{
  "success": true,
  "txHash": "0xabc123...",
  "settledAmount": "1000000",
  "network": "base",
  "payer": "0x...",
  "payee": "0x..."
}

The transfer is confirmed onchain. Use the txHash to verify on a Base block explorer.


Notes ​

  • Atomic units — all amounts are in USDC atomic units (6 decimals). 1000000 = 1.00 USDC.
  • Mandate host — UPL endpoints are served from walletapi.fluxapay.xyz. Include this host in your mandate's hostAllowlist, or omit the allowlist entirely.
  • Payment validity — the xPaymentB64 token expires based on validityWindowSeconds (default 60s). Submit it promptly after signing.
  • Idempotency — if the same signed payment is submitted twice, the second request will be rejected. Generate a new payment proof for each transfer.

Released under the MIT License.