# 用户取消订阅后无法重新购买订阅产品

**URL:** https://meta.discourse.org/t/user-cant-repurchase-a-subscription-product-after-canceling/199602
**Category:** Support
**Tags:** subscriptions
**Created:** [2021年八月6日 20:49 UTC](https://meta.discourse.org/t/user-cant-repurchase-a-subscription-product-after-canceling/199602 "2021-08-06T20:49:11Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![amalg](https://avatars.discourse-cdn.com/v4/letter/a/ed655f/32.png) [@amalg](https://meta.discourse.org/u/amalg)
#### Post date: [2021年八月6日 20:49 UTC](https://meta.discourse.org/t/user-cant-repurchase-a-subscription-product-after-canceling/199602/1 "2021-08-06T20:49:11Z")

</div>

我这里遇到一个奇怪的问题，涉及一位订阅用户。

在“计费”部分，他们没有任何有效的订阅：

 ![image](https://global.discourse-cdn.com/meta/original/3X/2/e/2ee8373983ac36eb6a8da1237d1f39e41392f97c.png)

在 Stripe 中显示为已取消：

![image](https://global.discourse-cdn.com/meta/original/3X/c/5/c5b203481bb7470ed866e8d5813ddf1d80d5baf7.png)

但他们无法重新订阅，系统提示“已购买”：

![image](https://global.discourse-cdn.com/meta/original/3X/6/3/63d8e2047e45aaddd3197d187a107524b06bd597.png)

是我哪里设置不正确吗？

---

<div class="post-metadata">

### Author: ![justin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/justin/32/157614_2.png) [@justin](https://meta.discourse.org/u/justin)
#### Post date: [2021年八月7日 16:50 UTC](https://meta.discourse.org/t/user-cant-repurchase-a-subscription-product-after-canceling/199602/2 "2021-08-07T16:50:12Z")

</div>

这看起来可能是您的 webhook 端点配置不当。当订阅期结束时，Stripe 会发送一个 webhook，插件会利用它来移除群组会员资格，并将该用户从该产品的现有客户列表中移除（从而允许用户再次购买）。

您需要按照此处 [Discourse 订阅](https://meta.discourse.org/t/discourse-subscriptions/140818) 的原帖说明进行配置。

**一种从服务器确认的方法：**

```ruby
./launcher enter app
rails c
u = User.find_by_username(<username>)
c = DiscourseSubscriptions::Customer.where(user_id: u.id)
subscription = DiscourseSubscriptions::Subscription.where(customer_id: c.customer_id)

```

请务必将 `<username>` 替换为实际的用户名。

如果 `subscription` 返回 `[]`，则说明存在其他问题。但如果它返回了某个值，这很可能证实了 webhook 缺失的问题。

**若要删除 `DiscourseSubscriptions::Subscription` 条目，以便用户可以再次购买该产品：**

先运行 `subscription.count`，确保 `subscription` 只包含一个值。如果返回的值大于 1，您需要进一步排查，以确保删除的是正确的订阅实例。如果删除了错误的条目，您的订阅数据将处于不一致状态，并可能导致异常行为。

一旦确认只有一个订阅，即可运行：

```ruby
subscription.destroy_all

```

请注意，`subscription` 是我们在 Rails 控制台中执行初始查询后返回的值。

希望这能帮到您！

---

<div class="post-metadata">

### Author: ![amalg](https://avatars.discourse-cdn.com/v4/letter/a/ed655f/32.png) [@amalg](https://meta.discourse.org/u/amalg)
#### Post date: [2021年八月9日 21:21 UTC](https://meta.discourse.org/t/user-cant-repurchase-a-subscription-product-after-canceling/199602/3 "2021-08-09T21:21:23Z")

</div>

谢谢 @justin

• 执行到了最后一行订阅代码并运行，返回了以下错误：

> NoMethodError: undefined method `customer_id' for #<DiscourseSubscriptions::Customer::ActiveRecord_Relation:0x000055be473772f0> from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activerecord-6.1.3.2/lib/active_record/relation/delegation.rb:110:in `method\_missing’

• 检查了 Stripe 的 Webhook 配置，它指向 https://./s/hooks

• 已发送到 Webhook 的事件包括：

- 

```
subscription_schedule.updated

```

- 

```
subscription_schedule.expiring

```

- 

```
subscription_schedule.created

```

- 

```
subscription_schedule.canceled

```

• Stripe 的 Webhook 日志中仅有一条来自设置日期的记录，看起来是在建立支持的事件列表。

• 我在 Stripe 中有一条订阅取消的事件记录，但该行条目显示（大致）为“[订阅已取消]"。然而，当我点击进入该事件详情时，显示事件类型为 customer.subscription.deleted……我注意到这个类型并未列在我的 Webhook 事件列表中。

上述情况是否可能是问题所在？

---

<div class="post-metadata">

### Author: ![justin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/justin/32/157614_2.png) [@justin](https://meta.discourse.org/u/justin)
#### Post date: [2021年八月9日 21:26 UTC](https://meta.discourse.org/t/user-cant-repurchase-a-subscription-product-after-canceling/199602/4 "2021-08-09T21:26:21Z")

</div>

> [@amalg](#):
>
> \<DiscourseSubscriptions::Customer::

看起来这一行应该是 `DiscourseSubscriptions::Subscription` 而不是 `::Customer`。试试看，看看结果如何！

---

<div class="post-metadata">

### Author: ![amalg](https://avatars.discourse-cdn.com/v4/letter/a/ed655f/32.png) [@amalg](https://meta.discourse.org/u/amalg)
#### Post date: [2021年八月9日 21:42 UTC](https://meta.discourse.org/t/user-cant-repurchase-a-subscription-product-after-canceling/199602/5 "2021-08-09T21:42:49Z")

</div>

> [2] pry(main)\> c = DiscourseSubscriptions::Subscription.where(user\_id: u.id)  
> =\> #DiscourseSubscriptions::Subscription::ActiveRecord\_Relation:0x8020  
> [3] pry(main)\> subscription = DiscourseSubscriptions::Subscription.where(customer\_id: c.customer\_id)  
> NoMethodError: 未定义方法 `customer_id'，对象为 #<DiscourseSubscriptions::Subscription::ActiveRecord_Relation:0x000055ec51164ca0> 来自 /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activerecord-6.1.3.2/lib/active_record/relation/delegation.rb:110:in `method\_missing’

---

<div class="post-metadata">

### Author: ![justin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/justin/32/157614_2.png) [@justin](https://meta.discourse.org/u/justin)
#### Post date: [2021年八月9日 21:45 UTC](https://meta.discourse.org/t/user-cant-repurchase-a-subscription-product-after-canceling/199602/6 "2021-08-09T21:45:19Z")

</div>

抱歉，我误解了问题发生的位置。

请尝试以下方法：

```plaintext
./launcher enter app
rails c
u = User.find_by_username(<username>)
c = DiscourseSubscriptions::Customer.find_by(user_id: u.id)
subscription = DiscourseSubscriptions::Subscription.where(customer_id: c[:customer_id])

```

---

<div class="post-metadata">

### Author: ![amalg](https://avatars.discourse-cdn.com/v4/letter/a/ed655f/32.png) [@amalg](https://meta.discourse.org/u/amalg)
#### Post date: [2021年八月9日 22:10 UTC](https://meta.discourse.org/t/user-cant-repurchase-a-subscription-product-after-canceling/199602/7 "2021-08-09T22:10:09Z")

</div>

啊……

> [3] pry(main)\> subscription = DiscourseSubscriptions::Subscription.where(customer\_id: c[:customer\_id])  
> =\>

---

<div class="post-metadata">

### Author: ![amalg](https://avatars.discourse-cdn.com/v4/letter/a/ed655f/32.png) [@amalg](https://meta.discourse.org/u/amalg)
#### Post date: [2021年八月11日 18:41 UTC](https://meta.discourse.org/t/user-cant-repurchase-a-subscription-product-after-canceling/199602/8 "2021-08-11T18:41:53Z")

</div>

您认为缺少订阅数据是否与 customer.subscription.deleted 事件缺失有关？

目前我接下来应该探索哪些方面？

我特别关注为什么订阅页面显示“已购买”，而活跃订阅部分却没有任何活跃订阅。数据库中是否存在其他存储订阅信息的位置，该位置在活跃订阅部分可能被清除或为空，但某个地方的“已购买”布尔值仍被设置为 true，或是类似的情况？

---

<div class="post-metadata">

### Author: ![amalg](https://avatars.discourse-cdn.com/v4/letter/a/ed655f/32.png) [@amalg](https://meta.discourse.org/u/amalg)
#### Post date: [2021年八月23日 17:25 UTC](https://meta.discourse.org/t/user-cant-repurchase-a-subscription-product-after-canceling/199602/9 "2021-08-23T17:25:20Z")

</div>

还有什么其他可以尝试的吗？

---

<div class="post-metadata">

### Author: ![justin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/justin/32/157614_2.png) [@justin](https://meta.discourse.org/u/justin)
#### Post date: [2021年八月24日 16:42 UTC](https://meta.discourse.org/t/user-cant-repurchase-a-subscription-product-after-canceling/199602/10 "2021-08-24T16:42:35Z")

</div>

请确保在 Stripe 中该订单已完全取消，而不是等待周期结束时取消。您还可以进入 管理 –\u003e 插件 –\u003e Discourse 订阅 –\u003e 订阅 区域，查找该用户的用户名。如果此处列出了该用户的订阅，您可以立即取消它。

在不进一步查看您的 Discourse 实例的情况下，我不确定还能提供多少帮助。

---

<div class="post-metadata">

### Author: ![amalg](https://avatars.discourse-cdn.com/v4/letter/a/ed655f/32.png) [@amalg](https://meta.discourse.org/u/amalg)
#### Post date: [2021年八月24日 20:51 UTC](https://meta.discourse.org/t/user-cant-repurchase-a-subscription-product-after-canceling/199602/11 "2021-08-24T20:51:55Z")

</div>

是的，它在插件区域的订阅下并未激活，Stripe 上也没有显示。唯一表明仍有活动状态的迹象是：如果用户进入订阅页面，会看到一个绿色的小“已购买”勾选标记以及“前往账单”按钮。

![image](https://global.discourse-cdn.com/meta/original/3X/e/a/ea8a44667e32914ca219c103c021164d9349fd66.png)

如果我以该用户身份进入账单页面，则没有任何显示：

 ![image](https://global.discourse-cdn.com/meta/original/3X/c/8/c845f980a1f387cffa84eb49ad3c4c901c6b8b8b.png)

所以我的问题是：数据库中是什么触发了那个绿色勾选标记？能否将其清除？

---

<div class="post-metadata">

### Author: ![justin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/justin/32/157614_2.png) [@justin](https://meta.discourse.org/u/justin)
#### Post date: [2021年八月24日 22:46 UTC](https://meta.discourse.org/t/user-cant-repurchase-a-subscription-product-after-canceling/199602/12 "2021-08-24T22:46:40Z")

</div>

> <https://github.com/discourse/discourse-subscriptions/blob/6e96f073788212b9c832fa397850e377a3298c47/app/controllers/discourse_subscriptions/subscribe_controller.rb#L161-L168>

如果此列表包含了此处所示的 Stripe 产品 ID：

> <https://github.com/discourse/discourse-subscriptions/blob/6e96f073788212b9c832fa397850e377a3298c47/app/controllers/discourse_subscriptions/subscribe_controller.rb#L156>

那么前端将会显示为已购买。您可能需要利用这些查询在控制台中深入查找，以确定其具体位置。我几乎可以肯定，那里仍有一条记录残留着。

---

<div class="post-metadata">

### Author: ![amalg](https://avatars.discourse-cdn.com/v4/letter/a/ed655f/32.png) [@amalg](https://meta.discourse.org/u/amalg)
#### Post date: [2023年二月2日 06:36 UTC](https://meta.discourse.org/t/user-cant-repurchase-a-subscription-product-after-canceling/199602/13 "2023-02-02T06:36:11Z")

</div>

好的，我知道我是在“复活”这个帖子，但首先 1) 这个问题一直没有得到解决，其次 2) 我花了一些时间重新研究这个问题……结果发现我是一个连说明都看不懂的白痴。我就是这样发现自己是个笨蛋的，也是为什么我现在准备（在一些帮助下）解决这个问题。

我最终的做法是从 Stripe 导出所有已取消帐户的 CSV。我重点关注了该主题中前面提到的 Discourse 用户，他是一名订阅者，已经取消了订阅，但之后无法重新订阅，因为订阅页面显示为“已购买”，尽管他的活动订阅页面没有显示任何订阅。在 CSV 数据中，他的记录显示为“已取消”，数据如下：

- **id** (sub\_JNWejdDo4qhLG5)
- **customer\_id** (cus\_JmiMoqZNTzUNxt)
- **user\_id** (discourse 用户 ID 4981)

然后我附加到应用程序容器，进入 Ruby 控制台，开始进行一些探索。首先，我在 DiscourseSubscriptions::Customer 中搜索了他的 customer\_id，找到了它。

```plaintext
[3] pry(main)> DiscourseSubscriptions::Customer.where(customer_id: 'cus_JNWeiIWTs6YOwQ')
=> [#<DiscourseSubscriptions::Customer:0x000055db2d48eb40
  id: 16,
  customer_id: "cus_JNWeiIWTs6YOwQ",
  product_id: "prod_JJbwYnKz0T5Z9h",
  user_id: 3256,
  created_at: Tue, 27 Apr 2021 07:45:07.455275000 UTC +00:00,
  updated_at: Tue, 27 Apr 2021 07:45:07.455275000 UTC +00:00>]

```

接下来，我搜索 DiscourseSubscriptions::Subscription，看看这个用户是否有任何订阅，结果是有的，确实有；

```plaintext
[1] pry(main)> DiscourseSubscriptions::Subscription.where(external_id: 'sub_JNWejdDo4qhLG5')
=> [#<DiscourseSubscriptions::Subscription:0x000055854e1e1620
  id: 16,
  customer_id: 16,
  external_id: "sub_JNWejdDo4qhLG5",
  created_at: Tue, 27 Apr 2021 07:45:07.459681000 UTC +00:00,
  updated_at: Tue, 27 Apr 2021 07:45:07.459681000 UTC +00:00>]

```

所以，看起来我只需要删除这个订阅记录就可以解决——至少对这个用户来说。事实是，我在 CSV 导出中检查的每个已取消订阅的用户在系统中仍然有剩余的订阅。显然，Stripe 网页钩子和订阅插件之间在某个地方存在某种断开……我只是不知道在哪里/如何。

- 首先；我如何安全地删除特定用户的订阅记录数据？像我 5 岁一样解释给我听……我现在在 Ruby 控制台提示符下……我如何确保只删除目标用户的订阅数据，而不会清除所有人的订阅数据？

- 其次，我如何对订阅取消网页钩子机制进行故障排除？

非常感谢您的所有帮助！

**更新：**

好的，我取得了一些进展……我设法弄清楚如何使用 `.delete_by` 来仅删除目标用户的订阅数据；

```plaintext
[1] pry(main)> DiscourseSubscriptions::Subscription.delete_by(external_id: 'sub_JNWejdDo4qhLG5')
[2] pry(main)> DiscourseSubscriptions::Subscription.where(external_id: 'sub_JNWejdDo4qhLG5')
=> []

```

但是，客户记录仍然有一个与之关联的 `product_id`；

```plaintext
[3] pry(main)> DiscourseSubscriptions::Customer.where(customer_id: 'cus_JNWeiIWTs6YOwQ')
=> [#<DiscourseSubscriptions::Customer:0x0000560ec18e4948
  id: 16,
  customer_id: "cus_JNWeiIWTs6YOwQ",
  product_id: "prod_JJbwYnKz0T5Z9h",
  user_id: 3256,
  created_at: Tue, 27 Apr 2021 07:45:07.455275000 UTC +00:00,
  updated_at: Tue, 27 Apr 2021 07:45:07.455275000 UTC +00:00>]

```

这意味着他们仍然看到绿色复选标记，并且无法重新订阅……所以我对 Customer 对象应用了“destroy\_all”……它奏效了！但当然只对那个用户有效……

```plaintext
[4] pry(main)> DiscourseSubscriptions::Customer.where(customer_id: 'cus_JNWeiIWTs6YOwQ').destroy_all
=> [#<DiscourseSubscriptions::Customer:0x0000560ec19770e0
  id: 16,
  customer_id: "cus_JNWeiIWTs6YOwQ",
  product_id: "prod_JJbwYnKz0T5Z9h",
  user_id: 3256,
  created_at: Tue, 27 Apr 2021 07:45:07.455275000 UTC +00:00,
  updated_at: Tue, 27 Apr 2021 07:45:07.455275000 UTC +00:00>]

```

所以现在只剩下诊断为什么 Stripe 取消订阅的网页钩子不起作用了。
