# `MPP.Client.Transport.HTTP`
[🔗](https://github.com/ZenHive/mpp/blob/v0.10.0/lib/mpp/client/transport/http.ex#L1)

HTTP implementation of `MPP.Client.Transport` over `Req`.

Operates on `Req.Response` / `Req.Request` structs — this module does not
construct Req clients itself. Callers (e.g. the payment-aware Req plugin)
feed responses in and receive modified requests out.

## Wire format

  * Payment-required response: HTTP status `402`
  * Challenges: one or more `WWW-Authenticate` headers carrying the `Payment`
    scheme. Multiple challenges may appear as repeated header values or as a
    single comma-separated header value; both forms are handled.
  * Credential attachment: `Authorization: Payment <base64url-json>`,
    produced via `MPP.Headers.format_credential/1`.
  * Optional `Accept-Payment` advertisement via `set_accept_payment/2` or
    `set_accept_payment_from_providers/3` (gated by `MPP.Client.AcceptPolicy`).

## API Functions
| Function | Arity | Description | Param Kinds |
| --- | --- | --- | --- |
| `set_accept_payment_from_providers` | 3 | Attach `Accept-Payment` from supported `(method, intent)` pairs when policy allows. | `request: value`, `providers: value`, `policy: value` |
| `set_accept_payment` | 2 | Attach an `Accept-Payment` header built from preference entries. | `request: value`, `entries: value` |
| `set_credential` | 2 | Attach a credential to a Req.Request as `Authorization: Payment <...>`. | `request: value`, `credential: value` |
| `get_challenges` | 1 | Parse the Payment challenges from a 402 response's WWW-Authenticate headers. | `response: value` |
| `payment_required?` | 1 | Return true if the HTTP response is a 402 Payment Required. | `response: value` |

# `get_challenges`

```elixir
@spec get_challenges(Req.Response.t()) ::
  {:ok, [MPP.Challenge.t()]} | {:error, term()}
```

Parse the Payment challenges from a 402 response's WWW-Authenticate headers.

## Parameters

  * `response` - Req.Response struct (value)

## Returns

`{:ok, [challenge]}` on success, `{:error, reason}` otherwise (`tagged_tuple`)

## Errors

  * `:no_payment_challenges`
  * `:missing_www_authenticate`
  * `:invalid_scheme`
  * `:missing_required_params`
  * `:duplicate_param`
  * `:invalid_auth_params`

```elixir
# descripex:contract
%{
  params: %{response: %{description: "Req.Response struct", kind: :value}},
  errors: [:no_payment_challenges, :missing_www_authenticate, :invalid_scheme,
   :missing_required_params, :duplicate_param, :invalid_auth_params],
  returns: %{
    type: :tagged_tuple,
    description: "`{:ok, [challenge]}` on success, `{:error, reason}` otherwise"
  }
}
```

# `payment_required?`

```elixir
@spec payment_required?(Req.Response.t()) :: boolean()
@spec payment_required?(Req.Response.t()) :: false
```

Return true if the HTTP response is a 402 Payment Required.

## Parameters

  * `response` - Req.Response struct (value)

## Returns

true if status is 402 (`boolean`)

```elixir
# descripex:contract
%{
  params: %{response: %{description: "Req.Response struct", kind: :value}},
  returns: %{type: :boolean, description: "true if status is 402"}
}
```

# `set_accept_payment`

```elixir
@spec set_accept_payment(Req.Request.t(), [MPP.AcceptPayment.entry() | map()]) ::
  Req.Request.t()
```

Attach an `Accept-Payment` header from preference entries.

Does not overwrite an existing `Accept-Payment` header on the request.

# `set_accept_payment_from_providers`

```elixir
@spec set_accept_payment_from_providers(
  Req.Request.t(),
  [{String.t(), String.t()}],
  MPP.Client.AcceptPolicy.t()
) :: Req.Request.t()
```

Attach `Accept-Payment` from a list of supported `{method, intent}` pairs.

Respects `MPP.Client.AcceptPolicy` — when `allows?/2` is false the request is
returned unchanged. Caller-set `Accept-Payment` headers are never overwritten.

# `set_credential`

```elixir
@spec set_credential(Req.Request.t(), MPP.Credential.t()) :: Req.Request.t()
```

Attach a credential to a Req.Request as `Authorization: Payment <...>`.

## Parameters

  * `request` - Req.Request struct (value)
  * `credential` - MPP.Credential struct (value)

## Returns

Req.Request with the Authorization header set (`struct`)

```elixir
# descripex:contract
%{
  params: %{
    request: %{description: "Req.Request struct", kind: :value},
    credential: %{description: "MPP.Credential struct", kind: :value}
  },
  returns: %{
    type: :struct,
    description: "Req.Request with the Authorization header set"
  }
}
```

---

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