Claude Code Boilerplate
FeaturesPricingBlogDocs
Get started →

Product

  • Features
  • Pricing
  • Skills

Compare

  • vs ShipFast
  • vs MakerKit
  • vs supastarter

Resources

  • Docs
  • Blog
  • Discord

Legal

  • License
  • Privacy Policy
  • Terms of Service
Claude Code Boilerplate

© 2026 Claude Code Boilerplate. All rights reserved.

← All posts

How to Send Slack Alerts From Your Next.js SaaS -- New Signups, Failed Payments, and Support Tickets

August 18, 2026
nextjssaasstripedrizzle-ormwebhooks

Most SaaS founders are in Slack all day. Their product dashboard? Not so much.

That gap costs you real money. A new enterprise signup sits ungreeted for hours. A failed payment gets noticed three days later. A support ticket goes stale while the user churns.

The fix is simple: push the events that matter directly to Slack, and you react in seconds instead of days.

Which events are worth alerting on

Not everything deserves a Slack message. Alert on too much and people start ignoring the channel. A useful rule of thumb:

  • Definitely alert: new paid signup, failed payment, first user from a new country, support ticket opened, plan upgrade
  • Alert with care: free signup (high volume on successful products -- use a dedicated channel), quota reached, 7-day inactive user
  • Skip the alert: every API call, every page view, every login

How Slack incoming webhooks work

Slack lets you create an "incoming webhook" URL for any channel. You POST a JSON body to that URL and a message appears in the channel. No OAuth, no Slack SDK, just a fetch call.

  1. Go to api.slack.com/apps and create a new app for your workspace.
  2. Enable "Incoming Webhooks" and add a webhook to a channel.
  3. Copy the webhook URL.
  4. Save it as SLACK_WEBHOOK_URL in your environment variables.

Sending an alert from a Next.js service

The call belongs in your service layer, not in a route. Here is the helper you need:

// lib/slack.ts
export async function sendSlackAlert(text: string): Promise<void> {
  const url = process.env.SLACK_WEBHOOK_URL;
  if (!url) return; // no-op in local dev
  await fetch(url, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ text }),
  });
}

Returning silently when the URL is missing means alerts do not crash your app in local dev or test environments -- they just do nothing.

Now call it wherever the event happens:

// After a successful signup in user.service.ts
await sendSlackAlert(`New signup: ${user.email} (${plan} plan)`);
 
// After detecting a failed Stripe payment
await sendSlackAlert(`Payment failed: ${user.email} -- card declined`);

Place the sendSlackAlert call after the database write succeeds, never inside a transaction. If Slack is slow or down, you do not want it rolling back your user record.

Formatting messages that are actually readable

Slack accepts richer blocks formatting, but plain text with emoji is readable enough and much easier to maintain. A useful alert format has three parts: what happened, who it involves, and one piece of context:

New signup: alice@example.com (Pro plan) -- referred by google
Payment failed: bob@startup.com -- retries: 2/4
Support ticket #81: carol@corp.com -- "Export not working"

Anything more and people start ignoring the channel.

Wiring it into Stripe webhook events

If you are already handling Stripe webhooks -- which any SaaS with payments should -- adding Slack alerts takes two lines per event:

case "customer.subscription.created":
  const sub = event.data.object as Stripe.Subscription;
  await sendSlackAlert(`New subscriber: ${sub.customer} -- plan ${sub.items.data[0].price.id}`);
  break;
 
case "invoice.payment_failed":
  const inv = event.data.object as Stripe.Invoice;
  await sendSlackAlert(`Payment failed: customer ${inv.customer}`);
  break;

Stripe sends these events every time they happen -- your Slack channel becomes a live stream of your business without any polling.

When to split into multiple channels

One channel is fine to start. Once volume grows, split by urgency:

#saas-revenue   -- paid signups, upgrades, churns
#saas-alerts    -- failed payments, errors, quota hits
#saas-signups   -- all signups including free (can be noisy)

Different webhook URLs, different environment variables. The same sendSlackAlert helper works -- just parameterize the URL.

The 10-minute setup

If you are building on this Next.js SaaS boilerplate, your service layer is already structured for this. Add the lib/slack.ts helper, set one environment variable, and drop two lines into the services that fire the events you care about. No new dependencies, no new infrastructure.

Related reads: how to handle Stripe failed payments and dunning, and error monitoring before your users notice.

Start with new paid signups and failed payments -- that is the 20% of events that drives 80% of the decisions you will make in the next 30 days. Set up the webhook this afternoon, get one real alert, and see how fast you start making better decisions.

Get started with the Next.js SaaS boilerplate and have Slack alerts running before your next deploy.