简体   繁体   中英

How to Cancel Paypal Subscription?

I finally figured out how to implement PayPal Recurring Billing using this tutorial. http://railscasts.com/episodes/289-paypal-recurring-billing

Everything works, But how does one cancel the subscription....

Below is all of the code I've written, and I've also added some comments/questions

ERROR

app/controllers/subscriptions_controller.rb:27:in `show'

Couldn't find Subscription with id=cancel_account

Please help new to rails. :)

CONTROLLER

class SubscriptionsController < ApplicationController

  def new
    plan = Plan.find(params[:plan_id])
    @subscription = plan.subscriptions.build
    @subscription.user_id = current_user.id
    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 destroy
    @subscription = current_user.subscription
    @previous_plan = @subscription.plan

    if @subscription.cancel_recurring
      flash[:success] = 'Subscription Canceled.'
    end
    redirect_to some_path
  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

end

MODELS

class Subscription < ActiveRecord::Base
  attr_accessible :paypal_customer_token, :paypal_recurring_profile_token, 
                  :plan_id, :user_id, :email, :paypal_payment_token

  attr_accessor :paypal_payment_token

  belongs_to :plan
  belongs_to :user

  validates_presence_of :plan_id
  validates_presence_of :email
  validates_presence_of :user_id

  def save_with_payment
    if valid?
      if paypal_payment_token.present?
       save_with_paypal_payment
    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 payment_provided?
    paypal_payment_token.present?
  end

end

class PaypalPayment
  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 + 1.month
  end

  def cancel_recurring
    response = ppr.cancel_subscription(at_date_end: true) #Needs a end period field in
    self.current_date_end_at = Time.at(response.current_date_end)
    self.plan_id = plan.id
    self.status = "canceled"
    return self.save
  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.to_i,
      currency: "USD"
    )
    response = PayPal::Recurring.new(options).send(action)
    raise response.errors.inspect if response.errors.present?
    response
  end
end

VIEWS

<%= form_for @subscription do |f| %>

  <%= f.hidden_field :plan_id %>
  <%= f.hidden_field :user_id %>
  <%= f.hidden_field :paypal_customer_token %>
  <%= f.hidden_field :paypal_payment_token %>

  <% unless @subscription.payment_provided? %>
  <div class="field">
    <%= radio_button_tag :pay_with, :paypal %>
    <%= label_tag :pay_with_paypal do %>
      <%= image_tag "paypal.png" %>
    <% end %>
  </div>
  <% end %>


*** WHAT WOULD BE THE LINK TO CANCEL THE SUBSCRIPTION ***

    <%= link_to image_tag("https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif"),
    paypal_checkout_path(plan_id: @subscription.plan_id) %>

    <%= link_to "Cancel Subscription", cancel_account_subscriptions_path(plan_id: 
    @subscription.plan_id) %>



  <div id="billing_fields">
    <div class="field">
      <%= f.label :email %>
      <%= f.text_field :email %>

    </div>
    <% if @subscription.payment_provided? %>
      Payment has been provided. Click "Subscribe" to complete the subscription.
    <% end %>
    <div class="actions">
      <%= f.submit "Subscribe" %>
    </div>
  </div>
<% end %>

ROUTES

App::Application.routes.draw do

  resources :subscriptions do
    collection do
      delete :cancel_account
    end
  end

  get 'paypal/checkout', to: 'subscriptions#paypal_checkout'

end

To destroy a users paypal subscription you should create a destroy action in your subscription model.

Subscription_controller.rb

  def destroy
    @subscription = current_user.subscription
    @previous_plan = @subscription.plan

    if @subscription.cancel_recurring
      flash[:success] = 'Subscription Canceled.'
    end
    redirect_to some_path
  end

In your model get the current user and cancel their subscription. If the user is subscribed monthly but canceled within 2days out of the 30 days, their account subscription should be valid until the at_end_date period(just a heads up).

  def cancel_recurring
    response = ppr.cancel_subscription(at_date_end: true) #Needs a end period field in
    self.current_date_end_at = Time.at(response.current_date_end)
    self.plan_id = plan.id
    self.status = "canceled"
    return self.save
  end

Routes.rb

resources :subscriptions do
 collection do
   delete :cancel_account
 end
end

In your view you would iterate through the plans like so

<% @plans.each do |plan| %>
  <%= link_to "Cancel Account", cancel_account_subscriptions_path(@subscription, plan_id: plan.id), method: :delete %>
<% end %>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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