Merge branch 'ipn' of github.com:zyphlar/Open-Source-Access-Control-Web-Interface into ipn

This commit is contained in:
Will Bradley 2013-08-24 03:44:00 -07:00
commit 805148ee40
6 changed files with 69 additions and 15 deletions

View File

@ -15,11 +15,21 @@ class IpnsController < ApplicationController
end end
def create def create
#TODO: ensure the request is actually from paypal
@ipn = Ipn.new_from_dynamic_params(params) @ipn = Ipn.new_from_dynamic_params(params)
@ipn.data = params.to_json @ipn.data = params.to_json
@ipn.save @ipn.save
render :nothing => true render :nothing => true
unless @ipn.validate!
Rails.logger.error "Unable to validate IPN: #{@ipn.inspect}"
end
end
def validate
if @ipn.validate!
redirect_to ipns_url, :notice => 'Valid!'
else
redirect_to ipns_url, :notice => 'INVALID'
end
end end
def link def link

View File

@ -1,3 +1,4 @@
require 'net/http'
class Ipn < ActiveRecord::Base class Ipn < ActiveRecord::Base
attr_accessible :data attr_accessible :data
belongs_to :payment belongs_to :payment
@ -16,6 +17,32 @@ class Ipn < ActiveRecord::Base
return ipn return ipn
end end
# 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
def link_payment def link_payment
create_payment create_payment
end end
@ -26,25 +53,34 @@ class Ipn < ActiveRecord::Base
user = User.find_by_email(self.payer_email) user = User.find_by_email(self.payer_email)
user = User.find_by_payee(self.payer_email) if user.nil? && self.payer_email.present? user = User.find_by_payee(self.payer_email) if user.nil? && self.payer_email.present?
# Only create payments if the amount matches a member level # Only create payments if the IPN matches a member
if user.present? if user.present?
if User.member_levels[self.payment_gross.to_i].present? # And is a payment (not a cancellation, etc)
payment = Payment.new payment_types = ["subscr_payment","send_money"]
payment.date = self.payment_date if payment_types.include?(self.txn_type)
payment.user_id = user.id # And a member level
payment.amount = self.payment_gross if User.member_levels[self.payment_gross.to_i].present?
if payment.save payment = Payment.new
self.payment_id = payment.id payment.date = Date.strptime(self.payment_date, "%H:%M:%S %b %e, %Y %Z")
self.save! 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
else else
return [false, "Unable to link payment. Payment error: #{payment.errors.full_messages.first}"] return [false, "Unable to link payment. Couldn't find membership level '#{self.payment_gross.to_i}'."]
end end
else else
return [false, "Unable to link payment. Couldn't find membership level '#{self.payment_gross.to_i}'."] return [false, "Unable to link payment. Transaction is a '#{self.txn_type}' instead of '#{payment_types.inspect}'."]
end end
else else
return [false, "Unable to link payment. Couldn't find user/payee '#{self.payer_email}'."] return [false, "Unable to link payment. Couldn't find user/payee '#{self.payer_email}'."]
end end
return [true]
end end
end end

View File

@ -11,7 +11,13 @@
<td><%= ipn.payment_date %></td> <td><%= ipn.payment_date %></td>
<td><%= ipn.first_name %> <%= ipn.last_name %></td> <td><%= ipn.first_name %> <%= ipn.last_name %></td>
<td><%= ipn.item_name %></td> <td><%= ipn.item_name %></td>
<td><%= ipn.payment_gross %></td> <td>
<% if ipn.payment_gross.blank? %>
<%= ipn.txn_type %>
<% else %>
<%= ipn.payment_gross %>
<% end %>
</td>
<td> <td>
<% if ipn.payment.present? %> <% if ipn.payment.present? %>
<%= link_to "Linked Payment", ipn.payment %> <%= link_to "Linked Payment", ipn.payment %>
@ -20,6 +26,7 @@
<% end %> <% end %>
</td> </td>
<td><%= link_to "Details", ipn %></td> <td><%= link_to "Details", ipn %></td>
<td><%= link_to "Validate", validate_ipn_path(ipn) %></td>
</tr> </tr>
<% end %> <% end %>
</table> </table>

View File

@ -35,7 +35,7 @@
</div> </div>
<div class="field"> <div class="field">
<%= label_tag :payment_date %> <%= label_tag :payment_date %>
<%= text_field_tag :payment_date, Date.today.to_s %> <%= text_field_tag :payment_date, "20:46:54 Jun 20, 2013 PDT" %>
</div> </div>
<div class="field"> <div class="field">
<%= label_tag :txn_type %> <%= label_tag :txn_type %>

View File

@ -1,6 +1,6 @@
<p> <p>
<b>User:</b> <b>User:</b>
<%= @payment.user.name_with_payee_and_member_level unless @payment.user.blank? %> <%= link_to @payment.user.name_with_payee_and_member_level, @payment.user unless @payment.user.blank? %>
</p> </p>
<p> <p>

View File

@ -1,6 +1,7 @@
Dooraccess::Application.routes.draw do Dooraccess::Application.routes.draw do
resources :ipns resources :ipns
match 'ipns/:id/link' => 'ipns#link', :as => :link_ipn match 'ipns/:id/link' => 'ipns#link', :as => :link_ipn
match 'ipns/:id/validate' => 'ipns#validate', :as => :validate_ipn
resources :payments resources :payments