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

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

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

在 Stripe 中显示为已取消:

image

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

image

是我哪里设置不正确吗?

1 个赞

这看起来可能是您的 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 控制台中执行初始查询后返回的值。

希望这能帮到您!

2 个赞

谢谢 @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 事件列表中。

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

1 个赞

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

1 个赞

[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’

1 个赞

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

请尝试以下方法:

./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])
1 个赞

啊……

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

1 个赞

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

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

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

1 个赞

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

1 个赞

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

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

1 个赞

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

image

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

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

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

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

1 个赞

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

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

  • id (sub_JNWejdDo4qhLG5)
  • customer_id (cus_JmiMoqZNTzUNxt)
  • user_id (discourse 用户 ID 4981)

然后我附加到应用程序容器,进入 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 取消订阅的网页钩子不起作用了。