# `X402.Client.Finch`
[🔗](https://github.com/cardotrejos/x402/blob/v0.9.0/lib/x402/client/finch.ex#L1)

Finch-backed payer client with an automatic 402 → sign → retry flow.

`request/3` performs an HTTP request; when the server answers `402` with a
`PAYMENT-REQUIRED` header, it decodes the payment requirements, builds and
signs a payment via `X402.Client.build_payment/3`, and retries the request
once with the `PAYMENT-SIGNATURE` header. A request is **never paid twice**:
at most one payment retry is made, and requests that already carry a
`payment-signature` header are refused.

Requires the optional `finch` dependency; without it every call returns
`{:error, :missing_dependency}`. Start your own Finch pool (with TLS peer
verification — see `X402.Facilitator.HTTP.secure_pool_opts/0`) and pass its
name.

## Example

    {:ok, signer} = X402.Signer.LocalKey.new(System.fetch_env!("PAYER_KEY"))

    {:ok, %{status: 200, body: body, payment_response: receipt}} =
      X402.Client.Finch.request(MyApp.Finch, "https://api.example.com/paid",
        signer: signer,
        max_amount: "10000",
        on_payment_required: fn payment_required ->
          IO.inspect(payment_required["accepts"], label: "about to pay")
          :ok
        end
      )

## Spend controls

Cap what an automated payer signs with `:max_amount` (per payment),
`:policies` (`X402.Client.Policy` filters on network, asset, scheme, or
anything else), and `:budget` (an `X402.Client.Budget` shared across
requests). With none of them configured a warning is logged once.

## Sign-In-With-X

With `siwx: [chain_id: :auto]` the client answers a server's
`sign-in-with-x` challenge before paying: a returning payer whose address
the server remembers gets the resource without a new payment
(`siwx_authenticated: true` in the response); otherwise the payment flow
runs as usual, with the proof attached to the paid request too.

## Security

Like the facilitator client, URLs must use `https://` — payment
authorizations must never travel in plaintext. Loopback hosts
(`localhost`, `127.0.0.1`, `::1`) are exempt for local development.

# `finch_name`

```elixir
@type finch_name() :: atom() | pid() | {:via, module(), term()}
```

A Finch pool name or pid.

# `request_error`

```elixir
@type request_error() ::
  :missing_dependency
  | :insecure_url
  | :payment_cancelled
  | :payment_already_attempted
  | {:transport_error, term()}
  | {:invalid_payment_required, term()}
  | {:siwx, X402.Client.SIWX.reason()}
  | X402.Client.Budget.reserve_error()
  | X402.Client.build_error()
```

# `response`

```elixir
@type response() :: %{
  status: non_neg_integer(),
  headers: [{String.t(), String.t()}],
  body: binary(),
  payment_response: map() | nil,
  siwx_authenticated: boolean()
}
```

A completed HTTP response.

`:payment_response` holds the decoded `PAYMENT-RESPONSE` header (the
settlement receipt) when the server sent a valid one, otherwise `nil`.
`:siwx_authenticated` is `true` when the server accepted a Sign-In-With-X
proof instead of a payment (see the `:siwx` option).

# `request`
*since 0.6.0* 

```elixir
@spec request(finch_name(), String.t(), keyword()) ::
  {:ok, response()} | {:error, request_error()}
```

Performs an HTTP request, paying for the resource if it requires payment.

Flow:

1. Perform the request. Anything other than a `402` with a
   `PAYMENT-REQUIRED` header is returned as-is.
2. Decode the `PAYMENT-REQUIRED` header (`X402.PaymentRequired.decode/1`).
3. With `:siwx` configured and a `sign-in-with-x` challenge advertised,
   sign it (`X402.Client.SIWX.authenticate/4`) and retry the request with
   the `SIGN-IN-WITH-X` header and no payment. Anything other than a
   `402` with a `PAYMENT-REQUIRED` header is returned as-is, with
   `siwx_authenticated: true` for a 2xx. On a second `402` the flow
   continues with the new payment requirements; the paid request carries a
   proof for the new challenge (when advertised) so the server can record
   the payer.
4. Invoke the `:on_payment_required` hook, which may cancel.
5. Build and sign a payment (`X402.Client.build_payment/3`), reserve its
   amount against `:budget` (when given), and retry the request once with
   the `PAYMENT-SIGNATURE` header.
6. Return the retried response with the decoded `PAYMENT-RESPONSE`
   settlement receipt, when present. A second `402` is returned as-is —
   the payment is never re-signed or re-sent — and the budget
   reservation is released unless the response is 2xx or carries a
   successful receipt.

When neither `:max_amount`, `:policies`, nor `:budget` is given a warning
is logged once per VM: the client will then sign any amount a server asks
for.

## Options

* `:signer` - Required. A struct implementing `X402.Signer`, used to sign the payment.

* `:method` - HTTP request method. The default value is `:get`.

* `:headers` - Additional `{name, value}` request headers. The default value is `[]`.

* `:body` - Request body. The default value is `nil`.

* `:receive_timeout_ms` (`t:non_neg_integer/0`) - Finch receive timeout per attempt, in milliseconds. The default value is `5000`.

* `:network` (`t:String.t/0`) - Payment selection filter — see `X402.Client.select_requirements/2`.

* `:scheme` (`t:String.t/0`) - Payment selection filter — see `X402.Client.select_requirements/2`.

* `:asset` (`t:String.t/0`) - Payment selection filter — see `X402.Client.select_requirements/2`.

* `:max_amount` - Maximum `amount` (atomic units) this client will pay — the budget guard
  for automated payers. Requirements above it are never selected.

* `:policies` (list of function of arity 2) - Selection policies forwarded to `X402.Client.select_requirements/2` —
  see `X402.Client.Policy`. The default value is `[]`.

* `:budget` - An `X402.Client.Budget` the selected amount is reserved against
  before the paid retry is sent. See `X402.Client.Budget` for what
  counts as spent. The default value is `nil`.

* `:hooks` - `X402.Client.Hooks` module forwarded to `X402.Client.build_payment/3`. The default value is `X402.Client.Hooks.Default`.

* `:siwx` - Automatic Sign-In-With-X: a keyword list of `X402.Client.SIWX`
  options (`chain_id:` required, or `:auto`). `nil`/`false` disables
  it. The default value is `nil`.

* `:valid_after_buffer` (`t:non_neg_integer/0`) - Clock-skew buffer for the authorization's `validAfter`, in seconds. The default value is `60`.

* `:auth_capture` - Auth-capture signing options forwarded to `X402.Client.build_payment/3`. The default value is `[]`.

* `:extensions` (list of function of arity 2) - Client extension enrichers forwarded to
  `X402.Client.build_payment/3` — see its `:extensions` option. The default value is `[]`.

* `:schemes` - Additional `X402.Scheme` modules forwarded to
  `X402.Client.build_payment/3` — see its `:schemes` option. The default value is `[]`.

* `:on_payment_required` - Budget/consent hook invoked with the decoded `PaymentRequired` map
  before any payment is signed. Return `:cancel` to abort with
  `{:error, :payment_cancelled}`; any other return value continues. The default value is `nil`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
