I'm using paypal-recurring gem for my app and i can't figure out how to cancel a user's subscription. i tried gabriel's answer from a similar question on here, but i get a NoMethodError in SubscriptionsController#suspend undefined method 'suspend_paypal' for User` when trying to cancel the subscription.
In my subscriptions.rb model
class Subscription < ApplicationRecord
belongs_to :plan
belongs_to :user
validates_presence_of :plan_id
validates_presence_of :user_id
attr_accessor :paypal_payment_token
def save_with_payment
if valid?
if paypal_payment_token.present?
save_with_paypal_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 suspend_paypal
paypal.suspend
self.status = "canceled"
save
end
def payment_provided?
paypal_payment_token.present?
end
end
subscriptions_controller
class SubscriptionsController < ApplicationController
before_action :authenticate_user! , only: [:new, :edit]
def new
plan = Plan.find(params[:plan_id])
#subscription = plan.subscriptions.build
#subscription.user_id = current_user.id
if params[:PayerID]
#subscription.paypal_cutomer_token = params[:PayerID]
#subscription.paypal_payment_token = params[:token]
#subscription.email = #subscription.paypal.checkout_details.email
end
end
def index
end
def create
#user = current_user
#subscription = Subscription.new(subscription_params)
if #subscription.save_with_payment
redirect_to root_path, :notice => "Thank you for subscribing"
#user.premium!
else
render :new
end
end
def suspend
#user = current_user
#user.suspend_paypal
flash[:success] = 'Subscription Canceled.'
#user.free!
redirect_to root_path
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
private
def subscription_params
params.require(:subscription).permit!
end
end
paypal_payment.rb
class PaypalPayment
def initialize(subscription)
#subscription = subscription
end
def checkout_details
process :checkout_details
end
def payment_active?
self.status = "active"
end
def suspend
process :suspend, :profile_id => #subscription.paypal_recurring_profile_token
end
def checkout_url(options)
process(:checkout, options).checkout_url
end
def save_with_paypal_payment
response = paypal.make_recurring
self.paypal_recurring_profile_token = response.profile_id
save!
end
def make_recurring
process :request_payment
process :create_recurring_profile, period: :monthly, frequency: 1, start_at: Time.zone.now
end
private
def process(action, options = {})
options = options.reverse_merge(
token: #subscription.paypal_payment_token,
payer_id: #subscription.paypal_cutomer_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
View
<%= link_to "Suspend paypal", subscriptions_suspend_path, :data => { :confirm => "Are you sure?" } %>
You have defined suspend_paypal on the Subscription model, but you're trying to call it on user. Get the subscription instead and call the method:
# class SubscriptionsController
def suspend
#subscription = Subscription.find(params[:id])
#subscription.suspend_paypal
flash[:success] = 'Subscription Canceled.'
current_user.free!
redirect_to root_path
end
Note -- you should add authorization logic, otherwise any user who can authenticate can suspend an arbitrary subscription by sending its ID. If a user has_many subscriptions, subscription = current_user.subscriptions.find(params[:id]). If has_one, just current_user.subscription and validate that that matches params[:id] for good measure.
You probably also don't need subscription to be an ivar since you're simply redirecting to root. Just replace #subscription with subscription. Use ivars when you need to access those variables in the views.
Related
I'm getting a bit confused as to why I am receiving this error as (i think) it is suggesting that my current_customer returns nil. I do not know how to fix this, is it a problem with my current_customer method, sessions controller, or my events_controller...
Event Model:
class Event < ActiveRecord::Base
belongs_to :calendar
end
Events Controller:
class EventsController < ApplicationController
def new
#event = Event.new
#calendar = current_customer.calendar #WHY IS IT NOT ERRORING HERE TOO?
end
def create
**#calendar = current_customer.calendar #IT IS CALLING ERROR HERE**
#event = #calendar.build.event(event_params)
if #event.save
redirect_to '/main'
else
redirect_to '/compose'
end
end
private
def event_params
params.require(:event).permit(:calendar_id, :name, :starts_at, :ends_at)
end
Customer model:
class Customer < ActiveRecord::Base
belongs_to :business
has_one :calendar
has_secure_password
attr_accessor :remember_token
#remembers a user in the database for use in persistent sessions
def remember
self.remember_token = Customer.new_token
update_attribute(:remember_digest, Customer.digest(remember_token))
end
def Customer.digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
def forget
update_attribute(:remember_digest, nil)
end
def Customer.new_token
SecureRandom.urlsafe_base64
end
#returns true if the given token matches the digest
def authenticated?(remember_token)
BCrypt::Password.new(remember_digest).is_password?(remember_token)
end
end
Customer controller:
class CustomersController < ApplicationController
def new
#customer = Customer.new
#businesses = Business.all
#calendar = Calendar.new
end
def create
#customer = Customer.create(customer_params)
#calendar = #customer.build_calendar
#customer.save!
session[:customer_id] = #customer.id
redirect_to '/'
rescue ActiveRecord::RecordInvalid => ex
render action: 'new', alert: ex.message
end
private
def customer_params
params.require(:customer).permit(:first_name, :last_name, :business_no, :email, :password, :business_id)
end
end
Sessions controller:
class SessionsController < ApplicationController
def new
end
def create
#customer = Customer.find_by_email(params[:session][:email])
if #customer && #customer.authenticate(params[:session][:password])
session[:customer_id] = #customer.id #log in
#customer.remember
cookies.permanent.signed[:customer_id] = #customer.id
cookies.permanent[:remember_token] = #customer.remember_token
redirect_to '/main'
else
#need to add flash error: invalid password/email combination
redirect_to '/login'
end
end
def destroy
#current_customer.forget
cookies.delete(:customer_id)
cookies.delete(:remember_token)
session.delete(:customer_id)
#current_customer = nil
redirect_to '/'
end
end
Current_customer method within application.controller:
helper_method :current_customer
def current_customer
if (customer_id = session[:customer_id])
#current_customer ||= Customer.find_by(id: customer_id)
elsif (customer_id = cookies.signed[:customer_id])
customer = Customer.find_by(id: customer_id)
if customer && customer.authenticated?(cookies[:remember_token])
session[:customer_id] = customer.id #log in
#current_customer = customer
end
end
end
Calendar model:
class Calendar < ActiveRecord::Base
belongs_to :customer
has_many :events
end
calendars_controller:
class CalendarsController < ApplicationController
def new
#calendar = Calendar.new(calendar_params)
end
def create
#calendar = Calendar.new(calendar_params)
end
private
def calendar_params
params.require(:customer_id)
end
end
I am new to Ruby/Rails so I would really appreciate any explanations and answers, please help! thanks
#calendar = current_customer.calendar
#event = #calendar.build.event(event_params)
According to the error message, #calendar is nil, so when you call #calendar.build.event(event_params) in the next line, it calls: nil.build and hence you get the error.
For some reason, your current_customer's calendar is nil for that request. Figure that out and make sure the current_customer has a calendar present in the database, then it should work.
Also, you need to change:
#event = #calendar.build.event(event_params)
To:
#event = #calendar.events.build(event_params)
It would seem that #calendar is nil in the events controller.
Start by checking the current_customer passes back the customer you were expecting.
Then check that the current_customer has a calendar created for you to reference.
I have PayPal setup using the paypal recurring gem. I need help understanding how to implement PayPal IPN.
Any help would be greatly appreciated as this is the last step for my project. I need to have the IPN setup so that when users cancel/suspend billing from their PayPal account that it will show as cancelled from my database.
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
def reactivate
process :reactivate, :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,
ipn_url: "http://mydomain.com/paypal/ipn",
currency: "USD"
)
response = PayPal::Recurring.new(options).send(action)
raise response.errors.inspect if response.errors.present?
response
end
end
Subscription.rb:
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 expires_at
self.updated_at + plan.duration.days
end
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
save
end
def reactivate_paypal
paypal.reactivate
save
end
def update_card(subscriber, card_info)
token = Stripe::Token.create(
card: {
number: card_info[:number],
exp_month: card_info[:exp_month],
exp_year: card_info[:exp_year],
cvc: card_info[:cvc]
}
)
customer = Stripe::Customer.retrieve(user.subscription.stripe_customer_token)
card = customer.cards.create(card: token.id)
card.save
customer.default_card = card.id
customer.save
rescue Stripe::InvalidRequestError => e
logger.error "Stripe error while updating card info: #{e.message}"
errors.add :base, "#{e.message}"
false
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)
if #user.subscription.plan_id == 12
#customer.update_subscription(:plan => "1", :prorate => true)
current_user.subscription.update_attributes(:plan_id => 1)
flash.alert = 'Your subscription has been changed to monthly!'
redirect_to root_url
elsif #user.subscription.plan_id == 1
#customer.update_subscription(:plan => "12", :prorate => true)
current_user.subscription.update_attributes(:plan_id => 12)
current_user.save!
flash.alert = 'Your subscription has been changed to annually!'
redirect_to root_url
end
end
def cancelsubscription
#user = current_user
#customer = Stripe::Customer.retrieve(#user.subscription.stripe_customer_token)
#customer.cancel_subscription()
current_user.subscription.update_attributes(:cancelled => 1)
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 suspend
#user = current_user
#user.subscription.suspend_paypal
current_user.subscription.update_attributes(:cancelled => 1)
flash.alert = 'Billing has been suspended!'
redirect_to root_url
end
def reactivate
#user = current_user
#user.subscription.reactivate_paypal
current_user.subscription.update_attributes(:cancelled => nil)
flash.alert = 'Billing has been activated!'
redirect_to root_url
end
def edit_card
#user = current_user
end
def update_card
#user = current_user
card_info = {
name: params[:name],
number: params[:number],
exp_month: params[:date][:month],
exp_year: params[:date][:year],
cvc: params[:cvc]
}
if #user.subscription.update_card(#subscriber, card_info)
flash.alert = 'Saved. Your card information has been updated.'
redirect_to root_url
else
flash.alert = 'Stripe reported an error while updating your card. Please try again.'
redirect_to root_url
end
end
end
routes:
post "paypal/ipn" => "notifications#create"
Payment Notifications controller:
def index
redirect_to root_url
end
def create
PaymentNotification.create!(:params => params, :status => params[:payment_status], :transaction_id => params[:txn_id])
render :nothing => true
end
end
Notifications controller:
def create
query = params
query[:cmd] = "_notify-validate"
if(response.body == "VERIFIED")
Rails.logger.debug params.inspect "Notification is valid"
end
end
end
You need to fix your routes.
It should be:
match '/paypal/ipn' => 'notifications#create', :via => [:get, :post], :as => 'notifications_create'
In the PayPal developer site there is an IPN test tool. You can provide it your callback URL and send sample calls. You'll have to register first to use it.
So you're only problem is getting the IPN's to trigger in your test account..?? When you use the Simulator does everything work as expected?
To get IPN working in the sandbox all you need to do is make sure it's enabled in your sandbox seller account profile. You can login to your sandbox account at http://sandbox.paypal.com just like you would a live account. Once you're in there go into the profile and then into IPN settings so you can enable it and set the URL accordingly.
I have this setup for Stripe, but I can't seem to figure it out for PayPal recurring gem. I am looking to allow users to switch their payment plan. If user is subscribed to the 1 month subscription (plan_id 1) they should be able to upgrade to year subscription (plan_id 12).
Any help would be appreciated!
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)
if #user.subscription.plan_id == 12
#customer.update_subscription(:plan => "1", :prorate => true)
current_user.subscription.update_attributes(:plan_id => 1)
flash.alert = 'Your subscription has been changed to monthly!'
redirect_to root_url
elsif #user.subscription.plan_id == 1
#customer.update_subscription(:plan => "12", :prorate => true)
current_user.subscription.update_attributes(:plan_id => 12)
current_user.save!
flash.alert = 'Your subscription has been changed to annually!'
redirect_to root_url
end
end
def cancelsubscription
#user = current_user
#customer = Stripe::Customer.retrieve(#user.subscription.stripe_customer_token)
#customer.cancel_subscription()
current_user.subscription.update_attributes(:cancelled => 1)
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
current_user.subscription.update_attributes(:cancelled => 1)
flash.alert = 'Billing has been suspended!'
redirect_to root_url
end
def reactivate
#user = current_user
#user.subscription.reactivate_paypal
current_user.subscription.update_attributes(:cancelled => nil)
flash.alert = 'Billing has been activated!'
redirect_to root_url
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
PayPal Payment model:
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
def reactivate
process :reactivate, :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
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
save
end
def reactivate_paypal
paypal.reactivate
save
end
end
Unfortunately it is not possible to update or change a subscription's term on PayPal. This subscription would have to be cancelled and a new one set up.
API Reference for UpdateRecurringPaymentsProfile
You would need to calculate the prorated difference, and charge them an INITAMT when setting up the new profile, then set the start date for new AMT that is to be collected after their term is up.
Edit: This is assuming you are using this gem. Since I am unable to find anywhere that it tries to do this automatically for you.
I am looking to setup payment suspension for the paypal recurring gem (followed rails cast). I'm not sure if setting up IPN is required as there's no mention of it in the docs for the 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:
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. 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.
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:
def suspend
process :suspend, :profile_id => #subscription.paypal_recurring_profile_token
end
So your model subscription.rb
def suspend_paypal
paypal.suspend
self.status = "canceled"
save
end
And the controller 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.
So that multiple people can be an administrator to a business page, we've created a model called administration where people can apply to be an admin of a business and thus the status of "0" is "pending" and "1" is accepted.
How can I prevent users from editing a page where their status for i is still "0" (pending).
class Administration < ActiveRecord::Base
attr_accessible :business_id, :user_id, :status
belongs_to :user
belongs_to :business
scope :pending, where('status = ?',0).order("updated_at desc")
def self.new_by_user_business( user, business)
admin = self.new
admin.business_id = business.id
admin.user_id = user.id
admin.status = 0
admin.save!
end
end
Here is the current "edit page"
<h1>Editing business</h1>
<%= render 'form1' %>
Here is the business controller.
class BusinessesController < ApplicationController
respond_to :html, :xml, :json
before_filter :authenticate_user!, except: [:index, :show]
def index
#businesses = Business.all
respond_with(#businesses)
end
def show
#business = Business.find(params[:id])
if request.path != business_path(#business)
redirect_to #business, status: :moved_permanently
end
end
def new
#business = Business.new
3.times { #business.assets.build }
respond_with(#business)
end
def edit
#business = get_business(params[:id])
#avatar = #business.assets.count
#avatar = 3-#avatar
#avatar.times {#business.assets.build}
end
def create
#business = Business.new(params[:business])
if #business.save
redirect_to #business, notice: 'Business was successfully created.'
else
3.times { #business.assets.build }
render 'new'
end
end
def update
#business = get_business(params[:id])
if #business.update_attributes(params[:business])
flash[:notice] = "Successfully updated Business."
end
#avatar = #business.assets.count
#avatar = 3-#avatar
#avatar.times {#business.assets.build}
respond_with(#business)
end
def destroy
#business = get_business(params[:id])
#business.destroy
respond_with(#business)
end
def my_business
#business = Business.all
end
def business_tickets
#user = current_user
#business = get_business(params[:id])
#tickets = #business.tickets
#business_inbox = TicketReply.where(:email => #business.callred_email)
end
def your_business
#user = current_user
#business = get_business(params[:id])
if #business.users.map(&:id).include? current_user.id
redirect_to my_business_businesses_path, notice: 'You are already an administator of this business.'
else
#admin = Administration.new_by_user_business( #user, #business)
BusinessMailer.delay(queue: "is_your_business", priority: 20, run_at: 5.minutes.from_now).is_your_business(#user,#business)
redirect_to #business, notice: 'Thank you for claiming your business, and we will be in touch with you shortly.'
end
end
def view_message
# #business = Business.find(params[:business_id])
#ticket = Ticket.find(params[:id])
#reply = #ticket.ticket_replies
end
private
def get_business(business_id)
#business = Business.find(business_id)
end
end
You could add a before_filter to check the status. You will have to change some of the logic but this is the idea
class BusinessesController < ApplicationController
before_filter :restrict_access, :only => [:edit, :update]
private
def restrict_access
#business = get_business(params[:id])
redirect to root_path, :notice => "Not Authorized" unless current_user.status == 1
end
end