---
title: "Webhooks"
description: "The inbound billing webhooks, how signatures are verified, and what is not there yet."
url: "https://bareledger.app/guides/api-webhooks"
category: "Developers & API"
updated: "2026-10-04"
publisher: "BareLedger (Syneria Technologies OPC)"
---

# Webhooks

> The inbound billing webhooks, how signatures are verified, and what is not there yet.

Both are public routes (no authentication) — authenticity comes from HMAC signature verification, not a bearer token.

| Method & Path | Purpose | Side effects |
|---|---|---|
| `POST webhooks/paddle` | Paddle billing webhook | Verifies `Paddle-Signature`; `WebhookProcessor::handle` updates subscriptions/invoices/payments; logged to the `billing` channel (never logs the raw body on signature failure) |
| `POST webhooks/paymongo` | PayMongo billing webhook | Verifies `Paymongo-Signature`; same processor path |

Both fail **closed** (reject with 401) in every environment except `local`/`development`/`testing` when the relevant secret (`PADDLE_WEBHOOK_SECRET`/`PAYMONGO_WEBHOOK_SECRET`) is unset — see Integrations — Paddle/PayMongo and [Security](https://bareledger.app/guides/security). Idempotency is enforced via `billing_webhook_events(provider, event_id)` — a redelivered event is a no-op, not a duplicate charge/state change.

The Paddle and PayMongo webhook endpoints — see Database — Billing & Subscriptions for the `billing_webhook_events` table this writes to.
