# `Accrue.Router`
[🔗](https://github.com/szTheory/accrue/blob/accrue-v1.5.1/lib/accrue/router.ex#L1)

Router helpers for mounting Accrue webhook endpoints.

## Usage (Phoenix router)

    import Accrue.Router

    pipeline :accrue_webhook_raw_body do
      plug Plug.Parsers,
        parsers: [:json],
        pass: ["*/*"],
        json_decoder: Jason,
        body_reader: {Accrue.Webhook.CachingBodyReader, :read_body, []},
        length: 1_000_000
    end

    scope "/webhooks" do
      pipe_through :accrue_webhook_raw_body
      accrue_webhook "/stripe", :stripe
    end

Apple App Store Server Notifications V2 use a dedicated route-scoped body
reader whose parser limit matches the notification plug's 256 KiB default:

    pipeline :accrue_apple_notifications_raw_body do
      plug Plug.Parsers,
        parsers: [:json],
        pass: ["*/*"],
        json_decoder: Jason,
        body_reader: {Accrue.Webhook.CachingBodyReader, :read_body, []},
        length: 262_144
    end

    scope "/webhooks" do
      pipe_through :accrue_apple_notifications_raw_body
      accrue_apple_notifications "/apple", verifier_config: apple_verifier_config,
        rate_limiter: &MyApp.AppleRateLimiter.check/1
    end

## Multi-endpoint (Phase 4 Connect ready, D2-18)

The macro accepts a processor atom. Calling `accrue_webhook/2` multiple
times with different processors works natively:

    scope "/webhooks" do
      pipe_through :accrue_webhook_raw_body
      accrue_webhook "/stripe", :stripe
      accrue_webhook "/connect", :stripe_connect
    end

Each resolves to its own signing secret via `Accrue.Config`.

## Entitlement guards (controller pipeline)

`require_feature/1` and `require_plan/1` are single-arg sugar over
`Accrue.Plug.RequireEntitlement` for the common "gate one feature / plan"
case in a controller's `plug` pipeline:

    import Accrue.Router

    defmodule MyAppWeb.ReportsController do
      use MyAppWeb, :controller

      require_feature :reports      # plug Accrue.Plug.RequireEntitlement, feature: :reports
      require_plan :pro             # plug Accrue.Plug.RequireEntitlement, plan: :pro
      # ... actions
    end

For advanced overrides (`status:`, `on_deny:`, `billable:`) use the explicit
plug form directly:

    plug Accrue.Plug.RequireEntitlement, feature: :reports, on_deny: {:redirect, "/pricing"}

# `accrue_apple_notifications`
*macro* 

Mounts the Apple App Store Server Notifications V2 plug at `path`.

`opts` are host-supplied `Accrue.Entitlements.Apple.NotificationPlug` options,
including `:verifier_config` and optional `:rate_limiter`. Must be called inside
a route-scoped `Plug.Parsers` pipeline using
`Accrue.Webhook.CachingBodyReader.read_body/2`, with the parser `:length`
matching `:max_body_bytes` (262,144 by default); otherwise the plug returns a
retryable `503` without verifying or persisting the notification.

# `accrue_webhook`
*macro* 

Mounts the Accrue webhook plug at the given `path` for the specified
`processor`.

Expands to `forward path, Accrue.Webhook.Plug, processor: processor`.
Must be called inside a scope that pipes through a pipeline containing
`Plug.Parsers` with `body_reader: {Accrue.Webhook.CachingBodyReader, :read_body, []}`.

# `require_feature`
*macro* 

Gates a controller pipeline on a single `feature`.

Expands to `plug Accrue.Plug.RequireEntitlement, feature: feature`. For
`status:` / `on_deny:` / `billable:` overrides, use the explicit
`plug Accrue.Plug.RequireEntitlement, …` form instead.

# `require_plan`
*macro* 

Gates a controller pipeline on an active `plan` (an atom plan key or a
`price_id` String).

Expands to `plug Accrue.Plug.RequireEntitlement, plan: plan`. For
`status:` / `on_deny:` / `billable:` overrides, use the explicit
`plug Accrue.Plug.RequireEntitlement, …` form instead.

---

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