简体   繁体   English

Paypal Recurring Gem - 暂停付款

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM