[英]Paypal Recurring Gem - suspend payment
I am looking to setup payment suspension for the paypal recurring gem (followed rails cast). 我正在寻找为paypal经常性宝石设置付款暂停(跟随铁轨演员)。 I'm not sure if setting up IPN is required as there's no mention of it in the docs for the gem.
我不确定是否需要设置IPN,因为在gem的文档中没有提到它。 The code I currently have takes no action.
我目前的代码不采取任何行动。
I defined cancel recurring in the model, though I am not sure how to finish the code as it is hard for me to understand how this all works. 我在模型中定义了取消重复,但我不知道如何完成代码,因为我很难理解这一切是如何工作的。 This question has been asked by others but there are no answers to it.
其他人已经问过这个问题,但没有答案。
If someone has the time to asset me that would be great! 如果有人有时间资产我,那就太棒了!
The question is how to suspend/cancel the user recurring payment. 问题是如何暂停/取消用户定期付款。
Paypal_payment.rb: Paypal_payment.rb:
def initialize(subscription)
@subscription = subscription
end
def checkout_details
process :checkout_details
end
def checkout_url(options)
process(:checkout, options).checkout_url
end
def make_recurring
process :request_payment
process :create_recurring_profile, period: :monthly, frequency: 1, start_at: Time.zone.now
end
def suspend
process :suspend, :profile_id => @subscription.paypal_recurring_profile_token
end
private
def process(action, options = {})
options = options.reverse_merge(
token: @subscription.paypal_payment_token,
payer_id: @subscription.paypal_customer_token,
description: @subscription.plan.name,
amount: @subscription.plan.price,
currency: "USD"
)
response = PayPal::Recurring.new(options).send(action)
raise response.errors.inspect if response.errors.present?
response
end
end
Subscriptions controller: 订阅控制器:
def new
plan = Plan.find(params[:plan_id])
@subscription = plan.subscriptions.build
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])
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)
@customer.update_subscription(:plan => "1", :prorate => true)
current_user.save!
flash.alert = 'Your subscription has been updated!'
redirect_to root_url
end
def cancelsubscription
@user = current_user
@customer = Stripe::Customer.retrieve(@user.subscription.stripe_customer_token)
@customer.cancel_subscription()
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 changecard
@user = current_user
@customer = Stripe::Customer.retrieve(@user.subscription.stripe_customer_token)
card = @customer.cards.create({
:card => @user.subscription.stripe_customer_token
})
@customer.default_card = card
@customer.save
end
def suspend
@user = current_user
@user.subscription.suspend_paypal
end
def updatebilling
@user = current_user
customer = Stripe::Customer.retrieve(@user.subscription.stripe_customer_token)
customer.cards.retrieve("#{@user.subscription.stripe_card_id}").delete()
customer.cards.create({
card: {
number: params[:user][:scardnumber],
exp_month: params[:user][:sexp_month],
exp_year: params[:user][:sexp_year],
cvc: params[:user][:scvc],
name: params[:user][:sname],
address_line1: params[:user][:sbilling_address1],
address_line2: params[:user][:sbilling_address2],
address_city: params[:user][:saddress_city],
address_zip: params[:user][:saddress_zip],
address_state: params[:user][:saddress_state],
address_country: params[:user][:saddress_country]
}
})
if customer.save!
@user.stripe_card_id = customer.active_card.id
@user.save!
flash.alert = 'Billing information updated successfully!'
redirect_to root_url
else
flash.alert = 'Stripe error'
redirect_to root_url
end
end
end
Subscription Model: 订阅模型:
belongs_to :plan
belongs_to :subscription
belongs_to :user
validates_presence_of :plan_id
validates_presence_of :email
attr_accessor :stripe_card_token, :paypal_payment_token
def save_with_payment
if valid?
if paypal_payment_token.present?
save_with_paypal_payment
else
save_with_stripe_payment
end
end
end
def paypal
PaypalPayment.new(self)
end
def save_with_paypal_payment
response = paypal.make_recurring
self.paypal_recurring_profile_token = response.profile_id
save!
end
def save_with_stripe_payment
customer = Stripe::Customer.create(description: email, plan: plan_id, card: stripe_card_token)
self.stripe_customer_token = customer.id
save!
rescue Stripe::InvalidRequestError => e
logger.error "Stripe error while creating customer: #{e.message}"
errors.add :base, "There was a problem with your credit card."
false
end
def payment_provided?
stripe_card_token.present? || paypal_payment_token.present?
end
def suspend_paypal
paypal.suspend
self.status = "canceled"
save
end
end
Routes: 路线:
get "subscriptions/cancelsubscription"
get "subscriptions/updatesubscription"
get "subscriptions/changecard"
get "subscriptions/suspend"
get "subscriptions/updatebilling"
resources :charges
resources :subscriptions
resources :plans
get 'paypal/checkout', to: 'subscriptions#paypal_checkout'
View: 视图:
<%= link_to "Suspend paypal", subscriptions_suspend_path, :data => { :confirm => "Are you sure?" } %>
This PaypalPayment is a kind of wrapper for the paypal-recurring gem. PaypalPayment是Paypal-recurring gem的一种包装。 So all of the methods in this class just prepare and delegate to PayPal::Recurring that's why all of the methods just call the 'process' method which instantiate and pass the action.
因此,本类中的所有方法都只是准备并委托给PayPal :: Recurring,这就是为什么所有方法都只调用实例化并传递操作的'process'方法。
So for suspending/cancelling you just need to add a method for each of this actions. 因此,对于暂停/取消,您只需为每个操作添加一个方法。 As the document states you need to do this for cancel
正如文档所述,您需要执行此操作以取消
ppr = PayPal::Recurring.new(:profile_id => "I-VCEL6TRG35CU")
ppr.suspend
So for your PaypalPayment class it would look like this: 所以对于你的PaypalPayment类,它看起来像这样:
def suspend
process :suspend, :profile_id => @subscription.paypal_recurring_profile_token
end
So your model subscription.rb 所以你的模型订阅.rb
def suspend_paypal
paypal.suspend
self.status = "canceled"
save
end
And the controller susbcription_controller.rb 和控制器susbcription_controller.rb
def suspend
current_user.suspend_paypal
end
About IPN, I don't think its necessary if the user suspend through your site, but as the user might cancel it directly through paypal you have to handle this case so the User don't stop paying but keep with an active subscription. 关于IPN,如果用户通过您的网站暂停,我认为没有必要,但由于用户可能直接通过PayPal取消它,您必须处理此案例,以便用户不要停止付费,而是保持有效订阅。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.