Preámbulo
Mi objetivo es crear código reutilizable para múltiples proyectos (y también publicarlo en github) para administrar suscripciones. Sé acerca de los proveedores de stripe y facturación recurrente, pero ese no es el objetivo de este módulo. Solo debe ser un contenedor / ayuda para calcular el saldo de la cuenta, notificaciones fáciles para renovar una suscripción y manejar los cálculos de precios.
Hay países en los que no puede utilizar la facturación recurrente debido a que los proveedores o las posibilidades de pago tienen poco o ningún soporte o son demasiado caros (micropagos). Y hay personas que no quieren usar la facturación recurrente, sino que pagan su factura manualmente / esperando una factura al final del año. Por lo tanto, no sugiera la facturación recurrente de PayPal, servicios recurrentes o similares.
Situación
Supongamos que tiene un modelo que puede suscribirse a un plan de suscripción (por ejemplo User
). Este modelo tiene un campo que almacena el identificador de un plan de suscripción al que está suscrito actualmente. Entonces, en cada cambio de plan, se registra el cambio.
Hay un modelo (por ejemplo SubscriptionPlanChanges
) con los siguientes campos que registran los cambios mencionados:
subscriber
relacionado con el modelo de suscripción (User
en este caso)from_plan
Definir el identificador del plan que tenía el modelo antes del cambioto_plan
definiendo el identificador de plan que el modelo ha seleccionado ahoracreated_at
es un campo de fecha y hora que almacena el cambiovalid_until
almacena la fecha hasta que la suscripción real sea válidapaid_at
también es un campo de fecha y hora que define si (y cuándo) se pagó la suscripción
Por supuesto, ese diseño es discutible.
Pregunta sobre el saldo de la cuenta
Cuando un Usuario cambia su plan de suscripción, necesito comparar los campos del plan, obtener los precios y calcular la deducción para el nuevo plan en función del plan actual valid_until
y su precio. Diga: Se suscribió por un año del plan A pero después de 6 meses, se actualiza al plan B, por lo que obtiene una deducción de la mitad del precio pagado por los 6 meses del plan A.
Lo que me pregunto: si un usuario, por ejemplo, cambia al plan gratuito, tiene un crédito que puede deducirse si el usuario desea cambiar nuevamente. ¿Guardaría ese valor en un campo adicional o calcularía todos los registros relacionados con ese usuario cada vez? ¿Agregarías / cambiarías algo sobre el diseño de la tabla?
Cuestión de fácil comprensión
Cuando llega el final de un período de suscripción, el usuario recibe una notificación y tiene la posibilidad de renovar su suscripción pagando nuevamente. La forma más fácil sería simplemente actualizar paid_at
y valid_until
con nuevas opciones de suscripción. Sin embargo, no estoy seguro de si almacena todos los datos que alguien pueda necesitar, como un historial de pagos / suscripciones.
Otra opción sería crear un registro adicional para esto, donde from_plan
y to_plan
estén teniendo el mismo identificador (simbolizando así "sin cambio"). ¿Pero eso no interferiría con el cálculo del saldo de la cuenta de alguna manera?
Si alguien pudiera señalarme en la dirección correcta sobre las lógicas que manejan tales suscripciones, lo agradecería mucho.
ACTUALIZACIÓN
Gracias por la ayuda por ahora. Creo que mi pregunta era demasiado vaga, así que intentaré ser más preciso usando menos abstracción. Desafortunadamente, no pude resolver mi problema todavía.
El caso A
User
puede seleccionar Subscription Plan A
. Actualmente almacena un SubscriptionPlanChange
para realizar un seguimiento. Después de, por ejemplo, 5 meses, User
actualiza su suscripción a Subscription Plan B
. Entonces paga el precio de su nueva suscripción, deduciendo el precio del plan a por los 7 meses no utilizados.
Caso B
Después de 3 meses, User
regresa al suyo Subscription Plan A
. No tiene que pagar, pero recibe un saldo para que, al final de la suscripción, obtenga ese saldo deducido por su nueva suscripción.
El Caso C
User
puede seleccionar un plan de suscripción para un subservicio que tenga planes de suscripción independientes. Lo mismo Case A
y Case B
puede solicitar esa suscripción de sub-servicio.
_Case D_
El usuario cancela una de sus suscripciones. Esto resulta en una recarga de su saldo.
Mi pregunta (actualmente, al menos) depende principalmente de cómo almacenar esos datos correctamente para poder reproducir un historial de suscripciones para análisis de negocios y calcular saldos, obtener pagos pendientes basados en las suscripciones, etc.
Tampoco estoy seguro de si la balanza debe almacenarse, por ejemplo, en el modelo del usuario, o si no está almacenada, pero puede calcularse en cualquier momento en función de los datos / historial almacenados.
Algunas cosas a tener en cuenta, aunque no creo que deban introducir problemas:
- No tiene que ser un
User
, podría ser cualquier cosa, es por eso queSubscriber
es polimórfico Plans
no necesariamente tiene que ser un plan, pero podría ser, por ejemplo,Magazines
como se menciona. Eso es lo que he descrito con el asunto C y Caso D .
fuente
Respuestas:
Lamentablemente, la respuesta a un problema complicado suele ser complicada. Mi consejo para usted sería guardar solo la información relevante, luego usar un modelo para construir una imagen más grande.
En otras palabras, su tabla SubscriptionPlanChanges tendría la siguiente información para su clave:
De esta manera, permite múltiples planes para el mismo suscriptor que pueden superponerse. Otros campos incluyen:
Tenga en cuenta que no hay un "plan de" o "plan de". Aunque podría tenerlos, la información es superflua y puede calcularse por su cuenta (almacenar dicha información significa que tiene la tarea adicional de mantenerla consistente). Cuando comienza un nuevo plan, en lugar de tener que modificar los planes existentes, los deja y simplemente agrega un nuevo registro. Si existe otro plan superpuesto después del nuevo plan nuevo, puede decidir que desea eliminarlo (más intuitivo de esta manera). Cuando carga estos planes para un suscriptor, los ordena por su fecha "válida desde".
Una vez que obtenga esto, calcular el crédito de un usuario es relativamente simple. Si dos planes no pueden superponerse, simplemente tome la menor de dos fechas entre la fecha "válida hasta" del plan anterior y la "válida desde" del plan actual para determinar la fecha de finalización. La fecha de inicio es la mayor de las dos fechas entre la fecha "válida desde" y la fecha "pagado hasta" (si está definida). El pago (o crédito) se puede calcular sobre la tasa multiplicada por el intervalo de tiempo entre las fechas de inicio y finalización mencionadas anteriormente de ese plan.
De esta manera, en teoría puedes calcular lo que necesites saber. Aconsejaría que no intente guardar los valores calculados, ya que cambiaría cuando se modifique, agregue o elimine un registro existente.
Las variaciones de cómo calcularía estos valores se pueden administrar agregando un campo de tipo adicional. En su código, puede crear controladores especiales para administrar la lógica de cálculo de planes particulares a fin de mantener su algoritmo principal relativamente libre de cálculos complicados. Mejor aún si logra crear un controlador para el caso en el que no se especifica ningún tipo, por lo que todo lo que tiene que hacer es llamar al controlador apropiado de acuerdo con su tipo para realizar cualquier tipo de cálculo que necesite.
Espero haber respondido a tu pregunta.
fuente
valid_until
fue mi terminología tuyapaid_until
. No hay una longitud máxima de un plan para suscribirse.Además de la respuesta anterior, crearía una tabla con créditos, donde un crédito sería igual a la moneda actual. Cada vez que el usuario cambia de plan a una alternativa más barata, el saldo no utilizado ingresa como créditos. Siempre que el usuario tenga algo que pagar, primero usará los créditos y solo solicitará el pago si los créditos se agotan o no existen. Si usa esta alternativa, cree la tabla como una lista de transacciones para poder reproducir el escenario de uso si alguna vez se produce una disputa. Ejemplo:
ID, UserId, TransactionDate, Credit (positivo cuando le da créditos al usuario y negativo cuando el usuario usa el crédito)
Simplemente sume los créditos para que el usuario le muestre el saldo.
Espero que esto sea de alguna utilidad para ti ...
fuente