我正在使用Stripe进行订阅,因此当用户取消订阅时(关闭自动续订),它会保持订阅有效,直到Stripe的结算周期结束。
该操作通过Stripe工作,但是如何设置以便我的数据库中的cancelled
列具有相同的效果?目前,如果用户点击取消订阅链接,则会将其cancelled
列标记为1
。我希望它不会在结算期结束前标记为已取消,因此用户可以继续访问该网站,直到最后一个结算日(我已打开autorenwal)
我已阅读txdavidtx建议。他建议将所有用户标记为在结算周期结束时取消。那种方法不适合我想要完成的任务。
我订阅设置为autorenew。我需要创建一个cancel
操作,只会将current_user
标记为在结算周期结束时取消。
例如:
用户A在9月27日注册月度订阅。用户A在12月15日决定取消订阅。用户A的订阅还剩12天。用户A点击cancel
链接。用户A在其PayPal或Stripe帐户中已取消自动更新和订阅。在我的数据库中,他们的cancelled
属性值在12天(12月27日)结束前不会改变。
如果有人可以提供帮助那就太好了。
订阅控制器:
def new
plan = Plan.find(params[:plan_id])
@subscription = plan.subscriptions.build
render layout: 'new_application'
if params[:PayerID]
@subscription.paypal_customer_token = params[:PayerID]
@subscription.paypal_payment_token = params[:token]
@subscription.email = @subscription.paypal.checkout_details.email
end
end
def create
@subscription = Subscription.new(params[:subscription])
if @subscription.save_with_payment
redirect_to @subscription, :notice => "Thank you for subscribing!"
else
render :new
end
end
def show
@subscription = Subscription.find(params[:id])
render layout: 'new_application'
end
def paypal_checkout
plan = Plan.find(params[:plan_id])
subscription = plan.subscriptions.build
redirect_to subscription.paypal.checkout_url(
return_url: new_subscription_url(:plan_id => plan.id),
cancel_url: root_url
)
end
def updatesubscription
@user = current_user
@customer = Stripe::Customer.retrieve(@user.subscription.stripe_customer_token)
if @user.subscription.plan_id == 12
@customer.update_subscription(:plan => "1", :prorate => true)
current_user.subscription.update_attributes(:plan_id => 1)
flash.alert = 'Your subscription has been changed to monthly!'
redirect_to root_url
elsif @user.subscription.plan_id == 1
@customer.update_subscription(:plan => "12", :prorate => true)
current_user.subscription.update_attributes(:plan_id => 12)
current_user.save!
flash.alert = 'Your subscription has been changed to annually!'
redirect_to root_url
end
end
def cancelsubscription
@user = current_user
@customer = Stripe::Customer.retrieve(@user.subscription.stripe_customer_token)
@customer.cancel_subscription(:at_period_end => true)
current_user.subscription.update_attributes(:cancelled => 1)
current_user.save!
flash.alert = 'Your subscription has been cancelled successfully!'
redirect_to root_url
end
def showcard
@user = current_user
Stripe::Customer.retrieve(@user.subscription.stripe_customer_token).cards.all()
end
def suspend
@user = current_user
@user.subscription.suspend_paypal
current_user.subscription.update_attributes(:cancelled => 1)
flash.alert = 'Billing has been suspended!'
redirect_to root_url
end
def reactivate
@user = current_user
@user.subscription.reactivate_paypal
current_user.subscription.update_attributes(:cancelled => nil)
flash.alert = 'Billing has been activated!'
redirect_to root_url
end
def edit_card
@user = current_user
end
def update_card
@user = current_user
card_info = {
name: params[:name],
number: params[:number],
exp_month: params[:date][:month],
exp_year: params[:date][:year],
cvc: params[:cvc]
}
if @user.subscription.update_card(@subscriber, card_info)
flash.alert = 'Saved. Your card information has been updated.'
redirect_to root_url
else
flash.alert = 'Stripe reported an error while updating your card. Please try again.'
redirect_to root_url
end
end
end
答案 0 :(得分:8)
我认为最简单的方法是使用条带webhooks,只要订阅结束,条带将使用customer.subscription.deleted事件ping您的系统,此时您应该取消用户订阅。
设置非常简单。
使用at_period_end params true检测用户并取消订阅
customer = Stripe::Customer.retrieve("cus_3R1W8PG2DmsmM9") customer.subscriptions.retrieve("sub_3R3PlB2YlJe84a").delete(:at_period_end => true
如果您在结算周期结束时取消订阅,则会立即触发customer.subscription.updated事件,反映订阅的cancel_at_period_end值的更改。当订阅在期末实际取消时,将发生customer.subscription.deleted事件。 Stripe Doc
4-然后设置回调控制器并检测订阅已删除
<pre>
class StripeEventsController
skip_before_filter :verify_authenticity_token
def catch
object = params[:data][:object]
case params[:type]
when "customer.subscription.deleted"
customer = object[:id]
user = User.find_by_stripe_id(customer)
user.subscription.update_attributes(cancelled: "1")
end
end
端
答案 1 :(得分:0)
我建议两件事之一。
第一个选项:
添加:cancellation_date属性,然后在应用程序控制器中创建一个帮助程序方法,以便在登录时检查取消日期。如果他们超过了他们的订阅结束日期,请将您的:订阅设置为&#34 1#34;
# application_controller.rb
def my_helper
if current_user.has_cancelled?
redirect_to registration_path
end
end
# user.rb although better to have the subscription do it instead
def has_cancelled?
if cancellation_date.present? && cancellation_date > (paid_on + 30)
subscription.update_attributes(cancelled: "1")
return true
else
return false
end
end
第二个选项:
使用像sucker_punch或sidekiq这样的后台工作每天早上运行并将过期的订阅设置为&#34; 1&#34;。
答案 2 :(得分:0)
错误的计划IMO:
您的订阅似乎是基于剩余的天数。因此,您只需要确保在请求user_is_subscripted时剩余的天数不为0.
current_user.subscription_expired?
def subscription_expired?
days == 0
end
创建一个列:订阅日期,每次用户续订订阅时,都会在计数中添加30天。每天运行一个脚本,将该列中的订阅日减少1.这样您就不需要考虑帐户日期。
此外:
if subscription_expired? and autorenewal?
renew_subscription(days)
end
def renew_subscription(days)
#paypal magic
current_user.subscription_days += days
end
当要求到期日时:
def expiration_day
Time.now + current_user.subscription_days.days
end
答案 3 :(得分:0)
您需要在试用期结束时更新用户的已取消列,而不是在实际取消时。
Kimooz几乎是对的。你将使用Stripe Webhook,我将解释你需要做什么才能达到你想要的效果。
首先,如果我理解正确,你想模仿Stripe中发生的事情。基本上,您希望数据库取消列在用户保持错误状态,直到用户所有时间都过期。这意味着如果您的用户单击“取消”,则取消列中的任何内容都不会更改,直到所有时间到期,此时应将其设置为true。
因此,使用Stripe取消用户帐户,就像用户点击取消时一样。此时,您的用户Stripe :: Subscription对象唯一不同的是属性cancel_at_period_end
设置为true。 subscription.status
属性保持active
,直到所有时间都过期。在所有时间到期之前,您的用户记录保持不变。
然后,设置一个Stripe Controller来处理webhook。通过这个过程似乎很痛苦,但这是实现解决方案的正确方法。
此时您需要解析customer.subscription.updated
事件不 customer.subscription.deleted
事件的webhook。 Stripe只会更新您的客户订阅。
如果您取消订阅,Stripe将不会删除您的客户订阅
...如果您取消订阅,它只会更新订阅状态。这意味着订阅以及与之相关的信息将保留在Stripe中,如果他们稍后续订,它仍然属于您的用户。
好的,所以..说你的用户在12月15日取消,但他们的订阅将于12月31日结束.Stripe会向你的webhook发送两个事件。
<强>十二月15 :此事件将是customer.subscription.updated
事件,它会告诉您cancel_at_period_end
属性已更新为true
。 (status
属性保持不变,active
)
<强>十二月31。:此活动将是customer.subscription.updated
事件,它会告诉您status
媒体资源已从active
更改为cancelled
。
当第二个事件发送到Stripe Webhook时,您现在可以解析事件并更改您自己数据库中的cancelled
状态,因为所有时间都已到期。
答案 4 :(得分:0)
对此最简单的解决方案是,检查用户是否仍有访问权限的方法,检查下一个重复日期是否在将来。
这样您就可以立即将canceled
标记为1
。