Paypal Recurring Gem - 暂停付款
Posted
技术标签:
【中文标题】Paypal Recurring Gem - 暂停付款【英文标题】:Paypal Recurring Gem - suspend payment 【发布时间】:2014-04-18 11:53:37 【问题描述】:我希望为 paypal 经常性 gem 设置付款暂停(跟随轨道演员)。我不确定是否需要设置 IPN,因为 gem 的文档中没有提到它。我目前拥有的代码不执行任何操作。
我在模型中定义了取消重复,但我不确定如何完成代码,因为我很难理解这一切是如何工作的。其他人已经问过这个问题,但没有答案。
如果有人有时间为我提供资产,那就太好了!
问题是如何暂停/取消用户的定期付款。
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
订阅控制器:
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
订阅模式:
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
路线:
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'
查看:
<%= link_to "Suspend paypal", subscriptions_suspend_path, :data => :confirm => "Are you sure?" %>
【问题讨论】:
【参考方案1】:此 PaypalPayment 是 paypal-recurring gem 的一种包装。因此,此类中的所有方法都只是准备并委托给 PayPal::Recurring,这就是为什么所有方法都只是调用实例化并传递操作的“流程”方法。
因此,对于暂停/取消,您只需为每个操作添加一个方法。正如文档所述,您需要这样做才能取消
ppr = PayPal::Recurring.new(:profile_id => "I-VCEL6TRG35CU")
ppr.suspend
所以对于您的 PaypalPayment 类,它看起来像这样:
def suspend
process :suspend, :profile_id => @subscription.paypal_recurring_profile_token
end
所以你的模型订阅.rb
def suspend_paypal
paypal.suspend
self.status = "canceled"
save
end
还有控制器 susbcription_controller.rb
def suspend
current_user.suspend_paypal
end
关于 IPN,如果用户通过您的网站暂停,我认为没有必要,但由于用户可能会直接通过贝宝取消它,您必须处理这种情况,以便用户不要停止支付,而是保持活跃订阅。
【讨论】:
我的印象是大部分工作应该在控制器中完成,但是你已经在模型中完成了大部分工作。话虽如此,我收到了一个错误[:code=>"11551", :messages=>["Profile Id is missing from the request", "Profile Id is missing from the request"]]
,所以它无法识别来自process :suspend, :profile_id => @subscription.paypal_recurring_profile_token
行的id。我更新了我的代码。
在 Rails 中他们有一句话“瘦控制器,胖模型”,所以通常你需要模型的大部分工作。关于错误,请确保您在订阅中拥有 profile_id,如果有,请尝试像这样直接调用:ppr = PayPal::Recurring.new(:profile_id => "SOME_PROFILE_ID_HERE"); ppr.suspend
问题是由于 Stripe 与 PayPal 的集成造成的。无法识别配置文件 ID,因为用户有一个使用 Stripe 运行的订阅。一旦我删除它,错误就会消失。感谢大家的帮助!
此外,我得到的唯一错误是 NoMethodError undefined method
status='`。对于self.status = "canceled"
行。我会修复它并在此处发布解决方案,以帮助需要此帮助的其他人。
该状态行更多是关于如何定义订阅已取消的示例,因此只需添加此列即可解决此问题以上是关于Paypal Recurring Gem - 暂停付款的主要内容,如果未能解决你的问题,请参考以下文章
recurring_select gem:jquery 在我的配置中不起作用
收款时Paypal Recurring Payment API CALL
Paypal recurring_payment_skipped 条件
Paypal Recurring Profile:如何每小时运行一次?