paypal 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ #--
2
+ # Copyright (c) 2005 Tobias Luetke
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
data/README ADDED
@@ -0,0 +1,83 @@
1
+ == Welcome to Paypal/ruby
2
+
3
+ This library is here to aid with integrating Paypal payments into ruby on rails
4
+ applications or similar. To set this up you will need to log into your paypal
5
+ business account and tell paypal where to send the IPN ( Instant payment notifications ).
6
+
7
+ == Download
8
+
9
+ * Preferred method of installation is using rubygems. gem install --source http://dist.leetsoft.com paypal
10
+ * Alternatively you can get the library packaged at http://dist.leetsoft.com/pkg/
11
+
12
+ == Requirements
13
+
14
+ * Valid paypal business account.
15
+ * The money library from http://dist.leetsoft.com/api/money
16
+
17
+ == Installation
18
+
19
+ 1) Either install the rubygem for this library ( rake install from source
20
+ or gem install --source <url> paypal using gems directly )
21
+
22
+ 2) Create a new controller which handels the paypal related tasks.
23
+ script/generate controller payment
24
+
25
+ 3) Add the Paypal::Helpers to the newly created controller.
26
+ module PaymentHelper
27
+ include Paypal::Helpers
28
+ end
29
+ 4) Create a paypal_ipn ( or similar ) action like the one in the "Example rails controller" appendix.
30
+
31
+ Within the new payment controller you can now create pages from which users can be sent to paypal. You always
32
+ have to sent users to paypal using a HTTP Post so a standard link won't work (well OK but you need some javascript for that). The +Paypal::Helper+ namespace has some examples of how such a forward page may look.
33
+
34
+ == Testing the integration
35
+
36
+ Under https://developer.paypal.com/ you can signup for a paypal developer account.
37
+ This allows you to set up "sandboxed" accounts which work and act like real accounts
38
+ with the difference that no money is exchanged. Its a good idea to sign up for a
39
+ sandbox account to use while the application is running in development mode.
40
+
41
+
42
+ == Example rails controller
43
+
44
+ class BackendController < ApplicationController
45
+ def paypal_ipn
46
+ notify = PaypalNotification.new(request.raw_post)
47
+
48
+ order = Order.find(notify.item_id)
49
+
50
+ if notify.acknowledge
51
+ begin
52
+
53
+ if notify.complete? and order.total == notify.amount
54
+ order.status = 'success'
55
+
56
+ shop.ship(order)
57
+ else
58
+ logger.error("Failed to verify Paypal's notification, please investigate")
59
+ end
60
+
61
+ rescue => e
62
+ order.status = 'failed'
63
+ raise
64
+ ensure
65
+ order.save
66
+ end
67
+ end
68
+
69
+ render :nothing
70
+ end
71
+ end
72
+
73
+
74
+ == Example paypal forward page
75
+
76
+ <%= paypal_form_tag %>
77
+ <%= paypal_setup "Item 500", Money.us_dollar(50000), "bob@bigbusiness.com" %>
78
+
79
+ Please press here to pay $500US using paypal. <br/>
80
+ <%= submit_tag "Go to paypal >>" %>
81
+
82
+ <% end_form_tag %>
83
+
data/Rakefile ADDED
@@ -0,0 +1,221 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/gempackagetask'
6
+ require 'rake/contrib/rubyforgepublisher'
7
+
8
+ PKG_VERSION = "0.5.0"
9
+ PKG_NAME = "paypal"
10
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
11
+
12
+ PKG_FILES = FileList[
13
+ "lib/**/*",
14
+ "test/*",
15
+ "misc/*",
16
+ "[A-Z]*",
17
+ "MIT-LICENSE",
18
+ "Rakefile"
19
+ ].exclude(/\bCVS\b|~$/)
20
+
21
+ desc "Default Task"
22
+ task :default => [ :test ]
23
+
24
+ desc "Delete tar.gz / zip / rdoc"
25
+ task :cleanup => [ :rm_packages, :clobber_rdoc ]
26
+
27
+ # Run the unit tests
28
+ Rake::TestTask.new("test") { |t|
29
+ t.libs << "test"
30
+ t.pattern = 'test/*_test.rb'
31
+ t.verbose = false
32
+ }
33
+
34
+ desc "Create a rubygem and install it. Might need root rights"
35
+ task :install => [:package] do
36
+ `gem install pkg/#{PKG_FILE_NAME}.gem`
37
+ end
38
+
39
+ # Genereate the RDoc documentation
40
+
41
+ Rake::RDocTask.new { |rdoc|
42
+ rdoc.rdoc_dir = 'doc'
43
+ rdoc.title = "Paypal library"
44
+ rdoc.options << '--line-numbers --inline-source'
45
+ rdoc.rdoc_files.include('README')
46
+ rdoc.rdoc_files.include('lib/**/*.rb')
47
+ }
48
+
49
+ task :lines do
50
+ lines = 0
51
+ codelines = 0
52
+ Dir.foreach("lib") { |file_name|
53
+ next unless file_name =~ /.*rb/
54
+
55
+ f = File.open("lib/" + file_name)
56
+
57
+ while line = f.gets
58
+ lines += 1
59
+ next if line =~ /^\s*$/
60
+ next if line =~ /^\s*#/
61
+ codelines += 1
62
+ end
63
+ }
64
+ puts "Lines #{lines}, LOC #{codelines}"
65
+ end
66
+
67
+
68
+ desc "Publish the gem on leetsoft"
69
+ task :publish => [:rdoc, :package] do
70
+ Rake::SshFilePublisher.new("leetsoft.com", "dist/pkg", "pkg", "#{PKG_FILE_NAME}.zip").upload
71
+ Rake::SshFilePublisher.new("leetsoft.com", "dist/pkg", "pkg", "#{PKG_FILE_NAME}.tgz").upload
72
+ Rake::SshFilePublisher.new("leetsoft.com", "dist/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
73
+ `ssh tobi@leetsoft.com "mkdir -p dist/api/#{PKG_NAME}"`
74
+ Rake::SshDirPublisher.new("leetsoft.com", "dist/api/#{PKG_NAME}", "doc").upload
75
+ `ssh tobi@leetsoft.com './gemupdate'`
76
+ end
77
+
78
+ spec = Gem::Specification.new do |s|
79
+ s.name = PKG_NAME
80
+ s.version = PKG_VERSION
81
+ s.summary = "Paypal IPN integration for rails apps and similar"
82
+ s.has_rdoc = true
83
+
84
+ s.files = %w(README Rakefile MIT-LICENSE) + Dir['lib/**/*'] + Dir['misc/*'] + Dir['tests/*']
85
+
86
+ s.require_path = 'lib'
87
+ s.autorequire = 'paypal'
88
+ s.author = "Tobias Luetke"
89
+ s.email = "tobi@leetsoft.com"
90
+ s.homepage = "http://dist.leetsoft.com/api/paypal"
91
+
92
+ s.add_dependency('money')
93
+ end
94
+
95
+ Rake::GemPackageTask.new(spec) do |p|
96
+ p.gem_spec = spec
97
+ p.need_tar = true
98
+ p.need_zip = true
99
+ end
100
+
101
+
102
+ # --- Ruby forge release manager by florian gross -------------------------------------------------
103
+
104
+ RUBY_FORGE_PROJECT = 'paypal'
105
+ RUBY_FORGE_USER = 'xal'
106
+ RELEASE_NAME = "REL #{PKG_VERSION}"
107
+
108
+ desc "Publish the release files to RubyForge."
109
+ task :release => [:gem] do
110
+ files = ["gem"].map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" }
111
+
112
+ if RUBY_FORGE_PROJECT then
113
+ require 'net/http'
114
+ require 'open-uri'
115
+
116
+ project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/"
117
+ project_data = open(project_uri) { |data| data.read }
118
+ group_id = project_data[/[?&]group_id=(\d+)/, 1]
119
+ raise "Couldn't get group id" unless group_id
120
+
121
+ # This echos password to shell which is a bit sucky
122
+ if ENV["RUBY_FORGE_PASSWORD"]
123
+ password = ENV["RUBY_FORGE_PASSWORD"]
124
+ else
125
+ print "#{RUBY_FORGE_USER}@rubyforge.org's password: "
126
+ password = STDIN.gets.chomp
127
+ end
128
+
129
+ login_response = Net::HTTP.start("rubyforge.org", 80) do |http|
130
+ data = [
131
+ "login=1",
132
+ "form_loginname=#{RUBY_FORGE_USER}",
133
+ "form_pw=#{password}"
134
+ ].join("&")
135
+ http.post("/account/login.php", data)
136
+ end
137
+
138
+ cookie = login_response["set-cookie"]
139
+ raise "Login failed" unless cookie
140
+ headers = { "Cookie" => cookie }
141
+
142
+ release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}"
143
+ release_data = open(release_uri, headers) { |data| data.read }
144
+ package_id = release_data[/[?&]package_id=(\d+)/, 1]
145
+ raise "Couldn't get package id" unless package_id
146
+
147
+ first_file = true
148
+ release_id = ""
149
+
150
+ files.each do |filename|
151
+ basename = File.basename(filename)
152
+ file_ext = File.extname(filename)
153
+ file_data = File.open(filename, "rb") { |file| file.read }
154
+
155
+ puts "Releasing #{basename}..."
156
+
157
+ release_response = Net::HTTP.start("rubyforge.org", 80) do |http|
158
+ release_date = Time.now.strftime("%Y-%m-%d %H:%M")
159
+ type_map = {
160
+ ".zip" => "3000",
161
+ ".tgz" => "3110",
162
+ ".gz" => "3110",
163
+ ".gem" => "1400"
164
+ }; type_map.default = "9999"
165
+ type = type_map[file_ext]
166
+ boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"
167
+
168
+ query_hash = if first_file then
169
+ {
170
+ "group_id" => group_id,
171
+ "package_id" => package_id,
172
+ "release_name" => RELEASE_NAME,
173
+ "release_date" => release_date,
174
+ "type_id" => type,
175
+ "processor_id" => "8000", # Any
176
+ "release_notes" => "",
177
+ "release_changes" => "",
178
+ "preformatted" => "1",
179
+ "submit" => "1"
180
+ }
181
+ else
182
+ {
183
+ "group_id" => group_id,
184
+ "release_id" => release_id,
185
+ "package_id" => package_id,
186
+ "step2" => "1",
187
+ "type_id" => type,
188
+ "processor_id" => "8000", # Any
189
+ "submit" => "Add This File"
190
+ }
191
+ end
192
+
193
+ query = "?" + query_hash.map do |(name, value)|
194
+ [name, URI.encode(value)].join("=")
195
+ end.join("&")
196
+
197
+ data = [
198
+ "--" + boundary,
199
+ "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"",
200
+ "Content-Type: application/octet-stream",
201
+ "Content-Transfer-Encoding: binary",
202
+ "", file_data, ""
203
+ ].join("\x0D\x0A")
204
+
205
+ release_headers = headers.merge(
206
+ "Content-Type" => "multipart/form-data; boundary=#{boundary}"
207
+ )
208
+
209
+ target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
210
+ http.post(target + query, data, release_headers)
211
+ end
212
+
213
+ if first_file then
214
+ release_id = release_response.body[/release_id=(\d+)/, 1]
215
+ raise("Couldn't get release id") unless release_id
216
+ end
217
+
218
+ first_file = false
219
+ end
220
+ end
221
+ end
data/lib/helper.rb ADDED
@@ -0,0 +1,86 @@
1
+ module Paypal
2
+ # This is a collection of helpers which aid in the creation of paypal buttons
3
+ #
4
+ # Example:
5
+ #
6
+ # <%= form_tag Paypal::Notification.ipn_url %>
7
+ #
8
+ # <%= paypal_setup "Item 500", Money.us_dollar(50000), "bob@bigbusiness.com" %>
9
+ # Please press here to pay $500US using paypal. <%= submit_tag %>
10
+ #
11
+ # <% end_form_tag %>
12
+ #
13
+ # For this to work you have to include these methods as helpers in your rails application.
14
+ # One way is to add "include Paypal::Helpers" in your application_helper.rb
15
+ # See Paypal::Notification for information on how to catch payment events.
16
+ module Helpers
17
+
18
+ # Convenience helper. Can replace <%= form_tag Paypal::Notification.ipn_url %>
19
+ def paypal_form_tag
20
+ form_tag(Paypal::Notification.ipn_url)
21
+ end
22
+
23
+ # This helper creates the hidden form data which is needed for a paypal purchase.
24
+ #
25
+ # * <tt>item_number</tt> -- The first parameter is the item number. This is for your personal organization and can
26
+ # be arbitrary. Paypal will sent the item number back with the IPN so its a great place to
27
+ # store a user ID or a order ID or something like this.
28
+ #
29
+ # * <tt>amount</tt> -- should be a parameter of type Money ( see http://leetsoft.com/api/money ) but can also
30
+ # be a string of type "50.00" for 50$. If you use the string syntax make sure you set the current
31
+ # currency as part of the options hash. The default is USD
32
+ #
33
+ # * <tt>business</tt> -- This is your paypal account name ( a email ). This needs to be a valid paypal business account.
34
+ #
35
+ # The last parameter is a options hash. You can override several things:
36
+ #
37
+ # * <tt>:return_url</tt> -- default is nil. If provided paypal will redirect a user back to your application after a
38
+ # successful purchase. Useful for a kind of thankyou page.
39
+ # * <tt>:item_name</tt> -- default is 'Store purchase'. This is the name of the purchase which will be displayed
40
+ # on the paypal page.
41
+ # * <tt>:no_shipping</tt> -- default is '1'. By default we tell paypal that no shipping is required. Usually
42
+ # the shipping address should be collected in our application, not by paypal.
43
+ # * <tt>:no_note</tt> -- default is '1'
44
+ # * <tt>:currency</tt> -- default is 'USD'
45
+ #
46
+ # Examples:
47
+ #
48
+ # <%= paypal_setup @order.id, Money.us_dollar(50000), "bob@bigbusiness.com" %>
49
+ # <%= paypal_setup @order.id, 50.00, "bob@bigbusiness.com", :currency => 'USD' %>
50
+ # <%= paypal_setup @order.id, Money.ca_dollar(50000), "bob@bigbusiness.com", :item_name => 'Snowdevil shop purchase', :return_url => url_for(:only_path => false, :action => 'thankyou') %>
51
+ #
52
+ def paypal_setup(item_number, amount, business, options = {})
53
+
54
+ params = {
55
+ :item_name => 'Store purchase',
56
+ :no_shipping => '1',
57
+ :no_note => '1',
58
+ :currency => 'USD',
59
+ :return_url => nil
60
+ }.merge(options)
61
+
62
+ # We accept both, strings and money objects as amount
63
+ amount = amount.cents / 100 if amount.respond_to?(:cents)
64
+ amount = sprintf("%.2f", amount)
65
+
66
+ # Build the form
67
+ returning button = [] do
68
+ button << form_tag(Paypal::Notification.ipn_url)
69
+
70
+ button << tag(:input, :type => 'hidden', :name => 'cmd', :value => "_xclick")
71
+ button << tag(:input, :type => 'hidden', :name => 'business', :value => business)
72
+ button << tag(:input, :type => 'hidden', :name => 'amount', :value => amount)
73
+ button << tag(:input, :type => 'hidden', :name => 'item_number', :value => item_number)
74
+ button << tag(:input, :type => 'hidden', :name => 'item_name', :value => params[:item_name])
75
+ button << tag(:input, :type => 'hidden', :name => 'no_shipping', :value => params[:no_shipping])
76
+ button << tag(:input, :type => 'hidden', :name => 'no_note', :value => params[:no_note])
77
+ button << tag(:input, :type => 'hidden', :name => 'return', :value => params[:return_url]) if params[:return_url]
78
+
79
+ # if amount was a object of type money or something compatible we will use its currency,
80
+ # otherwise get the currency from the options. default is USD
81
+ button << tag(:input, :type => 'hidden', :name => 'currency_code', :value => amount.respond_to?(:currency) ? amount.currency : params[:currency])
82
+ end.join("\n")
83
+ end
84
+
85
+ end
86
+ end
@@ -0,0 +1,160 @@
1
+ module Paypal
2
+ # Parser and handler for incoming Instant payment notifications from paypal.
3
+ # The Example shows a typical handler in a rails application.
4
+ #
5
+ # Example
6
+ #
7
+ # class BackendController < ApplicationController
8
+ #
9
+ # def paypal_ipn
10
+ # notify = PaypalNotification.new(request.raw_post)
11
+ #
12
+ # order = Order.find(notify.item_id)
13
+ #
14
+ # if notify.acknowledge
15
+ # begin
16
+ #
17
+ # if notify.complete? and order.total == notify.amount
18
+ # order.status = 'success'
19
+ #
20
+ # shop.ship(order)
21
+ # else
22
+ # logger.error("Failed to verify Paypal's notification, please investigate")
23
+ # end
24
+ #
25
+ # rescue => e
26
+ # order.status = 'failed'
27
+ # raise
28
+ # ensure
29
+ # order.save
30
+ # end
31
+ # end
32
+ #
33
+ # render :nothing
34
+ # end
35
+ # end
36
+ class Notification
37
+ attr_accessor :params
38
+ attr_accessor :raw
39
+
40
+ # Overwrite this url. It points to the Paypal sandbox by default.
41
+ # Please note that the Paypal technical overview (doc directory)
42
+ # speaks of a https:// address for production use. In my tests
43
+ # this https address does not in fact work.
44
+ #
45
+ # Example:
46
+ # Paypal::Notification.ipn_url = http://www.paypal.com/cgi-bin/webscr
47
+ #
48
+ cattr_accessor :ipn_url
49
+ @@ipn_url = 'http://www.sandbox.paypal.com/cgi-bin/webscr'
50
+
51
+ # Creates a new paypal object. Pass the raw html you got from paypal in.
52
+ # In a rails application this looks something like this
53
+ #
54
+ # def paypal_ipn
55
+ # paypal = Paypal::Notification.new(request.raw_post)
56
+ # ...
57
+ # end
58
+ def initialize(post)
59
+ empty!
60
+ parse(post)
61
+ end
62
+
63
+ # Was the transaction complete?
64
+ def complete?
65
+ status == "Completed"
66
+ end
67
+
68
+ # When was this payment received by the client.
69
+ # sometimes it can happen that we get the notification much later.
70
+ # One possible scenario is that our web application was down. In this case paypal tries several
71
+ # times an hour to inform us about the notification
72
+ def recieved_at
73
+ Time.parse params['payment_date']
74
+ end
75
+
76
+ # Whats the status of this transaction?
77
+ def status
78
+ params['payment_status']
79
+ end
80
+
81
+ # Id of this transaction (paypal number)
82
+ def transaction_id
83
+ params['txn_id']
84
+ end
85
+
86
+ # What type of transaction are we dealing with?
87
+ # "cart" "send_money" "web_accept" are possible here.
88
+ def type
89
+ params['txn_type']
90
+ end
91
+
92
+ # the money amount we received in X.2 decimal.
93
+ def gross
94
+ params['mc_gross']
95
+ end
96
+
97
+ # the markup paypal charges for the transaction
98
+ def fee
99
+ params['mc_fee']
100
+ end
101
+
102
+ # What currency have we been dealing with
103
+ def currency
104
+ params['mc_currency']
105
+ end
106
+
107
+ # This is the item number which we submitted to paypal
108
+ def item_id
109
+ params['item_number']
110
+ end
111
+
112
+ # This combines the gross and currency and returns a proper Money object.
113
+ # this requires the money library located at http://dist.leetsoft.com/api/money
114
+ def amount
115
+ amount = gross.sub(/[^\d]/, '').to_i
116
+ Money.new(amount, currency)
117
+ end
118
+
119
+ # reset the notification.
120
+ def empty!
121
+ @params = Hash.new
122
+ @raw = ""
123
+ end
124
+
125
+ # Acknowledge the transaction to paypal. This method has to be called after a new
126
+ # ipn arrives. Paypal will verify that all the information we received are correct and will return a
127
+ # ok or a fail.
128
+ #
129
+ # Example:
130
+ #
131
+ # def paypal_ipn
132
+ # notify = PaypalNotification.new(request.raw_post)
133
+ #
134
+ # if notify.acknowledge
135
+ # ... process order ... if notify.complete?
136
+ # else
137
+ # ... log possible hacking attempt ...
138
+ # end
139
+ def acknowledge
140
+ uri = URI.parse(self.class.ipn_url)
141
+ status = nil
142
+ Net::HTTP.start(uri.host, uri.port) do |request|
143
+ status = request.post(uri.path, raw + "&cmd=_notify-validate").body
144
+ end
145
+ status == "VERIFIED"
146
+ end
147
+
148
+ private
149
+
150
+ # Take the posted data and move the relevant data into a hash
151
+ def parse(post)
152
+ @raw = post
153
+ for line in post.split('&')
154
+ key, value = *line.scan( %r{^(\w+)\=(.*)$} ).flatten
155
+ params[key] = CGI.unescape(value)
156
+ end
157
+ end
158
+
159
+ end
160
+ end
data/lib/paypal.rb ADDED
@@ -0,0 +1,36 @@
1
+ #--
2
+ # Copyright (c) 2005 Tobias Luetke
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ require 'cgi'
25
+ require 'net/http'
26
+ require 'net/https'
27
+
28
+ begin
29
+ require 'money'
30
+ rescue LoadError
31
+ require 'rubygems'
32
+ require_gem 'money'
33
+ end
34
+
35
+ require File.dirname(__FILE__) + '/notification'
36
+ require File.dirname(__FILE__) + '/helper'
data/misc/paypal.psd ADDED
Binary file
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.10
3
+ specification_version: 1
4
+ name: paypal
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.5.0
7
+ date: 2005-06-08
8
+ summary: Paypal IPN integration for rails apps and similar
9
+ require_paths:
10
+ - lib
11
+ email: tobi@leetsoft.com
12
+ homepage: http://dist.leetsoft.com/api/paypal
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: paypal
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ -
22
+ - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ authors:
28
+ - Tobias Luetke
29
+ files:
30
+ - README
31
+ - Rakefile
32
+ - MIT-LICENSE
33
+ - lib/helper.rb
34
+ - lib/notification.rb
35
+ - lib/paypal.rb
36
+ - "misc/PayPal - Instant Payment Notification - Technical Overview.pdf"
37
+ - misc/paypal.psd
38
+ test_files: []
39
+ rdoc_options: []
40
+ extra_rdoc_files: []
41
+ executables: []
42
+ extensions: []
43
+ requirements: []
44
+ dependencies:
45
+ - !ruby/object:Gem::Dependency
46
+ name: money
47
+ version_requirement:
48
+ version_requirements: !ruby/object:Gem::Version::Requirement
49
+ requirements:
50
+ -
51
+ - ">"
52
+ - !ruby/object:Gem::Version
53
+ version: 0.0.0
54
+ version: