功能说明:
所以我有一个基于订阅的网站,有两个计划:每月和每年。每月订阅按月收取月费,而每年订阅则收取每年10个月的一次性累积费用。 (29美元/月和290美元/年)
对于每个被推荐的活跃会员(最多100%),我每个月都有10%的定期推荐折扣。因此,如果Bob在10月份报名参加月度订阅,并且在整个下个月提到5位注册用户,他应该累积50%的折扣。这将适用于他11月份的订阅费,这将导致该月的14.50美元。但假设他的一个转介在11月取消。这将使他12月的折扣降低10%,这将给他40%的折扣,有4个有效的推荐,导致12月的17.40美元。
工作代码示例:
如果每个Bob的推荐都是每月一次,那么使用webhooks这很简单。如果与该付款相关的用户是Bob的推介之一,则每次成功付款时,只需从Bob的当前余额中扣除一笔金额。
# Webhooks Controller
def payment_success
referred_user = User.find_by_customer_id(@subscription.customer.reference)
if referring_user = User.find_by_affiliate_code(referred_user.referral_code)
balance = referring_user.subscription.balance_in_cents
referring_user.subscription.adjustment({"amount_in_cents"=>"-290","memo"=>"Balance adjusted for referring #{referred_user.email}. Payment for referral was successful."})
referring_user.subscription.save
end
head :ok
end
这会向我正在使用的付款处理商 Chargify 发送请求,以相应地调整余额。
我的真正问题:
但是,当Bob的一个推荐人是年度用户时,这并不是直截了当的。
由于年度订阅是一次性付款,因此payment_success
每个月都不会发送Plan
个网络挂钩,这意味着不能每次扣除10%的Bob订阅费用。这个年度用户的有效推荐月份。
我想把Bob的计划价格设定为比标准价格低10%,而不是每个月调整余额。但是,这需要9个不同的计划,因为计划价格直接引用Chargify上的price
对象,该对象指向其90%_monthly_plan
属性。这意味着需要80%_monthly_plan
,# modified Webhooks Controller
def payment_success
referred_user = User.find_by_customer_id(@subscription.customer.reference)
if referring_user = User.find_by_affiliate_code(referred_user.referral_code)
balance = referring_user.subscription.balance_in_cents
referring_user.subscription.adjustment({"amount_in_cents"=>"-290","memo"=>"Balance adjusted for referring #{referred_user.email}. Payment for referral was successful."})
referring_user.subscription.save
if @subscription.product.handle == 'yearly'
schedule = ReferralSchedule.create(
type_of: "yearly discount",
referred_user_id: referred_user.id,
referring_user_id: referring_user.id,
time_to_execute: "30.41d"
)
ReferralScheduler::create_yearly_discounts_schedule(schedule)
end
end
head :ok
end
等等,这些都存在于Chargify服务器上。这看起来过于复杂,如果引起其他问题,我也不会感到惊讶。我现在甚至没有考虑过。
我目前的(不满意的)解决方案:
因此,我决定只在我的服务器上创建一个调度程序,该调度程序在每年用户注册时创建,并且每个月都会触发。
我正在使用rufus-scheduler。需要注意的一件重要事项 - 重新启动服务器时会破坏计划,因此我创建了计划记录,初始化程序会遍历这些记录,并在每次服务器重新启动时创建这些计划。
module ReferralScheduler
def self.create_yearly_discounts_schedule(schedule)
referred_user = User.find(schedule.referred_user_id)
referring_user = User.find(schedule.referring_user_id)
# first_date is calculated to be the first date in the future, that the scheduler should run.
first_date = Time.now + (30.41-(DateTime.now - schedule.created_at.to_datetime).fdiv(30.41)%1*30.41).days
scheduler = Rufus::Scheduler.new
scheduler.every schedule.time_to_execute, first: first_date , last_at: (schedule.created_at+12.months) do
if referring_user && referred_user.subscription_status == :active
balance = referring_user.subscription.balance_in_cents
referring_user.subscription.adjustment({"amount_in_cents"=>"-290","memo"=>"Balance adjusted for referring #{referred_user.email}. Referral is still active."})
referring_user.subscription.save
end
end
scheduler.at (schedule.created_at+12.months) do
schedule.destroy!
end
end
end
处理计划创建的模块:
require 'rufus-scheduler'
ReferralSchedule.where(type_of: "yearly discount").each do |schedule|
ReferralScheduler::create_yearly_discounts_schedule(schedule)
end
初始化程序:
public function report(\Exception $e)
{
if ($e instanceof \Exception) {
$debugSetting = Config::get('app.debug');
Config::set('app.debug', true);
if (ExceptionHandler::isHttpException($e)) {
$content = ExceptionHandler::toIlluminateResponse(ExceptionHandler::renderHttpException($e), $e);
} else {
$content = ExceptionHandler::toIlluminateResponse(ExceptionHandler::convertExceptionToResponse($e), $e);
}
Config::set('app.debug', $debugSetting);
$data['content'] = (!isset($content->original)) ? $e->getMessage() : $content->original;
Mail::queue('errors.emails.error', $data, function ($m) {
$m->to('email@email.com', 'Server Message')->subject('Error');
});
}
return parent::report($e);
}
我真的很讨厌使用这种方法,因为它看起来不是很干净。当我试图以较短的间隔运行它时,它已经搞砸了我的本地服务器。
我还考虑过使用rake任务和/或Grunt来执行此操作,但我对这些内容的知识非常有限,而且我不确定它们是否一定是更容易/更好的解决方案。
有什么想法吗?
答案 0 :(得分:0)
一种选择可能是使用Bob的订阅上的upcoming_renewal_notice
webhook作为触发器来查看他在年度计划中提出的推荐数量,并应用任何其他折扣。
https://docs.chargify.com/webhooks
upcoming_renewal_notice
- 订阅设置为在3天内续订