Skip to content

Instantly share code, notes, and snippets.

@McRipper
Created December 3, 2012 21:01
Show Gist options
  • Save McRipper/4197985 to your computer and use it in GitHub Desktop.
Save McRipper/4197985 to your computer and use it in GitHub Desktop.
Rails PayPal recurring monthly payment
class PaymentsController < ActionController::Base
skip_before_filter :verify_authenticity_token, :only => :notification
before_filter :load_subscription
def checkout
redirect_to @subscription.paypal.checkout_url(
return_url: "http://www.example.com" + "/paypal/review/#{@subscription.id}",
cancel_url: "http://www.example.com" + "/paypal/cancel/#{@subscription.id}"
)
end
def review
@subscription.update_attributes(paypal_token: params["token"], paypal_payer_id: params["PayerID"])
end
def complete
@subscription.paypal.make_recurring
end
def cancel
end
# Manage the paypal IPN
#
def notification
notify = PaypalNotification.new(request.raw_post)
if notify.acknowledge
begin
if notify.complete? && @subscription.amount == notify.amount
# Mark as paid
else
# Mark as error and investigate
end
rescue => e
# Mark as error and investigate
raise
end
end
render :nothing => true
end
private
def load_subscription
@subscription = Subscription.find(params[:id])
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
payment = process(:request_payment)
if payment.approved? && payment.completed?
# Set the subscription as paid
end
recurring = process(:create_recurring_profile, {period: :monthly, frequency: 1, start_at: Time.zone.now + 30.days})
@subscription.update_attribute(:paypal_profile_id, recurring.profile_id)
end
def cancel_recurring
ppr = PayPal::Recurring.new(:profile_id => @subscription.paypal_profile_id)
ppr.cancel
end
private
def process(action, options = {})
options = options.reverse_merge(
token: @subscription.paypal_token,
payer_id: @subscription.paypal_payer_id,
description: @subscription.name,
amount: @subscription.amount,
currency: "USD",
ipn_url: "http://www.example.com" + "/paypal/notifications/#{@subscription.id}"
)
response = PayPal::Recurring.new(options).send(action)
raise response.errors.inspect if response.errors.present?
response
end
end
class Subscription < ActiveRecord::Base
# Paypal specific fields
#
# t.string "paypal_token"
# t.string "paypal_payer_id"
# t.string "paypal_profile_id"
def paypal
PaypalPayment.new(self)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment