# Discourse Subscriptions Plugin

**URL:** https://meta.discourse.org/t/discourse-subscriptions-plugin/140818
**Category:** Plugin
**Tags:** official, subscriptions, payments, included-in-core
**Created:** [February 6, 2020, 4:15am UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818 "2020-02-06T04:15:07Z")
**Posts on this page:** 20
**Page:** 2

<div class="post-metadata">

### Author: ![nathank](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nathank/32/290039_2.png) [@nathank](https://meta.discourse.org/u/nathank)
#### Post date: [July 1, 2025, 5:43pm UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/709 "2025-07-01T17:43:06Z")

</div>

Have you got the webhooks configured correctly? I remember these being quite curly to set up, and the instructions of how to do so could be a bit clearer.

---

<div class="post-metadata">

### Author: ![SubStrider](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/substrider/32/512604_2.png) [@SubStrider](https://meta.discourse.org/u/SubStrider)
#### Post date: [July 1, 2025, 5:47pm UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/710 "2025-07-01T17:47:52Z")

</div>

Yeah got the webhooks setup nicely thats how the response was flowing back.

I found out the issue. The instructions are missing a point where we have to setup the custom tags with the group name to be promoted to on Stripe price config page.

Its working fine now for me. The plugin is great but documentation is not detailed.

---

<div class="post-metadata">

### Author: ![MarkDoerr](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/markdoerr/32/549630_2.png) [@MarkDoerr](https://meta.discourse.org/u/MarkDoerr)
#### Post date: [July 1, 2025, 6:17pm UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/711 "2025-07-01T18:17:12Z")

</div>

> [@SubStrider](#):
>
> The instructions are missing a point where we have to setup the custom tags with the group name to be promoted to on Stripe price config page.

Can you explain this just a bit more so we can have someone update the documentation? What custom tag did you add, and where did you add it?

---

<div class="post-metadata">

### Author: ![SubStrider](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/substrider/32/512604_2.png) [@SubStrider](https://meta.discourse.org/u/SubStrider)
#### Post date: [July 1, 2025, 6:29pm UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/712 "2025-07-01T18:29:25Z")

</div>

### **[Guide] How to Set Up Discourse Subscriptions with Stripe Pricing Tables (and Common Pitfalls)**

Hello everyone,

After a lengthy troubleshooting process, I wanted to share a definitive guide for setting up the official `discourse-subscriptions` plugin using the modern **Stripe Pricing Table** method. This approach is powerful but has a few critical steps that are not immediately obvious and can lead to errors like failing webhooks (`404 Not Found`) or users not being added to groups after a successful payment.

Here is the step-by-step process that is confirmed to work.

* * *

### **Part 1: Stripe Configuration**

This process uses Stripe as the “source of truth” for all products and prices.

**1. Create Your Products and Prices**

- In your Stripe Dashboard, make sure you are in **Live Mode**.
- Go to **Products** \> **Product catalog**.
- Create your main products first (e.g., “Premium Membership”, “VIP Access”).
- Under each product, create all the associated prices (e.g., `XX / month`, `XXX / year`).

**2. The CRUCIAL Metadata Step** For the plugin to automatically add users to a group, you must add specific metadata to **every single Price object** you create. The Stripe dashboard UI can make this hard to find.

- When creating a new price (or if you can find the “Edit price” option), you must add metadata. You may need to click on **“Additional options”** during price creation to reveal the metadata fields.
- Click **+ Add metadata** and enter the following:
  - **KEY:** `group_name`
  - **VALUE:** The group’s unique, URL-safe **slug/handle** from Discourse, **not** its full name.

> **Example:**
> 
> - If your Discourse group’s full name is **“Enclave Plus”** , its slug is likely `EnclavePlus`.
> - You must use `EnclavePlus` as the value. Using `"Enclave Plus"` with a space will fail.

- You must repeat this for **every price plan** you want to link to a group.

 ![Screenshot 2025-07-01 at 11.58.13 PM](https://global.discourse-cdn.com/meta/original/4X/2/f/e/2fe0f876448bc6ad1c6076f6d6541a95b7154348.jpeg)

**3. Create Your Stripe Pricing Table**

- Go to **Products \> Pricing tables**.
- Create a new table and add the Prices you just configured.
- After publishing the table, click the “Copy code” button to get your **Pricing table ID** (it starts with `prctbl_...`).

**4. Configure the Webhook Endpoint (The `404` Error Fix)** This is the most common point of failure.

- Go to **Developers \> Webhooks** and click **+ Add endpoint**.
- The **Endpoint URL** must be in the following format:`https://your-discourse-site.com/s/hooks`_Note: The correct path is `/s/hooks`, **not** `/s/stripe/webhook`._
- For **Events to send** , add at a minimum:
  - `checkout.session.completed`
  - `customer.subscription.deleted`

- Create the endpoint and copy the **Signing secret** (it starts with `whsec_...`).

* * *

### **Part 2: Discourse Configuration**

Now, let’s configure the plugin to use everything you set up in Stripe.

**1. Enter API Keys and Pricing Table ID**

- Go to `Admin > Settings` and search for `discourse subscriptions`.
- Fill in your live Stripe keys:
  - `discourse subscriptions public key` (`pk_live_...`)
  - `discourse subscriptions secret key` (`sk_live_...`)
  - `discourse subscriptions webhook secret` (`whsec_...`)

- Enable the pricing table mode:
  - Check the box for `discourse subscriptions pricing table enabled`.
  - Paste your `prctbl_...` ID into the `discourse subscriptions pricing table id` field.

**2. Link Stripe Products to Discourse Groups** Even with a pricing table, you need to tell Discourse which group belongs to which product.

- Go to `Admin > Plugins > Subscriptions` and click the **Products** tab.
- Click **Create New Product**.
- Enter a **Product Name** that **exactly matches** the Product Name in Stripe (e.g., `Enclave Plus`).
- Save the product. On the product’s page, scroll down and click **Add New Plan**.
- This plan is just a “bridge”. The only critical field is **User Group**.
  - **Plan Nickname:** `Enclave Plus Group Link` (or anything for your reference).
  - **User Group:** Select the correct Discourse group from the dropdown.
  - The other fields (Amount, Interval) can be left as default, as they will be ignored.

- Save the plan. Repeat this for all your different products.

* * *

### **Troubleshooting Summary**

- **Problem:** Webhooks are failing with a **`404 Not Found`** error.
  - **Solution:** Your Endpoint URL in Stripe is wrong. It must be `https://your-discourse-site.com/s/hooks`.

- **Problem:** The webhook is successful (`200 OK`) and the payment appears in the user’s billing profile, but they are **not added to the group**.
  - **Solution:** Your metadata is incorrect. Check three things:
    1. The metadata must be on the **Stripe Price** object, not the Product object.
    2. The metadata KEY must be exactly `group_name`.
    3. The metadata VALUE must be the group’s unique **slug/handle** (e.g., `EnclavePlus`), not its full name with spaces.

I hope this guide saves others the time and frustration of this complex but very powerful setup.

---

<div class="post-metadata">

### Author: ![jessii](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jessii/32/354015_2.png) [@jessii](https://meta.discourse.org/u/jessii)
#### Post date: [July 1, 2025, 11:46pm UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/713 "2025-07-01T23:46:14Z")

</div>

> [@SubStrider](#):
>
> **4. Configure the Webhook Endpoint (The `404` Error Fix)** This is the most common point of failure.
> 
> - Go to **Developers \> Webhooks** and click **+ Add endpoint**.
> - The **Endpoint URL** must be in the following format:`https://your-discourse-site.com/s/hooks` _Note: The correct path is `/s/hooks`, **not** `/s/stripe/webhook`._
> - For **Events to send** , add at a minimum:
> - `checkout.session.completed`
> - `customer.subscription.deleted`
> 
> - Create the endpoint and copy the **Signing secret** (it starts with `whsec_...`).

I just tested this out and it was perfect! We will go ahead and update the original documentation to include this!

---

<div class="post-metadata">

### Author: ![SubStrider](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/substrider/32/512604_2.png) [@SubStrider](https://meta.discourse.org/u/SubStrider)
#### Post date: [July 2, 2025, 5:15am UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/714 "2025-07-02T05:15:36Z")

</div>

> [@SubStrider](#):
>
> **2. The CRUCIAL Metadata Step** For the plugin to automatically add users to a group, you must add specific metadata to **every single Price object** you create. The Stripe dashboard UI can make this hard to find.
> 
> - When creating a new price (or if you can find the “Edit price” option), you must add metadata. You may need to click on **“Additional options”** during price creation to reveal the metadata fields.
> - Click **+ Add metadata** and enter the following:
> - **KEY:** `group_name`
> - **VALUE:** The group’s unique, URL-safe **slug/handle** from Discourse, **not** its full name.
> 
> > **Example:**
> > 
> > - If your Discourse group’s full name is **“Enclave Plus”** , its slug is likely `EnclavePlus`.
> > - You must use `EnclavePlus` as the value. Using `"Enclave Plus"` with a space will fail.
> 
> - You must repeat this for **every price plan** you want to link to a group.
> 
> ![Screenshot 2025-07-01 at 11.58.13 PM](https://global.discourse-cdn.com/meta/original/4X/2/f/e/2fe0f876448bc6ad1c6076f6d6541a95b7154348.jpeg)

The key missing part in the documentation is this. Pointing out since you quoted another part.

---

<div class="post-metadata">

### Author: ![TheNab](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/thenab/32/510092_2.png) [@TheNab](https://meta.discourse.org/u/TheNab)
#### Post date: [July 2, 2025, 6:48am UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/715 "2025-07-02T06:48:23Z")

</div>

Is there any way to automatically set the anchor date with this? If someone pays I have to manually adjust the subscription period to reset on the 1st of the month for every user within Stripe.

Stripe documentation says it can be done with API at checkout but we don’t currently have a way to adjust it in the plugin.

---

<div class="post-metadata">

### Author: ![SubStrider](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/substrider/32/512604_2.png) [@SubStrider](https://meta.discourse.org/u/SubStrider)
#### Post date: [July 7, 2025, 8:35am UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/716 "2025-07-07T08:35:18Z")

</div>

> [@Enhancements to the Subscriptions Plugin](https://meta.discourse.org/t/enhancements-to-the-subscriptions-plugin/373165):
>
> Hello, I have made the following changes to this plugin and wanted to know if the Discourse team is open to a PR. Would also love if others can do an extensive testing. I am right now testing the flows with whatever scenarios are critical to me. The original plugin is an excellent foundation but is primarily focused on recurring subscriptions via Stripe. Have made the following changes: Summary of New Features & Enhancements 1. Multi-Provider Payment System (feat. Razorpay) The plugin is no …

Moving this to the new thread as it could get long as I post updates.

---

<div class="post-metadata">

### Author: ![tobiaseigen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tobiaseigen/32/539204_2.png) [@tobiaseigen](https://meta.discourse.org/u/tobiaseigen)
#### Post date: [July 16, 2025, 9:50pm UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/719 "2025-07-16T21:50:33Z")

</div>

🥳 This plugin is now bundled with Discourse core as part of [Bundling more popular plugins with Discourse core](https://meta.discourse.org/t/bundling-more-popular-plugins-with-discourse-core/373574). If you are self-hosting and use the plugin, you need to remove it from your `app.yml` before your next upgrade.

---

<div class="post-metadata">

### Author: ![SubStrider](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/substrider/32/512604_2.png) [@SubStrider](https://meta.discourse.org/u/SubStrider)
#### Post date: [July 17, 2025, 12:40am UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/720 "2025-07-17T00:40:52Z")

</div>

How do I remove it from the core before upgrading? As I would be using the plugin fork that I have enhanced.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [July 17, 2025, 7:03am UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/722 "2025-07-17T07:03:06Z")

</div>

Something like

`rm - rf discourse-subscroptions`

Before the `git clone`.

---

<div class="post-metadata">

### Author: ![SubStrider](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/substrider/32/512604_2.png) [@SubStrider](https://meta.discourse.org/u/SubStrider)
#### Post date: [July 17, 2025, 9:43am UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/723 "2025-07-17T09:43:42Z")

</div>

Sorry did not understand, during the rebuild it will fetch this integrated plugin code and build it, all in one step, isnt it?

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [July 17, 2025, 4:06pm UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/725 "2025-07-17T16:06:37Z")

</div>

I haven’t tested this, but I’m pretty sure this will work:

```plaintext
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - rm -rf discourse-subscriptions
          - git clone https://github.com/yourForkUser/discourse-subscriptions

```

Since this gets run from the plugins directory, it’ll remove the `discourse-subscriptions` that’s now included in core and replace it with the one that you’ve always used before. So adding just that `rm -rf` to your `app.yml` before your `git clone` (for this or any other plugin you want not included or to replace) should do what you want and replace the core plugin with your fork.

---

<div class="post-metadata">

### Author: ![SubStrider](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/substrider/32/512604_2.png) [@SubStrider](https://meta.discourse.org/u/SubStrider)
#### Post date: [July 18, 2025, 12:21am UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/726 "2025-07-18T00:21:35Z")

</div>

Alright so when they say that X plugin is part of core now, all they mean is that the plugin will be pre-packaged in the core repo in the plugin directory and we don’t have to pull that code optionally. Got it. Structurally nothing changes.

---

<div class="post-metadata">

### Author: ![TheNab](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/thenab/32/510092_2.png) [@TheNab](https://meta.discourse.org/u/TheNab)
#### Post date: [July 24, 2025, 1:01am UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/729 "2025-07-24T01:01:58Z")

</div>

If it’s prepacked now. Will I lose all the data in the plugin version? Will I have to set it up all over again or will it carry over?

---

<div class="post-metadata">

### Author: ![tobiaseigen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tobiaseigen/32/539204_2.png) [@tobiaseigen](https://meta.discourse.org/u/tobiaseigen)
#### Post date: [July 24, 2025, 1:24am UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/730 "2025-07-24T01:24:15Z")

</div>

You will not lose data. Just remove the line from `app.yml` and the plugin will continue working as before.

---

<div class="post-metadata">

### Author: ![jrgong](https://avatars.discourse-cdn.com/v4/letter/j/c57346/32.png) [@jrgong](https://meta.discourse.org/u/jrgong)
#### Post date: [July 26, 2025, 11:34am UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/732 "2025-07-26T11:34:26Z")

</div>

Is it expected behavior that after entering a coupon code, the total subscription amount does not update immediately?

Tested on Discourse 3.5.0.beta8-dev

---

<div class="post-metadata">

### Author: ![RowBro](https://avatars.discourse-cdn.com/v4/letter/r/85f322/32.png) [@RowBro](https://meta.discourse.org/u/RowBro)
#### Post date: [July 27, 2025, 8:56am UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/733 "2025-07-27T08:56:00Z")

</div>

I’ve found that if a user attempts to sign up and their payment fails, the entry in the `discourse_subscriptions_customer` table associating them to their stripe customer id is removed. I’m not sure if this behaviour is intentional, but regardless, I don’t think it is a good behaviour since it results in orphaned customers in stripe which have to be manually deleted. This also results in duplicate customers being created if they retry which can impact our reporting.

---

<div class="post-metadata">

### Author: ![TheNab](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/thenab/32/510092_2.png) [@TheNab](https://meta.discourse.org/u/TheNab)
#### Post date: [August 1, 2025, 4:21am UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/734 "2025-08-01T04:21:50Z")

</div>

Is there any way to reset the campaign? Was hoping for a monthly donation goal but it’s the start of a new month and I don’t see a way to reset it back to zero for a new monthly goal.

---

<div class="post-metadata">

### Author: ![chrismalone](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/chrismalone/32/506946_2.png) [@chrismalone](https://meta.discourse.org/u/chrismalone)
#### Post date: [August 5, 2025, 12:47pm UTC](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818/735 "2025-08-05T12:47:18Z")

</div>

I would love to see this plugin in action on a site. Is anyone willing to share the link to their forum that uses Subscriptions Plugin? Thanks!

[Previous page](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818.md?page=1)

[Next page](https://meta.discourse.org/t/discourse-subscriptions-plugin/140818.md?page=3)
