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

# create_payment

> Persist a payment, independently validate its route, and create its authorization state.

**Authentication:** `settlement:prepare`\
**Mutates state:** Yes\
**Idempotency:** Stable `request_id`\
**Confirmation:** `confirmed_by_user=true` under the active authorization policy

```json theme={null}
{
  "request_id": "client-generated stable ID",
  "confirmed_by_user": true,
  "source": { "asset": {}, "amount": "..." },
  "destination": { "asset": {}, "amount": "...", "recipient_id": "..." },
  "amount_mode": "exact_source",
  "routing_preference": "balanced",
  "intermediate_asset": {},
  "hops": [
    {
      "hop_index": 0,
      "intent_id": "...",
      "direction": "on_ramp",
      "source": "quote_accept",
      "client_quote_id": "..."
    },
    {
      "hop_index": 1,
      "intent_id": "...",
      "direction": "off_ramp",
      "source": "quote_accept",
      "client_quote_id": "..."
    }
  ]
}
```

One or two hops are allowed. Directions are `on_ramp`, `off_ramp`, and
`on_chain_swap`; sources are `quote_accept` and `auto_selected`. Two hops
require top-level `intermediate_asset`. Hops contain route data only; MCP binds
the top-level destination recipient and the internal two-hop reference.

For a plan-bound payment, also provide `plan_id` and a unique `plan_position`.
Its confirmation occurs when the complete plan is submitted, so it does not
use standalone `confirmed_by_user`.

Core independently validates quote references, amount continuity, readiness,
and the route. If the fiat rail is not ready, it returns `need_review` with
`payment_created=false` and `reason=rail_not_ready`; no payment or authorization
was created.

A successful result is the durable payment view. Use the exact hops from an
unexpired estimate while its inputs are unchanged. On `QUOTE_EXPIRED` or
`PRICE_MISMATCH`, estimate again and reconfirm the refreshed terms.

When status is `approval_required`, hosted OAuth calls
`show_payment_approval`; local clients show the expiring first-party approval
URL. When status is `approval_ready`, continue the same payment.
