class PaypalRequest

Public Class Methods

new(params) click to toggle source
# File lib/sinatra/paypal/paypal-request.rb, line 4
def initialize(params)
        if params.is_a? String
                 params = JSON.parse(params, {:symbolize_names => true})
        end

        @fields = params
        @custom_data = nil
end

Public Instance Methods

accountable?()
Alias for: is_accountable?
amount() click to toggle source
# File lib/sinatra/paypal/paypal-request.rb, line 60
def amount
        Float(@fields[:mc_gross] || 0)
end
complete?() click to toggle source

Returns true if status is Completed

# File lib/sinatra/paypal/paypal-request.rb, line 136
def complete?
        self.status == 'Completed'
end
custom_data() click to toggle source

Whatever is put in the custom_data field on the payment form will be sent back in the payment notification. This is useful for tracking the username and other information that is required to process the payment.

The sinatra-paypal module expects this to be either a plain string containing the username or a json string that can be parse into a ruby object.

Note that this field can be modified by the user before submitting the form, so you should verify the contents of it before using it.

payment.custom_data # => { :username => 'dave' }
# File lib/sinatra/paypal/paypal-request.rb, line 102
def custom_data
        if @custom_data.nil? && !@fields[:custom].nil?
                if @fields[:custom].strip.start_with? '{'
                        # we could get a json object through, in which case it needs to be parsed...
                        @custom_data = JSON.parse(@fields[:custom], {:symbolize_names => true})
                else
                        # ...or would just have a string (which we assume is the target username) in that
                        # case we need to normalize it into an object
                        @custom_data = {:username => @fields[:custom]}
                end
        end

        return @custom_data
end
Also aliased as: data
custom_data?() click to toggle source
# File lib/sinatra/paypal/paypal-request.rb, line 117
def custom_data?
        !custom_data.nil?
end
data()
Alias for: custom_data
fields() click to toggle source

A Hash with the raw data for the paypal transaction, this contains many less useful fields not listed above

Here is a list of the fields for a Completed transaction. These fields differ slightly between the main transaction types.

:business: you@yourcompany.com
:charset: UTF-8
:cmd: _notify-validate
:custom: ! '{"thread_id":"3f3fc5","username":"customer_user_name"}'
:first_name: Bill
:handling_amount: '0.00'
:ipn_track_id: a5d596fffd057
:item_name: Describe your item
:item_number: I01
:last_name: Davies
:mc_currency: USD
:mc_fee: '0.37'
:mc_gross: '2.00'
:notify_version: '3.8'
:payer_email: customer@gmail.com
:payer_id: 9AFYVBV9TTT5L
:payer_status: verified
:payment_date: 18:01:26 Jul 29, 2015 PDT
:payment_fee: '0.37'
:payment_gross: '2.00'
:payment_status: Completed
:payment_type: instant
:protection_eligibility: Ineligible
:quantity: '1'
:receiver_email: you@yourcompany.com
:receiver_id: 4SUZXXXXFMC28
:residence_country: US
:shipping: '0.00'
:tax: '0.00'
:transaction_subject: ! '{"thread_id":"3f3fc5","username":"customer_user_name"}'
:txn_id: 6FH51036BB6776017
:txn_type: web_accept
:verify_sign: AmydMwaMHzmxRimnFMnKy3o9n-ElAWWRtiJ9TEixE0iGouC6EaMS0mWI

See developer.paypal.com/docs/classic/ipn/integration-guide/IPNandPDTVariables/ for a full description of the notification fields

# File lib/sinatra/paypal/paypal-request.rb, line 198
def fields
        @fields
end
id() click to toggle source

a unique id for the transaction (event if the paypal transaction_id is the same)

payment.id # => 661295c9cbf9d6b2f6428414504a8deed3020641
# File lib/sinatra/paypal/paypal-request.rb, line 18
def id
        self.transaction_hash
end
is_accountable?() click to toggle source

Returns true if the transaction results in a change of the merchant account balance. This doesn't apply to all IPN notifications - some (such as those with status Pending) are simply notifications that do not actually result in money chaning hands

# File lib/sinatra/paypal/paypal-request.rb, line 143
def is_accountable?
        # these are payment statues that actually result in the paypal balance changing, so we should set them as
        # accountable in the payment_log
        (self.complete? || self.status == 'Refunded' || self.status == 'Reversed' || self.status == 'Canceled_Reversal')
end
Also aliased as: accountable?
item_number() click to toggle source
# File lib/sinatra/paypal/paypal-request.rb, line 56
def item_number
        @fields[:item_number] || @fields[:item_number1]
end
item_valid?(item_list, offer_data = nil) click to toggle source
# File lib/sinatra/paypal/paypal-request.rb, line 37
def item_valid?(item_list, offer_data = nil)
        if item_list[self.item_number] != nil
                if item_list[self.item_number][:amount] == self.amount
                        # this is a regular purchase at the regular price
                        return true
                elsif self.uses_offer?(offer_data)
                        # the price comes from a special offer, its valid
                        return true
                end
        end

        return false
end
payment_fee() click to toggle source
# File lib/sinatra/paypal/paypal-request.rb, line 64
def payment_fee
        Float(@fields[:mc_fee] || 0)
end
profit() click to toggle source

The payment amount minus any fees, giving the net profit

payment.profit # => 1.63
# File lib/sinatra/paypal/paypal-request.rb, line 72
def profit
        # defined as the gross amount, minus transaction fees
        # could also subtract shipping and tax here as well, but we don't have to deal with
        # any of that yet
        self.amount - self.payment_fee
end
reason_code() click to toggle source

returns the reason code for noticiations that have one (usually Pending or Refunded transactions) if a reason code is not applicable, this will return nil

# File lib/sinatra/paypal/paypal-request.rb, line 151
def reason_code
        @fields[:reason_code] || @fields[:pending_reason]
end
status() click to toggle source

The payment status. The most common is Completed, but you might also see

- Refunded 
- Pending
- Reversed
- Canceled_Reversal
- Completed

   payment.status # => Pending
# File lib/sinatra/paypal/paypal-request.rb, line 131
def status
        @fields[:payment_status]
end
transaction_hash() click to toggle source

alias for id

# File lib/sinatra/paypal/paypal-request.rb, line 23
def transaction_hash
        # the same transaction id can come in mulitple times with different statuses
        # so we need to check both of them in order to see if the txn is unquie
        "#{self.transaction_id}-#{@fields[:payment_status]}".sha1
end
transaction_id() click to toggle source

the paypal transaction_id

payment.transaction_id # => 6FH51066BB6306017
# File lib/sinatra/paypal/paypal-request.rb, line 33
def transaction_id
        @fields[:txn_id]
end
username() click to toggle source

One of the most common peices of data to send through with the payment is the username that the payment applies to. This method will return the username from the custom_data field, if it contains one

payment.username # => reednj
# File lib/sinatra/paypal/paypal-request.rb, line 85
def username
        return nil if !custom_data?
        self.custom_data[:username]
end
uses_offer?(offer_data) click to toggle source
# File lib/sinatra/paypal/paypal-request.rb, line 51
def uses_offer?(offer_data)
        # to check if the offer is valid on this purchase we need to check the item code and the price matches
        return !offer_data.nil? && offer_data[:offer][:item_code] == self.item_number && offer_data[:offer][:amount]  == self.amount
end