2013-08-24 10:40:34 +00:00
|
|
|
require 'net/http'
|
2013-08-24 09:18:37 +00:00
|
|
|
class Ipn < ActiveRecord::Base
|
|
|
|
attr_accessible :data
|
|
|
|
belongs_to :payment
|
|
|
|
|
|
|
|
after_create :create_payment
|
|
|
|
|
|
|
|
def self.new_from_dynamic_params(params)
|
|
|
|
ipn = Ipn.new()
|
|
|
|
|
|
|
|
ipn.attributes.each do |c|
|
|
|
|
unless params[c.first.to_sym].nil?
|
|
|
|
ipn[c.first.to_sym] = params[c.first.to_sym]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return ipn
|
|
|
|
end
|
|
|
|
|
2013-08-24 10:40:34 +00:00
|
|
|
# Post back to Paypal to make sure it's valid
|
|
|
|
def validate!
|
|
|
|
uri = URI.parse('https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate')
|
|
|
|
|
|
|
|
http = Net::HTTP.new(uri.host, uri.port)
|
|
|
|
http.open_timeout = 60
|
|
|
|
http.read_timeout = 60
|
|
|
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
|
|
http.use_ssl = true
|
|
|
|
response = http.post(uri.request_uri, self.data,
|
|
|
|
'Content-Length' => "#{self.data.size}",
|
|
|
|
'User-Agent' => "Ruby on Rails"
|
|
|
|
).body
|
|
|
|
|
|
|
|
unless ["VERIFIED", "INVALID"].include?(response)
|
|
|
|
Rails.logger.error "Faulty paypal result: #{response}"
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
unless response == "VERIFIED"
|
|
|
|
Rails.logger.error "Invalid IPN: #{response}"
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2013-08-24 09:18:37 +00:00
|
|
|
def link_payment
|
|
|
|
create_payment
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
def create_payment
|
|
|
|
# find user by email, then by payee
|
|
|
|
user = User.find_by_email(self.payer_email)
|
|
|
|
user = User.find_by_payee(self.payer_email) if user.nil? && self.payer_email.present?
|
|
|
|
|
2013-08-24 10:40:34 +00:00
|
|
|
# Only create payments if the IPN matches a member
|
2013-08-24 09:18:37 +00:00
|
|
|
if user.present?
|
2013-08-24 10:40:34 +00:00
|
|
|
# And is a payment (not a cancellation, etc)
|
|
|
|
payment_types = ["subscr_payment","send_money"]
|
|
|
|
if payment_types.include?(self.txn_type)
|
|
|
|
# And a member level
|
|
|
|
if User.member_levels[self.payment_gross.to_i].present?
|
|
|
|
payment = Payment.new
|
|
|
|
payment.date = Date.strptime(self.payment_date, "%H:%M:%S %b %e, %Y %Z")
|
|
|
|
payment.user_id = user.id
|
|
|
|
payment.amount = self.payment_gross
|
|
|
|
if payment.save
|
|
|
|
self.payment_id = payment.id
|
|
|
|
self.save!
|
|
|
|
else
|
|
|
|
return [false, "Unable to link payment. Payment error: #{payment.errors.full_messages.first}"]
|
|
|
|
end
|
2013-08-24 09:18:37 +00:00
|
|
|
else
|
2013-08-24 10:40:34 +00:00
|
|
|
return [false, "Unable to link payment. Couldn't find membership level '#{self.payment_gross.to_i}'."]
|
2013-08-24 09:18:37 +00:00
|
|
|
end
|
|
|
|
else
|
2013-08-24 10:40:34 +00:00
|
|
|
return [false, "Unable to link payment. Transaction is a '#{self.txn_type}' instead of '#{payment_types.inspect}'."]
|
2013-08-24 09:18:37 +00:00
|
|
|
end
|
|
|
|
else
|
|
|
|
return [false, "Unable to link payment. Couldn't find user/payee '#{self.payer_email}'."]
|
|
|
|
end
|
2013-08-24 10:40:34 +00:00
|
|
|
|
|
|
|
return [true]
|
2013-08-24 09:18:37 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|