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.