# `Worldpay.Webhooks`
[🔗](https://github.com/iamkanishka/worldpay/blob/v1.0.0/lib/worldpay/webhooks.ex#L1)

Worldpay webhook event parsing and dispatch.

Worldpay pushes payment lifecycle events to your HTTPS endpoint as JSON.

## Setup

Register your endpoint URL with your Worldpay Implementation Manager.
Your endpoint must use HTTPS with a SHA-256+ certificate chain.

### Phoenix example

    # router.ex
    post "/worldpay/webhook", WorldpayWebhookController, :handle

    # controller
    def handle(conn, _params) do
      {:ok, body, conn} = Plug.Conn.read_body(conn)

      case Worldpay.Webhooks.parse(body) do
        {:ok, event} ->
          MyApp.PaymentHandler.handle_event(event)
          send_resp(conn, 200, "ok")

        {:error, reason} ->
          Logger.error("Worldpay webhook parse error: #{inspect(reason)}")
          send_resp(conn, 400, "bad request")
      end
    end

## Event types

Card: `:authorized` · `:sent_for_settlement` · `:settled` · `:settlement_failed` ·
`:charged_back` · `:chargeback_reversed` · `:dispute_expired` · `:refunded` ·
`:partially_refunded` · `:cancelled` · `:refused` · `:sent_for_authorization` · `:updated`

APM: `:apm_authorized` · `:apm_pending_merchant` · `:apm_failed` · `:apm_request_expired` · `:pix_confirmed`

Payout: `:payout_sent` · `:payout_failed` · `:payout_reversed`

Token: `:token_created` · `:network_token_created` · `:network_token_updated` · `:network_token_deleted`

# `event`

```elixir
@type event() :: %{
  type: atom(),
  payment_id: String.t() | nil,
  order_reference: String.t() | nil,
  command_id: String.t() | nil,
  downstream_reference: String.t() | nil,
  last_event: String.t() | nil,
  amount: %{required(String.t()) =&gt; term()} | nil,
  currency: String.t() | nil,
  payment_instrument: %{required(String.t()) =&gt; term()} | nil,
  risk_factors: [term()] | nil,
  raw: %{required(String.t()) =&gt; term()}
}
```

# `event_type`

```elixir
@spec event_type(%{required(String.t()) =&gt; term()}) :: atom()
```

Extract the event type atom from a raw webhook body map.

# `handle`

```elixir
@spec handle(event(), module()) :: :ok | {:error, term()}
```

Dispatch a parsed event to a handler module implementing `Handler`.

# `parse`

```elixir
@spec parse(String.t() | %{required(String.t()) =&gt; term()}) ::
  {:ok, event()}
  | {:error, {:json_decode_error, Jason.DecodeError.t()} | :invalid_body}
```

Parse a raw Worldpay webhook JSON body into a structured event.

Accepts a JSON binary or a pre-decoded string-keyed map.
Returns `{:ok, event()}` or `{:error, {:json_decode_error, Jason.DecodeError.t()} | :invalid_body}`.

---

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