Class: Paypal::Notification

Inherits:
Object
  • Object
show all
Defined in:
lib/paypal/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 (Sinatra)

def raw_post
  request.env["rack.input"].read
end

post "/paypal_ipn" do
  notify = Paypal::Notification.new(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

    nil
  end
end

Example (Rails)

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

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

Raises:



86
87
88
89
90
91
92
93
# File 'lib/paypal/notification.rb', line 86

def initialize(post)
  raise NoDataError if post.to_s.empty?

  @params  = {}
  @raw     = ""

  parse(post)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object



170
171
172
# File 'lib/paypal/notification.rb', line 170

def method_missing(method, *args)
  params[method.to_s] || super
end

Instance Attribute Details

#paramsObject

Returns the value of attribute params.



76
77
78
# File 'lib/paypal/notification.rb', line 76

def params
  @params
end

#rawObject

Returns the value of attribute raw.



77
78
79
# File 'lib/paypal/notification.rb', line 77

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

Raises:

  • (StandardError)


150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/paypal/notification.rb', line 150

def acknowledge
  payload = raw

  uri = URI.parse(Paypal::Config.ipn_url)
  request = Net::HTTP::Post.new(Paypal::Config.ipn_validation_path)
  request['Content-Length'] = "#{payload.size}"
  request['User-Agent']     = "paypal ruby -- http://github.com/JonathanTron/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

#canceled_reversal?Boolean

Transaction statuses

Returns:

  • (Boolean)


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

def canceled_reversal?
  status == :Canceled_Reversal
end

#completed?Boolean

Returns:

  • (Boolean)


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

def completed?
  status == :Completed
end

#denied?Boolean

Returns:

  • (Boolean)


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

def denied?
  status == :Denied
end

#expired?Boolean

Returns:

  • (Boolean)


108
109
110
# File 'lib/paypal/notification.rb', line 108

def expired?
  status == :Expired
end

#failed?Boolean

Returns:

  • (Boolean)


112
113
114
# File 'lib/paypal/notification.rb', line 112

def failed?
  status == :Failed
end

#pending?Boolean

Returns:

  • (Boolean)


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

def pending?
  status == :Pending
end

#processed?Boolean

Returns:

  • (Boolean)


120
121
122
# File 'lib/paypal/notification.rb', line 120

def processed?
  status == :Processed
end

#refunded?Boolean

Returns:

  • (Boolean)


124
125
126
# File 'lib/paypal/notification.rb', line 124

def refunded?
  status == :Refunded
end

#reversed?Boolean

Returns:

  • (Boolean)


128
129
130
# File 'lib/paypal/notification.rb', line 128

def reversed?
  status == :Reversed
end

#voided?Boolean

Returns:

  • (Boolean)


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

def voided?
  status == :Voided
end