class PaymentNotificationsController < ApplicationController # Paypal needs to be able to access this without passing the auth token protect_from_forgery :except => [:create] unloadable # https://cms.paypal.com/cms_content/en_US/files/developer/PP_OrderMgmt_IntegrationGuide.pdf SUCCESSFUL_PAYPAL_STATES = %w[instant echeck completed processed pending] # For cart info, see: # https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_Appx_websitestandard_htmlvariables def index if request_seems_to_be_valid() pm = PaymentNotification.create!(:params => params, :cart_id => params[:invoice], :status => params[:payment_status].downcase, :transaction_id => params[:txn_id]) render :text => pm.inspect else Rails.logger.warn("Something was wrong with this transaction! See PaymentNotification entry for cart_id #{params[:invoice]} and transaction_id #{params[:txn_id]}") render :text => 'test failed' end end def create if request_seems_to_be_valid() PaymentNotification.create!(:params => params, :cart_id => params[:invoice], :status => params[:payment_status].downcase, :transaction_id => params[:txn_id]) else Rails.logger.warn("Something was wrong with this transaction! See PaymentNotification entry for cart_id #{params[:invoice]} and transaction_id #{params[:txn_id]}") end render :nothing => true end protected # TODO -- younker [2011-03-27 15:12] # Move this into the payment notification model and do validations there (change request_seems_to_be_valid to pm.valid?) def request_seems_to_be_valid() # current_cart = find_cart() txn_cart = Cart.find_by_id(params[:invoice]) # unless current_cart.id.eql?(txn_cart.id) # Rails.logger.fatal("The user's current cart (#{current_cart.id}) does not match the cart for this transaction #{txn_cart.id}") # return false # end # unless current_cart.total.eql?(txn_cart.total) # Rails.logger.warn("The total for the current cart (#{current_cart.total}) does not equal the total for the transaction cart #{txn_cart.total}") # return false # end # unless txn_cart.total.to_f.eql?(params[:payment_gross].to_f) # Rails.logger.warn("The total for the current cart (#{txn_cart.total}) does not equal the payment_gross #{params[:payment_gross]}sent back from paypal") # return false # end unless ECO['paypal']['email'].eql?(params[:receiver_email]) Rails.logger.warn("The receiver email from paypal (#{params[:receiver_email]}) does not match our ECO.paypal_email (#{ECO['paypal']['email']})") return false end unless ECO['paypal']['secret'].eql?(params[:secret]) Rails.logger.warn("Our secret (#{ECO['paypal']['secret']}) does not match their secret (#{params[:secret]})") return false end if SUCCESSFUL_PAYPAL_STATES.detect{ |str| str.eql?(params[:payment_status].downcase) }.nil? Rails.logger.warn("The payment state reported back from paypal (#{params[:payment_status].downcase}) does not indicate success") return false end true end end