处理订阅,余额和定价计划更改


11

序言
我的目的是为多个项目创建可重用的代码(并在github上发布)以管理订阅。我了解条带化和定期计费提供商,但这不是该模块的目标。它应该只是用于计算帐户余额,轻松通知续订订阅以及处理价格计算的包装程序/帮助程序。

在某些国家/地区,您可能无法使用重复计费,因为提供商或付款方式对此支持不佳或没有支持,或者价格太高(小额付款)。而且有些人不想使用循环计费,而是手动支付账单/在年末开具发票。因此,请不要建议贝宝定期计费,递归或类似服务。

情况
假设您有一个可以订阅订阅计划的模型(例如User)。该模型具有一个字段,该字段存储当前正在订阅的订阅计划的标识符。因此,在每次计划更改时,都会记录更改。

有一个模型(例如SubscriptionPlanChanges),其中的以下字段记录了提到的更改:

  • subscriber与订阅模型有关(User在这种情况下)
  • from_plan 定义更改之前模型具有的计划标识符
  • to_plan 定义模型现在选择的计划标识符
  • created_at 是存储更改的日期时间字段
  • valid_until 存储日期,直到实际订阅有效
  • paid_at 也是一个日期时间字段,用于定义是否(以及何时)订阅已支付

当然,这种布局是可以讨论的。

帐户余额问题
当用户更改其订阅计划时,我需要比较计划字段,获取价格,并根据当前计划valid_until及其价格计算新计划的扣除额。说:您订购了计划A的一年,但是在6个月后,您升级到计划B,因此您可以从计划A的6个月中扣除一半的已付价格。

我想知道的是:如果某个用户(例如)切换到免费计划,那么他有一个积分,如果该用户想要再次切换,则可以扣除该积分。您会在另一个字段中缓存该值,还是每次都计算与该用户相关的所有记录?您会添加/更改有关表格布局的内容吗?

易于理解的问题
当订阅期结束时,用户会收到通知,并有可能通过再次付费来续订其订阅。最简单的方法是只更新paid_atvalid_until新的订阅选项。但是,我不确定您是否存储了某人可能需要的所有数据,例如付款/订阅历史记录。

另一个选择是为此创建一个附加记录,其中from_planto_plan具有相同的标识符(因此表示“无变化”)。但是这不会以某种方式干扰帐户余额的计算吗?

如果有人能为我指出有关处理此类订阅的逻辑的正确方向,我将非常感激。


更新
感谢您的帮助。我认为我的问题太模糊了,因此我将尝试通过使用较少的抽象来使其更加精确。不幸的是,我还不能解决我的问题。

案例A
User可以选择Subscription Plan A。当前,此文件存储了一个SubscriptionPlanChange以进行跟踪。例如5个月后,User将其订阅升级为Subscription Plan B。因此,他为新订阅支付价格,减去未使用的7个月的方案a的价格。

案例B
3个月后,User回滚到他的Subscription Plan A。他不必付款,但会收到一笔余额,因此,在订阅结束时,他将从新订阅中扣除该余额。

案例C
User可以为具有独立订阅计划的子服务选择订阅计划。相同Case ACase B可以申请该子服务订阅。

_Case D_ 用户取消其订阅之一。这导致他的余额增加了。

我的问题(目前至少是)主要取决于如何正确存储数据,以便我可以重现订阅的历史以进行业务分析和计算余额,并根据订阅获得未付款项等。

我也不确定是否应将余额存储在例如用户模型本身中,或者是否未存储但可以根据存储的数据/历史记录随时进行计算。

需要注意一些事项,尽管我认为它们不应该引入问题:

  • 它不一定是a User,也可以是任何东西,这就是为什么a Subscriber是多态的
  • Plans不一定必须是计划,而可以例如Magazines是提到的。这就是我在案例C案例D中描述的内容。

1
您当然可以做的一件事就是为每个发行分配一个价格(这可以取决于计划,以便[计划,发行]的组合映射到[发行价格]),然后简单地跟踪每个杂志的每个订户的余额(或您喜欢的任何一种术语)。
CVn

谢谢大家,我需要更新问题,因为我还不能解决问题。
pduersteler

1
请问您如何最终实现这一目标?
JCM

Answers:


6

不幸的是,对一个复杂问题的答案通常很复杂。我对您的建议是只保存相关信息,然后使用模型构建更大的图景。

换句话说,您的表SubscriptionPlanChanges的键将具有以下信息:

  • 订户
  • 计划
  • 有效期自

这样,您就可以为同一订户提供多个可以重叠的计划。其他字段包括:

  • 有效期至
  • 直到支付
  • 费率(如果免费,也为0)

请注意,没有“计划自”或“计划至”。尽管您可以拥有这些信息,但是这些信息是多余的,可以自己计算(存储此类信息意味着您还有保持一致的附加任务)。当新计划开始时,您不必保留现有计划,而只需修改新记录即可,而不必修改现有计划。如果新计划之后还存在另一个重叠计划,则可以决定要删除它(这种方式更加直观)。当为订户加载这些计划时,可以按它们的“有效期自”日期对其进行排序。

一旦获得这一点,计算用户信用就相对简单。如果两个计划不能重叠,则只需取前一个计划的“有效至”日期与当前计划的“有效自”日期之间的两个日期中的较小者,即可确定结束日期。开始日期是“有效期自”日期与“付款至”日期(如果已定义)之间的两个日期中较大的日期。然后,可以根据比率乘以该计划的上述开始日期和结束日期之间的时间间隔来计算付款(或贷项)。

这样,您理论上就可以计算任何您需要知道的内容。我建议不要尝试保存计算值,因为当修改,添加或删除现有记录时,计算值将更改。

您可以通过添加其他类型字段来管理如何计算这些值。在您的代码中,您可以创建特殊的处理程序来管理计算特定计划的逻辑,以使您的主要算法相对不复杂。如果您设法为未指定类型的情况创建处理程序,则更好的是,您要做的就是根据其类型调用适当的处理程序,以便进行所需的任何类型的计算。

我希望能回答您的问题。


非常感谢,这说明了一切!尽管我感觉不清楚“有效”字段。valid_until是你的我的术语paid_until。没有订阅计划的最大长度。
pduersteler 2013年

@pduersteler啊,那是我的错误。这只会使计算变得容易得多,因为“结束”日期仅仅是新计划的开始。
Neil

1
率是支付的金额?如果是,那么这可能是另一个实体,例如发票,对吗?
JCM

3

除了上述答案外,我还将创建一个带有贷方的表格,其中贷方将等于当前货币。每当用户将计划切换到更便宜的替代方案时,未使用的余额即作为积分输入。每当用户有东西要付款时,您将首先使用信用额度,并且仅在信用额度用完或不存在时才要求付款。如果使用此替代方法,则将该表创建为事务列表,以便在发生纠纷时能够重现使用情况。例:

ID,UserId,TransactionDate,信用(当您给用户信用时为正,当用户使用信用时为负)

只需对用户的信用额加总即可显示其余额。

希望这对您有帮助...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.