Class: Paypal::Notification
- Inherits:
-
Object
- Object
- Paypal::Notification
- Defined in:
- lib/notification.rb
Overview
Parser and handler for incoming Instant payment notifications from paypal. The Example shows a typical handler in a rails application. Note that this is an example, please read the Paypal API documentation for all the details on creating a safe payment controller.
Example
class BackendController < ApplicationController
def paypal_ipn
notify = Paypal::Notification.new(request.raw_post)
order = Order.find(notify.item_id)
if notify.acknowledge
begin
if notify.complete? and order.total == notify.amount and notify.business == '[email protected]'
order.status = 'success'
shop.ship(order)
else
logger.error("Failed to verify Paypal's notification, please investigate")
end
rescue => e
order.status = 'failed'
raise
ensure
order.save
end
end
render :nothing
end
end
Constant Summary collapse
- @@ipn_url =
'https://www.sandbox.paypal.com/cgi-bin/webscr'- @@paypal_cert =
""" -----BEGIN CERTIFICATE----- MIIDoTCCAwqgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBmDELMAkGA1UEBhMCVVMx EzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcTCFNhbiBKb3NlMRUwEwYDVQQK EwxQYXlQYWwsIEluYy4xFjAUBgNVBAsUDXNhbmRib3hfY2VydHMxFDASBgNVBAMU C3NhbmRib3hfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMB4XDTA0 MDQxOTA3MDI1NFoXDTM1MDQxOTA3MDI1NFowgZgxCzAJBgNVBAYTAlVTMRMwEQYD VQQIEwpDYWxpZm9ybmlhMREwDwYDVQQHEwhTYW4gSm9zZTEVMBMGA1UEChMMUGF5 UGFsLCBJbmMuMRYwFAYDVQQLFA1zYW5kYm94X2NlcnRzMRQwEgYDVQQDFAtzYW5k Ym94X2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbTCBnzANBgkqhkiG 9w0BAQEFAAOBjQAwgYkCgYEAt5bjv/0N0qN3TiBL+1+L/EjpO1jeqPaJC1fDi+cC 6t6tTbQ55Od4poT8xjSzNH5S48iHdZh0C7EqfE1MPCc2coJqCSpDqxmOrO+9QXsj HWAnx6sb6foHHpsPm7WgQyUmDsNwTWT3OGR398ERmBzzcoL5owf3zBSpRP0NlTWo nPMCAwEAAaOB+DCB9TAdBgNVHQ4EFgQUgy4i2asqiC1rp5Ms81Dx8nfVqdIwgcUG A1UdIwSBvTCBuoAUgy4i2asqiC1rp5Ms81Dx8nfVqdKhgZ6kgZswgZgxCzAJBgNV BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQHEwhTYW4gSm9zZTEV MBMGA1UEChMMUGF5UGFsLCBJbmMuMRYwFAYDVQQLFA1zYW5kYm94X2NlcnRzMRQw EgYDVQQDFAtzYW5kYm94X2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNv bYIBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAFc288DYGX+GX2+W P/dwdXwficf+rlG+0V9GBPJZYKZJQ069W/ZRkUuWFQ+Opd2yhPpneGezmw3aU222 CGrdKhOrBJRRcpoO3FjHHmXWkqgbQqDWdG7S+/l8n1QfDPp+jpULOrcnGEUY41Im jZJTylbJQ1b5PBBjGiP0PpK48cdF -----END CERTIFICATE----- """
Instance Attribute Summary collapse
-
#params ⇒ Object
Returns the value of attribute params.
-
#raw ⇒ Object
Returns the value of attribute raw.
Instance Method Summary collapse
-
#acknowledge ⇒ Object
Acknowledge the transaction to paypal.
-
#amount ⇒ Object
This combines the gross and currency and returns a proper Money object.
-
#business ⇒ Object
This is the email address associated to the paypal account that recieved the payment.
-
#complete? ⇒ Boolean
Was the transaction complete?.
-
#currency ⇒ Object
What currency have we been dealing with.
-
#custom ⇒ Object
This is the custom field which you passed to paypal.
- #denied? ⇒ Boolean
-
#empty! ⇒ Object
reset the notification.
-
#exchange_rate ⇒ Object
The exchange rate used if there was a conversion.
- #failed? ⇒ Boolean
-
#fee ⇒ Object
the markup paypal charges for the transaction.
-
#gross ⇒ Object
the money amount we received in X.2 decimal.
- #gross_cents ⇒ Object
-
#initialize(post) ⇒ Notification
constructor
Creates a new paypal object.
-
#invoice ⇒ Object
This is the invocie which you passed to paypal.
-
#item_id ⇒ Object
This is the item number which we submitted to paypal.
-
#item_name ⇒ Object
This is the item_name which you passed to paypal.
-
#memo ⇒ Object
Memo entered by customer if any.
-
#payment_type ⇒ Object
Well, the payment type.
-
#pending_reason ⇒ Object
Reason for pending status, nil if status is not pending.
-
#reason_code ⇒ Object
Reason for reversed status, nil if status is not reversed.
-
#received_at ⇒ Object
When was this payment received by the client.
-
#status ⇒ Object
Whats the status of this transaction?.
-
#test? ⇒ Boolean
This is the invocie which you passed to paypal.
-
#transaction_id ⇒ Object
Id of this transaction (paypal number).
-
#type ⇒ Object
What type of transaction are we dealing with? “cart” “send_money” “web_accept” are possible here.
Constructor Details
#initialize(post) ⇒ Notification
Creates a new paypal object. Pass the raw html you got from paypal in. In a rails application this looks something like this
def paypal_ipn
paypal = Paypal::Notification.new(request.raw_post)
...
end
93 94 95 96 |
# File 'lib/notification.rb', line 93 def initialize(post) empty! parse(post) end |
Instance Attribute Details
#params ⇒ Object
Returns the value of attribute params.
41 42 43 |
# File 'lib/notification.rb', line 41 def params @params end |
#raw ⇒ Object
Returns the value of attribute raw.
42 43 44 |
# File 'lib/notification.rb', line 42 def raw @raw end |
Instance Method Details
#acknowledge ⇒ Object
Acknowledge the transaction to paypal. This method has to be called after a new ipn arrives. Paypal will verify that all the information we received are correct and will return a ok or a fail.
Example:
def paypal_ipn
notify = PaypalNotification.new(request.raw_post)
if notify.acknowledge
... process order ... if notify.complete?
else
... log possible hacking attempt ...
end
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/notification.rb', line 237 def acknowledge payload = raw uri = URI.parse(self.class.ipn_url) request_path = "#{uri.path}?cmd=_notify-validate" request = Net::HTTP::Post.new(request_path) request['Content-Length'] = "#{payload.size}" request['User-Agent'] = "paypal-ruby -- http://rubyforge.org/projects/paypal/" http = Net::HTTP.new(uri.host, uri.port) http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @ssl_strict http.use_ssl = true request = http.request(request, payload) raise StandardError.new("Faulty paypal result: #{request.body}") unless ["VERIFIED", "INVALID"].include?(request.body) request.body == "VERIFIED" end |
#amount ⇒ Object
This combines the gross and currency and returns a proper Money object. this requires the money library located at dist.leetsoft.com/api/money
212 213 214 215 |
# File 'lib/notification.rb', line 212 def amount return Money.new(gross_cents, currency) rescue ArgumentError return Money.new(gross_cents) # maybe you have an own money object which doesn't take a currency? end |
#business ⇒ Object
This is the email address associated to the paypal account that recieved the payment.
157 158 159 |
# File 'lib/notification.rb', line 157 def business params['business'] end |
#complete? ⇒ Boolean
Was the transaction complete?
99 100 101 |
# File 'lib/notification.rb', line 99 def complete? status == "Completed" end |
#currency ⇒ Object
What currency have we been dealing with
146 147 148 |
# File 'lib/notification.rb', line 146 def currency params['mc_currency'] end |
#custom ⇒ Object
This is the custom field which you passed to paypal
177 178 179 |
# File 'lib/notification.rb', line 177 def custom params['custom'] end |
#denied? ⇒ Boolean
107 108 109 |
# File 'lib/notification.rb', line 107 def denied? status == "Denied" end |
#empty! ⇒ Object
reset the notification.
218 219 220 221 |
# File 'lib/notification.rb', line 218 def empty! @params = Hash.new @raw = "" end |
#exchange_rate ⇒ Object
The exchange rate used if there was a conversion.
202 203 204 |
# File 'lib/notification.rb', line 202 def exchange_rate params['exchange_rate'] end |
#failed? ⇒ Boolean
103 104 105 |
# File 'lib/notification.rb', line 103 def failed? status == "Failed" end |
#fee ⇒ Object
the markup paypal charges for the transaction
141 142 143 |
# File 'lib/notification.rb', line 141 def fee params['mc_fee'] end |
#gross ⇒ Object
the money amount we received in X.2 decimal.
136 137 138 |
# File 'lib/notification.rb', line 136 def gross params['mc_gross'] end |
#gross_cents ⇒ Object
206 207 208 |
# File 'lib/notification.rb', line 206 def gross_cents (gross.to_f * 100.0).round end |
#invoice ⇒ Object
This is the invocie which you passed to paypal
167 168 169 |
# File 'lib/notification.rb', line 167 def invoice params['invoice'] end |
#item_id ⇒ Object
This is the item number which we submitted to paypal
151 152 153 |
# File 'lib/notification.rb', line 151 def item_id params['item_number'] end |
#item_name ⇒ Object
This is the item_name which you passed to paypal
162 163 164 |
# File 'lib/notification.rb', line 162 def item_name params['item_name'] end |
#memo ⇒ Object
Memo entered by customer if any
192 193 194 |
# File 'lib/notification.rb', line 192 def memo params['memo'] end |
#payment_type ⇒ Object
Well, the payment type.
197 198 199 |
# File 'lib/notification.rb', line 197 def payment_type params['payment_type'] end |
#pending_reason ⇒ Object
Reason for pending status, nil if status is not pending.
182 183 184 |
# File 'lib/notification.rb', line 182 def pending_reason params['pending_reason'] end |
#reason_code ⇒ Object
Reason for reversed status, nil if status is not reversed.
187 188 189 |
# File 'lib/notification.rb', line 187 def reason_code params['reason_code'] end |
#received_at ⇒ Object
When was this payment received by the client. sometimes it can happen that we get the notification much later. One possible scenario is that our web application was down. In this case paypal tries several times an hour to inform us about the notification
115 116 117 |
# File 'lib/notification.rb', line 115 def received_at Time.parse params['payment_date'] end |
#status ⇒ Object
Whats the status of this transaction?
120 121 122 |
# File 'lib/notification.rb', line 120 def status params['payment_status'] end |
#test? ⇒ Boolean
This is the invocie which you passed to paypal
172 173 174 |
# File 'lib/notification.rb', line 172 def test? params['test_ipn'] == '1' end |
#transaction_id ⇒ Object
Id of this transaction (paypal number)
125 126 127 |
# File 'lib/notification.rb', line 125 def transaction_id params['txn_id'] end |
#type ⇒ Object
What type of transaction are we dealing with?
"cart" "send_money" "web_accept" are possible here.
131 132 133 |
# File 'lib/notification.rb', line 131 def type params['txn_type'] end |