Class: Paypal::Notification

Inherits:
Object
  • Object
show all
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
          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 =
'http://www.sandbox.paypal.com/cgi-bin/webscr'

Instance Attribute Summary collapse

Instance Method Summary collapse

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


60
61
62
63
# File 'lib/notification.rb', line 60

def initialize(post)
  empty!
  parse(post)
end

Instance Attribute Details

#paramsObject

Returns the value of attribute params.



39
40
41
# File 'lib/notification.rb', line 39

def params
  @params
end

#rawObject

Returns the value of attribute raw.



40
41
42
# File 'lib/notification.rb', line 40

def raw
  @raw
end

Instance Method Details

#acknowledgeObject

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


151
152
153
154
155
156
157
158
# File 'lib/notification.rb', line 151

def acknowledge
  uri = URI.parse(self.class.ipn_url)
  status = nil
  Net::HTTP.start(uri.host, uri.port) do |request|
    status = request.post(uri.path, raw + "&cmd=_notify-validate").body
  end
  status == "VERIFIED"
end

#amountObject

This combines the gross and currency and returns a proper Money object. this requires the money library located at dist.leetsoft.com/api/money



126
127
128
129
# File 'lib/notification.rb', line 126

def amount
  amount = gross.sub(/[^\d]/, '').to_i
  Money.new(amount, currency)
end

#complete?Boolean

Was the transaction complete?

Returns:

  • (Boolean)


66
67
68
# File 'lib/notification.rb', line 66

def complete?
  status == "Completed"
end

#currencyObject

What currency have we been dealing with



105
106
107
# File 'lib/notification.rb', line 105

def currency
  params['mc_currency']
end

#empty!Object

reset the notification.



132
133
134
135
# File 'lib/notification.rb', line 132

def empty!
  @params  = Hash.new
  @raw     = ""      
end

#feeObject

the markup paypal charges for the transaction



100
101
102
# File 'lib/notification.rb', line 100

def fee
  params['mc_fee']
end

#grossObject

the money amount we received in X.2 decimal.



95
96
97
# File 'lib/notification.rb', line 95

def gross
  params['mc_gross']
end

#invoiceObject

This is the custom field which you passed to paypal



115
116
117
# File 'lib/notification.rb', line 115

def invoice
  params['invoice']
end

#item_idObject

This is the item number which we submitted to paypal



110
111
112
# File 'lib/notification.rb', line 110

def item_id
  params['item_number']
end

#received_atObject

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



74
75
76
# File 'lib/notification.rb', line 74

def received_at
  Time.parse params['payment_date']
end

#statusObject

Whats the status of this transaction?



79
80
81
# File 'lib/notification.rb', line 79

def status
  params['payment_status']
end

#transaction_idObject

Id of this transaction (paypal number)



84
85
86
# File 'lib/notification.rb', line 84

def transaction_id
  params['txn_id']
end

#typeObject

What type of transaction are we dealing with?

"cart" "send_money" "web_accept" are possible here.


90
91
92
# File 'lib/notification.rb', line 90

def type
  params['txn_type']
end