Obsługa subskrypcji, sald i zmian planów cenowych [zamknięte]

11

Preambuła
Moim celem jest stworzenie kodu wielokrotnego użytku dla wielu projektów (a także opublikowanie go na github) w celu zarządzania subskrypcjami. Wiem o rozłożonych i powtarzających się dostawcach faktur, ale nie o to chodzi w tym module. Powinien to być po prostu pomocnik do obliczania salda konta, łatwe powiadomienia o odnowieniu subskrypcji i obsługa obliczeń cen.

Są kraje, w których nie można korzystać z rozliczeń cyklicznych, ponieważ dostawcy lub możliwości płatności mają słabą lub zerową obsługę lub są zbyt drogie (mikropłatności). Są też ludzie, którzy nie chcą korzystać z cyklicznych rozliczeń, ale płacą rachunek ręcznie / wystawiają fakturę pod koniec roku. Dlatego nie sugeruj, aby usługi PayPal były regularnie rozliczane, powtarzalne lub podobne.

Sytuacja
Załóżmy, że masz model, który może subskrybować plan subskrypcji (np User.). Ten model ma pole, w którym jest przechowywany identyfikator planu subskrypcji, który jest obecnie subskrybowany. Tak więc przy każdej zmianie planu zmiana jest rejestrowana.

Istnieje model (np. SubscriptionPlanChanges) Z następującymi polami rejestrującymi wspomniane zmiany:

  • subscriberodnoszący się do modelu subskrybującego ( Userw tym przypadku)
  • from_plan definiowanie identyfikatora planu, który model miał przed zmianą
  • to_plan definiowanie identyfikatora planu, który model wybrał teraz
  • created_at to pole daty i godziny przechowujące zmianę
  • valid_until przechowuje datę, aż aktualna subskrypcja jest ważna
  • paid_at to także pole daty i godziny określające, czy (i kiedy) subskrypcja została opłacona

Oczywiście ten układ jest dyskusyjny.

Pytanie o saldo konta
Kiedy użytkownik zmienia swój abonament, muszę porównać pola planu, uzyskać ceny i obliczyć potrącenie dla nowego planu na podstawie aktualnego planu valid_untili jego ceny. Powiedz: Subskrybowałeś rok planu A, ale po 6 miesiącach uaktualniasz do planu B, więc otrzymujesz odliczenie połowy zapłaconej ceny za 6 miesięcy planu A.

Zastanawiam się: jeśli użytkownik np. Przełączy się na bezpłatny abonament, ma kredyt, który można odliczyć, jeśli użytkownik chce ponownie przełączyć. Czy umieścisz w pamięci podręcznej tę wartość w dodatkowym polu, czy za każdym razem obliczysz wszystkie rekordy związane z tym użytkownikiem? Czy mógłbyś dodać / zmienić coś w układzie tabeli?

Pytanie łatwego zrozumienia
Kiedy nadejdzie okres subskrypcji, użytkownik zostanie powiadomiony i będzie mógł odnowić subskrypcję, płacąc ponownie. Najłatwiejszym sposobem jest po prostu aktualizacja paid_ati valid_untilnowe opcje subskrypcji. Nie jestem jednak pewien, czy przechowujesz wszystkie dane, które mogą być potrzebne, na przykład historię płatności / subskrypcji.

Inną opcją byłoby utworzenie dodatkowego rekordu dla tego, gdzie from_plani to_planmają ten sam identyfikator (symbolizując w ten sposób „brak zmian”). Ale czy nie przeszkadzałoby to w jakikolwiek sposób obliczać salda konta?

Jeśli ktoś mógłby skierować mnie w dobrym kierunku na temat logiki obsługującej takie subskrypcje, byłbym bardzo wdzięczny.


AKTUALIZACJA
Dziękujemy za pomoc. Myślę, że moje pytanie było zbyt niejasne, więc postaram się uściślić, używając mniej abstrakcji. Niestety nie udało mi się jeszcze rozwiązać mojego problemu.

Przypadek A
User może wybrać Subscription Plan A. Obecnie przechowuje to w SubscriptionPlanChangecelu śledzenia. Po np. 5 miesiącach Useruaktualnia swoją subskrypcję do Subscription Plan B. Więc płaci cenę za nową subskrypcję, odejmując cenę abonamentu za niewykorzystane 7 miesięcy.

Przypadek B
Po 3 miesiącach Userwycofuje się do swojego Subscription Plan A. Nie musi płacić, ale otrzymuje za to saldo, dzięki czemu pod koniec subskrypcji pobiera saldo od swojej nowej subskrypcji.

Przypadek C
User może wybrać plan subskrypcji dla usługi podrzędnej, która ma niezależne plany subskrypcji. To samo Case Ai Case Bmoże dotyczyć subskrypcji tej usługi podrzędnej.

_Case D_ Użytkownik anuluje jedną ze swoich subskrypcji. To powoduje doładowanie jego równowagi.

Moje pytanie (przynajmniej obecnie) zależy głównie od tego, jak właściwie przechowywać te dane, aby móc odtworzyć historię subskrypcji do analizy biznesowej i obliczyć salda, uzyskać zaległe płatności na podstawie subskrypcji itp.

Nie jestem również pewien, czy saldo powinno być przechowywane np. W samym modelu użytkownika, czy też nie jest przechowywane, ale można je obliczyć w dowolnym momencie na podstawie przechowywanych danych / historii.

Należy zwrócić uwagę na kilka rzeczy, choć nie sądzę, że powinny one wprowadzać problemy:

  • To nie musi być User, może być cokolwiek, dlatego Subscriberjest polimorficzny
  • Plansniekoniecznie muszą to być plany, ale mogą być np Magazines. wspomniane. To co mam opisane sprawie C i Przypadek D .
pduersteler
źródło
1
Jedną rzeczą, którą z pewnością możesz zrobić, to przypisać każdemu wydaniu cenę (która może być zależna od planu, tak że kombinacja [plan, wydanie] odwzorowuje na [cena emisyjna]), a następnie po prostu śledzić saldo każdego subskrybenta na magazyn (lub dowolną terminologię, którą preferujesz).
CVn
Dzięki wszystkim, musiałem zaktualizować pytanie, ponieważ nie mogłem jeszcze rozwiązać mojego problemu.
pduersteler
1
Czy mogę zapytać, jak to się stało?
JCM

Odpowiedzi:

6

Niestety odpowiedź na skomplikowany problem jest zwykle skomplikowana. Radzę ci zapisać tylko istotne informacje, a następnie użyć modelu, aby skonstruować większy obraz.

Innymi słowy, twoja tabela SubscriptionPlanChanges będzie zawierała następujące informacje dla swojego klucza:

  • abonent
  • plan
  • ważny od

W ten sposób zezwalasz na wiele planów dla tego samego subskrybenta, które mogą się pokrywać. Inne pola obejmują:

  • ważne do
  • opłacone do
  • stawka (również 0, jeśli bezpłatne)

Zauważ, że nie ma „planu z” ani „planu do”. Chociaż możesz je mieć, informacje są zbędne i można je obliczyć samodzielnie (przechowywanie takich informacji oznacza, że ​​masz dodatkowe zadanie, aby zachować spójność). Kiedy zaczyna się nowy plan, zamiast modyfikować istniejące plany, zostawiasz je i po prostu dodajesz nowy rekord. Jeśli po nowym planie istnieje inny nakładający się plan, możesz zdecydować, że chcesz go usunąć (w ten sposób bardziej intuicyjnie). Kiedy ładujesz te plany dla subskrybenta, sortujesz je według daty ważności od.

Po uzyskaniu tego, obliczenie kredytu użytkownika jest stosunkowo proste. Jeśli dwa plany nie mogą się pokrywać, po prostu weź mniejszą z dwóch dat między datą „ważna do” poprzedniego planu i „aktualną od” bieżącego planu, aby ustalić datę końcową. Data początkowa to większa z dwóch dat między datą „ważna od” a datą „płatna do” (jeśli jest zdefiniowana). Płatność (lub kredyt) można następnie obliczyć na podstawie stawki pomnożonej przez przedział czasu między wyżej wymienionymi datami rozpoczęcia i zakończenia tego planu.

W ten sposób możesz teoretycznie obliczyć wszystko, co musisz wiedzieć. Odradzałbym próbę zapisywania obliczonych wartości, ponieważ zmieniłyby się one po zmodyfikowaniu, dodaniu lub usunięciu istniejącego rekordu.

Odmiany sposobu obliczania tych wartości można zarządzać, dodając dodatkowe pole typu. W swoim kodzie możesz stworzyć specjalne moduły do ​​zarządzania logiką obliczania poszczególnych planów, aby utrzymać główny algorytm względnie wolny od skomplikowanych obliczeń. Jeszcze lepiej, jeśli uda Ci się utworzyć moduł obsługi dla przypadku, w którym nie określono żadnego typu, więc wystarczy zadzwonić do odpowiedniego modułu obsługi zgodnie z jego typem, aby wykonać dowolne obliczenia, których potrzebujesz.

Mam nadzieję, że to odpowiada na twoje pytanie.

Neil
źródło
Wielkie dzięki, że rzucić trochę światła! Chociaż wydaje mi się, że nie byłem pewien, co do „ważnego” pola. valid_untilbyła moja terminologia paid_until. Nie ma maksymalnej długości abonamentu.
pduersteler
@pduersteler Ah mój błąd wtedy. To tylko sprawia, że ​​obliczenia są o wiele łatwiejsze, ponieważ data „zakończenia” to dopiero początek nowego planu.
Neil
1
Stawka jest wypłacana? Jeśli tak, to może to być inny podmiot, na przykład faktura, czy mam rację?
JCM
3

Oprócz powyższej odpowiedzi stworzyłbym tabelę z kredytami, w której kredyt byłby równy bieżącej walucie. Ilekroć użytkownik przełącza się na tańszą alternatywę, niewykorzystane saldo pojawia się jako kredyty. Ilekroć użytkownik musi coś zapłacić, najpierw wykorzystasz kredyty i poprosisz o płatność tylko wtedy, gdy kredyty się wyczerpią lub nie będą istnieć. Jeśli korzystasz z tej alternatywy, utwórz tabelę jako listę transakcji, aby móc odtworzyć scenariusz użycia, jeśli kiedykolwiek dojdzie do sporu. Przykład:

Identyfikator, identyfikator użytkownika, data transakcji, kredyt (dodatni, gdy użytkownik przyznaje kredyty, a ujemny, gdy użytkownik korzysta z kredytu)

Wystarczy zsumować kredyty, aby użytkownik pokazał mu saldo.

Mam nadzieję, że to ci się przyda ...

Lars Hofvander
źródło