2014-03-13 254 views
4

我期待爲貝寶定期寶石設置付款暫停(按照鋼軌投射)。我不確定是否需要設置IPN,因爲在該文檔中沒有提及它。我目前的代碼不採取任何行動。貝寶定期寶石 - 暫停付款

我定義了取消在模型中反覆出現,但我不知道如何完成代碼,因爲我很難理解這是如何工作的。這個問題已被其他人問過,但沒有答案。

如果有人有時間資助我,這將是偉大的!

問題是如何暫停/取消用戶定期付款。

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?" } %> 

回答

5

這PaypalPayment是一種包裝的貝寶經常性寶石。因此,此類中的所有方法都只是準備並委託給PayPal :: Recurring,這就是爲什麼所有方法都只是調用實例化和傳遞操作的'process'方法。

因此,暫停/取消您只需要爲每個操作添加一個方法。正如文件指出,你需要做到這一點的取消

ppr = PayPal::Recurring.new(:profile_id => "I-VCEL6TRG35CU") 
ppr.suspend 

因此,對於你PaypalPayment類它是這樣的:

def suspend 
    process :suspend, :profile_id => @subscription.paypal_recurring_profile_token 
end 

所以你的模型subscription.rb

def suspend_paypal 
    paypal.suspend 
    self.status = "canceled" 
    save 
end 

而且控制器susbcription_controller.rb

def suspend 
    current_user.suspend_paypal 
end 

關於IPN,如果用戶通過您的網站暫停,我不認爲它是必要的,但是由於用戶可能通過PayPal直接取消它,您必須處理此情況,以便用戶不停止付款,而是保持活動訂閱。

+0

我在印象中應該在控制器中完成批量工作,但是您已經完成了模型中的大部分工作。這就是說我收到一個錯誤'[{:code =>「11551」,:messages => [「請求中缺少配置文件ID」,「請求中缺少配置文件ID」]}]'不識別來自'process:suspend,:profile_id => @ subscription.paypal_recurring_profile_token'行的id。我更新了我的代碼。 –

+1

在欄杆中,他們有一句話叫「瘦瘦的控制器,胖胖的模特」,所以通常你需要模型上的大部分工作。關於錯誤,請確保您在訂閱時擁有了profile_id,如果有,請嘗試像下面這樣調用:'ppr = PayPal :: Recurring.new(:profile_id =>「SOME_PROFILE_ID_HERE」); PPR。暫停「 – gabrielrios

+0

該問題是由於Stripe與PayPal的集成。配置文件ID未被識別,因爲用戶有一個訂閱正在運行Stripe。一旦我刪除它,錯誤消失。感謝所有的幫助! –