Stripe integration

Stripe webhooks → else.events → the right billing email

Receive Stripe webhook events in your backend, forward them to else.events and let rules match the right template. No billing email logic in your webhook handler.

Stripe handles payments — not product email workflows

Stripe sends receipts — not your product emails

Stripe can send a receipt. It does not send your onboarding email, your dunning sequence or your plan-change confirmation.

Webhook handlers accumulate email logic

invoice.payment_failed, customer.subscription.updated, checkout.session.completed — each needs its own email path in your webhook handler.

No template management for billing emails

Billing email copy is hardcoded in your webhook handler or in an inline template string.

Dunning logic lives in your app

First failure, second failure, final notice — that sequencing logic ends up in your codebase.

Forward Stripe events — else.events handles email routing

Map Stripe events to else.events event types

Receive the Stripe webhook, validate the signature, extract user and billing data, POST to else.events. One pattern for every Stripe event.

Rules handle the email logic

Set rules: invoice.payment_failed + plan=Pro → Pro dunning template. invoice.payment_failed + attempt=3 → final notice template. No if/else in your handler.

Templates editable without redeploys

Change your payment failed copy or CTA in the else.events dashboard — no webhook handler change.

Full audit: Stripe event to email delivery

See which Stripe event triggered which rule, which template rendered and whether the email was delivered.

// Node.js Stripe webhook → else.events

Forward Stripe events to else.events.

// webhook handler (Express / Next.js route handler)
app.post('/webhooks/stripe', express.raw({ type: 'application/json' }), async (req, res) => {
  const sig = req.headers['stripe-signature'] as string;
  const event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET!);

  if (event.type === 'invoice.payment_failed') {
    const invoice = event.data.object as Stripe.Invoice;
    const customer = await stripe.customers.retrieve(invoice.customer as string) as Stripe.Customer;

    await fetch('https://app.else.events/api/events', {
      method: 'POST',
      headers: { Authorization: `Bearer ${process.env.ELSE_EVENTS_API_KEY}`, 'Content-Type': 'application/json' },
      body: JSON.stringify({
        type: 'invoice.payment_failed',
        user: { email: customer.email!, name: customer.name ?? 'Customer' },
        data: { plan: invoice.metadata?.plan, amount: (invoice.amount_due / 100).toFixed(2),
                currency: invoice.currency.toUpperCase(), attempt: invoice.attempt_count,
                update_payment_url: invoice.hosted_invoice_url },
      }),
    });
  }
  res.json({ received: true });
});

Validate the Stripe signature, extract customer data, forward as an else.events event. Rules and templates handle what email gets sent — not your webhook handler.

Stripe events → emails you can manage

invoice.payment_failed

Payment failed dunning

First, second and final payment failure emails with different copy — handled by rules, not code.

customer.subscription.updated

Subscription updated

Plan upgrade, downgrade or cancellation confirmation with dynamic plan details.

checkout.session.completed

Checkout completed

Welcome and onboarding email when a new customer completes checkout.

customer.subscription.trial_will_end

Trial ending

Reminder email a few days before trial expires — timed via your backend, triggered via else.events.

Frequently asked questions

Do I need to forward every Stripe event?
No. Only forward the events you want to trigger product emails. Ignore Stripe events your app does not need to act on.
How do I handle Stripe retries?
Stripe retries webhook delivery on failure. Make your handler idempotent — check if you've already processed the event.id before forwarding.
Can I test this without real Stripe events?
Yes. Use the Stripe CLI to replay events locally (stripe trigger invoice.payment_failed) and forward to your local webhook handler.
Can else.events replace Stripe email notifications entirely?
No. Stripe sends its own receipts and some system notifications. else.events handles your product emails on top of — not instead of — Stripe.

Stripe billing emails — handled by rules, not webhook code.

Forward Stripe events and let else.events route, render and deliver the right billing email every time.

  • Works with any Stripe webhook setup
  • Rules replace billing email if/else
  • Templates editable without redeploys