class OffsitePayments::Integrations::Paypal::Notification
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 include OffsitePayments::Integrations def paypal_ipn notify = Paypal::Notification.new(request.raw_post) if notify.masspay? masspay_items = notify.items end order = Order.find(notify.item_id) if notify.acknowledge begin if notify.complete? and order.total == notify.amount 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
Public Class Methods
OffsitePayments::Notification::new
# File lib/offsite_payments/integrations/paypal.rb, line 185 def initialize(post, options = {}) super extend MassPayNotification if masspay? end
Public Instance Methods
# File lib/offsite_payments/integrations/paypal.rb, line 276 def account params['business'] || params['receiver_email'] end
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
# File lib/offsite_payments/integrations/paypal.rb, line 294 def acknowledge(authcode = nil) payload = raw response = ssl_post(Paypal.service_url + '?cmd=_notify-validate', payload, 'Content-Length' => "#{payload.size}", 'User-Agent' => "Active Merchant -- http://activemerchant.org" ) raise StandardError.new("Faulty paypal result: #{response}") unless ["VERIFIED", "INVALID"].include?(response) response == "VERIFIED" end
Was the transaction complete?
# File lib/offsite_payments/integrations/paypal.rb, line 191 def complete? status == "Completed" end
What currency have we been dealing with
# File lib/offsite_payments/integrations/paypal.rb, line 255 def currency params['mc_currency'] end
the markup paypal charges for the transaction
# File lib/offsite_payments/integrations/paypal.rb, line 250 def fee params['mc_fee'] end
the money amount we received in X.2 decimal.
# File lib/offsite_payments/integrations/paypal.rb, line 245 def gross params['mc_gross'] end
This is the invoice which you passed to paypal
# File lib/offsite_payments/integrations/paypal.rb, line 267 def invoice params['invoice'] end
This is the item number which we submitted to paypal The custom field is also mapped to item_id
because PayPal doesn’t return item_number in dispute notifications
# File lib/offsite_payments/integrations/paypal.rb, line 262 def item_id params['item_number'] || params['custom'] end
Is it a masspay notification?
# File lib/offsite_payments/integrations/paypal.rb, line 196 def masspay? type == "masspay" end
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
# File lib/offsite_payments/integrations/paypal.rb, line 204 def received_at parsed_time_fields = DateTime._strptime(params['payment_date'], "%H:%M:%S %b %d, %Y %Z") Time.gm( parsed_time_fields[:year], parsed_time_fields[:mon], parsed_time_fields[:mday], parsed_time_fields[:hour], parsed_time_fields[:min], parsed_time_fields[:sec] ) - Time.zone_offset(parsed_time_fields[:zone]) end
Status of transaction. List of possible values:
Canceled-Reversal
Completed
Denied
Expired
Failed
In-Progress
Partially-Refunded
Pending
Processed
Refunded
Reversed
Voided
# File lib/offsite_payments/integrations/paypal.rb, line 229 def status params['payment_status'] end
Was this a test transaction?
# File lib/offsite_payments/integrations/paypal.rb, line 272 def test? params['test_ipn'] == '1' end
Id of this transaction (paypal number)
# File lib/offsite_payments/integrations/paypal.rb, line 234 def transaction_id params['txn_id'] end
What type of transaction are we dealing with?
"cart" "send_money" "web_accept" are possible here.
# File lib/offsite_payments/integrations/paypal.rb, line 240 def type params['txn_type'] end