Préambule
[.____] Mon objectif est de créer du code réutilisable pour plusieurs projets (et de le publier également sur GitHub) de gérer les abonnements. Je sais sur des fournisseurs de facturation de rayures et récurrents, mais ce n'est pas ce que ce module vise. Il devrait simplement être un wrapper/assistant pour calculer le solde du compte, les notifications faciles de renouveler une abonnement et de gérer les calculs de prix.
Il y a des pays que vous ne pouvez pas utiliser la facturation récurrente en raison des fournisseurs ou des possibilités de paiement ayant un soutien médiocre ou pas trop cher (micropaiments). Et il y a des gens qui ne veulent pas utiliser la facturation récurrente mais payer leur facture manuellement/avingg une facture à la fin de l'année. Donc, veuillez ne pas suggérer de la facturation de PayPal récurrente, du recrossité ou des services similaires.
Situation
Disons que vous avez un modèle qui peut abonner à un plan d'abonnement (par exemple User
). Ce modèle a un champ qui stocke l'identifiant d'un plan d'abonnement qu'il est actuellement souscrit à. Donc, sur chaque changement de plan, le changement est enregistré.
Il y a un modèle (par exemple SubscriptionPlanChanges
) avec les champs suivants enregistrant les modifications mentionnées:
subscriber
relatif au modèle d'abonnement (User
dans ce cas)from_plan
définissant l'identifiant du plan Le modèle avait avant de changerto_plan
Définition de l'identifiant du plan Le modèle a sélectionné maintenantcreated_at
est un champ de date-heure stockant le changementvalid_until
stocke la date jusqu'à ce que l'abonnement réel soit validepaid_at
est également un champ de date qui définit si (et quand) abonnement a été payéBien sûr, cette mise en page est discutable.
Question du solde du compte
[.____] Lorsqu'un utilisateur change son plan d'abonnement, je dois comparer les champs de plan, obtenir les prix et calculer la déduction du nouveau plan en fonction du plan actuel valid_until
et de son prix. Dites: Vous avez souscrit une année de plan A mais après 6 mois, vous passez à la mise à niveau vers le plan B, de sorte que vous obtenez une déduction de la moitié du prix payé pour les 6 mois de plan A.
Ce que je me demande: si un utilisateur par exemple Allumez le plan gratuit, il a un crédit qui peut être déduit si l'utilisateur souhaite basculer à nouveau. Souhaitez-vous mettre en cache cette valeur dans un champ supplémentaire ou calculer via tous les enregistrements liés à cet utilisateur à chaque fois? Ajoutez-vous/changeriez-vous quelque chose à propos de la mise en page de la table?
Question de la compréhensibilité facile
[.____] Lorsque la fin d'une période d'abonnement arrive, l'utilisateur est notifié et a la possibilité de renouveler son abonnement en payant à nouveau. Le moyen le plus simple serait de simplement mettre à jour paid_at
et valid_until
avec de nouvelles options d'abonnement. Cependant, je ne sais pas si vous stockez toutes les données que quelqu'un pourrait avoir besoin, comme un historique de paiement/abonnement.
Une autre option serait de créer un enregistrement supplémentaire pour cela, où from_plan
et to_plan
ont le même identifiant (symbolisant ainsi "aucun changement"). Mais cela ne serait-il pas interférer avec le calcul du solde du compte d'une manière ou d'une autre?
Si quelqu'un pouvait me signaler dans la bonne direction sur les logiques qui manipulent de tels abonnements, je l'apprécierais beaucoup.
MISE À JOUR
[.____] Merci pour l'aide maintenant. Je pense que ma question était trop vague, je vais donc essayer d'être plus précisément en utilisant moins d'abstraction. Malheureusement, je ne pouvais pas encore résoudre mon problème.
cas A User
peut sélectionner Subscription Plan A
. Cela stocke actuellement un SubscriptionPlanChange
pour le suivre. Après par exemple 5 mois, User
met à niveau son abonnement à Subscription Plan B
. Il paie donc le prix de son nouvel abonnement, déduisant le prix du plan A pour les 7 mois inutilisés.
Case B
[.____] après 3 mois, User
retourne à son Subscription Plan A
. Il n'a pas à payer, mais reçoit un équilibre pour cela afin que, à la fin de l'abonnement, il obtient cet équilibre déduit pour son nouvel abonnement.
Case C User
peut sélectionner un plan d'abonnement pour un sous-service contenant des plans d'abonnement indépendants. Même Case A
et Case B
peuvent demander cet abonnement sous-service.
_Case D_
L'utilisateur annule l'un de ses abonnements. Cela se traduit par une recharge de son équilibre.
Ma question (actuellement au moins) dépend principalement de la manière de stocker ces données correctement afin que je puisse reproduire une histoire d'abonnements pour analyse des affaires et calculer les soldes, obtenir des paiements exceptionnels basés sur les abonnements, etc.
Je ne sais pas non plus si le solde doit être stocké par ex. Les utilisateurs modélisent ou s'il n'est pas stocké mais peuvent être calculés à tout moment sur la base des données/historique stockés.
Certaines choses à noter, bien que je ne pense pas qu'ils devraient introduire des problèmes:
User
, cela pourrait être n'importe quoi, c'est pourquoi le Subscriber
est polymorphePlans
ne doit pas nécessairement être des plans, mais peut-être par exemple. Magazines
comme mentionné. C'est ce que j'ai décrit avec Case C et Case D .Malheureusement, la réponse à un problème complexe est généralement compliquée. Mon conseil vous permettrait d'enregistrer uniquement des informations pertinentes, puis utilisez un modèle pour construire la plus grande image.
En d'autres termes, votre souscription de tableLanchanges aurait les informations suivantes pour sa clé:
De cette manière, vous permettez de multiples plans pour le même abonné pouvant se chevaucher. D'autres domaines incluent:
Notez qu'il n'y a pas de "plan de" ou "plan à". Bien que vous puissiez les avoir, les informations sont superflues et peuvent être calculées seules (stocker ces informations signifie que vous avez la tâche supplémentaire de la garder cohérente). Lorsqu'un nouveau plan commence plutôt que de devoir modifier les plans existants, vous les laissez et ajoutez simplement un nouvel enregistrement. Si un autre plan de chevauchement existe après le nouveau plan, vous pouvez alors décider de la suppression (plus intuitive de cette façon). Lorsque vous chargez ces plans pour un abonné, vous les triez par la date "Valide de".
Une fois que vous l'avez obtenu, le calcul du crédit d'un utilisateur est relativement simple. Si deux plans ne peuvent pas se chevaucher, vous prenez simplement le moindre de deux dates entre la date "Valide jusqu'à" du plan précédent et du "Valable de" du plan actuel afin de déterminer la date de fin. La date de début est la plus grande des deux dates entre la date "valide de" et la date "payée jusqu'à" (si définie). Le paiement (ou le crédit) peut ensuite être calculé sur la vitesse multipliée par l'intervalle de temps entre les dates de début et de fin susmentionnées de ce plan.
De cette façon, vous pouvez en théorie calculer ce que vous auriez besoin de savoir. Je conseillerais d'essayer d'économiser des valeurs calculées, car cela changerait lorsqu'un enregistrement existant est modifié, ajouté ou supprimé.
Variations de la manière dont vous calculeriez ces valeurs peut être gérée en ajoutant un champ de type supplémentaire. Dans votre code, vous pouvez créer des gestionnaires spéciaux pour gérer la logique de calcul des plans particuliers afin de maintenir votre algorithme principal relativement clair des calculs compliqués. Mieux encore, si vous parvenez à créer un gestionnaire pour le cas dans lequel aucun type n'est spécifié, tout ce que vous avez à faire est d'appeler le gestionnaire approprié en fonction de son type afin de créer une sorte de calcul dont vous avez besoin.
J'espère que cela répond à votre question.
En plus de la réponse ci-dessus, je créerais une table avec des crédits, où un crédit correspondrait à la monnaie actuelle. Chaque fois que l'utilisateur interdit de planifier une alternative moins chère, la balance inutilisée entre en tant que crédits. Chaque fois que l'utilisateur a quelque chose à payer, vous utiliseriez d'abord les crédits et seulement demander le paiement si les crédits s'épuisent ou n'existent pas. Si vous utilisez cette alternative, créez le tableau comme une liste de transactions afin de pouvoir reproduire le scénario d'utilisation si jamais un différendait. Exemple:
ID, ID utilisateur, transactionDate, crédit (positif lorsque vous donnez les crédits d'utilisateur et négatifs lorsque l'utilisateur utilise le crédit)
Sumez simplement les crédits pour l'utilisateur de lui montrer l'équilibre.
J'espère que cela vous convient ...