> ## Documentation Index
> Fetch the complete documentation index at: https://docs.unwall.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Payments

> Three payment rails unified under a single endpoint.

# Payments

Unwall provides three payment rails -- x402 protocol, on-chain USDC transfer, and fiat ACH -- all accessible through a single endpoint. The `POST /v1/pay` endpoint auto-routes to the correct rail based on the `recipient` field.

## Unified Endpoint

```
POST /v1/pay
```

The endpoint inspects the `recipient` value and routes automatically:

| Recipient Format           | Rail          | Example                                               |
| -------------------------- | ------------- | ----------------------------------------------------- |
| URL (`https://...`)        | x402 Protocol | `"https://api.example.com/v1/data"`                   |
| Ethereum address (`0x...`) | USDC Transfer | `"0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18"`        |
| Object with bank details   | Fiat ACH      | `{"name": "Acme Corp", "account_number": "...", ...}` |

No rail selection logic is needed in your agent. Just provide the recipient and Unwall handles the rest.

## Three Payment Rails

### x402 Protocol

Pay for API calls in USDC using the HTTP 402 payment standard. When the recipient is a URL:

1. Unwall proxies your request to the target API.
2. If the API returns HTTP 402 with payment requirements, Unwall parses the payment details.
3. Unwall signs a USDC authorization (EIP-3009) and retries the request with payment attached.
4. The API response is returned to your agent.

If the target API responds normally (no 402), the response is passed through at no charge.

<Info>
  Set `max_amount_usdc` to cap how much your agent can spend per x402 call. See the [x402 Protocol guide](/guides/x402-payments) for details.
</Info>

### USDC Transfer

Send USDC on-chain to any Ethereum address on Base. The transfer is executed through Bridge.xyz and recorded in the ledger.

### Fiat ACH

Convert USDC to USD and send via ACH bank transfer. Provide the recipient's name, account number, routing number, and email. Bridge.xyz handles the off-ramp conversion and transfer.

<Note>
  ACH transfers are not instant. Expect 2-3 business days for settlement.
</Note>

## Fee Model

Fees are tier-based and charged **on top of** the payment amount:

| Plan         | Fee Rate |
| ------------ | -------- |
| **Free**     | 2%       |
| **Pro**      | 1.5%     |
| **Business** | 1%       |

For example, if you send a $100 payment on the Pro plan, $101.50 is debited from your wallet ($100 payment + $1.50 fee). The fee is recorded as a `PLATFORM_FEE` transaction in the ledger.

## Idempotency

Include an `idempotency_key` in your request to prevent duplicate payments. If a request is retried with the same key, the original transaction is returned without creating a new one.

```json theme={null}
{
  "recipient": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18",
  "amount_usd": 50.00,
  "idempotency_key": "invoice-1234-payment"
}
```

Idempotency keys are unique per project. The same key can be used in different projects without conflict.

## Transaction Lifecycle

Every payment goes through a defined set of statuses:

```
pending → processing → completed
                    ↘ failed
                    ↘ reversed
```

| Status       | Meaning                                                                |
| ------------ | ---------------------------------------------------------------------- |
| `pending`    | Payment recorded, not yet submitted to the payment provider            |
| `processing` | Submitted to Bridge.xyz or x402 facilitator, awaiting confirmation     |
| `completed`  | Payment settled successfully                                           |
| `failed`     | Payment failed. Balance is automatically credited back to the project. |
| `reversed`   | Payment was reversed after completion (e.g., ACH return)               |

## Safety Guarantees

<AccordionGroup>
  <Accordion title="Atomic balance debit">
    Balance is debited using ledger RPC functions with PostgreSQL advisory locks for per-project serialization. Two concurrent payment requests cannot both succeed when only enough balance exists for one.
  </Accordion>

  <Accordion title="Fresh balance on every payment">
    The project balance is never served from cache when authorizing a payment. It is always fetched directly from the ledger to prevent overdraw.
  </Accordion>

  <Accordion title="Automatic rollback on failure">
    If a payment fails after the balance has been debited, the amount is automatically credited back to the project. If the rollback itself fails, the error is captured in Sentry for manual resolution.
  </Accordion>

  <Accordion title="x402 max amount cap">
    For x402 payments, the `max_amount_usdc` field ensures an agent never pays more than intended for a single API call.
  </Accordion>
</AccordionGroup>

## Deprecated Endpoints

The following endpoints still work but `POST /v1/pay` is the recommended replacement:

| Deprecated Endpoint      | Rail          | Replacement                                |
| ------------------------ | ------------- | ------------------------------------------ |
| `POST /v1/payments`      | Fiat ACH      | `POST /v1/pay` with bank details recipient |
| `POST /v1/x402/pay`      | x402 Protocol | `POST /v1/pay` with URL recipient          |
| `POST /v1/usdc/transfer` | USDC Transfer | `POST /v1/pay` with 0x address recipient   |

## Next Steps

<CardGroup cols={2}>
  <Card title="Send a Payment" icon="paper-plane" href="/guides/send-payment">
    Step-by-step guide with code examples for all three rails.
  </Card>

  <Card title="x402 Protocol" icon="bolt" href="/guides/x402-payments">
    Deep dive into how x402 payments work under the hood.
  </Card>
</CardGroup>
