Präambel
Mein Ziel ist es, wiederverwendbaren Code für mehrere Projekte zu erstellen (und ihn auch auf Github zu veröffentlichen), um Abonnements zu verwalten. Ich kenne Stripe- und wiederkehrende Abrechnungsanbieter, aber das ist nicht das Ziel dieses Moduls. Es sollte nur ein Wrapper / Helfer für die Berechnung des Kontostands, einfache Benachrichtigungen zur Verlängerung eines Abonnements und die Durchführung von Preisberechnungen sein.
Es gibt Länder, in denen Sie keine wiederkehrende Abrechnung verwenden können, weil die Anbieter oder Zahlungsmöglichkeiten schlecht oder gar nicht unterstützt werden oder zu teuer sind (Mikrozahlungen). Und es gibt Leute, die keine wiederkehrende Abrechnung verwenden möchten, sondern ihre Rechnung manuell bezahlen / eine Rechnung am Ende des Jahres erhalten. Schlagen Sie daher bitte keine wiederkehrenden, wiederkehrenden oder ähnlichen Paypal-Abrechnungsdienste vor.
Situation
Angenommen, Sie haben ein Modell, das einen Abonnementplan abonnieren kann (z User
. B. ). Dieses Modell verfügt über ein Feld, in dem die Kennung eines Abonnementplans gespeichert ist, für den es derzeit abonniert ist. Bei jeder Planänderung wird die Änderung aufgezeichnet.
Es gibt ein Modell (z. B. SubscriptionPlanChanges
) mit den folgenden Feldern, in denen die genannten Änderungen aufgezeichnet sind:
subscriber
in Bezug auf das Abonnementmodell (User
in diesem Fall)from_plan
Definieren der Plan-ID, die das Modell vor der Änderung hatteto_plan
Definieren der Plan-ID, die das Modell jetzt ausgewählt hatcreated_at
ist ein Datums- / Uhrzeitfeld, in dem die Änderung gespeichert wirdvalid_until
speichert das Datum, bis das tatsächliche Abonnement gültig istpaid_at
ist auch ein Datum / Uhrzeit-Feld, das definiert, ob (und wann) ein Abonnement bezahlt wurde
Natürlich ist dieses Layout diskutierbar.
Frage des Kontostands
Wenn ein Benutzer sein Abonnement ändert, muss ich die Planfelder vergleichen, die Preise abrufen und den Abzug für den neuen Plan basierend auf dem aktuellen Plan valid_until
und seinem Preis berechnen . Sprich: Sie haben ein Jahr für Plan A abonniert, aber nach 6 Monaten führen Sie ein Upgrade auf Plan B durch, sodass Sie einen Abzug von der Hälfte des bezahlten Preises für die 6 Monate von Plan A erhalten.
Was ich mich frage: Wenn ein Benutzer z. B. zum kostenlosen Tarif wechselt, hat er eine Gutschrift, die abgezogen werden kann, wenn der Benutzer erneut wechseln möchte. Würden Sie diesen Wert in einem zusätzlichen Feld zwischenspeichern oder jedes Mal alle Datensätze berechnen, die sich auf diesen Benutzer beziehen? Würden Sie etwas am Tabellenlayout hinzufügen / ändern?
Frage der einfachen Verständlichkeit
Wenn das Ende eines Abonnementzeitraums eintrifft, wird der Benutzer benachrichtigt und hat die Möglichkeit, sein Abonnement durch erneutes Bezahlen zu verlängern. Der einfachste Weg wäre, nur zu aktualisieren paid_at
und valid_until
mit neuen Abonnementoptionen. Ich bin mir jedoch nicht sicher, ob Sie alle Daten speichern, die jemand benötigt, z. B. einen Zahlungs- / Abonnementverlauf.
Eine andere Möglichkeit wäre, einen zusätzlichen Datensatz dafür zu erstellen, wobei from_plan
und to_plan
die gleiche Kennung haben (was "keine Änderung" symbolisiert). Aber würde das nicht in irgendeiner Weise die Berechnung des Kontostands beeinträchtigen?
Wenn mich jemand in die richtige Richtung bezüglich der Logik beim Umgang mit solchen Abonnements weisen könnte, würde ich es sehr schätzen.
UPDATE
Vielen Dank für die Hilfe. Ich denke, meine Frage war zu vage, deshalb werde ich versuchen, genauer zu sein, indem ich weniger Abstraktion verwende. Leider konnte ich mein Problem noch nicht lösen.
Fall A
User
kann auswählen Subscription Plan A
. Hier wird derzeit ein gespeichert SubscriptionPlanChange
, um den Überblick zu behalten. User
Aktualisiert nach zB 5 Monaten sein Abonnement auf Subscription Plan B
. Also zahlt er den Preis für sein neues Abonnement und zieht den Preis für Plan a für die nicht genutzten 7 Monate ab.
Fall B
Nach 3 Monaten User
rollt er zu seinem zurück Subscription Plan A
. Er muss nicht bezahlen, erhält aber einen Restbetrag dafür, sodass er am Ende des Abonnements diesen Restbetrag für sein neues Abonnement abzieht.
Fall C
User
kann einen Abonnementplan für einen Unterdienst mit unabhängigen Abonnementplänen auswählen. Gleiches Case A
und Case B
kann für dieses Sub-Service-Abonnement gelten.
_Case D_
Der Benutzer kündigt eines seiner Abonnements. Dies führt zu einer Aufladung seines Gleichgewichts.
Meine Frage (zumindest derzeit) hängt hauptsächlich davon ab, wie diese Daten ordnungsgemäß gespeichert werden, damit ich einen Verlauf von Abonnements für die Geschäftsanalyse reproduzieren und Salden berechnen, ausstehende Zahlungen basierend auf den Abonnements usw. erhalten kann.
Ich bin mir auch nicht sicher, ob der Kontostand beispielsweise im Benutzermodell selbst gespeichert werden soll oder ob er nicht gespeichert ist, aber jederzeit basierend auf den gespeicherten Daten / dem Verlauf berechnet werden kann.
Einige Dinge zu beachten, obwohl ich nicht denke, dass sie Probleme verursachen sollten:
- Es muss kein sein
User
, es könnte alles sein, deshalbSubscriber
ist das polymorph Plans
müssen nicht unbedingt pläne sein, könnten aber zBMagazines
wie erwähnt sein. Das habe ich mit Fall C und Fall D beschrieben .
quelle
Antworten:
Leider ist die Antwort auf ein kompliziertes Problem normalerweise kompliziert. Mein Rat an Sie wäre, nur relevante Informationen zu speichern und dann ein Modell zu verwenden, um das Gesamtbild zu erstellen.
Mit anderen Worten, Ihre Tabelle SubscriptionPlanChanges enthält die folgenden Informationen für ihren Schlüssel:
Auf diese Weise können Sie mehrere Pläne für denselben Teilnehmer zulassen, die sich überschneiden können. Andere Felder umfassen:
Beachten Sie, dass es keinen "Plan von" oder "Plan bis" gibt. Obwohl Sie sie haben könnten, sind die Informationen überflüssig und können selbst berechnet werden (das Speichern solcher Informationen bedeutet, dass Sie die zusätzliche Aufgabe haben, sie konsistent zu halten). Wenn ein neuer Plan beginnt, anstatt vorhandene Pläne ändern zu müssen, verlassen Sie sie und fügen einfach einen neuen Datensatz hinzu. Wenn nach dem neuen Plan ein anderer überlappender Plan vorhanden ist, können Sie ihn löschen (auf diese Weise intuitiver). Wenn Sie diese Pläne für einen Abonnenten laden, sortieren Sie sie nach dem Datum "gültig ab".
Sobald Sie dies erhalten haben, ist die Berechnung des Guthabens eines Benutzers relativ einfach. Wenn sich zwei Pläne nicht überschneiden können, nehmen Sie einfach das kleinere von zwei Daten zwischen dem Datum "gültig bis" des vorherigen Plans und dem Datum "gültig ab" des aktuellen Plans, um das Enddatum zu bestimmen. Das Startdatum ist das größere der beiden Daten zwischen dem Datum "gültig ab" und dem Datum "bezahlt bis" (falls definiert). Die Zahlung (oder Gutschrift) kann dann anhand des Satzes multipliziert mit dem Zeitintervall zwischen dem oben genannten Start- und Enddatum dieses Plans berechnet werden.
Auf diese Weise können Sie theoretisch berechnen, was Sie wissen müssen. Ich würde davon abraten, berechnete Werte zu speichern, da sich dies ändern würde, wenn ein vorhandener Datensatz geändert, hinzugefügt oder gelöscht wird.
Variationen, wie Sie diese Werte berechnen würden, können durch Hinzufügen eines zusätzlichen Typfelds verwaltet werden. In Ihrem Code können Sie spezielle Handler erstellen, um die Logik der Berechnung bestimmter Pläne zu verwalten und Ihren Hauptalgorithmus relativ frei von komplizierten Berechnungen zu halten. Besser noch, wenn Sie es schaffen, einen Handler für den Fall zu erstellen, in dem kein Typ angegeben ist. Sie müssen also nur den entsprechenden Handler entsprechend seinem Typ aufrufen, um die von Ihnen gewünschte Berechnung durchzuführen.
Ich hoffe das beantwortet deine Frage.
quelle
valid_until
war meine Terminologie von dirpaid_until
. Es gibt keine maximale Länge eines zu abonnierenden Plans.Zusätzlich zu der obigen Antwort würde ich eine Tabelle mit Gutschriften erstellen, in der eine Gutschrift der aktuellen Währung entspricht. Immer wenn der Benutzer den Plan auf eine günstigere Alternative umstellt, wird das nicht verwendete Guthaben als Guthaben eingegeben. Wann immer der Benutzer etwas zu bezahlen hat, würden Sie zuerst die Credits verwenden und nur dann um Zahlung bitten, wenn die Credits aufgebraucht sind oder nicht existieren. Wenn Sie diese Alternative verwenden, erstellen Sie die Tabelle als Transaktionsliste, um das Verwendungsszenario reproduzieren zu können, falls jemals ein Streit auftreten sollte. Beispiel:
ID, UserId, TransactionDate, Credit (positiv, wenn Sie dem Benutzer Credits geben, und negativ, wenn der Benutzer das Guthaben verwendet)
Summieren Sie einfach die Credits für den Benutzer, um ihm den Kontostand anzuzeigen.
Hoffe, das nützt dir etwas ...
quelle