Webhook for Subscription Product: SaaS Use Case

You’ve built a SaaS product. Free users can create up to 3 projects. Pro subscribers get unlimited projects, priority support, and API access. The plan should upgrade the moment someone pays and downgrade the moment they cancel.

This is what a webhook for subscription products solves. Every time something happens to a customer’s subscription (signup, renewal, or cancellation) Vandly sends a real-time POST request to your server. Your server reads the event and updates the user’s plan instantly. No polling, no manual checks, no support tickets about missing access.

This article walks through the full integration for this scenario: the events you’ll receive, how to handle each one, the technical setup, and what to do after go-live to make sure it holds up in production.

The Use Case: SaaS Feature Gating

Imagine your SaaS has three plan tiers:

PlanAccessManaged By
Free3 projects, basic featuresDefault on signup
Pro (monthly)Unlimited projects, API access, priority supportVandly subscription webhook
Pro (yearly)Same as monthly, discounted rateVandly subscription webhook

When a user subscribes to Pro via Vandly, your server receives a subscription.created event and sets their plan to pro. When they renew, subscription.renewed keeps them on pro. When they cancel, subscription.canceled drops them back to free. Everything automated, nothing manual.

How to Set Up a Webhook for Subscription Product on Vandly

Setting up a webhook for SaaS subscription in Vandly takes 5 steps in the product wizard. Here’s exactly what you’ll see:

Step 1: Product Type

From the Products page, click + New Product. On the Create New Product screen:

  • Under ‘How will customers pay?’, select Subscription (customers are billed on a recurring monthly or yearly basis)
  • Under ‘How do you want to manage subscriber access?’, select Webhook (Vandly calls your endpoint on subscription events: created, renewed, canceled)
  • In the Webhook URL field that appears, enter your publicly accessible HTTPS endpoint — e.g. https://api.yourapp.com/webhooks/vandly
  • Note: Vandly signs every request with an HMAC secret so you can verify it came from them

Step 2: Details and Pricing

Fill in your product details:

  • Product Name: e.g. ‘YourSaaS Pro Plan’
  • Description: describe what Pro subscribers get access to
  • Category: select the category that best fits your SaaS tool
  • Billing model: choose Recurring (bill customers monthly and/or yearly) or Lifetime (customers pay once and keep access forever)
  • If Recurring: check Monthly, Yearly, or both (set the price for each)
  • If Lifetime: set the price for customers pay once and keep access forever
  • Delivery Method — Email Delivery: product details sent by email after purchase

Step 3: Policy

Vandly auto-configures three subscription policies:

  • Refund Policy: No Partial Refunds — customers can cancel anytime; access continues until the end of the current billing period
  • Access Duration: Active Subscription — customers retain access as long as their subscription stays active; access ends automatically if a renewal payment fails or the subscription is canceled
  • Fulfillment Failure Policy — Vandly notifies your webhook endpoint on subscription events and automatically retries failed deliveries; if events consistently fail, Vandly will help you troubleshoot

These are automatically applied, no action needed. Click Next.

Step 4: Additional Information

Optional fields that help Vandly optimise your product listing:

  • Previous Platform URL: if you’ve sold this SaaS tool on Gumroad, Etsy, or elsewhere, paste the link
  • Demo Link: link to a live demo or interactive preview of your product
  • Embedded URL: an iframe-friendly URL if you want to embed a product preview
  • Expected Monthly Sales: your estimate helps Vandly optimise your product page

Step 5: Review and Confirm

Review your product in preview mode, this is exactly how it will appear to customers once approved. Confirm:

  • The product shows the correct name, price, and status
  • Delivery Information shows: Delivery Method: Email, Access Duration: Subscription, and the correct Fulfillment Failure Policy
  • Pricing & Policy shows the billing model (Recurring or Lifetime), Fulfillment: Subscription · Webhook, and Refund Policy: Non-Refundable
  • Tick all three confirmations: No illegal or harmful content, Accurate information, I own the rights
  • Click Save Changes to submit for review

After submission, your product goes into Pending status. Once approved, your webhook URL is live. Vandly will send subscription events to your endpoint immediately when a customer subscribes, renews, or cancels.

After Approval: Find Your Signing Secret

Once your product is approved, go to Products > your product > Overview & Settings. You’ll see a Webhook section showing:

  • Endpoint URL: the webhook URL you entered during setup, shown here for confirmation
  • Active status: a green ‘Active’ badge confirming the webhook is live
  • Signing Secret:  displayed as masked dots (••••••••••••)

Click Show secret to reveal your HMAC signing secret. Copy it immediately and store it as an environment variable on your server, for example VANDLY_WEBHOOK_SECRET. This is the secret you’ll use to verify every incoming webhook request is genuinely from Vandly.

Never put the signing secret in client-side code, a public repo, or your frontend. It lives on your server only. Anyone who has it can send fake subscription events to your endpoint, upgrading or downgrading user plans at will.

You can return to this page at any time to reveal the secret again if you need to reconfigure your server. The secret doesn’t change unless you regenerate it.

The Full Event Flow

Here’s what happens end to end for each subscription event:

subscription.created — Upgrade to Pro

A user clicks Subscribe on your pricing page. They’re taken to your Vandly checkout. Payment succeeds. Vandly sends subscription.created to your endpoint within seconds.

Your server should:

  • Find the user by customerEmail in your database
  • Set their plan field to ‘pro’
  • Store the subscriptionId, you’ll need it to match future events
  • Unlock the gated features (unlimited projects, API access, priority support)
  • Send a confirmation email: “You’re now on Pro. Here’s what’s unlocked.”

if (event.event === “subscription.created”) {

  const { subscriptionId, customerEmail } = event.data;

  const user = await db.users.findByEmail(customerEmail);

  if (!user) {

    // Edge case: no account yet — create one

    await db.users.create({ email: customerEmail, plan: “pro”, subscriptionId });

  } else {

    await db.users.update(user.id, { plan: “pro”, subscriptionId });

  }

  await sendUpgradeEmail(customerEmail);

}

subscription.renewed — Keep Pro Active

Every billing period, Vandly charges the customer automatically. When it succeeds, you receive subscription.renewed. In most cases the user is already on pro, so the primary action is confirming that status and updating any period tracking you maintain.

Your server should:

  • Find the user by subscriptionId (not email, they may have changed it on your platform)
  • Confirm their plan is still ‘pro’, restore it if somehow it was reset
  • Update any renewal timestamp you track for internal analytics

if (event.event === “subscription.renewed”) {

  const { subscriptionId } = event.data;

  const user = await db.users.findBySubscriptionId(subscriptionId);

  if (!user) return; // unexpected — log for investigation

  await db.users.update(user.id, {

    plan: “pro”,

    lastRenewedAt: event.timestamp,

  });

}

subscription.canceled — Downgrade to Free

The user cancels. Vandly sends subscription.canceled. Your server needs to downgrade their plan immediately or at the end of their current billing period, depending on your policy.

Your server should:

  • Find the user by subscriptionId
  • Set their plan to ‘free’
  • Clear the subscriptionId from their record
  • Re-enforce free-tier limits (e.g. if they have more than 3 projects, show a downgrade prompt on next login, don’t delete their data)
  • Send a cancellation confirmation email

if (event.event === “subscription.canceled”) {

  const { subscriptionId } = event.data;

  const user = await db.users.findBySubscriptionId(subscriptionId);

  if (!user) return;

  await db.users.update(user.id, {

    plan: “free”,

    subscriptionId: null,

  });

  // Don’t delete projects — show downgrade prompt on next login

  await sendCancellationEmail(user.email);

}

What to Do After Setup

1. Test the full upgrade and downgrade flow

Use a real test subscription on Vandly and confirm the plan field changes correctly in your database for all three events. Don’t assume it works, verify it. Check that:

  • A new subscription sets plan to ‘pro’ and stores subscriptionId
  • A renewal confirms the user is still on ‘pro’
  • A cancellation sets plan to ‘free’ and clears subscriptionId

2. Look up renewals and cancellations by subscriptionId

A user might change their email on your platform after subscribing. Renewal and cancellation events carry the subscriptionId from the original subscription.created event, use that to find them, not email.

3. Don’t delete user data on downgrade

When a user downgrades from pro to free, enforce the free limits but preserve their data. If they had 10 projects on pro and free allows 3, show a prompt on their next login, don’t delete 7 projects. If they resubscribe, they should be right back where they left off.

4. Check the Webhook Delivery Log regularly

Go to Product Details > Subscriptions tab > Webhook Delivery Log. A failed delivery means a user’s plan wasn’t updated — they may be locked out after paying, or retaining pro access after canceling. Both are live product issues. The log shows you the event type, response code, number of attempts, and timestamp of each delivery attempt.

Retries

If your endpoint doesn’t respond successfully, Vandly retries up to 6 times:

AttemptWhen
1When the event happens
2After 1 minute
3After 5 minutes
4After 30 minutes
5After 2 hours
6After 12 hours

If all 6 fail, the delivery is marked failed in the log. Manually update the affected user’s plan and investigate why your endpoint was unreachable. Contact info@vandly.co if you need help identifying the delivery.

Frequently Asked Questions

What if a user subscribes but doesn’t have an account on my platform yet?

Handle it in the subscription.created event: if no account exists for that email, create one. Give them a temporary password or a magic login link in the welcome email. Don’t assume the user already exists.

Can the same event arrive twice?

Yes, if your server processed a request but didn’t respond within 10 seconds, Vandly retries. Build your handler to be idempotent: check whether the plan is already set before setting it again.

Should I look up users by email or subscriptionId?

Use email for subscription.created, it’s how you match the subscriber to an existing account. Use subscriptionId for subscription.renewed and subscription.canceled, it’s stable even if their email changes on your platform.

What if I want to give users access until the end of their billing period after canceling?

Don’t immediately downgrade on subscription.canceled. Instead, store the event and schedule the downgrade for the end of their current period. The event tells you they’ve canceled, your platform decides when to enforce it.

Do I need an API key to receive webhooks?

No. Vandly pushes events to your endpoint. The webhook secret is only used to verify incoming requests, you don’t need to authenticate with Vandly to receive them.

Start selling subscriptions on Vandly → Your first sale is free.

Prefer a simpler access model without server-side events? See License Key for Subscription Products: How It Works.