Skip to main content

Webhooks

The MLM Platform uses Stripe webhooks to receive real-time notifications about subscription and payment events.

Overview

When events occur in Stripe (e.g., subscription created, payment succeeded), Stripe sends webhook events to the MLM Platform, which then processes them to:
  • Create commission entries for purchases
  • Update subscription statuses
  • Track payment lifecycle events

Setting Up Webhooks

Step 1: Get Your Webhook Endpoint

Your webhook endpoint is:
https://api.mlm-platform.example.com/functions/v1/stripe-webhook
For sandbox environments:
https://api.mlm-platform.example.com/functions/v1/stripe-webhook?environment=sandbox

Step 2: Configure in Stripe Dashboard

  1. Go to Stripe Dashboard
  2. Click Add endpoint
  3. Enter your webhook URL
  4. Select events to listen for (see below)
  5. Click Add endpoint
  6. Copy the Signing secret

Step 3: Save the Webhook Secret

In the MLM Platform Admin Dashboard:
  1. Navigate to Settings > Integrations > Stripe
  2. Enter the webhook signing secret
  3. Click Save

Supported Events

EventDescriptionAction
checkout.session.completedCheckout completedCreates commission entries
invoice.paidInvoice payment succeededRecords purchase event
customer.subscription.createdNew subscriptionCreates subscription record
customer.subscription.updatedSubscription changedUpdates subscription status
customer.subscription.deletedSubscription cancelledMarks subscription inactive

Webhook Signature Verification

All webhook requests are verified using Stripe’s signature verification:
import Stripe from 'stripe';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

async function handleWebhook(req) {
  const sig = req.headers['stripe-signature'];
  const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;
  
  let event;
  try {
    event = stripe.webhooks.constructEvent(
      req.body,
      sig,
      webhookSecret
    );
  } catch (err) {
    console.error('Webhook signature verification failed:', err.message);
    return { status: 400, body: 'Invalid signature' };
  }
  
  // Process the event
  switch (event.type) {
    case 'checkout.session.completed':
      await handleCheckoutComplete(event.data.object);
      break;
    // ... handle other events
  }
  
  return { status: 200, body: 'OK' };
}
Always verify webhook signatures to prevent spoofed requests.

Idempotent Handling

Stripe may send the same event multiple times. Handle this by:
  1. Storing processed event IDs
  2. Checking before processing
async function handleWebhook(event) {
  // Check if already processed
  const existing = await db.webhookEvents.findUnique({
    where: { stripeEventId: event.id }
  });
  
  if (existing) {
    console.log('Event already processed:', event.id);
    return { status: 200, body: 'Already processed' };
  }
  
  // Process the event
  await processEvent(event);
  
  // Mark as processed
  await db.webhookEvents.create({
    data: {
      stripeEventId: event.id,
      type: event.type,
      processedAt: new Date()
    }
  });
  
  return { status: 200, body: 'OK' };
}

Retry Behavior

Stripe retries failed webhook deliveries:
AttemptDelay
1Immediate
25 minutes
330 minutes
42 hours
55 hours
610 hours
7+24 hours (up to 3 days)
Return a 2xx status code quickly to acknowledge receipt. Process events asynchronously if needed.

Testing Webhooks

Using Stripe CLI

# Install Stripe CLI
brew install stripe/stripe-cli/stripe

# Login
stripe login

# Forward webhooks to local server
stripe listen --forward-to localhost:54321/functions/v1/stripe-webhook

# Trigger test events
stripe trigger checkout.session.completed

Using Sandbox Environment

  1. Use Stripe test mode
  2. Use sandbox API keys
  3. Create test subscriptions with test cards
Test card numbers:
  • 4242 4242 4242 4242 - Succeeds
  • 4000 0000 0000 0002 - Declines

Troubleshooting

Webhook Not Received

  1. Check endpoint URL is correct
  2. Verify webhook is enabled in Stripe
  3. Check Stripe webhook logs for errors
  4. Ensure firewall allows Stripe IPs

Signature Verification Failed

  1. Verify webhook secret is correct
  2. Ensure raw request body is used (not parsed JSON)
  3. Check for proxy modifications to headers

Event Processing Failed

  1. Check MLM Platform logs
  2. Verify user exists for the customer
  3. Check commission rules are configured