SellVia Docs — menu
DocsSecurityWebhook Security

Webhook Security

Security/Webhook Security.md
backendUpdated Aug 23, 2026

Webhook Security

Purpose

Securing the Paddle webhook endpoint specifically — this is one of the highest-value attack surfaces in the whole system, since a forged webhook could fake a "sale" or "payout" event.

Non-Negotiable Practices

  • Verify Paddle's webhook signature on every single request, using Paddle's signing secret — reject anything that doesn't verify, no exceptions, regardless of how urgent or legitimate a request might look
  • Webhook endpoint is not authenticated via Kratos (Paddle isn't a logged-in user) — signature verification is the entire trust mechanism here, which is exactly why it can't be skipped or relaxed
  • Idempotent processing (see 02. Event-Driven Architecture) — a replayed or duplicated webhook must never double-credit a wallet or double-trigger a payout

Why This Is Called Out Separately From API Security

Because this endpoint is deliberately unauthenticated (it has to be, since it's called by Paddle, not a logged-in user), it's a fundamentally different threat model than the rest of the API — worth its own explicit doc rather than being buried inside general API Security.

Open Questions

  • None blocking — this is a well-established pattern (Paddle's own documentation covers this exact setup); the requirement here is discipline in implementation, not a design decision.

Update (2026-08-23): Paddle → Swich, Plus a Second Webhook Source (Shopify)

Founder decisions, full reasoning in 02. Architecture Decision Log. This doc's every "Paddle" now means Swich, and there's a genuinely new second endpoint with the identical threat model:

  • Verify Swich's webhook signature on every single request (POST /webhooks/swich), using Swich's signing secret — same non-negotiable rule as before, exact signature scheme unconfirmed pending real Swich integration docs.
  • POST /webhooks/shopify-sales needs the same treatment, independently — verified via Shopify's own webhook HMAC scheme, per-merchant-store secret (05. Payment Flow's per-merchant signed-request note). This is a second unauthenticated, signature-trust-only endpoint this doc's original scope didn't cover — a forged Shopify webhook could fake a sale report just as damagingly as a forged payment webhook could fake a payout.
  • Idempotent processing (unchanged principle) applies to both endpoints independently — a replayed Swich webhook must never double-credit a wallet; a replayed Shopify webhook must never double-count a sale (already covered by the external_order_id uniqueness check, 01. Commission Engine).
  • Title/Purpose framing above ("Securing the Paddle webhook endpoint specifically") should be read as "Securing SellVia's inbound webhook endpoints" now that there are two independent sources, not one.