Guides / Payments
In the Paddle Dashboard → Developer Tools → Notifications → New Destination, enter your endpoint URL and enable:
transaction.completedtransaction.payment_failedsubscription.cancelled// app/api/webhooks/paddle/route.ts
import { logit } from "@/lib/logit";
export async function POST(req: Request) {
const event = await req.json();
if (event.event_type === "transaction.completed") {
const txn = event.data;
const amount = txn.details?.totals?.total ?? 0;
const currency = txn.currency_code ?? "USD";
const customerEmail = txn.customer?.email ?? "unknown";
await logit.now("payments", {
event: "Paddle payment received",
description: `${customerEmail} — ${(amount / 100).toFixed(2)} ${currency}`,
icon: "💰",
notify: true,
tags: { currency: currency.toLowerCase(), status: txn.status },
metadata: {
transactionId: txn.id,
customerId: txn.customer_id,
customerEmail,
amount,
currency,
subscriptionId: txn.subscription_id ?? null,
},
});
}
if (event.event_type === "transaction.payment_failed") {
const txn = event.data;
await logit.now("payments", {
event: "Paddle payment failed",
description: `Customer ${txn.customer_id} — ${txn.details?.error_code ?? "unknown error"}`,
icon: "❌",
notify: false,
tags: { status: "failed", currency: txn.currency_code?.toLowerCase() ?? "usd" },
metadata: { transactionId: txn.id, customerId: txn.customer_id },
});
}
if (event.event_type === "subscription.cancelled") {
const sub = event.data;
await logit.now("churn", {
event: "Paddle subscription cancelled",
description: `Customer ${sub.customer_id} cancelled`,
icon: "😢",
notify: true,
tags: { status: "cancelled" },
metadata: { subscriptionId: sub.id, customerId: sub.customer_id },
});
}
return new Response("ok");
}
payments channel targeting "Paddle payment failed" to alert on failure clusters.Try LogIt free
7-day trial. No credit card required.