Class: ActiveMerchant::Billing::Integrations::Paypal::Notification

Inherits:
Notification
  • Object
show all
Includes:
PostsData
Defined in:
lib/active_merchant/billing/integrations/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

class BackendController < ApplicationController
include ActiveMerchant::Billing::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

Instance Attribute Summary

Attributes inherited from Notification

#params, #raw

Instance Method Summary collapse

Methods inherited from Notification

#amount, #empty!, #gross_cents, #valid_sender?

Constructor Details

#initialize(post, options = {}) ⇒ Notification

Returns a new instance of Notification.



51
52
53
54
# File 'lib/active_merchant/billing/integrations/paypal/notification.rb', line 51

def initialize(post, options = {})
  super
  extend MassPayNotification if masspay?
end

Instance Method Details

#accountObject



135
136
137
# File 'lib/active_merchant/billing/integrations/paypal/notification.rb', line 135

def 
  params['business'] || params['receiver_email']
end

#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)


153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/active_merchant/billing/integrations/paypal/notification.rb', line 153

def acknowledge
  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

#complete?Boolean

Was the transaction complete?

Returns:

  • (Boolean)


57
58
59
# File 'lib/active_merchant/billing/integrations/paypal/notification.rb', line 57

def complete?
  status == "Completed"
end

#currencyObject

What currency have we been dealing with



114
115
116
# File 'lib/active_merchant/billing/integrations/paypal/notification.rb', line 114

def currency
  params['mc_currency']
end

#feeObject

the markup paypal charges for the transaction



109
110
111
# File 'lib/active_merchant/billing/integrations/paypal/notification.rb', line 109

def fee
  params['mc_fee']
end

#grossObject

the money amount we received in X.2 decimal.



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

def gross
  params['mc_gross']
end

#invoiceObject

This is the invoice which you passed to paypal



126
127
128
# File 'lib/active_merchant/billing/integrations/paypal/notification.rb', line 126

def invoice
  params['invoice']
end

#item_idObject

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



121
122
123
# File 'lib/active_merchant/billing/integrations/paypal/notification.rb', line 121

def item_id
  params['item_number'] || params['custom']
end

#masspay?Boolean

Is it a masspay notification?

Returns:

  • (Boolean)


62
63
64
# File 'lib/active_merchant/billing/integrations/paypal/notification.rb', line 62

def masspay?
  type == "masspay"
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



70
71
72
73
# File 'lib/active_merchant/billing/integrations/paypal/notification.rb', line 70

def received_at
  parsed_time_fields = DateTime._strptime(params['payment_date'], "%H:%M:%S %b %d, %Y %z")
  Time.mktime(*parsed_time_fields.values_at(:year, :mon, :mday, :hour, :min, :sec, :zone))
end

#statusObject

Status of transaction. List of possible values:

Canceled-Reversal
Completed
Denied
Expired
Failed
In-Progress
Partially-Refunded
Pending
Processed
Refunded
Reversed
Voided


88
89
90
# File 'lib/active_merchant/billing/integrations/paypal/notification.rb', line 88

def status
  params['payment_status']
end

#test?Boolean

Was this a test transaction?

Returns:

  • (Boolean)


131
132
133
# File 'lib/active_merchant/billing/integrations/paypal/notification.rb', line 131

def test?
  params['test_ipn'] == '1'
end

#transaction_idObject

Id of this transaction (paypal number)



93
94
95
# File 'lib/active_merchant/billing/integrations/paypal/notification.rb', line 93

def transaction_id
  params['txn_id']
end

#typeObject

What type of transaction are we dealing with? "cart" "send_money" "web_accept" are possible here.



99
100
101
# File 'lib/active_merchant/billing/integrations/paypal/notification.rb', line 99

def type
  params['txn_type']
end