Question

I am new to Rails and trying to figure out how to setup the view for user to cancel a subscription or update (to a higher or lower plan). I added code to the subscription controller, but I am not understanding how to call this in the view so it can take action for switching from plan 1 to plan 12 (monthly to yearly) and to cancel the subscription altogether.

The code in the controller should allow the user to cancel their subscription or change the plan. Need help with creating the view action for it.

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 update_subscription
       @customer = Stripe::Customer.retrieve(@user.stripe_customer_token)
       @subscription = customer.subscriptions.retrieve(@user.plan_id)
       @subscription.plan = params[:plan_id]
       subscription.save
     end

     def cancel_subscription
       @customer = Stripe::Customer.retrieve(@user.stripe_customer_token)
       @customer.subscriptions.retrieve(@user.plan_id).delete()
     end
end

Routes:

 resources :charges
  resources :subscriptions
  resources :plans
  get 'paypal/checkout', to: 'subscriptions#paypal_checkout'

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
end
Was it helpful?

Solution

You would need to add to routes:

get "subscriptions/cancelsubscription"

Then in your view, <%= link_to "Cancel my subscription", subscriptions_cancelsubscription_path, :data => { :confirm => "Are you sure?" } %>

OTHER TIPS

You can move these functions to your controller and call them via a custom route.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top