# `Stancer.Webhook`

Webhook utilities for Stancer payment processor.

This module provides:
- Signature validation (HMAC-SHA256)
- Event type definitions
- Event parsing and type safety

## Signature Validation

All webhooks sent by Stancer include an `X-Stancer-Signature` header
containing an HMAC-SHA256 signature of the raw request body.

Example:

    defmodule MyAppWeb.WebhookController do
      def handle_webhook(conn, _params) do
        {:ok, body, conn} = Plug.Conn.read_body(conn)
        signature = Plug.Conn.get_req_header(conn, "x-stancer-signature") |> List.first()

        case Stancer.Webhook.verify(body, signature) do
          :ok ->
            event = Jason.decode!(body)
            process_event(event)
            send_resp(conn, 200, "OK")

          :error ->
            send_resp(conn, 401, "Unauthorized")
        end
      end

      defp process_event(event) do
        case event["type"] do
          "payment.captured" -> handle_payment_captured(event["data"])
          "payment.failed" -> handle_payment_failed(event["data"])
          _ -> :ok
        end
      end
    end

## Available Event Types

- `payment.captured` — Payment was successfully captured
- `payment.refunded` — Payment was refunded
- `payment.failed` — Payment authorization failed
- `payment.pending` — Payment is pending
- `payment.voided` — Payment was voided
- `customer.created` — Customer was created
- `customer.updated` — Customer was updated
- `customer.deleted` — Customer was deleted
- `card.created` — Card was tokenized
- `card.deleted` — Card was deleted
- `dispute.created` — Dispute was filed
- `dispute.updated` — Dispute status changed

# `event_types`

```elixir
@spec event_types() :: [binary()]
```

List all valid webhook event types that Stancer can emit.

## Returns

  List of binary event type names.

## Example

    Stancer.Webhook.event_types()
    # => ["payment.captured", "payment.refunded", "payment.failed", ...]

# `parse`

```elixir
@spec parse(body :: binary()) :: {:ok, map()} | {:error, term()}
```

Parse a webhook event from raw JSON body.

Returns a map with keys: `type`, `created_at`, `data`, `id`.

## Example

    {:ok, event} = Stancer.Webhook.parse(body)
    IO.inspect(event.type)  # "payment.captured"
    IO.inspect(event.data)  # %{"id" => "paym_...", ...}

# `verify`

```elixir
@spec verify(body :: binary(), signature :: binary() | nil) :: :ok | :error
```

Verify webhook signature using HMAC-SHA256.

Compares the provided signature with a computed signature of the raw body
using your API key as the HMAC secret.

## Arguments

  - `body` (binary) — Raw request body (must be the exact body received)
  - `signature` (binary) — Value from X-Stancer-Signature header

## Returns

  - `:ok` — Signature is valid
  - `:error` — Signature is invalid or missing

## Example

    {:ok, body, _conn} = Plug.Conn.read_body(conn)
    signature = Plug.Conn.get_req_header(conn, "x-stancer-signature") |> List.first()

    case Stancer.Webhook.verify(body, signature) do
      :ok -> process_webhook(body)
      :error -> Logger.warning("Invalid webhook signature")
    end

---

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