PhoenixKitBilling.Plugs.CacheBodyReader (PhoenixKitBilling v0.3.2)

Copy Markdown View Source

Body reader for Plug.Parsers that stashes the raw request body in conn.assigns.raw_body so the webhook controller can verify provider signatures.

Webhook signature verification (Stripe, PayPal, Razorpay) requires the exact bytes the provider signed. Plug.Parsers consumes the request body during JSON decoding, so the raw bytes are unavailable to downstream plugs unless we capture them here.

Host application setup

In your Endpoint, replace the default body reader on Plug.Parsers with this module only for the webhook path to avoid keeping every request body in memory:

plug Plug.Parsers,
  parsers: [:urlencoded, :multipart, {:json, length: 10_000_000}],
  pass: ["*/*"],
  body_reader: {PhoenixKitBilling.Plugs.CacheBodyReader, :read_body, []},
  json_decoder: Phoenix.json_library()

The reader only caches the body when the request path matches /webhooks/billing/*, so other requests behave normally.

Why not a pipeline plug?

Plug.Parsers runs in the Endpoint, before router pipelines. Once the body is parsed, the underlying socket is empty and a pipeline plug cannot recover the raw bytes. The body reader is the only safe seam.

Summary

Functions

Reads the request body, caches it in conn.assigns.raw_body for webhook paths, and returns the standard Plug.Conn.read_body/2 tuple.

Functions

read_body(conn, opts)

Reads the request body, caches it in conn.assigns.raw_body for webhook paths, and returns the standard Plug.Conn.read_body/2 tuple.