El usuario no puede volver a comprar un producto de suscripción después de cancelarlo

He tenido un problema extraño con un suscriptor.

No tienen suscripciones activas en la sección de Facturación;

En Stripe aparece como cancelado;

image

sin embargo, no pueden volver a suscribirse… dice que ya está comprado;

image

¿He configurado algo incorrectamente?

1 me gusta

Parece que tu endpoint de webhook podría estar configurado incorrectamente. Cuando finaliza el período de suscripción, Stripe envía un webhook que el plugin utiliza para eliminar la membresía del grupo y retirar al usuario como cliente existente de ese producto (lo que permite al usuario volver a comprarlo).

Debes asegurarte de configurarlo según lo indicado en el hilo original aquí: Discourse Subscriptions

Una forma de verificarlo desde tu servidor:

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

Asegúrate de reemplazar <username> con el nombre de usuario real del usuario.

Si subscription devuelve [], hay otro problema en curso. Pero si devuelve un valor, eso probablemente confirma la falta del webhook.

Para eliminar la entrada DiscourseSubscriptions::Subscription para que el usuario pueda volver a comprar el producto:

Asegúrate de que subscription tenga un solo valor ejecutando subscription.count. Si el valor devuelto es mayor que 1, tendrás que investigar un poco más para asegurarte de que estás eliminando la instancia de suscripción correcta. Si eliminas la incorrecta, los datos de tus suscripciones quedarán en un estado inconsistente y probablemente generarán comportamientos extraños.

Una vez confirmado que solo hay una suscripción, puedes ejecutar:

subscription.destroy_all

Ten en cuenta que subscription es el valor devuelto por el conjunto inicial de consultas que ejecutamos en la consola de Rails.

¡Esperamos que esto te ayude!

2 Me gusta

Gracias @justin

• Llegué a la última línea de la suscripción y la ejecuté… devolvió esto;

NoMethodError: método no definido customer_id' para #<DiscourseSubscriptions::Customer::ActiveRecord_Relation:0x000055be473772f0> desde /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’

• Verifiqué los webhooks de Stripe y apuntan a https://./s/hooks

• Eventos enviados al webhook;

  • subscription_schedule.updated
    
  • subscription_schedule.expiring
    
  • subscription_schedule.created
    
  • subscription_schedule.canceled
    

• El registro del webhook de Stripe tiene una entrada desde la fecha de configuración que parece estar estableciendo los eventos admitidos.

• Tengo una entrada de evento en Stripe que es una cancelación de una suscripción, pero… la entrada de la línea dice (efectivamente) “[la suscripción fue cancelada]”, sin embargo, cuando hago clic en el evento, indica que el tipo de evento es customer.subscription.deleted… lo cual noto que no está listado en mi lista de eventos de webhook.

¿Podría ser lo anterior el problema?

1 me gusta

Parece que la línea debería ser DiscourseSubscriptions::Subscription en lugar de ::Customer. ¡Pruébalo y dime qué obtienes!

1 me gusta

[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: método customer_id no definido para #DiscourseSubscriptions::Subscription::ActiveRecord_Relation:0x000055ec51164ca0
desde /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 me gusta

Lo siento, malinterpreté dónde estaba ocurriendo esto.

Prueba esto en su lugar:

./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 me gusta

Ah..

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

1 me gusta

¿Crees que la falta de datos de suscripción tiene algo que ver con la ausencia del evento customer.subscription.deleted?

¿Hay algo más que deba explorar en este punto?

Me interesa especialmente entender por qué la página de suscripción muestra “comprado”, mientras que la sección de suscripciones activas no muestra ninguna suscripción activa. ¿Existe algún otro lugar en la base de datos donde se almacene la información de suscripción que pueda estar vacía o borrada en la sección de suscripciones activas, pero donde, de alguna manera, un booleano de “comprado” siga establecido en verdadero… o algo similar?

1 me gusta

¿Hay algo más que se pueda probar aquí?

1 me gusta

Asegúrate de que en Stripe la compra esté completamente cancelada y no pendiente de cancelación al final del período. También puedes revisar en el área Administración –\u003e Complementos –\u003e Suscripciones de Discourse –\u003e Suscripciones y buscar el nombre de usuario de esta persona. Si aparece una suscripción listada allí, puedes cancelarla de inmediato.

Sin investigar más a fondo tu instancia de Discourse, no estoy seguro de cuánto más puedo ayudarte.

1 me gusta

sí, no está activo en las suscripciones del área del plugin, ni tampoco en Stripe. Lo único que indica que algo sigue activo es que, si el usuario va a la página de suscripción, ve una pequeña marca de verificación verde que dice “comprado” y un enlace “ir a facturación”.

image

Si entro a la facturación como el usuario en cuestión, no hay nada:

Mi pregunta es: ¿qué elemento en la base de datos activa esa marca de verificación verde y puede ser eliminado?

Si esta lista incluye el ID del producto de Stripe, como se muestra aquí:

Entonces la interfaz de usuario lo mostrará como comprado. Es posible que necesites explorar la consola con estas consultas para descubrir dónde se encuentra. Casi puedo garantizar que aún hay un registro allí.

1 me gusta

Ok, sé que estoy reviviendo este hilo, pero 1) esto sigue sin resolverse y 2) encontré tiempo para investigar esto de nuevo… resulta que era un imbécil que no sabía seguir instrucciones. Así es como descubrí que soy un tonto y por qué ahora estoy listo para resolver esto (con algo de ayuda).

Lo que terminé haciendo fue exportar un CSV de Stripe de todas las cuentas canceladas. Me centré en el mismo usuario de Discourse al que se hace referencia anteriormente en este hilo, que era suscriptor, se había cancelado, pero luego no pudo volver a suscribirse porque la página de suscripción aparecía como “comprada” a pesar de que su página de suscripciones activas no mostraba ninguna suscripción. En los datos del CSV, su registro aparecía como “cancelado” con los siguientes datos:

  • id (sub_JNWejdDo4qhLG5)
  • customer_id (cus_JmiMoqZNTzUNxt)
  • user_id (id de usuario de Discourse 4981)

Luego me adjunté al contenedor de la aplicación, entré en la consola de Ruby y comencé a investigar. Primero busqué su ID de cliente en DiscourseSubscriptions::Customer y lo encontré.

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

A continuación, busqué en DiscourseSubscriptions::Subscription para ver si este usuario tenía alguna suscripción y resulta que sí, sí la tenía;

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

Entonces, parece que simplemente puedo eliminar este registro de suscripción y arreglar todo… para este usuario. El hecho es que cada usuario cancelado que revisé en mi exportación CSV todavía tenía suscripciones restantes en el sistema. Obviamente, hay una desconexión de alguna manera / en algún lugar entre el webhook de Stripe y el plugin de suscripción… simplemente no sé dónde / cómo.

  • Primero; ¿cómo elimino de forma segura el registro de suscripción de un usuario en particular? Explícamelo como si tuviera 5 años. Estoy en el prompt de la consola de Ruby… ¿cómo me aseguro de que solo se eliminen los datos de suscripción del usuario objetivo y no se borren los datos de suscripción de todos?

  • Segundo, ¿cómo soluciono el mecanismo del webhook de cancelación de suscripción?

¡Toda tu ayuda es muy apreciada!

ACTUALIZACIÓN:

Ok, avancé un poco más… logré averiguar cómo usar .delete_by para eliminar solo los datos de suscripción del usuario objetivo;

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

Sin embargo, el registro del cliente todavía tiene un product_id asociado;

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

Esto significa que todavía ven la marca verde y no pueden volver a suscribirse… así que apliqué el “destroy_all” al objeto Customer… ¡y funcionó! Pero solo para ese usuario, por supuesto…

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

Así que ahora solo queda diagnosticar por qué el webhook de Stripe para suscripciones canceladas no está funcionando.