# `TruelayerClient.Payments`
[🔗](https://github.com/iamkanishka/truelayer_client/blob/v1.0.0/lib/truelayer_client/payments.ex#L1)

TrueLayer Payments API v3.

All mutating calls (POST) are:
  * **Request-signed** via ES512 JWS (`Tl-Signature` header)
  * **Idempotent** — stable `Idempotency-Key` per `:operation_id`
  * **Retried** on `Tl-Should-Retry: true` responses

## Example

    {:ok, payment} = TruelayerClient.Payments.create_payment(client,
      %{
        amount_in_minor: 1000,
        currency: "GBP",
        payment_method: %{
          type: "bank_transfer",
          provider_selection: %{type: "user_selected"},
          beneficiary: %{type: "merchant_account", merchant_account_id: ma_id}
        },
        user: %{name: "Jane Doe", email: "jane@example.com"}
      },
      operation_id: "order-001"
    )

# `cancel_payment`

```elixir
@spec cancel_payment(TruelayerClient.t(), String.t(), keyword()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

Cancel a payment (POST /v3/payments/{id}/cancel).

# `create_payment`

```elixir
@spec create_payment(TruelayerClient.t(), map(), keyword()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

Create a payment intent (POST /v3/payments).

## Required option

  * `:operation_id` — stable caller-supplied ID used to derive the
    `Idempotency-Key`. Safe to retry with the same ID.

# `create_payment_link`

```elixir
@spec create_payment_link(TruelayerClient.t(), map(), keyword()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

Create a payment link (POST /v3/payment-links).

## Required option

  * `:operation_id` — stable ID for idempotency

# `create_refund`

```elixir
@spec create_refund(TruelayerClient.t(), String.t(), map(), keyword()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

Create a refund (POST /v3/payments/{id}/refunds).

Pass `amount_in_minor: 0` or omit for a full refund.

## Required option

  * `:operation_id` — stable ID for idempotency

# `get_payment`

```elixir
@spec get_payment(TruelayerClient.t(), String.t()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

Get a payment by ID (GET /v3/payments/{id}).

# `get_payment_link`

```elixir
@spec get_payment_link(TruelayerClient.t(), String.t()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

Get a payment link by ID (GET /v3/payment-links/{id}).

# `get_provider`

```elixir
@spec get_provider(TruelayerClient.t(), String.t()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

Get a payment provider by ID (GET /v3/payments-providers/{id}).

# `get_refund`

```elixir
@spec get_refund(TruelayerClient.t(), String.t(), String.t()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

Get a refund by ID (GET /v3/payments/{id}/refunds/{refund_id}).

# `list_payment_link_payments`

```elixir
@spec list_payment_link_payments(TruelayerClient.t(), String.t(), keyword()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

List payments for a payment link (GET /v3/payment-links/{id}/payments).

# `list_refunds`

```elixir
@spec list_refunds(TruelayerClient.t(), String.t()) ::
  {:ok, [map()]} | {:error, TruelayerClient.Error.t()}
```

List all refunds for a payment (GET /v3/payments/{id}/refunds).

# `search_providers`

```elixir
@spec search_providers(TruelayerClient.t(), map()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

Search payment providers (POST /v3/payments-providers/search).

# `start_authorization_flow`

```elixir
@spec start_authorization_flow(TruelayerClient.t(), String.t(), map()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

Start the authorization flow (POST /v3/payments/{id}/authorization-flow).

# `submit_consent`

```elixir
@spec submit_consent(TruelayerClient.t(), String.t()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

Submit PSU consent.

# `submit_form`

```elixir
@spec submit_form(TruelayerClient.t(), String.t(), map()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

Submit form inputs.

# `submit_provider_selection`

```elixir
@spec submit_provider_selection(TruelayerClient.t(), String.t(), String.t()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

Submit provider selection.

# `submit_return_parameters`

```elixir
@spec submit_return_parameters(TruelayerClient.t(), map()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

Submit bank-redirect return parameters (POST /v3/payments-providers/return).

# `submit_scheme_selection`

```elixir
@spec submit_scheme_selection(TruelayerClient.t(), String.t(), String.t()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

Submit scheme selection.

# `wait_for_final_status`

```elixir
@spec wait_for_final_status(TruelayerClient.t(), String.t(), keyword()) ::
  {:ok, map()} | {:error, TruelayerClient.Error.t()}
```

Poll `get_payment/2` until a terminal status is reached or the timeout expires.

Terminal statuses: `executed`, `settled`, `failed`, `cancelled`.

> Prefer webhook-driven status updates in production systems.

## Options

  * `:timeout_ms` - maximum wait time in milliseconds (default: 60_000)
  * `:interval_ms` - polling interval in milliseconds (default: 2_000)

---

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