Module: Paypal::Helpers

Defined in:
lib/helper.rb

Overview

This is a collection of helpers which aid in the creation of paypal buttons

Example:

<%= form_tag Paypal::Notification.ipn_url %>

  <%= paypal_setup "Item 500", Money.us_dollar(50000), "[email protected]" %>  
  Please press here to pay $500US using paypal. <%= submit_tag %>

<% end_form_tag %>

For this to work you have to include these methods as helpers in your rails application. One way is to add “include Paypal::Helpers” in your application_helper.rb See Paypal::Notification for information on how to catch payment events.

Instance Method Summary collapse

Instance Method Details

#paypal_address(options = {}) ⇒ Object

Pass an address to paypal so that all singup forms can be prefilled

  • email – Customer’s email address

  • first_name – Customer’s first name. Must be alpha-numeric, with a 32 character limit

  • last_name – Customer’s last name. Must be alpha-numeric, with a 64 character limit

  • address1 – First line of customer’s address. Must be alpha-numeric, with a 100 character limit

  • address2 – Second line of customer’s address. Must be alpha-numeric, with a 100 character limit

  • city – City of customer’s address. Must be alpha-numeric, with a 100 character limit

  • state – State of customer’s address. Must be official 2 letter abbreviation

  • zip – Zip code of customer’s address

  • night_phone_a – Area code of customer’s night telephone number

  • night_phone_b – First three digits of customer’s night telephone number

  • day_phone_a – Area code of customer’s daytime telephone number

  • day_phone_b – First three digits of customer’s daytime telephon



164
165
166
167
168
# File 'lib/helper.rb', line 164

def paypal_address(options = {})
  options.collect do |key, value|
    tag(:input, :type => 'hidden', :name => key, :value => value)
  end.join("\n")
end

#paypal_form_tag(url = Paypal::Notification.ipn_url, options = {}) ⇒ Object

Convenience helper. Can replace <%= form_tag Paypal::Notification.ipn_url %> takes optional url parameter, default is Paypal::Notification.ipn_url



20
21
22
# File 'lib/helper.rb', line 20

def paypal_form_tag(url = Paypal::Notification.ipn_url, options = {})
  form_tag(url, options)
end

#paypal_setup(item_number, amount, business, options = {}) ⇒ Object

This helper creates the hidden form data which is needed for a paypal purchase.

  • item_number – The first parameter is the item number. This is for your personal organization and can be arbitrary. Paypal will sent the item number back with the IPN so its a great place to store a user ID or a order ID or something like this.

  • amount – should be a parameter of type Money ( see leetsoft.com/api/money ) but can also be a string of type “50.00” for 50$. If you use the string syntax make sure you set the current currency as part of the options hash. The default is USD

  • business – This is your paypal account name ( a email ). This needs to be a valid paypal business account.

The last parameter is a options hash. You can set or override any Paypal-recognized parameter, including:

  • :cmd – default is ‘_xclick’.

  • :quantity – default is ‘1’.

  • :no_note – default is ‘1’.

  • :item_name – default is ‘Store purchase’. This is the name of the purchase which will be displayed on the paypal page.

  • :no_shipping – default is ‘1’. By default we tell paypal that no shipping is required. Usually the shipping address should be collected in our application, not by paypal.

  • :currency – default is ‘USD’. If you provide a Money object, that will automatically override the value.

  • :charset – default is ‘utf-8’.

  • :notify_url – If provided paypal will send its IPN notification once a purchase is made, canceled or any other status changes occur.

  • :return – If provided paypal will redirect a user back to this url after a successful purchase. Useful for a kind of thankyou page.

  • :cancel_return – If provided paypal will redirect a user back to this url when the user cancels the purchase.

  • :tax – the tax for the store purchase. Same format as the amount parameter but optional

  • :invoice – Unique invoice number. User will never see this. optional

  • :custom – Custom field. User will never see this. optional

Generating encrypted form data

The helper also supports the generation of encrypted button data. Please see the README for more information on the setup and prerequisite steps for using encrypted forms.

The following options must all be provided (as strings) to encrypt the data:

  • :business_key – The private key you have generated

  • :business_cert – The public certificate you have also uploaded to Paypal

  • :business_certid – The certificate ID that Paypal has assigned to your certificate.

Examples:

<%= paypal_setup @order.id, Money.us_dollar(50000), "[email protected]" %>  
<%= paypal_setup @order.id, '50.00', "[email protected]", :currency => 'USD' %>  
<%= paypal_setup @order.id, '50.00', "[email protected]", :currency => 'USD', :notify_url => url_for(:only_path => false, :action => 'paypal_ipn') %>  
<%= paypal_setup @order.id, Money.ca_dollar(50000), "[email protected]", :item_name => 'Snowdevil shop purchase', :return_url => paypal_return_url, :cancel_url => paypal_cancel_url, :notify_url => paypal_ipn_url  %>  
<%= paypal_setup @order.id, Money.ca_dollar(50000), "[email protected]", :item_name => 'Snowdevil shop purchase', :return_url => paypal_return_url, :cancel_url => paypal_cancel_url, :business_key => @business_key, :business_cert => @business_cert, :business_certid => @business_certid  %>

Raises:

  • (ArgumentError)


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/helper.rb', line 77

def paypal_setup(item_number, amount, business, options = {})
  
  misses = (options.keys - valid_setup_options)
  raise ArgumentError, "Unknown option #{misses.inspect}" if not misses.empty?

  params = {
    :cmd => "_ext-enter",
    :redirect_cmd => "_xclick",
    :quantity => 1,
    :business => business,
    :item_number => item_number,
    :item_name => 'Store purchase',
    :no_shipping => '1',
    :no_note => '1',
    :charset => 'utf-8'
  }.merge(options)
        
  params[:currency_code] = amount.currency if amount.respond_to?(:currency)
  params[:currency_code] = params.delete(:currency) if params[:currency]
  params[:currency_code] ||= 'USD'

  # We accept both strings and money objects as amount    
  amount = amount.cents.to_f / 100.0 if amount.respond_to?(:cents)
  params[:amount] = sprintf("%.2f", amount)
  
  # same for tax
  tax = params[:tax]
  if tax
    tax = tax.cents.to_f / 100.0 if tax.respond_to?(:cents)
    params[:tax] = sprintf("%.2f", tax)
  end

  # look for encryption parameters, save them outsite the parameter hash.
  business_key = params.delete(:business_key)
  business_cert = params.delete(:business_cert)
  business_certid = params.delete(:business_certid)

  # Build the form 
  returning button = [] do
    # Only attempt an encrypted form if we have all the required fields.
    if business_key and business_cert and business_certid
      require 'openssl'

      # Convert the key and certificates into OpenSSL-friendly objects.
      paypal_cert = OpenSSL::X509::Certificate.new(Paypal::Notification.paypal_cert)
      business_key = OpenSSL::PKey::RSA.new(business_key)
      business_cert = OpenSSL::X509::Certificate.new(business_cert)
      # Put the certificate ID back into the parameter hash the way Paypal wants it.
      params[:cert_id] = business_certid

      # Prepare a string of data for encryption
      data = ""
      params.each_pair {|k,v| data << "#{k}=#{v}\n"}

      # Sign the data with our key/certificate pair
      signed = OpenSSL::PKCS7::sign(business_cert, business_key, data, [], OpenSSL::PKCS7::BINARY)
      # Encrypt the signed data with Paypal's public certificate.
      encrypted = OpenSSL::PKCS7::encrypt([paypal_cert], signed.to_der, OpenSSL::Cipher::Cipher::new("DES3"), OpenSSL::PKCS7::BINARY)

      # The command for encrypted forms is always '_s-xclick'; the real command is in the encrypted data.
      button << tag(:input, :type => 'hidden', :name => 'cmd', :value => "_s-xclick")
      button << tag(:input, :type => 'hidden', :name => 'encrypted', :value => encrypted)
    else
      # Just emit all the parameters that we have as hidden fields.
      # Note that the sorting isn't really needed, but it makes testing a lot easier for now.
      params.each do |key, value|
        button << tag(:input, :type => 'hidden', :name => key, :value => value)
      end
    end
  end.join("\n")
end