Webhook receiver

Verify PayProof-Signature and route checkout / subscription events.

AGENTS.md

Next.js App Router example

ts
import { NextRequest, NextResponse } from "next/server";
import crypto from "crypto";

export async function POST(req: NextRequest) {
  const raw = await req.text();
  const header = req.headers.get("payproof-signature") || "";
  const secret = process.env.PAYPROOF_WEBHOOK_SECRET!;

  const parts = Object.fromEntries(
    header.split(",").map((p) => p.trim().split("="))
  );
  const digest = crypto
    .createHmac("sha256", secret)
    .update(`${parts.t}.${raw}`)
    .digest("hex");
  if (digest !== parts.v1) {
    return NextResponse.json({ error: "invalid signature" }, { status: 401 });
  }

  const event = JSON.parse(raw);
  switch (event.type) {
    case "checkout.verified":
    case "payment.verified":
      // mark order paid
      break;
    case "subscription.activated":
    case "subscription.renewed":
      // unlock membership
      break;
    case "checkout.failed":
    case "checkout.expired":
      // notify customer
      break;
  }
  return NextResponse.json({ received: true });
}