sinatra-paypal 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/lib/sinatra/paypal.rb +31 -14
- data/lib/sinatra/paypal/paypal-request.rb +9 -6
- data/lib/sinatra/paypal/version.rb +1 -1
- data/test/app.rb +7 -3
- data/test/form_test.rb +2 -1
- data/test/paypal_test.rb +24 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a60ac8cab5ae922c45d7c630945fff359fefbf6
|
4
|
+
data.tar.gz: 47dca80829bd0bfa71148c9e4b90fa00144df985
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6b8b5d328770f3e9ad58ac726d2ed1b8644081711ddc86d5500d02db545f43220128cdfc04396f2f47f090d072b483dd8c186a4890784cf77ea0109d349727c
|
7
|
+
data.tar.gz: f7fde5572ccfd005187e8f780b9f84ffa4f324de2d3d22c26edf06c742d75914d2fb04dc1dcb1469ad8cedfc5685d872455951a0884701dc225d2e9e2e90852b
|
data/lib/sinatra/paypal.rb
CHANGED
@@ -4,15 +4,9 @@ require 'sinatra/paypal/version'
|
|
4
4
|
require 'sinatra/paypal/paypal-helper'
|
5
5
|
require 'sinatra/paypal/paypal-request'
|
6
6
|
|
7
|
-
PAYPAL_BLOCKS = {}
|
8
|
-
|
9
7
|
module PayPal
|
10
8
|
|
11
9
|
module Helpers
|
12
|
-
def _paypal_block(name)
|
13
|
-
return Proc.new{} if !PAYPAL_BLOCKS.key? name
|
14
|
-
PAYPAL_BLOCKS[name]
|
15
|
-
end
|
16
10
|
|
17
11
|
def paypal_form_url
|
18
12
|
PaypalHelper.form_url(settings.paypal.sandbox?)
|
@@ -39,6 +33,7 @@ module PayPal
|
|
39
33
|
|
40
34
|
def self.registered(app)
|
41
35
|
app.helpers PayPal::Helpers
|
36
|
+
app._paypal_register_default_callbacks
|
42
37
|
|
43
38
|
app.set :paypal, OpenStruct.new({
|
44
39
|
:return_url => '/payment/complete',
|
@@ -53,27 +48,25 @@ module PayPal
|
|
53
48
|
|
54
49
|
# first we check the request against paypal to make sure it is ok
|
55
50
|
if settings.production?
|
56
|
-
halt
|
51
|
+
halt 500, 'request could not be validated' if !paypal_helper.ipn_valid? params
|
57
52
|
end
|
58
|
-
|
59
|
-
halt 400, 'no username provided' if paypal_request.username.nil?
|
60
53
|
|
61
54
|
# check transaction log to make sure this not a replay attack
|
62
|
-
if
|
55
|
+
if app._call_paypal_method(:repeated?, paypal_request)
|
63
56
|
# we also want to return 200, because if it is paypal sending this, it will send
|
64
57
|
# it again and again until it gets a 200 back
|
65
58
|
halt 200, 'already processed'
|
66
59
|
end
|
67
60
|
|
68
|
-
|
61
|
+
app._call_paypal_method(:validate!, paypal_request)
|
69
62
|
|
70
63
|
# check that the payment is complete. we still return 200 if not, but
|
71
64
|
# we don't need to do anymore processing (except for marking it as accountable, if it is)
|
72
65
|
if paypal_request.complete?
|
73
|
-
|
66
|
+
app._call_paypal_method(:complete, paypal_request)
|
74
67
|
end
|
75
68
|
|
76
|
-
|
69
|
+
app._call_paypal_method(:finish, paypal_request)
|
77
70
|
|
78
71
|
return 200
|
79
72
|
end
|
@@ -89,8 +82,32 @@ module PayPal
|
|
89
82
|
# end
|
90
83
|
#
|
91
84
|
def payment(name, &block)
|
92
|
-
|
85
|
+
raise "#{name.to_s} is not a valid payment callback" if !_paypal_valid_blocks.include? name
|
86
|
+
_paypal_register_callback name, &block
|
87
|
+
end
|
88
|
+
|
89
|
+
def _paypal_register_default_callbacks
|
90
|
+
_paypal_valid_blocks.each do |key|
|
91
|
+
_paypal_register_callback(key) { |p| }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def _paypal_register_callback(key, &block)
|
96
|
+
self.class.send :define_method, _paypal_method_name(key), &block
|
93
97
|
end
|
98
|
+
|
99
|
+
def _paypal_valid_blocks
|
100
|
+
[:complete, :finish, :validate!, :repeated?]
|
101
|
+
end
|
102
|
+
|
103
|
+
def _call_paypal_method(key, paypal_request)
|
104
|
+
self.send _paypal_method_name(key), paypal_request
|
105
|
+
end
|
106
|
+
|
107
|
+
def _paypal_method_name(key)
|
108
|
+
"payment_event_#{key}".to_sym
|
109
|
+
end
|
110
|
+
|
94
111
|
end
|
95
112
|
|
96
113
|
|
@@ -83,6 +83,7 @@ class PaypalRequest
|
|
83
83
|
# payment.username # => reednj
|
84
84
|
#
|
85
85
|
def username
|
86
|
+
return nil if !custom_data?
|
86
87
|
self.custom_data[:username]
|
87
88
|
end
|
88
89
|
|
@@ -96,10 +97,10 @@ class PaypalRequest
|
|
96
97
|
# Note that this field can be modified by the user before submitting the form,
|
97
98
|
# so you should verify the contents of it before using it.
|
98
99
|
#
|
99
|
-
#
|
100
|
+
# payment.custom_data # => { :username => 'dave' }
|
100
101
|
#
|
101
102
|
def custom_data
|
102
|
-
if @custom_data.nil?
|
103
|
+
if @custom_data.nil? && !@fields[:custom].nil?
|
103
104
|
if @fields[:custom].strip.start_with? '{'
|
104
105
|
# we could get a json object through, in which case it needs to be parsed...
|
105
106
|
@custom_data = JSON.parse(@fields[:custom], {:symbolize_names => true})
|
@@ -113,9 +114,8 @@ class PaypalRequest
|
|
113
114
|
return @custom_data
|
114
115
|
end
|
115
116
|
|
116
|
-
|
117
|
-
|
118
|
-
custom_data
|
117
|
+
def custom_data?
|
118
|
+
!custom_data.nil?
|
119
119
|
end
|
120
120
|
|
121
121
|
# The payment status. The most common is Completed, but you might also see
|
@@ -126,7 +126,7 @@ class PaypalRequest
|
|
126
126
|
# - Canceled_Reversal
|
127
127
|
# - Completed
|
128
128
|
#
|
129
|
-
#
|
129
|
+
# payment.status # => Pending
|
130
130
|
#
|
131
131
|
def status
|
132
132
|
@fields[:payment_status]
|
@@ -198,6 +198,9 @@ class PaypalRequest
|
|
198
198
|
def fields
|
199
199
|
@fields
|
200
200
|
end
|
201
|
+
|
202
|
+
alias_method :data, :custom_data
|
203
|
+
alias_method :accountable?, :is_accountable?
|
201
204
|
end
|
202
205
|
|
203
206
|
# extensions needed for the paypal request to work
|
data/test/app.rb
CHANGED
@@ -4,6 +4,7 @@ Bundler.require
|
|
4
4
|
|
5
5
|
require 'sinatra'
|
6
6
|
require 'sinatra/paypal'
|
7
|
+
require 'fileutils'
|
7
8
|
|
8
9
|
# this allows us to handle errors in test without the default page
|
9
10
|
# getting generated (which isn't very useful inside unit-tests)
|
@@ -19,15 +20,18 @@ error do
|
|
19
20
|
end
|
20
21
|
|
21
22
|
payment :repeated? do |p|
|
22
|
-
path = '
|
23
|
+
path = 'test.sinatra-payment.log'
|
24
|
+
path = File.join '/tmp', path if !Gem.win_platform?
|
25
|
+
FileUtils.touch path if !File.exist? path
|
26
|
+
|
23
27
|
data = File.read path
|
24
28
|
id = "#{p.id}\n"
|
25
29
|
|
26
30
|
if data.include? id
|
27
|
-
true
|
31
|
+
return true
|
28
32
|
else
|
29
33
|
File.append path, "#{p.id}\n"
|
30
|
-
false
|
34
|
+
return false
|
31
35
|
end
|
32
36
|
end
|
33
37
|
|
data/test/form_test.rb
CHANGED
@@ -52,6 +52,7 @@ class RedditStreamTest < Test::Unit::TestCase
|
|
52
52
|
get '/payment/form/empty'
|
53
53
|
assert last_response.ok?, page_error('could not generate payment form')
|
54
54
|
assert last_response.body.include?(app.paypal.email), 'account email not found in form'
|
55
|
+
assert !last_response.body.include?('"username":'), 'should not include username custom_data by default'
|
55
56
|
end
|
56
57
|
|
57
58
|
def test_form_helper_with_item
|
@@ -69,7 +70,7 @@ class RedditStreamTest < Test::Unit::TestCase
|
|
69
70
|
|
70
71
|
code = 'ITEM-0'
|
71
72
|
desc = 'item description'
|
72
|
-
get '/payment/form', { :item_code => code, :item_price => '5.00', :item_name => desc}
|
73
|
+
get '/payment/form', { :item_code => code, :item_price => '5.00', :item_name => desc }
|
73
74
|
assert last_response.ok?, page_error('could not generate payment form')
|
74
75
|
assert last_response.body.include?(app.paypal.email), 'account email not found in form'
|
75
76
|
assert last_response.body.include?(code), 'item_code not found in form'
|
data/test/paypal_test.rb
CHANGED
@@ -99,7 +99,7 @@ class RedditStreamTest < Test::Unit::TestCase
|
|
99
99
|
}.to_json
|
100
100
|
|
101
101
|
post '/payment/validate', data
|
102
|
-
|
102
|
+
assert last_response.ok?, page_error("Payment not accepted")
|
103
103
|
end
|
104
104
|
|
105
105
|
def test_payment_accepted_json_custom_data
|
@@ -112,10 +112,32 @@ class RedditStreamTest < Test::Unit::TestCase
|
|
112
112
|
|
113
113
|
def test_payment_accepted
|
114
114
|
data = standard_payment_data
|
115
|
-
|
115
|
+
post '/payment/validate', data
|
116
|
+
assert last_response.ok?, page_error("Payment not accepted")
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_payment_accepted_no_custom_data
|
120
|
+
data = standard_payment_data
|
121
|
+
data[:custom] = nil
|
116
122
|
|
117
123
|
post '/payment/validate', data
|
118
124
|
assert last_response.ok?, page_error("Payment not accepted")
|
125
|
+
|
126
|
+
data[:custom] = '{}'
|
127
|
+
post '/payment/validate', data
|
128
|
+
assert last_response.ok?, page_error("Payment not accepted")
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_invalid_callbacks_error
|
132
|
+
ex = false
|
133
|
+
begin
|
134
|
+
app.payment :fake_callback do |p|
|
135
|
+
end
|
136
|
+
rescue => e
|
137
|
+
ex = true
|
138
|
+
end
|
139
|
+
|
140
|
+
assert ex, 'callback did not raise exception'
|
119
141
|
end
|
120
142
|
|
121
143
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinatra-paypal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Reed
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|