paypal 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +6 -11
- data/Rakefile +11 -10
- data/init.rb +29 -0
- data/lib/notification.rb +2 -0
- data/test/helper_test.rb +154 -0
- data/test/mocks/method_mock.rb +33 -0
- data/test/notification_test.rb +83 -0
- data/test/remote/remote_test.rb +16 -0
- metadata +9 -2
data/README
CHANGED
@@ -17,18 +17,10 @@ business account and tell paypal where to send the IPN ( Instant payment notific
|
|
17
17
|
|
18
18
|
== Installation
|
19
19
|
|
20
|
-
1)
|
21
|
-
|
22
|
-
|
23
|
-
2) Create a new controller which handels the paypal related tasks.
|
24
|
-
script/generate controller payment
|
25
|
-
|
26
|
-
3) Add the Paypal::Helpers to the newly created controller.
|
27
|
-
module PaymentHelper
|
28
|
-
include Paypal::Helpers
|
29
|
-
end
|
20
|
+
1) Install the plugin using ./script/plugin install svn://vault.jadedpixel.com/paypal/trunk/paypal
|
21
|
+
|
30
22
|
|
31
|
-
|
23
|
+
2) Create a paypal_ipn ( or similar ) action like the one in the "Example rails controller" appendix.
|
32
24
|
|
33
25
|
Within the new payment controller you can now create pages from which users can be sent to paypal. You always
|
34
26
|
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.
|
@@ -103,6 +95,9 @@ uninitalized constant Paypal - Make sure your ruby has openssl support
|
|
103
95
|
|
104
96
|
== Changelog
|
105
97
|
|
98
|
+
2006-04-20 -- 1.7.0
|
99
|
+
* Now a rails plugin
|
100
|
+
|
106
101
|
2006-02-10 -- 1.5.1
|
107
102
|
* added complete list of valid paypal options (Paul Hart)
|
108
103
|
|
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ require 'rake/rdoctask'
|
|
5
5
|
require 'rake/gempackagetask'
|
6
6
|
require 'rake/contrib/rubyforgepublisher'
|
7
7
|
|
8
|
-
PKG_VERSION = "1.
|
8
|
+
PKG_VERSION = "1.9.0"
|
9
9
|
PKG_NAME = "paypal"
|
10
10
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
11
11
|
|
@@ -49,7 +49,6 @@ end
|
|
49
49
|
Rake::RDocTask.new { |rdoc|
|
50
50
|
rdoc.rdoc_dir = 'doc'
|
51
51
|
rdoc.title = "Paypal library"
|
52
|
-
rdoc.options << '--line-numbers --inline-source'
|
53
52
|
rdoc.rdoc_files.include('README')
|
54
53
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
55
54
|
}
|
@@ -89,8 +88,8 @@ spec = Gem::Specification.new do |s|
|
|
89
88
|
s.description = s.summary = "Paypal IPN integration library for rails and other web applications"
|
90
89
|
s.has_rdoc = true
|
91
90
|
|
92
|
-
s.files = %w(README Rakefile MIT-LICENSE) + Dir['lib/**/*'] + Dir['misc
|
93
|
-
|
91
|
+
s.files = %w(init.rb README Rakefile MIT-LICENSE) + Dir['lib/**/*'] + Dir['misc/**/*'] + Dir['test/**/*']
|
92
|
+
s.files.reject! { |f| /\/\.\_/ }
|
94
93
|
s.require_path = 'lib'
|
95
94
|
s.autorequire = 'paypal'
|
96
95
|
s.author = "Tobias Luetke"
|
@@ -114,12 +113,14 @@ RUBY_FORGE_USER = 'xal'
|
|
114
113
|
RELEASE_NAME = "REL #{PKG_VERSION}"
|
115
114
|
|
116
115
|
desc "Publish the release files to RubyForge."
|
117
|
-
task :release => [:
|
116
|
+
task :release => [:publish] do
|
118
117
|
`rubyforge login`
|
118
|
+
release_command = "rubyforge add_release #{PKG_NAME} #{PKG_NAME} 'REL #{PKG_VERSION}' pkg/#{PKG_NAME}-#{PKG_VERSION}.gem"
|
119
|
+
puts release_command
|
120
|
+
system(release_command)
|
121
|
+
|
122
|
+
release_command = "rubyforge add_release #{PKG_NAME} #{PKG_NAME} 'REL #{PKG_VERSION}' pkg/#{PKG_NAME}-#{PKG_VERSION}.zip"
|
123
|
+
puts release_command
|
124
|
+
system(release_command)
|
119
125
|
|
120
|
-
for ext in %w( gem tgz zip )
|
121
|
-
release_command = "rubyforge add_release #{PKG_NAME} #{PKG_NAME} 'REL #{PKG_VERSION}' pkg/#{PKG_NAME}-#{PKG_VERSION}.#{ext}"
|
122
|
-
puts release_command
|
123
|
-
system(release_command)
|
124
|
-
end
|
125
126
|
end
|
data/init.rb
ADDED
@@ -0,0 +1,29 @@
|
|
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
|
+
|
25
|
+
# Please note: Paypal is by default in *production* mode.
|
26
|
+
# During development you will want to add
|
27
|
+
#
|
28
|
+
|
29
|
+
ActionView::Base.send(:include, Paypal::Helpers)
|
data/lib/notification.rb
CHANGED
data/test/helper_test.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'paypal'
|
5
|
+
|
6
|
+
require_gem 'money'
|
7
|
+
require_gem 'actionpack' rescue LoadError raise(StandardErrror.new("This test needs ActionPack installed as gem to run"))
|
8
|
+
|
9
|
+
|
10
|
+
# Little hack class which pretends to be a active controller
|
11
|
+
class TestController
|
12
|
+
include Paypal::Helpers
|
13
|
+
include ActionView::Helpers::TagHelper
|
14
|
+
include ActionView::Helpers::FormHelper
|
15
|
+
include ActionView::Helpers::UrlHelper
|
16
|
+
include ActionView::Helpers::FormTagHelper
|
17
|
+
|
18
|
+
def url_for(options, *parameters_for_method_reference)
|
19
|
+
"http://www.sandbox.paypal.com/cgi-bin/webscr"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class HelperTest < Test::Unit::TestCase
|
24
|
+
|
25
|
+
|
26
|
+
def assert_inputs(options, text)
|
27
|
+
all = text.scan(/name\=\"(\w+)\"/).flatten
|
28
|
+
|
29
|
+
xor = (options.keys | all) - (options.keys & all)
|
30
|
+
|
31
|
+
# xor
|
32
|
+
assert_equal [], xor, "options do not match expectations does not have keys #{xor.inspect} only appear in one of both sides in \n\n#{text}"
|
33
|
+
|
34
|
+
text.scan(/name\=\"([^"]+).*?value\=\"([^"]+)/) do |key, value|
|
35
|
+
if options.has_key?(key)
|
36
|
+
assert_equal options[key], value, "key #{key} was '#{options[key]}' and not '#{value}' in \n\n#{text}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def setup
|
42
|
+
@helpers = TestController.new
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_paypal_form_start
|
46
|
+
assert_equal %{<form action="http://www.sandbox.paypal.com/cgi-bin/webscr" method="post">}, @helpers.paypal_form_tag
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_paypal_setup_with_money
|
50
|
+
actual = @helpers.paypal_setup("100", Money.us_dollar(50000), "bob@bigbusiness.com")
|
51
|
+
assert_inputs({ "amount" => "500.00",
|
52
|
+
"business" => "bob@bigbusiness.com",
|
53
|
+
"charset" => "utf-8",
|
54
|
+
"cmd" => "_xclick",
|
55
|
+
"currency_code" => "USD",
|
56
|
+
"item_name" => "Store purchase",
|
57
|
+
"item_number" => "100",
|
58
|
+
"no_note" => "1",
|
59
|
+
"no_shipping" => "1",
|
60
|
+
"quantity" => "1"}, actual)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_paypal_setup_with_money_and_tax
|
64
|
+
actual = @helpers.paypal_setup("100", Money.us_dollar(50000), "bob@bigbusiness.com", :tax => Money.us_dollar(500))
|
65
|
+
assert_inputs({ "amount" => "500.00",
|
66
|
+
"business" => "bob@bigbusiness.com",
|
67
|
+
"charset" => "utf-8",
|
68
|
+
"cmd" => "_xclick",
|
69
|
+
"currency_code" => "USD",
|
70
|
+
"item_name" => "Store purchase",
|
71
|
+
"item_number" => "100",
|
72
|
+
"no_note" => "1",
|
73
|
+
"no_shipping" => "1",
|
74
|
+
"quantity" => "1",
|
75
|
+
"tax" => "5.00"}, actual)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_paypal_setup_with_money_and_invoice
|
79
|
+
actual = @helpers.paypal_setup("100", Money.us_dollar(50000), "bob@bigbusiness.com", :invoice => "Cool invoice!")
|
80
|
+
assert_inputs({ "amount" => "500.00",
|
81
|
+
"business" => "bob@bigbusiness.com",
|
82
|
+
"charset" => "utf-8",
|
83
|
+
"cmd" => "_xclick",
|
84
|
+
"currency_code" => "USD",
|
85
|
+
"invoice" => "Cool invoice!",
|
86
|
+
"item_name" => "Store purchase",
|
87
|
+
"item_number" => "100",
|
88
|
+
"no_note" => "1",
|
89
|
+
"no_shipping" => "1",
|
90
|
+
"quantity" => "1"}, actual)
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_paypal_setup_with_money_and_custom
|
94
|
+
actual = @helpers.paypal_setup("100", Money.us_dollar(50000), "bob@bigbusiness.com", :custom => "Custom")
|
95
|
+
assert_inputs({ "amount" => "500.00",
|
96
|
+
"business" => "bob@bigbusiness.com",
|
97
|
+
"charset" => "utf-8",
|
98
|
+
"cmd" => "_xclick",
|
99
|
+
"currency_code" => "USD",
|
100
|
+
"custom" => "Custom",
|
101
|
+
"item_name" => "Store purchase",
|
102
|
+
"item_number" => "100",
|
103
|
+
"no_note" => "1",
|
104
|
+
"no_shipping" => "1",
|
105
|
+
"quantity" => "1"}, actual)
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_paypal_setup_with_float
|
109
|
+
actual = @helpers.paypal_setup("100", 50.00, "bob@bigbusiness.com", :currency => 'CAD')
|
110
|
+
assert_inputs({ "amount" => "50.00",
|
111
|
+
"business" => "bob@bigbusiness.com",
|
112
|
+
"charset" => "utf-8",
|
113
|
+
"cmd" => "_xclick",
|
114
|
+
"currency_code" => "CAD",
|
115
|
+
"item_name" => "Store purchase",
|
116
|
+
"item_number" => "100",
|
117
|
+
"no_note" => "1",
|
118
|
+
"no_shipping" => "1",
|
119
|
+
"quantity" => "1"}, actual)
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_paypal_setup_with_string
|
123
|
+
actual = @helpers.paypal_setup("100", "50.00", "bob@bigbusiness.com", :currency => 'CAD')
|
124
|
+
assert_inputs({ "amount" => "50.00",
|
125
|
+
"business" => "bob@bigbusiness.com",
|
126
|
+
"charset" => "utf-8",
|
127
|
+
"cmd" => "_xclick",
|
128
|
+
"currency_code" => "CAD",
|
129
|
+
"item_name" => "Store purchase",
|
130
|
+
"item_number" => "100",
|
131
|
+
"no_note" => "1",
|
132
|
+
"no_shipping" => "1",
|
133
|
+
"quantity" => "1"}, actual)
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_paypal_setup_options
|
137
|
+
actual = @helpers.paypal_setup("100", Money.us_dollar(100), "bob@bigbusiness.com", :item_name => "MegaBob's shop purchase", :return => 'http://www.bigbusiness.com', :cancel_return => 'http://www.bigbusiness.com', :notify_url => 'http://www.bigbusiness.com', :no_shipping => 0, :no_note => 0 )
|
138
|
+
assert_inputs({ "amount" => "1.00",
|
139
|
+
"business" => "bob@bigbusiness.com",
|
140
|
+
"cancel_return" => "http://www.bigbusiness.com",
|
141
|
+
"charset" => "utf-8",
|
142
|
+
"cmd" => "_xclick",
|
143
|
+
"currency_code" => "USD",
|
144
|
+
"item_name" => "MegaBob's shop purchase",
|
145
|
+
"item_number" => "100",
|
146
|
+
"no_note" => "0",
|
147
|
+
"no_shipping" => "0",
|
148
|
+
"notify_url" => "http://www.bigbusiness.com",
|
149
|
+
"quantity" => "1",
|
150
|
+
"return" => "http://www.bigbusiness.com"}, actual )
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Module
|
2
|
+
def mock_methods(mock_methods)
|
3
|
+
raise "mock methods needs a block" unless block_given?
|
4
|
+
|
5
|
+
original = self
|
6
|
+
namespace = original.name.split("::")
|
7
|
+
class_name = namespace.last
|
8
|
+
|
9
|
+
mod = namespace[0..-2].inject(Object) { |mod, part| mod.const_get(part) }
|
10
|
+
|
11
|
+
klass = (original.is_a?(Class) ? Class : Module).new(self) do
|
12
|
+
|
13
|
+
instance_eval do
|
14
|
+
mock_methods.each do |method, proc|
|
15
|
+
define_method("mocked_#{method}", &proc)
|
16
|
+
alias_method method, "mocked_#{method}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
begin
|
23
|
+
mod.send(:remove_const, class_name)
|
24
|
+
mod.const_set(class_name, klass)
|
25
|
+
|
26
|
+
yield
|
27
|
+
ensure
|
28
|
+
mod.send(:remove_const, class_name)
|
29
|
+
mod.const_set(class_name, original)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'openssl'
|
4
|
+
require 'net/http'
|
5
|
+
require File.dirname(__FILE__) + '/mocks/method_mock'
|
6
|
+
require 'test/unit'
|
7
|
+
require 'paypal'
|
8
|
+
|
9
|
+
$paypal_success = Class.new do
|
10
|
+
def body; "VERIFIED"; end
|
11
|
+
end
|
12
|
+
|
13
|
+
$paypal_failure = Class.new do
|
14
|
+
def body; "INVALID"; end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
class NotificationTest < Test::Unit::TestCase
|
19
|
+
|
20
|
+
def setup
|
21
|
+
Paypal::Notification.ipn_url = "http://www.paypal.com/some/address"
|
22
|
+
|
23
|
+
@paypal = Paypal::Notification.new(http_raw_data)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_raw
|
27
|
+
assert_equal http_raw_data, @paypal.raw
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_parse
|
31
|
+
@paypal = Paypal::Notification.new(http_raw_data)
|
32
|
+
assert_equal "500.00", @paypal.params['mc_gross']
|
33
|
+
assert_equal "confirmed", @paypal.params['address_status']
|
34
|
+
assert_equal "EVMXCLDZJV77Q", @paypal.params['payer_id']
|
35
|
+
assert_equal "Completed", @paypal.params['payment_status']
|
36
|
+
assert_equal CGI.unescape("15%3A23%3A54+Apr+15%2C+2005+PDT"), @paypal.params['payment_date']
|
37
|
+
# ...
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_accessors
|
41
|
+
assert @paypal.complete?
|
42
|
+
assert_equal "Completed", @paypal.status
|
43
|
+
assert_equal "6G996328CK404320L", @paypal.transaction_id
|
44
|
+
assert_equal "web_accept", @paypal.type
|
45
|
+
assert_equal "500.00", @paypal.gross
|
46
|
+
assert_equal "15.05", @paypal.fee
|
47
|
+
assert_equal "CAD", @paypal.currency
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_compositions
|
51
|
+
assert_equal Money.ca_dollar(50000), @paypal.amount
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_acknowledgement
|
55
|
+
|
56
|
+
|
57
|
+
Net::HTTP.mock_methods( :request => Proc.new { |r, b| $paypal_success.new } ) do
|
58
|
+
assert @paypal.acknowledge
|
59
|
+
end
|
60
|
+
|
61
|
+
Net::HTTP.mock_methods( :request => Proc.new { |r, b| $paypal_failure.new } ) do
|
62
|
+
assert !@paypal.acknowledge
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_send_acknowledgement
|
68
|
+
request, body = nil
|
69
|
+
|
70
|
+
Net::HTTP.mock_methods( :request => Proc.new { |r, b| request = r; body = b; $paypal_success.new } ) do
|
71
|
+
assert @paypal.acknowledge
|
72
|
+
end
|
73
|
+
|
74
|
+
assert_equal '/some/address?cmd=_notify-validate', request.path
|
75
|
+
assert_equal http_raw_data, body
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def http_raw_data
|
81
|
+
"mc_gross=500.00&address_status=confirmed&payer_id=EVMXCLDZJV77Q&tax=0.00&address_street=164+Waverley+Street&payment_date=15%3A23%3A54+Apr+15%2C+2005+PDT&payment_status=Completed&address_zip=K2P0V6&first_name=Tobias&mc_fee=15.05&address_country_code=CA&address_name=Tobias+Luetke¬ify_version=1.7&custom=&payer_status=unverified&business=tobi%40leetsoft.com&address_country=Canada&address_city=Ottawa&quantity=1&payer_email=tobi%40snowdevil.ca&verify_sign=AEt48rmhLYtkZ9VzOGAtwL7rTGxUAoLNsuf7UewmX7UGvcyC3wfUmzJP&txn_id=6G996328CK404320L&payment_type=instant&last_name=Luetke&address_state=Ontario&receiver_email=tobi%40leetsoft.com&payment_fee=&receiver_id=UQ8PDYXJZQD9Y&txn_type=web_accept&item_name=Store+Purchase&mc_currency=CAD&item_number=&test_ipn=1&payment_gross=&shipping=0.00"
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../../lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'paypal'
|
5
|
+
|
6
|
+
class RemoteTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_raw
|
9
|
+
Paypal::Notification.ipn_url = "https://www.sandbox.paypal.com/cgi-bin/webscr"
|
10
|
+
@paypal = Paypal::Notification.new('')
|
11
|
+
|
12
|
+
assert_nothing_raised do
|
13
|
+
assert_equal false, @paypal.acknowledge
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: paypal
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.
|
7
|
-
date: 2006-04-
|
6
|
+
version: 1.9.0
|
7
|
+
date: 2006-04-29 00:00:00 -04:00
|
8
8
|
summary: Paypal IPN integration library for rails and other web applications
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -28,6 +28,7 @@ cert_chain:
|
|
28
28
|
authors:
|
29
29
|
- Tobias Luetke
|
30
30
|
files:
|
31
|
+
- init.rb
|
31
32
|
- README
|
32
33
|
- Rakefile
|
33
34
|
- MIT-LICENSE
|
@@ -36,6 +37,12 @@ files:
|
|
36
37
|
- lib/paypal.rb
|
37
38
|
- misc/PayPal - Instant Payment Notification - Technical Overview.pdf
|
38
39
|
- misc/paypal.psd
|
40
|
+
- test/helper_test.rb
|
41
|
+
- test/mocks
|
42
|
+
- test/notification_test.rb
|
43
|
+
- test/remote
|
44
|
+
- test/mocks/method_mock.rb
|
45
|
+
- test/remote/remote_test.rb
|
39
46
|
test_files: []
|
40
47
|
|
41
48
|
rdoc_options: []
|