Documentation
Payments

Webhooks

Handle Stripe events, update billing states, and trigger custom logic.

Use Stripe webhooks to correctly keep track of billing states, send user email notifications, and trigger custom post-purchase logic.

The core Stripe webhook handler is located at: src/app/api/payments/webhook/stripe/route.ts

Required Stripe events

Configure these events in your Stripe webhook dashboard to ensure billing operates correctly:

  • checkout.session.completed
  • invoice.payment_succeeded
  • customer.subscription.updated
  • customer.subscription.deleted

Custom Payment Callbacks

When specific billing events occur, the webhook handler fires corresponding callback functions. You can add your custom business logic (e.g., 3rd-party integrations, CRM updates, logging, offboarding flows) inside these functions.

The callback service is located at: src/features/common/payments/service/payment-callback.service.ts

Subscriptions

Subscription Success

Called after a new subscription is activated or an existing one is upgraded.

export async function onSubscriptionSuccess(
  payload: SubscriptionSuccessPayload,
): Promise<void> {
  // Available fields in payload:
  // userId, email, name, planId, planName, amountText
  console.log('[subscription] success', payload);
}

Subscription Cancelled

Called after a user cancels their subscription.

export async function onSubscriptionCancelled(
  payload: SubscriptionCancelledPayload,
): Promise<void> {
  // Available fields in payload:
  // userId, email, name, periodEndText
  console.log('[subscription] cancelled', payload);
}

One-Time Purchases

One-Time Purchase Success

Called after a successful one-time purchase (for both guest and authenticated checkouts).

export async function onOneTimePurchaseSuccess(
  payload: OneTimePurchaseSuccessPayload,
): Promise<void> {
  // Available fields in payload:
  // productId, productName, email, name, amountText, isGuest, userId
  console.log('[one-time] purchase success', payload);
}

Credits

Credits Top-Up

Called after a user purchases a credits top-up package.

export async function onCreditsTopUp(
  payload: CreditsTopUpPayload,
): Promise<void> {
  // Available fields in payload:
  // userId, email, name, creditsAdded, amountText
  console.log('[credits] top-up', payload);
}

On this page