我这里遇到一个奇怪的问题,涉及一位订阅用户。
在“计费”部分,他们没有任何有效的订阅:
在 Stripe 中显示为已取消:
![]()
但他们无法重新订阅,系统提示“已购买”:

是我哪里设置不正确吗?
这看起来可能是您的 webhook 端点配置不当。当订阅期结束时,Stripe 会发送一个 webhook,插件会利用它来移除群组会员资格,并将该用户从该产品的现有客户列表中移除(从而允许用户再次购买)。
您需要按照此处 Discourse 订阅 的原帖说明进行配置。
一种从服务器确认的方法:
./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,您需要进一步排查,以确保删除的是正确的订阅实例。如果删除了错误的条目,您的订阅数据将处于不一致状态,并可能导致异常行为。
一旦确认只有一个订阅,即可运行:
subscription.destroy_all
请注意,subscription 是我们在 Rails 控制台中执行初始查询后返回的值。
希望这能帮到您!
谢谢 @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:inmethod_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 事件列表中。
上述情况是否可能是问题所在?
看起来这一行应该是 DiscourseSubscriptions::Subscription 而不是 ::Customer。试试看,看看结果如何!
[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:inmethod_missing’
抱歉,我误解了问题发生的位置。
请尝试以下方法:
./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])
啊……
[3] pry(main)> subscription = DiscourseSubscriptions::Subscription.where(customer_id: c[:customer_id])
=>
您认为缺少订阅数据是否与 customer.subscription.deleted 事件缺失有关?
目前我接下来应该探索哪些方面?
我特别关注为什么订阅页面显示“已购买”,而活跃订阅部分却没有任何活跃订阅。数据库中是否存在其他存储订阅信息的位置,该位置在活跃订阅部分可能被清除或为空,但某个地方的“已购买”布尔值仍被设置为 true,或是类似的情况?
还有什么其他可以尝试的吗?
请确保在 Stripe 中该订单已完全取消,而不是等待周期结束时取消。您还可以进入 管理 –\u003e 插件 –\u003e Discourse 订阅 –\u003e 订阅 区域,查找该用户的用户名。如果此处列出了该用户的订阅,您可以立即取消它。
在不进一步查看您的 Discourse 实例的情况下,我不确定还能提供多少帮助。
是的,它在插件区域的订阅下并未激活,Stripe 上也没有显示。唯一表明仍有活动状态的迹象是:如果用户进入订阅页面,会看到一个绿色的小“已购买”勾选标记以及“前往账单”按钮。

如果我以该用户身份进入账单页面,则没有任何显示:
所以我的问题是:数据库中是什么触发了那个绿色勾选标记?能否将其清除?
如果此列表包含了此处所示的 Stripe 产品 ID:
那么前端将会显示为已购买。您可能需要利用这些查询在控制台中深入查找,以确定其具体位置。我几乎可以肯定,那里仍有一条记录残留着。
好的,我知道我是在“复活”这个帖子,但首先 1) 这个问题一直没有得到解决,其次 2) 我花了一些时间重新研究这个问题……结果发现我是一个连说明都看不懂的白痴。我就是这样发现自己是个笨蛋的,也是为什么我现在准备(在一些帮助下)解决这个问题。
我最终的做法是从 Stripe 导出所有已取消帐户的 CSV。我重点关注了该主题中前面提到的 Discourse 用户,他是一名订阅者,已经取消了订阅,但之后无法重新订阅,因为订阅页面显示为“已购买”,尽管他的活动订阅页面没有显示任何订阅。在 CSV 数据中,他的记录显示为“已取消”,数据如下:
然后我附加到应用程序容器,进入 Ruby 控制台,开始进行一些探索。首先,我在 DiscourseSubscriptions::Customer 中搜索了他的 customer_id,找到了它。
[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,看看这个用户是否有任何订阅,结果是有的,确实有;
[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 来仅删除目标用户的订阅数据;
[1] pry(main)> DiscourseSubscriptions::Subscription.delete_by(external_id: 'sub_JNWejdDo4qhLG5')
[2] pry(main)> DiscourseSubscriptions::Subscription.where(external_id: 'sub_JNWejdDo4qhLG5')
=> []
但是,客户记录仍然有一个与之关联的 product_id;
[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”……它奏效了!但当然只对那个用户有效……
[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 取消订阅的网页钩子不起作用了。