Обробка підписок, залишків та зміни плану ціноутворення [закрито]


11

Преамбула
Моя мета - створити код для багаторазового використання для декількох проектів (а також опублікувати його на github) для управління підписками. Я знаю про смугових та періодичних постачальників платежів, але це не те, до чого спрямований цей модуль. Він повинен бути просто обгорткою / помічником для обчислення залишку на рахунку, прості сповіщення про поновлення підписки та обробку розрахунків цін.

Є країни, в яких не можна використовувати періодичні платежі через те, що постачальники послуг або можливості оплати мають погану або не підтримують її або занадто дорогі (мікроплатежі). І є люди, які не хочуть використовувати періодичні рахунки, але сплачують рахунок вручну / надсилаючи рахунок-фактуру в кінці року. Тому, будь ласка, не пропонуйте PayPal періодичні рахунки, періодично чи подібні послуги.

Ситуація
Скажімо, у вас є модель, яка може підписатися на план підписки (наприклад, User). Ця модель має поле, в якому зберігається ідентифікатор плану підписки, на який він підписаний. Отже, при кожній зміні плану фіксується зміна.

Існує модель (наприклад SubscriptionPlanChanges) із наступними полями, що записують згадані зміни:

  • subscriber, що стосуються моделі передплати ( Userв даному випадку)
  • from_plan визначення ідентифікатора плану, який модель мала до зміни
  • to_plan визначення ідентифікатора плану, який модель обрала зараз
  • created_at це поле дати та часу, яке зберігає зміни
  • valid_until зберігає дату, поки фактична підписка не дійсна
  • paid_at також є полем дата-час, яке визначає, чи була (і коли) передплата

Звичайно, ця схема є дискусійною.

Питання про залишок рахунку
Коли Користувач змінює свій план підписки, мені потрібно порівняти поля плану, отримати ціноутворення та обчислити відрахування за новим планом виходячи з поточного плану valid_untilта його ціни. Скажіть: Ви підписалися на рік плану A, але через 6 місяців ви переходите на план B, тож ви отримуєте відрахування вдвічі сплаченої ціни за 6 місяців плану А.

Що мені цікаво: Якщо користувач, наприклад, переходить на безкоштовний план, у нього є кредит, який можна вирахувати, якщо користувач захоче переключитися знову. Чи хочете ви кешувати це значення в додатковому полі або щоразу обчислювати всі записи, пов’язані з цим користувачем? Ви б додали / змінили щось про макет таблиці?

Питання про легку зрозумілість
Коли настає кінець періоду підписки, користувач отримує сповіщення та має можливість відновити свою підписку, заплативши ще раз. Найпростішим способом було б просто оновити paid_atі valid_untilз новими параметрами підписки. Однак я не впевнений, що ви зберігаєте всі дані, які комусь можуть знадобитися, наприклад історію платежів / підписок.

Іншим варіантом було б створити для цього додатковий запис, де from_planі to_planмають той самий ідентифікатор (таким чином символізуючи "без змін"). Але хіба це не завадило б розрахувати залишки на рахунку певним чином?

Якщо хтось міг би вказати мені на правильний напрямок щодо логіки, що обробляє такі підписки, я дуже вдячний.


ОНОВЛЕННЯ
Дякуємо за допомогу на даний момент. Я думаю, що моє запитання було занадто розпливчастим, тому я постараюся бути більш точним, використовуючи менше абстракцій. На жаль, я ще не міг вирішити свою проблему.

Випадок А
User може вибрати Subscription Plan A. Наразі це SubscriptionPlanChangeсховище для його відстеження. Через 5 місяців Userоновлення підписки до Subscription Plan B. Тож він платить ціну за свою нову підписку, вирахувавши ціну плану a за невикористані 7 місяців.

Справа В
Через 3 місяці Userвідкочується до його Subscription Plan A. Він не повинен платити, але отримує залишок за це, щоб в кінці підписки отримувати цей залишок, який віднімається за його нову підписку.

Випадок C
User може вибрати план передплати для субслужби, яка має незалежні плани підписки. Те ж саме Case Aі Case Bможе застосовуватися для цієї підписки суб-послуг.

_Case D_ Користувач скасовує одну зі своїх підписок. Це призводить до поповнення його балансу.

Моє запитання (принаймні на даний момент) головним чином залежить від того, як правильно зберігати ці дані, щоб я міг відтворити історію підписок для аналізу бізнесу та обчислити залишки, отримати непогашені платежі на основі підписок тощо.

Я також не впевнений, чи слід зберігати баланс у, наприклад, самій моделі користувачів, чи вона не зберігається, але її можна обчислити будь-який час, виходячи із збережених даних / історії.

Деякі речі, які слід зазначити, хоча я не думаю, що вони повинні створювати проблеми:

  • Це не повинно бути User, може бути чим завгодно, ось чому Subscriberполіморфно
  • Plansне обов'язково повинні бути планами, але це може бути, наприклад, Magazinesзгаданим. Ось що я описав у справі С та " Справі D" .

1
Одне, що ви, безумовно, можете зробити, це присвоїти кожному випуску ціну (яка може залежати від плану, щоб комбінація [план, випуск] мапи [ціна випуску]), а потім просто відслідковувати баланс кожного абонента за журнал (або залежно від термінології).
CVn

Дякую всім, мені потрібно було оновити питання, оскільки я ще не міг вирішити свою проблему.
pduersteler

1
Чи можу я запитати, як ви закінчили це реалізувати?
JCM

Відповіді:


6

На жаль, відповідь на складну проблему зазвичай є складною. Моя рада вам буде зберегти лише релевантну інформацію, а потім використовувати модель для побудови більшої картини.

Іншими словами, ваша таблиця SubscriptionPlanChanges міститиме таку інформацію для свого ключа:

  • абонент
  • план
  • діє з

Таким чином, ви дозволяєте створювати кілька планів для одного абонента, які можуть перекриватися. Інші поля включають:

  • дійсний до
  • виплачено до
  • ставка (також 0, якщо безкоштовно)

Зауважте, що немає "плану від" або "плану до". Хоча ви можете їх мати, інформація є зайвою і може бути розрахована самостійно (зберігання такої інформації означає, що у вас є додаткове завдання їх збереження). Коли починається новий план, замість того, щоб змінювати існуючі плани, ви залишаєте їх і просто додаєте новий запис. Якщо після нового плану існує інший план, що перекривається, ви можете вирішити, що хочете його видалити (більш інтуїтивно зрозумілим). Завантажуючи ці плани для абонента, ви сортуєте їх за датою "дійсного з".

Як тільки ви це отримаєте, розрахувати кредит користувача порівняно просто. Якщо два плани не можуть перекриватися, ви просто переймете меншу з двох дат між датою "дійсного до" попереднього плану і "дійсною з" поточного плану, щоб визначити дату закінчення. Дата початку - більша від двох дат між датою "дійсна з" та датою "сплачено до" (якщо вона визначена). Потім платіж (або кредит) може бути розрахований на ставку, помножену на проміжок часу між згаданими датами початку та кінця цього плану.

Таким чином, ви можете теоретично розрахувати все, що вам потрібно знати. Я б радив не намагатися зберегти обчислені значення, оскільки це зміниться, коли існуючий запис буде змінено, додано чи видалено.

Варіанти способів обчислення цих значень можна керувати, додавши додаткове поле типу. У своєму коді ви можете створити спеціальні обробники для управління логікою обчислення конкретних планів, щоб ваш основний алгоритм був відносно чітким від складних обчислень. Ще краще, якщо вам вдасться створити обробник для випадку, в якому не вказано тип, тому все, що вам потрібно зробити, - це зателефонувати до відповідного обробника відповідно до його типу, щоб зробити будь-який потрібний вам розрахунок.

Я сподіваюся, що це відповість на ваше запитання.


Велике спасибі, що пролили трохи світла! Хоча я відчуваю, що мені було незрозуміло щодо "дійсного" поля. valid_untilбула моєю вашою термінологією paid_until. Немає максимальної тривалості плану підписки.
pduersteler

@pduersteler Ага, моя помилка тоді. Це лише робить обчислення набагато простішим, оскільки дата "закінчення" - це лише початок нового плану.
Ніл

1
Ставка - це сплачена сума? Якщо так, то це може бути інша організація, наприклад, рахунок-фактура, я прав?
JCM

3

На додаток до вищезгаданої відповіді я створив би таблицю з кредитами, де кредит дорівнював би поточній валюті. Щоразу, коли користувач перемикає план на більш дешеву альтернативу, невикористаний баланс вводиться як кредити. Щоразу, коли користувачеві є що платити, ви спочатку користуєтеся кредитами, а просити про сплату лише тоді, коли кредити закінчаться або їх немає. Якщо ви використовуєте цю альтернативу, створіть таблицю як список транзакцій, щоб мати можливість відтворити сценарій використання, якщо коли-небудь виникне суперечка. Приклад:

Ідентифікатор, UserId, TransactionDate, Кредит (позитивний, коли ви надаєте користувачеві кредити, а негативний, коли користувач використовує кредит)

Просто підсумуйте кредити для користувача, щоб показати йому / їй баланс.

Сподіваюся, це вам корисно ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.