ユーザーはサブスクリプション製品をキャンセル後に再購入できません

サブスクライバーに奇妙な問題が発生しました。

請求セクションにはアクティブなサブスクリプションが表示されていません。

Stripe ではキャンセル済みとして表示されています。

image

しかし、再購読しようとすると「すでに購入済み」と表示されます。

image

設定を間違えているのでしょうか?

これは、Webhook エンドポイントの設定が不適切な可能性があります。サブスクリプション期間が終了すると、Stripe から Webhook が送信され、プラグインがそれを使用してグループへの参加を解除し、その製品における既存顧客としてのユーザー登録を削除します(これにより、ユーザーは再度購入できるようになります)。

この設定は、以下の OP に従って行う必要があります:Discourse Subscriptions

サーバー側で確認する方法:

./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 つだけ含まれていることを確認してください。返された値が 1 より大きい場合は、正しいサブスクリプションインスタンスを削除していることを確認するために、さらに詳しく調べる必要があります。間違ったものを削除すると、サブスクリプションデータが不整合な状態になり、予期せぬ動作を引き起こす可能性があります。

サブスクリプションが 1 つだけであることを確認したら、以下のコマンドを実行できます:

subscription.destroy_all

ここで subscription は、Rails コンソールで最初に実行した一連のクエリから返された値であることを覚えておいてください。

お役に立てれば幸いです!

@justin さん、ありがとうございます。

• 最後の行の subscription を実行しました。以下が返されました。

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 ログには、設定日からのエントリが 1 つあり、サポートされるイベントの確立を示しているようです。

• Stripe にはサブスクリプションのキャンセルを示すイベントエントリがありますが、その行のエントリは(実質的に)「[サブスクリプションがキャンセルされました]」と表示されています。しかし、そのイベントをクリックすると、イベントタイプは customer.subscription.deleted と表示されます。これは、私の webhook イベントリストに記載されていないことに気づきました。

上記が問題の原因でしょうか?

行は ::Customer ではなく DiscourseSubscriptions::Subscription であるべきようです。試してみてください。

[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: #DiscourseSubscriptions::Subscription::ActiveRecord_Relation:0x000055ec51164ca0customer_id' メソッドが定義されていません 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’

申し訳ありません、どこで問題が起きているのか誤解していました。

代わりにこちらをお試しください:

./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])
=>

顧客の subscription.deleted イベントが欠落していることが、サブスクリプションデータの不足と関係しているとお考えですか?

次に確認すべきことはありますか?

特に、サブスクリプションページでは「購入済み」と表示されているのに、アクティブなサブスクリプションセクションにはアクティブなサブスクリプションが表示されない理由に関心があります。アクティブなサブスクリプションセクションでは情報が消去または空になっているが、どこかで「購入済み」のブール値が true に設定されたままになっているなど、データベース内にサブスクリプション情報が格納されている別の場所があるのでしょうか?それともそのような状況でしょうか?

他に試せることはありますか?

Stripe で購入が完全にキャンセルされ、期間終了時にキャンセル待ちになっていないことを確認してください。また、[管理] → [プラグイン] → [Discourse サブスクリプション] → [サブスクリプション] のセクションで、該当ユーザーのユーザー名を検索することもできます。そこにサブスクリプションが表示されている場合は、すぐにキャンセルできます。

Discourse インスタンスをさらに詳しく調査しない限り、これ以上どのようにお手伝いできるか確信が持てません。

はい、プラグインエリアのサブスクリプション項目でも、Stripe 側でもアクティブにはなっていません。まだアクティブであることを示す唯一の兆候は、ユーザーがサブスクリプションページにアクセスすると、小さな緑色の「購入済み」チェックマークと「請求へ進む」ボタンが表示されることです。

image

該当ユーザーとして請求ページに移動しても、何も表示されません。

そこで質問ですが、データベース内でその緑色のチェックマークをトリガーしているのは何でしょうか?また、それをクリアすることは可能でしょうか?

このリストに、以下の場所にある Stripe 製品 ID が含まれている場合、

フロントエンドでは購入済みとして表示されます。それがどこにあるかを確認するには、これらのクエリを使ってコンソールを調べてみる必要があるかもしれません。そこにまだレコードが残っていることはほぼ確実です。

スレッドを掘り起こしていることは承知していますが、1) この問題は未解決のままであり、2) 再度調査する時間が取れたためです。結果として、指示に従えない間抜けだったことが判明しました。自分がどれほど愚かだったか、そして(助けを借りて)この問題を解決する準備ができた理由がわかりました。

ストライプからキャンセルされたアカウントのCSVをエクスポートしました。このスレッドで言及されている、購読者だったがキャンセル後に再購読できなくなったDiscourseユーザーに焦点を当てました。購読ページは「購入済み」と表示されていましたが、アクティブな購読ページにはサブスクリプションが表示されていませんでした。CSVデータでは、彼のレコードは「キャンセル済み」と表示され、以下のデータが含まれていました。

  • id (sub_JNWejdDo4qhLG5)
  • customer_id (cus_JmiMoqZNTzUNxt)
  • user_id (DiscourseユーザーID 4981)

次に、アプリコンテナにアタッチし、Rubyコンソールに入り、調査を開始しました。まず、DiscourseSubscriptions::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 webhookとサブスクリプションプラグインの間で何らかの不整合があります。どこで、どのように発生しているのかは不明です。

  • まず、特定のユーザーのサブスクリプションレコードデータを安全に削除するにはどうすればよいですか?5歳児に説明するように教えてください。Rubyコンソールプロンプトにいます。ターゲットユーザーのサブスクリプションデータのみが削除され、全員のサブスクリプションデータが消去されないようにするにはどうすればよいですか?

  • 次に、サブスクリプションキャンセルwebhookメカニズムのトラブルシューティング方法を教えてください。

皆様のご協力に心より感謝いたします!

更新:

少し進みました。ターゲットユーザーのサブスクリプションデータのみを削除するために.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 webhookでキャンセルされたサブスクリプションが機能しない理由を診断するだけになりました。