adyen 1.3.1 → 1.3.2
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/.travis.yml +12 -2
- data/adyen.gemspec +3 -3
- data/lib/adyen.rb +1 -1
- data/lib/adyen/api.rb +8 -2
- data/lib/adyen/api/recurring_service.rb +6 -7
- data/lib/adyen/configuration.rb +19 -11
- data/lib/adyen/form.rb +139 -43
- data/lib/adyen/templates/notification_migration.rb +1 -1
- data/lib/adyen/templates/notification_model.rb +16 -15
- data/spec/api/recurring_service_spec.rb +19 -2
- data/spec/api/spec_helper.rb +15 -0
- data/spec/form_spec.rb +103 -18
- metadata +67 -80
data/.travis.yml
CHANGED
@@ -1,9 +1,19 @@
|
|
1
1
|
language: ruby
|
2
|
+
script: bundle exec rake
|
2
3
|
rvm:
|
3
4
|
- 1.8.7
|
4
5
|
- 1.9.2
|
5
6
|
- 1.9.3
|
6
7
|
- ruby-head
|
7
8
|
- ree
|
8
|
-
- rbx
|
9
|
-
-
|
9
|
+
- rbx-18mode
|
10
|
+
- rbx-19mode
|
11
|
+
- jruby-18mode
|
12
|
+
- jruby-19mode
|
13
|
+
- jruby-head
|
14
|
+
matrix:
|
15
|
+
allow_failures:
|
16
|
+
- rvm: rbx-19mode
|
17
|
+
- rvm: jruby-19mode
|
18
|
+
- rvm: jruby-head
|
19
|
+
- rvm: ruby-head
|
data/adyen.gemspec
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'adyen'
|
3
|
-
s.version = "1.3.
|
4
|
-
s.date = "
|
3
|
+
s.version = "1.3.2"
|
4
|
+
s.date = "2013-01-14"
|
5
5
|
|
6
6
|
s.summary = "Integrate Adyen payment services in your Ruby on Rails application."
|
7
7
|
s.description = <<-EOS
|
8
8
|
Package to simplify including the Adyen payments services into a Ruby on Rails application.
|
9
9
|
The package provides functionality to create payment forms, handling and storing notifications
|
10
10
|
sent by Adyen and consuming the SOAP services provided by Adyen. Moreover, it contains helper
|
11
|
-
methods, mocks and matchers to simpify writing tests/
|
11
|
+
methods, mocks and matchers to simpify writing tests/specs for your code.
|
12
12
|
EOS
|
13
13
|
|
14
14
|
s.authors = ['Willem van Bergen', 'Michel Barbosa', 'Stefan Borsje', 'Eloy Duran']
|
data/lib/adyen.rb
CHANGED
@@ -12,7 +12,7 @@ module Adyen
|
|
12
12
|
# Version constant for the Adyen plugin.
|
13
13
|
# DO NOT CHANGE THIS VALUE BY HAND. It will be updated automatically by
|
14
14
|
# the gem:release rake task.
|
15
|
-
VERSION = "1.3.
|
15
|
+
VERSION = "1.3.2"
|
16
16
|
|
17
17
|
# @return [Configuration] The configuration singleton.
|
18
18
|
def self.configuration
|
data/lib/adyen/api.rb
CHANGED
@@ -20,8 +20,14 @@ module Adyen
|
|
20
20
|
# * {RecurringService} - for handling recurring contract details.
|
21
21
|
#
|
22
22
|
# *However*, direct use of these classes is discouraged in favor of the shortcut methods defined
|
23
|
-
# on the API module. These methods *
|
24
|
-
# parameter
|
23
|
+
# on the API module. These methods *require* that you set the :merchant_account *beforehand* as
|
24
|
+
# a default parameter passed in all API calls:
|
25
|
+
#
|
26
|
+
# Adyen.configuration.default_api_params[:merchant_account] = 'MerchantAccount'
|
27
|
+
#
|
28
|
+
# For Rails apps, you can also set it `application.rb` config block, like this:
|
29
|
+
#
|
30
|
+
# config.adyen.default_api_params = { :merchant_account => 'MerchantAccount' }
|
25
31
|
#
|
26
32
|
# Note that you'll need an Adyen notification PSP reference for some of the calls. Because of
|
27
33
|
# this, store all notifications that Adyen sends to you. Moreover, the responses to these calls
|
@@ -96,7 +96,7 @@ module Adyen
|
|
96
96
|
response_attrs :details, :last_known_shopper_email, :shopper_reference, :creation_date
|
97
97
|
|
98
98
|
def references
|
99
|
-
details.map { |d| d[:recurring_detail_reference] }
|
99
|
+
details ? details.map { |d| d[:recurring_detail_reference] } : []
|
100
100
|
end
|
101
101
|
|
102
102
|
def params
|
@@ -113,7 +113,6 @@ module Adyen
|
|
113
113
|
|
114
114
|
private
|
115
115
|
|
116
|
-
# @todo add support for elv
|
117
116
|
def parse_recurring_detail(node)
|
118
117
|
result = {
|
119
118
|
:recurring_detail_reference => node.text('./recurring:recurringDetailReference'),
|
@@ -146,11 +145,11 @@ module Adyen
|
|
146
145
|
|
147
146
|
def parse_elv_details(elv)
|
148
147
|
{
|
149
|
-
:holder_name =>
|
150
|
-
:number =>
|
151
|
-
:bank_location =>
|
152
|
-
:bank_location_id =>
|
153
|
-
:bank_name =>
|
148
|
+
:holder_name => elv.text('./payment:accountHolderName'),
|
149
|
+
:number => elv.text('./payment:bankAccountNumber'),
|
150
|
+
:bank_location => elv.text('./payment:bankLocation'),
|
151
|
+
:bank_location_id => elv.text('./payment:bankLocationId'),
|
152
|
+
:bank_name => elv.text('./payment:bankName')
|
154
153
|
}
|
155
154
|
end
|
156
155
|
|
data/lib/adyen/configuration.rb
CHANGED
@@ -36,11 +36,11 @@ class Adyen::Configuration
|
|
36
36
|
elsif defined?(::RAILS_ENV)
|
37
37
|
::RAILS_ENV.to_s
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
LIVE_RAILS_ENVIRONMENTS.include?(rails_env) ? 'live' : 'test'
|
41
41
|
end
|
42
|
-
|
43
|
-
# The payment flow
|
42
|
+
|
43
|
+
# The payment flow page type that’s used to choose the payment process
|
44
44
|
#
|
45
45
|
# @example
|
46
46
|
# Adyen.configuration.payment_flow = :select
|
@@ -49,7 +49,15 @@ class Adyen::Configuration
|
|
49
49
|
#
|
50
50
|
# @return [String]
|
51
51
|
attr_accessor :payment_flow
|
52
|
-
|
52
|
+
|
53
|
+
# The payment flow domain that’s used to choose the payment process
|
54
|
+
#
|
55
|
+
# @example
|
56
|
+
# Adyen.configuration.payment_flow_domain = checkout.mydomain.com
|
57
|
+
#
|
58
|
+
# @return [String]
|
59
|
+
attr_accessor :payment_flow_domain
|
60
|
+
|
53
61
|
# The username that’s used to authenticate for the Adyen SOAP services. It should look
|
54
62
|
# something like ‘+ws@AndyInc.SuperShop+’
|
55
63
|
#
|
@@ -78,13 +86,13 @@ class Adyen::Configuration
|
|
78
86
|
#
|
79
87
|
# @return [Hash]
|
80
88
|
attr_accessor :default_form_params
|
81
|
-
|
82
|
-
# Username that's set in Notification settings screen in Adyen PSP system and used by notification service to
|
89
|
+
|
90
|
+
# Username that's set in Notification settings screen in Adyen PSP system and used by notification service to
|
83
91
|
# authenticate instant payment notification requests.
|
84
92
|
#
|
85
93
|
# @return [String]
|
86
94
|
attr_accessor :ipn_username
|
87
|
-
|
95
|
+
|
88
96
|
# Password used to authenticate notification requests together with '+ipn_username+' configuration attribute.
|
89
97
|
#
|
90
98
|
# @return [String]
|
@@ -98,10 +106,10 @@ class Adyen::Configuration
|
|
98
106
|
#
|
99
107
|
# @return [Hash] The hash of registered skins.
|
100
108
|
attr_reader :form_skins
|
101
|
-
|
109
|
+
|
102
110
|
# Sets the registered skins.
|
103
111
|
#
|
104
|
-
# @param [Hash<Symbol, Hash>] hash A hash with the skin name as key and the skin parameter hash
|
112
|
+
# @param [Hash<Symbol, Hash>] hash A hash with the skin name as key and the skin parameter hash
|
105
113
|
# (which should include +:skin_code+ and +:shared_secret+) as value.
|
106
114
|
#
|
107
115
|
# @see Adyen::Configuration.register_form_skin
|
@@ -125,8 +133,8 @@ class Adyen::Configuration
|
|
125
133
|
# @param [Symbol] name The name of the skin.
|
126
134
|
# @param [String] skin_code The skin code for this skin, as defined by Adyen.
|
127
135
|
# @param [String] shared_secret The shared secret used for signature calculation.
|
128
|
-
def register_form_skin(name, skin_code, shared_secret)
|
129
|
-
@form_skins[name.to_sym] = { :name => name.to_sym, :skin_code => skin_code, :shared_secret => shared_secret }
|
136
|
+
def register_form_skin(name, skin_code, shared_secret, default_form_params = {})
|
137
|
+
@form_skins[name.to_sym] = { :name => name.to_sym, :skin_code => skin_code, :shared_secret => shared_secret, :default_form_params => default_form_params}
|
130
138
|
end
|
131
139
|
|
132
140
|
# Returns a skin information by name.
|
data/lib/adyen/form.rb
CHANGED
@@ -2,8 +2,8 @@ require 'cgi'
|
|
2
2
|
|
3
3
|
module Adyen
|
4
4
|
|
5
|
-
# The Adyen::Form module contains all functionality that is used to send payment requests
|
6
|
-
# to the Adyen payment system, using either a HTML form (see {Adyen::Form.hidden_fields})
|
5
|
+
# The Adyen::Form module contains all functionality that is used to send payment requests
|
6
|
+
# to the Adyen payment system, using either a HTML form (see {Adyen::Form.hidden_fields})
|
7
7
|
# or a HTTP redirect (see {Adyen::Form.redirect_url}).
|
8
8
|
#
|
9
9
|
# Moreover, this module contains the method {Adyen::Form.redirect_signature_check} to
|
@@ -12,7 +12,7 @@ module Adyen
|
|
12
12
|
#
|
13
13
|
# You can use different skins in Adyen to define different payment environments. You can
|
14
14
|
# register these skins under a custom name in the module. The other methods will automatically
|
15
|
-
# use this information (i.e. the skin code and the shared secret) if it is available.
|
15
|
+
# use this information (i.e. the skin code and the shared secret) if it is available.
|
16
16
|
# Otherwise, you have to provide it yourself for every method call you make. See
|
17
17
|
# {Adyen::Configuration#register_form_skin} for more information.
|
18
18
|
#
|
@@ -27,22 +27,41 @@ module Adyen
|
|
27
27
|
# ADYEN FORM URL
|
28
28
|
######################################################
|
29
29
|
|
30
|
+
# The DOMAIN of the Adyen payment system that still requires the current
|
31
|
+
# Adyen enviroment.
|
32
|
+
ACTION_DOMAIN = "%s.adyen.com"
|
33
|
+
|
30
34
|
# The URL of the Adyen payment system that still requires the current
|
31
|
-
#
|
32
|
-
ACTION_URL = "https://%s
|
35
|
+
# domain and payment flow to be filled.
|
36
|
+
ACTION_URL = "https://%s/hpp/%s.shtml"
|
37
|
+
|
38
|
+
# Returns the DOMAIN of the Adyen payment system, adjusted for an Adyen environment.
|
39
|
+
#
|
40
|
+
# @param [String] environment The Adyen environment to use. This parameter can be
|
41
|
+
# left out, in which case the 'current' environment will be used.
|
42
|
+
# @return [String] The domain of the Adyen payment system that can be used
|
43
|
+
# for payment forms or redirects.
|
44
|
+
# @see Adyen::Form.environment
|
45
|
+
# @see Adyen::Form.redirect_url
|
46
|
+
def domain(environment = nil)
|
47
|
+
environment ||= Adyen.configuration.environment
|
48
|
+
(Adyen.configuration.payment_flow_domain || ACTION_DOMAIN) % [environment.to_s]
|
49
|
+
end
|
33
50
|
|
34
51
|
# Returns the URL of the Adyen payment system, adjusted for an Adyen environment.
|
35
52
|
#
|
36
|
-
# @param [String] environment The Adyen environment to use. This parameter can be
|
53
|
+
# @param [String] environment The Adyen environment to use. This parameter can be
|
37
54
|
# left out, in which case the 'current' environment will be used.
|
55
|
+
# @param [String] payment_flow The Adyen payment type to use. This parameter can be
|
56
|
+
# left out, in which case the default payment type will be used.
|
38
57
|
# @return [String] The absolute URL of the Adyen payment system that can be used
|
39
58
|
# for payment forms or redirects.
|
40
59
|
# @see Adyen::Form.environment
|
60
|
+
# @see Adyen::Form.domain
|
41
61
|
# @see Adyen::Form.redirect_url
|
42
62
|
def url(environment = nil, payment_flow = nil)
|
43
|
-
environment ||= Adyen.configuration.environment
|
44
63
|
payment_flow ||= Adyen.configuration.payment_flow
|
45
|
-
Adyen::Form::ACTION_URL % [environment
|
64
|
+
Adyen::Form::ACTION_URL % [domain(environment), payment_flow.to_s]
|
46
65
|
end
|
47
66
|
|
48
67
|
######################################################
|
@@ -58,22 +77,24 @@ module Adyen
|
|
58
77
|
# @param [Hash] parameters The payment parameters hash to transform
|
59
78
|
def do_parameter_transformations!(parameters = {})
|
60
79
|
parameters.replace(Adyen.configuration.default_form_params.merge(parameters))
|
61
|
-
|
62
|
-
parameters[:order_data] = Adyen::Encoding.gzip_base64(parameters.delete(:order_data_raw)) if parameters[:order_data_raw]
|
63
|
-
parameters[:ship_before_date] = Adyen::Formatter::DateTime.fmt_date(parameters[:ship_before_date])
|
64
|
-
parameters[:session_validity] = Adyen::Formatter::DateTime.fmt_time(parameters[:session_validity])
|
65
|
-
|
80
|
+
|
66
81
|
if parameters[:skin]
|
67
82
|
skin = Adyen.configuration.form_skin_by_name(parameters.delete(:skin))
|
68
83
|
parameters[:skin_code] ||= skin[:skin_code]
|
69
84
|
parameters[:shared_secret] ||= skin[:shared_secret]
|
85
|
+
parameters.merge!(skin[:default_form_params])
|
70
86
|
end
|
87
|
+
|
88
|
+
parameters[:recurring_contract] = 'RECURRING' if parameters.delete(:recurring) == true
|
89
|
+
parameters[:order_data] = Adyen::Encoding.gzip_base64(parameters.delete(:order_data_raw)) if parameters[:order_data_raw]
|
90
|
+
parameters[:ship_before_date] = Adyen::Formatter::DateTime.fmt_date(parameters[:ship_before_date])
|
91
|
+
parameters[:session_validity] = Adyen::Formatter::DateTime.fmt_time(parameters[:session_validity])
|
71
92
|
end
|
72
93
|
|
73
94
|
# Transforms the payment parameters to be in the correct format and calculates the merchant
|
74
95
|
# signature parameter. It also does some basic health checks on the parameters hash.
|
75
96
|
#
|
76
|
-
# @param [Hash] parameters The payment parameters. The parameters set in the
|
97
|
+
# @param [Hash] parameters The payment parameters. The parameters set in the
|
77
98
|
# {Adyen::Configuration#default_form_params} hash will be included automatically.
|
78
99
|
# @param [String] shared_secret The shared secret that should be used to calculate
|
79
100
|
# the payment request signature. This parameter can be left if the skin that is
|
@@ -83,7 +104,7 @@ module Adyen
|
|
83
104
|
# @raise [ArgumentError] Thrown if some parameter health check fails.
|
84
105
|
def payment_parameters(parameters = {}, shared_secret = nil)
|
85
106
|
do_parameter_transformations!(parameters)
|
86
|
-
|
107
|
+
|
87
108
|
raise ArgumentError, "Cannot generate form: :currency code attribute not found!" unless parameters[:currency_code]
|
88
109
|
raise ArgumentError, "Cannot generate form: :payment_amount code attribute not found!" unless parameters[:payment_amount]
|
89
110
|
raise ArgumentError, "Cannot generate form: :merchant_account attribute not found!" unless parameters[:merchant_account]
|
@@ -93,14 +114,27 @@ module Adyen
|
|
93
114
|
shared_secret ||= parameters.delete(:shared_secret)
|
94
115
|
raise ArgumentError, "Cannot calculate payment request signature without shared secret!" unless shared_secret
|
95
116
|
parameters[:merchant_sig] = calculate_signature(parameters, shared_secret)
|
96
|
-
|
117
|
+
|
118
|
+
if parameters[:billing_address]
|
119
|
+
parameters[:billing_address_sig] = calculate_billing_address_signature(parameters, shared_secret)
|
120
|
+
end
|
121
|
+
|
97
122
|
return parameters
|
98
123
|
end
|
99
|
-
|
124
|
+
|
125
|
+
# Transforms and flattens payment parameters to be in the correct format which is understood and accepted by adyen
|
126
|
+
#
|
127
|
+
# @param [Hash] parameters The payment parameters. The parameters set in the
|
128
|
+
# {Adyen::Configuration#default_form_params} hash will be included automatically.
|
129
|
+
# @return [Hash] The payment parameters flatten, with camelized and prefixed key, stringified value
|
130
|
+
def flat_payment_parameters(parameters = {})
|
131
|
+
flatten(payment_parameters(parameters))
|
132
|
+
end
|
133
|
+
|
100
134
|
# Returns an absolute URL to the Adyen payment system, with the payment parameters included
|
101
135
|
# as GET parameters in the URL. The URL also depends on the current Adyen enviroment.
|
102
136
|
#
|
103
|
-
# The payment parameters that are provided to this method will be merged with the
|
137
|
+
# The payment parameters that are provided to this method will be merged with the
|
104
138
|
# {Adyen::Configuration#default_form_params} hash. The default parameter values will be
|
105
139
|
# overrided if another value is provided to this method.
|
106
140
|
#
|
@@ -108,7 +142,7 @@ module Adyen
|
|
108
142
|
# if you provide either a registered skin name as the +:skin+ parameter or provide both the
|
109
143
|
# +:skin_code+ and +:shared_secret+ parameters.
|
110
144
|
#
|
111
|
-
# Note that Internet Explorer has a maximum length for URLs it can handle (2083 characters).
|
145
|
+
# Note that Internet Explorer has a maximum length for URLs it can handle (2083 characters).
|
112
146
|
# Make sure that the URL is not longer than this limit if you want your site to work in IE.
|
113
147
|
#
|
114
148
|
# @example
|
@@ -117,7 +151,7 @@ module Adyen
|
|
117
151
|
# # Genarate a URL to redirect to Adyen's payment system.
|
118
152
|
# adyen_url = Adyen::Form.redirect_url(:skin => :my_skin, :currency_code => 'USD',
|
119
153
|
# :payment_amount => 1000, merchant_account => 'MyMerchant', ... )
|
120
|
-
#
|
154
|
+
#
|
121
155
|
# respond_to do |format|
|
122
156
|
# format.html { redirect_to(adyen_url) }
|
123
157
|
# end
|
@@ -126,14 +160,15 @@ module Adyen
|
|
126
160
|
# @param [Hash] parameters The payment parameters to include in the payment request.
|
127
161
|
# @return [String] An absolute URL to redirect to the Adyen payment system.
|
128
162
|
def redirect_url(parameters = {})
|
129
|
-
url + '?' +
|
130
|
-
"#{
|
163
|
+
url + '?' + flat_payment_parameters(parameters).map { |(k, v)|
|
164
|
+
"#{k}=#{CGI.escape(v)}"
|
165
|
+
}.join('&')
|
131
166
|
end
|
132
|
-
|
133
|
-
# Returns a HTML snippet of hidden INPUT tags with the provided payment parameters.
|
167
|
+
|
168
|
+
# Returns a HTML snippet of hidden INPUT tags with the provided payment parameters.
|
134
169
|
# The snippet can be included in a payment form that POSTs to the Adyen payment system.
|
135
170
|
#
|
136
|
-
# The payment parameters that are provided to this method will be merged with the
|
171
|
+
# The payment parameters that are provided to this method will be merged with the
|
137
172
|
# {Adyen::Configuration#default_form_params} hash. The default parameter values will be
|
138
173
|
# overrided if another value is provided to this method.
|
139
174
|
#
|
@@ -152,15 +187,15 @@ module Adyen
|
|
152
187
|
# @return [String] An HTML snippet that can be included in a form that POSTs to the
|
153
188
|
# Adyen payment system.
|
154
189
|
def hidden_fields(parameters = {})
|
155
|
-
|
190
|
+
|
156
191
|
# Generate a hidden input tag per parameter, join them by newlines.
|
157
|
-
form_str =
|
158
|
-
"<input type=\"hidden\" name=\"#{CGI.escapeHTML(
|
192
|
+
form_str = flat_payment_parameters(parameters).map { |key, value|
|
193
|
+
"<input type=\"hidden\" name=\"#{CGI.escapeHTML(key)}\" value=\"#{CGI.escapeHTML(value)}\" />"
|
159
194
|
}.join("\n")
|
160
|
-
|
195
|
+
|
161
196
|
form_str.respond_to?(:html_safe) ? form_str.html_safe : form_str
|
162
197
|
end
|
163
|
-
|
198
|
+
|
164
199
|
######################################################
|
165
200
|
# MERCHANT SIGNATURE CALCULATION
|
166
201
|
######################################################
|
@@ -181,7 +216,7 @@ module Adyen
|
|
181
216
|
parameters[:billing_address_type].to_s << parameters[:offset].to_s
|
182
217
|
end
|
183
218
|
|
184
|
-
# Calculates the payment request signature for the given payment parameters.
|
219
|
+
# Calculates the payment request signature for the given payment parameters.
|
185
220
|
#
|
186
221
|
# This signature is used by Adyen to check whether the request is
|
187
222
|
# genuinely originating from you. The resulting signature should be
|
@@ -190,15 +225,47 @@ module Adyen
|
|
190
225
|
#
|
191
226
|
# @param [Hash] parameters The payment parameters for which to calculate
|
192
227
|
# the payment request signature.
|
193
|
-
# @param [String] shared_secret The shared secret to use for this signature.
|
194
|
-
# It should correspond with the skin_code parameter. This parameter can be
|
228
|
+
# @param [String] shared_secret The shared secret to use for this signature.
|
229
|
+
# It should correspond with the skin_code parameter. This parameter can be
|
195
230
|
# left out if the shared_secret is included as key in the parameters.
|
196
231
|
# @return [String] The signature of the payment request
|
232
|
+
# @raise [ArgumentError] Thrown if shared_secret is empty
|
197
233
|
def calculate_signature(parameters, shared_secret = nil)
|
198
234
|
shared_secret ||= parameters.delete(:shared_secret)
|
235
|
+
raise ArgumentError, "Cannot calculate payment request signature with empty shared_secret" if shared_secret.to_s.empty?
|
199
236
|
Adyen::Encoding.hmac_base64(shared_secret, calculate_signature_string(parameters))
|
200
237
|
end
|
201
238
|
|
239
|
+
# Generates the string that is used to calculate the request signature. This signature
|
240
|
+
# is used by Adyen to check whether the request is genuinely originating from you.
|
241
|
+
# @param [Hash] parameters The parameters that will be included in the billing address request.
|
242
|
+
# @return [String] The string for which the siganture is calculated.
|
243
|
+
def calculate_billing_address_signature_string(parameters)
|
244
|
+
%w(street house_number_or_name city postal_code state_or_province country).map do |key|
|
245
|
+
parameters[key.to_sym]
|
246
|
+
end.join
|
247
|
+
end
|
248
|
+
|
249
|
+
# Calculates the billing address request signature for the given billing address parameters.
|
250
|
+
#
|
251
|
+
# This signature is used by Adyen to check whether the request is
|
252
|
+
# genuinely originating from you. The resulting signature should be
|
253
|
+
# included in the billing address request parameters as the +billingAddressSig+
|
254
|
+
# parameter; the shared secret should of course not be included.
|
255
|
+
#
|
256
|
+
# @param [Hash] parameters The billing address parameters for which to calculate
|
257
|
+
# the billing address request signature.
|
258
|
+
# @param [String] shared_secret The shared secret to use for this signature.
|
259
|
+
# It should correspond with the skin_code parameter. This parameter can be
|
260
|
+
# left out if the shared_secret is included as key in the parameters.
|
261
|
+
# @return [String] The signature of the billing address request
|
262
|
+
# @raise [ArgumentError] Thrown if shared_secret is empty
|
263
|
+
def calculate_billing_address_signature(parameters, shared_secret = nil)
|
264
|
+
shared_secret ||= parameters.delete(:shared_secret)
|
265
|
+
raise ArgumentError, "Cannot calculate billing address request signature with empty shared_secret" if shared_secret.to_s.empty?
|
266
|
+
Adyen::Encoding.hmac_base64(shared_secret, calculate_billing_address_signature_string(parameters[:billing_address]))
|
267
|
+
end
|
268
|
+
|
202
269
|
######################################################
|
203
270
|
# REDIRECT SIGNATURE CHECKING
|
204
271
|
######################################################
|
@@ -207,20 +274,22 @@ module Adyen
|
|
207
274
|
# @param [Hash] params A hash of HTTP GET parameters for the redirect request.
|
208
275
|
# @return [String] The signature string.
|
209
276
|
def redirect_signature_string(params)
|
210
|
-
params[:authResult].to_s + params[:pspReference].to_s + params[:merchantReference].to_s +
|
277
|
+
params[:authResult].to_s + params[:pspReference].to_s + params[:merchantReference].to_s +
|
211
278
|
params[:skinCode].to_s + params[:merchantReturnData].to_s
|
212
279
|
end
|
213
|
-
|
214
|
-
# Computes the redirect signature using the request parameters, so that the
|
280
|
+
|
281
|
+
# Computes the redirect signature using the request parameters, so that the
|
215
282
|
# redirect can be checked for forgery.
|
216
283
|
#
|
217
284
|
# @param [Hash] params A hash of HTTP GET parameters for the redirect request.
|
218
285
|
# @param [String] shared_secret The shared secret for the Adyen skin that was used for
|
219
|
-
# the original payment form. You can leave this out of the skin is registered
|
286
|
+
# the original payment form. You can leave this out of the skin is registered
|
220
287
|
# using the {Adyen::Form.register_skin} method.
|
221
288
|
# @return [String] The redirect signature
|
289
|
+
# @raise [ArgumentError] Thrown if shared_secret is empty
|
222
290
|
def redirect_signature(params, shared_secret = nil)
|
223
291
|
shared_secret ||= Adyen.configuration.form_skin_shared_secret_by_code(params[:skinCode])
|
292
|
+
raise ArgumentError, "Cannot compute redirect signature with empty shared_secret" if shared_secret.to_s.empty?
|
224
293
|
Adyen::Encoding.hmac_base64(shared_secret, redirect_signature_string(params))
|
225
294
|
end
|
226
295
|
|
@@ -235,14 +304,14 @@ module Adyen
|
|
235
304
|
# @example
|
236
305
|
# class PaymentsController < ApplicationController
|
237
306
|
# before_filter :check_signature, :only => [:return_from_adyen]
|
238
|
-
#
|
307
|
+
#
|
239
308
|
# def return_from_adyen
|
240
309
|
# @invoice = Invoice.find(params[:merchantReference])
|
241
310
|
# @invoice.set_paid! if params[:authResult] == 'AUTHORISED'
|
242
311
|
# end
|
243
|
-
#
|
312
|
+
#
|
244
313
|
# private
|
245
|
-
#
|
314
|
+
#
|
246
315
|
# def check_signature
|
247
316
|
# raise "Forgery!" unless Adyen::Form.redirect_signature_check(params)
|
248
317
|
# end
|
@@ -251,19 +320,46 @@ module Adyen
|
|
251
320
|
# @param [Hash] params params A hash of HTTP GET parameters for the redirect request. This
|
252
321
|
# should include the +:merchantSig+ parameter, which contains the signature.
|
253
322
|
# @param [String] shared_secret The shared secret for the Adyen skin that was used for
|
254
|
-
# the original payment form. You can leave this out of the skin is registered
|
323
|
+
# the original payment form. You can leave this out of the skin is registered
|
255
324
|
# using the {Adyen::Configuration#register_form_skin} method.
|
256
325
|
# @return [true, false] Returns true only if the signature in the parameters is correct.
|
257
326
|
def redirect_signature_check(params, shared_secret = nil)
|
258
327
|
params[:merchantSig] == redirect_signature(params, shared_secret)
|
259
328
|
end
|
260
|
-
|
329
|
+
|
261
330
|
# Returns the camelized version of a string.
|
262
331
|
# @param [:to_s] identifier The identifier to turn to camelcase
|
263
332
|
# @return [String] The camelcase version of the identifier provided.
|
264
333
|
def camelize(identifier)
|
265
334
|
identifier.to_s.gsub(/_(.)/) { $1.upcase }
|
266
335
|
end
|
267
|
-
|
336
|
+
|
337
|
+
# Transforms the nested parameters Hash into a 'flat' Hash which is understood by adyen. This is:
|
338
|
+
# * all keys are camelized
|
339
|
+
# * all keys are stringified
|
340
|
+
# * nested hash is flattened, keys are prefixed with root key
|
341
|
+
#
|
342
|
+
# @example
|
343
|
+
# flatten {:billing_address => { :street => 'My Street'}}
|
344
|
+
#
|
345
|
+
# # resolves in:
|
346
|
+
# {'billingAddress.street' => 'My Street'}
|
347
|
+
#
|
348
|
+
# @param [Hash] parameters The payment parameters which to transform
|
349
|
+
# @param [String] prefix The prefix to add to the key
|
350
|
+
# @param [Hash] return_hash The new hash which is retruned (needed for recursive calls)
|
351
|
+
# @return [Hash] The return_hash filled with camelized and prefixed key, stringified value
|
352
|
+
def flatten(parameters, prefix = "", return_hash = {})
|
353
|
+
parameters ||= {}
|
354
|
+
parameters.inject(return_hash) do |hash, (key, value)|
|
355
|
+
key = "#{prefix}#{camelize(key)}"
|
356
|
+
if value.is_a?(Hash)
|
357
|
+
flatten(value, "#{key}.", return_hash)
|
358
|
+
else
|
359
|
+
hash[key] = value.to_s
|
360
|
+
end
|
361
|
+
hash
|
362
|
+
end
|
363
|
+
end
|
268
364
|
end
|
269
365
|
end
|
@@ -5,7 +5,7 @@ class CreateAdyenNotifications < ActiveRecord::Migration
|
|
5
5
|
create_table :adyen_notifications do |t|
|
6
6
|
t.boolean :live, :null => false, :default => false
|
7
7
|
t.string :event_code, :null => false, :limit => 20
|
8
|
-
t.string :psp_reference, :null => false, :limit =>
|
8
|
+
t.string :psp_reference, :null => false, :limit => 50
|
9
9
|
t.string :original_reference, :null => true
|
10
10
|
t.string :merchant_reference, :null => false
|
11
11
|
t.string :merchant_account_code, :null => false
|
@@ -16,20 +16,20 @@
|
|
16
16
|
# @invoice.set_paid!
|
17
17
|
# end
|
18
18
|
class AdyenNotification < ActiveRecord::Base
|
19
|
-
|
19
|
+
|
20
20
|
# A notification should always include an event_code
|
21
21
|
validates_presence_of :event_code
|
22
|
-
|
22
|
+
|
23
23
|
# A notification should always include a psp_reference
|
24
24
|
validates_presence_of :psp_reference
|
25
|
-
|
25
|
+
|
26
26
|
# A notification should be unique using the composed key of
|
27
27
|
# [:psp_reference, :event_code, :success]
|
28
28
|
validates_uniqueness_of :success, :scope => [:psp_reference, :event_code]
|
29
|
-
|
29
|
+
|
30
30
|
# Make sure we don't end up with an original_reference with an empty string
|
31
31
|
before_validation { |notification| notification.original_reference = nil if notification.original_reference.blank? }
|
32
|
-
|
32
|
+
|
33
33
|
# Logs an incoming notification into the database.
|
34
34
|
#
|
35
35
|
# @param [Hash] params The notification parameters that should be stored in the database.
|
@@ -38,15 +38,16 @@ class AdyenNotification < ActiveRecord::Base
|
|
38
38
|
# @see Adyen::Notification::HttpPost.log
|
39
39
|
def self.log(params)
|
40
40
|
converted_params = {}
|
41
|
-
|
42
|
-
#
|
41
|
+
|
42
|
+
# Assign explicit each attribute from CamelCase notation to notification
|
43
43
|
# For example, merchantReference will be converted to merchant_reference
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
self.new.tap do |notification|
|
45
|
+
params.each do |key, value|
|
46
|
+
setter = "#{key.to_s.underscore}="
|
47
|
+
notification.send(setter, value) if notification.respond_to?(setter)
|
48
|
+
end
|
49
|
+
notification.save!
|
47
50
|
end
|
48
|
-
|
49
|
-
self.create!(converted_params)
|
50
51
|
end
|
51
52
|
|
52
53
|
# Returns true if this notification is an AUTHORISATION notification
|
@@ -57,14 +58,14 @@ class AdyenNotification < ActiveRecord::Base
|
|
57
58
|
end
|
58
59
|
|
59
60
|
alias_method :authorization?, :authorisation?
|
60
|
-
|
61
|
+
|
61
62
|
# Returns true if this notification is an AUTHORISATION notification and
|
62
63
|
# the success status indicates that the authorization was successfull.
|
63
64
|
# @return [true, false] true iff the notification is an authorization
|
64
65
|
# and the authorization was successful according to the success field.
|
65
66
|
def successful_authorisation?
|
66
|
-
|
67
|
+
authorisation? && success?
|
67
68
|
end
|
68
|
-
|
69
|
+
|
69
70
|
alias_method :successful_authorization?, :successful_authorisation?
|
70
71
|
end
|
@@ -88,17 +88,34 @@ describe Adyen::API::RecurringService do
|
|
88
88
|
:variant => 'IDEAL',
|
89
89
|
:creation_date => DateTime.parse('2009-10-27T11:26:22.216+01:00')
|
90
90
|
},
|
91
|
+
{
|
92
|
+
:elv => {
|
93
|
+
:holder_name => 'S. Hopper',
|
94
|
+
:number => '1234567890',
|
95
|
+
:bank_location => 'Berlin',
|
96
|
+
:bank_location_id => '12345678',
|
97
|
+
:bank_name => 'TestBank',
|
98
|
+
},
|
99
|
+
:recurring_detail_reference => 'RecurringDetailReference3',
|
100
|
+
:variant => 'elv',
|
101
|
+
:creation_date => DateTime.parse('2009-10-27T11:26:22.216+01:00')
|
102
|
+
}
|
91
103
|
],
|
92
104
|
})
|
93
105
|
|
94
106
|
it "returns an array with just the detail references" do
|
95
|
-
@response.references.should == %w{ RecurringDetailReference1 RecurringDetailReference2 }
|
107
|
+
@response.references.should == %w{ RecurringDetailReference1 RecurringDetailReference2 RecurringDetailReference3 }
|
96
108
|
end
|
109
|
+
end
|
97
110
|
|
111
|
+
describe_response_from :list, LIST_EMPTY_RESPONSE, 'listRecurringDetails' do
|
98
112
|
it "returns an empty hash when there are no details" do
|
99
|
-
stub_net_http(LIST_EMPTY_RESPONSE)
|
100
113
|
@recurring.list.params.should == {}
|
101
114
|
end
|
115
|
+
|
116
|
+
it "returns an empty array when there are no references" do
|
117
|
+
@response.references.should == []
|
118
|
+
end
|
102
119
|
end
|
103
120
|
|
104
121
|
describe_request_body_of :disable, '//recurring:disable/recurring:request' do
|
data/spec/api/spec_helper.rb
CHANGED
@@ -332,6 +332,21 @@ LIST_RESPONSE = <<EOS
|
|
332
332
|
<recurringDetailReference>RecurringDetailReference2</recurringDetailReference>
|
333
333
|
<variant>IDEAL</variant>
|
334
334
|
</RecurringDetail>
|
335
|
+
<RecurringDetail>
|
336
|
+
<card xsi:nil="true"/>
|
337
|
+
<bank xsi:nil="true"/>
|
338
|
+
<elv>
|
339
|
+
<accountHolderName xmlns="http://payment.services.adyen.com">S. Hopper</accountHolderName>
|
340
|
+
<bankAccountNumber xmlns="http://payment.services.adyen.com">1234567890</bankAccountNumber>
|
341
|
+
<bankLocation xmlns="http://payment.services.adyen.com">Berlin</bankLocation>
|
342
|
+
<bankLocationId xmlns="http://payment.services.adyen.com">12345678</bankLocationId>
|
343
|
+
<bankName xmlns="http://payment.services.adyen.com">TestBank</bankName>
|
344
|
+
</elv>
|
345
|
+
<creationDate>2009-10-27T11:26:22.216+01:00</creationDate>
|
346
|
+
<name/>
|
347
|
+
<recurringDetailReference>RecurringDetailReference3</recurringDetailReference>
|
348
|
+
<variant>elv</variant>
|
349
|
+
</RecurringDetail>
|
335
350
|
</details>
|
336
351
|
<ns1:lastKnownShopperEmail>s.hopper@example.com</ns1:lastKnownShopperEmail>
|
337
352
|
<ns1:shopperReference>user-id</ns1:shopperReference>
|
data/spec/form_spec.rb
CHANGED
@@ -6,7 +6,7 @@ require 'adyen/form'
|
|
6
6
|
|
7
7
|
describe Adyen::Form do
|
8
8
|
|
9
|
-
before(:
|
9
|
+
before(:each) do
|
10
10
|
Adyen.configuration.register_form_skin(:testing, '4aD37dJA', 'Kah942*$7sdp0)')
|
11
11
|
Adyen.configuration.default_form_params[:merchant_account] = 'TestMerchant'
|
12
12
|
end
|
@@ -35,21 +35,32 @@ describe Adyen::Form do
|
|
35
35
|
it "should generate correct live url if explicitely asked for" do
|
36
36
|
Adyen::Form.url(:live).should == 'https://live.adyen.com/hpp/select.shtml'
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
it "should generate correct testing url if the payment flow selection is set to select" do
|
40
40
|
Adyen.configuration.payment_flow = :select
|
41
41
|
Adyen::Form.url.should == 'https://test.adyen.com/hpp/select.shtml'
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
it "should generate correct testing url if the payment flow selection is set to pay" do
|
45
45
|
Adyen.configuration.payment_flow = :pay
|
46
46
|
Adyen::Form.url.should == 'https://test.adyen.com/hpp/pay.shtml'
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
it "should generate correct testing url if the payment flow selection is set to details" do
|
50
50
|
Adyen.configuration.payment_flow = :details
|
51
51
|
Adyen::Form.url.should == 'https://test.adyen.com/hpp/details.shtml'
|
52
52
|
end
|
53
|
+
|
54
|
+
context "with custom domain" do
|
55
|
+
before(:each) do
|
56
|
+
Adyen.configuration.payment_flow = :select
|
57
|
+
Adyen.configuration.payment_flow_domain = "checkout.mydomain.com"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should generate correct testing url" do
|
61
|
+
Adyen::Form.url.should == 'https://checkout.mydomain.com/hpp/select.shtml'
|
62
|
+
end
|
63
|
+
end
|
53
64
|
end
|
54
65
|
|
55
66
|
describe 'redirect signature check' do
|
@@ -80,6 +91,18 @@ describe Adyen::Form do
|
|
80
91
|
Adyen::Form.redirect_signature_check(@params).should be_true
|
81
92
|
end
|
82
93
|
|
94
|
+
it "should raise ArgumentError on missing skinCode" do
|
95
|
+
expect do
|
96
|
+
@params.delete(:skinCode)
|
97
|
+
Adyen::Form.redirect_signature_check(@params).should be_false
|
98
|
+
end.to raise_error ArgumentError
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should raise ArgumentError on empty input" do
|
102
|
+
expect do
|
103
|
+
Adyen::Form.redirect_signature_check({}).should be_false
|
104
|
+
end.to raise_error ArgumentError
|
105
|
+
end
|
83
106
|
|
84
107
|
it "should detect a tampered field" do
|
85
108
|
Adyen::Form.redirect_signature_check(@params.merge(:pspReference => 'tampered')).should be_false
|
@@ -99,16 +122,16 @@ describe Adyen::Form do
|
|
99
122
|
|
100
123
|
@redirect_url = Adyen::Form.redirect_url(@attributes)
|
101
124
|
end
|
102
|
-
|
125
|
+
|
103
126
|
it "should return an URL pointing to the adyen server" do
|
104
127
|
@redirect_url.should =~ %r[^#{Adyen::Form.url}]
|
105
128
|
end
|
106
|
-
|
129
|
+
|
107
130
|
it "should include all provided attributes" do
|
108
131
|
params = @redirect_url.split('?', 2).last.split('&').map { |param| param.split('=', 2).first }
|
109
132
|
params.should include(*(@attributes.keys.map { |k| Adyen::Form.camelize(k) }))
|
110
133
|
end
|
111
|
-
|
134
|
+
|
112
135
|
it "should include the merchant signature" do
|
113
136
|
params = @redirect_url.split('?', 2).last.split('&').map { |param| param.split('=', 2).first }
|
114
137
|
params.should include('merchantSig')
|
@@ -116,6 +139,7 @@ describe Adyen::Form do
|
|
116
139
|
end
|
117
140
|
|
118
141
|
describe 'hidden fields generation' do
|
142
|
+
subject { %Q'<form action="#{CGI.escapeHTML(Adyen::Form.url)}" method="post">#{Adyen::Form.hidden_fields(@attributes)}</form>' }
|
119
143
|
|
120
144
|
before(:each) do
|
121
145
|
@attributes = { :currency_code => 'GBP', :payment_amount => 10000, :ship_before_date => Date.today,
|
@@ -123,12 +147,18 @@ describe Adyen::Form do
|
|
123
147
|
:session_validity => Time.now + 3600 }
|
124
148
|
end
|
125
149
|
|
126
|
-
it
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
150
|
+
it { should have_adyen_payment_form }
|
151
|
+
it { should include('<input type="hidden" name="merchantAccount" value="TestMerchant" />') }
|
152
|
+
|
153
|
+
context "width default_form_params" do
|
154
|
+
before(:each) do
|
155
|
+
Adyen.configuration.register_form_skin(:testing, '4aD37dJA', 'Kah942*$7sdp0)', {
|
156
|
+
:merchant_account => 'OtherMerchant',
|
157
|
+
})
|
158
|
+
end
|
159
|
+
|
160
|
+
it { should include('<input type="hidden" name="merchantAccount" value="OtherMerchant" />') }
|
161
|
+
it { should_not include('<input type="hidden" name="merchantAccount" value="TestMerchant" />') }
|
132
162
|
end
|
133
163
|
end
|
134
164
|
|
@@ -140,7 +170,16 @@ describe Adyen::Form do
|
|
140
170
|
|
141
171
|
@parameters = { :currency_code => 'GBP', :payment_amount => 10000,
|
142
172
|
:ship_before_date => '2007-10-20', :merchant_reference => 'Internet Order 12345',
|
143
|
-
:skin => :testing, :session_validity => '2007-10-11T11:00:00Z'
|
173
|
+
:skin => :testing, :session_validity => '2007-10-11T11:00:00Z',
|
174
|
+
:billing_address => {
|
175
|
+
:street => 'Alexanderplatz',
|
176
|
+
:house_number_or_name => '0815',
|
177
|
+
:city => 'Berlin',
|
178
|
+
:postal_code => '10119',
|
179
|
+
:state_or_province => 'Berlin',
|
180
|
+
:country => 'Germany',
|
181
|
+
}
|
182
|
+
}
|
144
183
|
|
145
184
|
Adyen::Form.do_parameter_transformations!(@parameters)
|
146
185
|
end
|
@@ -148,17 +187,24 @@ describe Adyen::Form do
|
|
148
187
|
it "should construct the signature base string correctly" do
|
149
188
|
signature_string = Adyen::Form.calculate_signature_string(@parameters)
|
150
189
|
signature_string.should == "10000GBP2007-10-20Internet Order 123454aD37dJATestMerchant2007-10-11T11:00:00Z"
|
151
|
-
|
190
|
+
|
152
191
|
signature_string = Adyen::Form.calculate_signature_string(@parameters.merge(:merchant_return_data => 'testing123'))
|
153
192
|
signature_string.should == "10000GBP2007-10-20Internet Order 123454aD37dJATestMerchant2007-10-11T11:00:00Ztesting123"
|
154
|
-
|
193
|
+
|
155
194
|
end
|
156
|
-
|
195
|
+
|
157
196
|
it "should calculate the signature correctly" do
|
158
197
|
signature = Adyen::Form.calculate_signature(@parameters)
|
159
198
|
signature.should == 'x58ZcRVL1H6y+XSeBGrySJ9ACVo='
|
160
199
|
end
|
161
200
|
|
201
|
+
it "should raise ArgumentError on empty shared_secret" do
|
202
|
+
expect do
|
203
|
+
@parameters.delete(:shared_secret)
|
204
|
+
signature = Adyen::Form.calculate_signature(@parameters)
|
205
|
+
end.to raise_error ArgumentError
|
206
|
+
end
|
207
|
+
|
162
208
|
it "should calculate the signature base string correctly for a recurring payment" do
|
163
209
|
# Add the required recurrent payment attributes
|
164
210
|
@parameters.merge!(:recurring_contract => 'DEFAULT', :shopper_reference => 'grasshopper52', :shopper_email => 'gras.shopper@somewhere.org')
|
@@ -174,5 +220,44 @@ describe Adyen::Form do
|
|
174
220
|
signature = Adyen::Form.calculate_signature(@parameters)
|
175
221
|
signature.should == 'F2BQEYbE+EUhiRGuPtcD16Gm7JY='
|
176
222
|
end
|
223
|
+
|
224
|
+
context 'billing address' do
|
225
|
+
|
226
|
+
it "should construct the signature base string correctly" do
|
227
|
+
signature_string = Adyen::Form.calculate_billing_address_signature_string(@parameters[:billing_address])
|
228
|
+
signature_string.should == "Alexanderplatz0815Berlin10119BerlinGermany"
|
229
|
+
end
|
230
|
+
|
231
|
+
it "should calculate the signature correctly" do
|
232
|
+
signature = Adyen::Form.calculate_billing_address_signature(@parameters)
|
233
|
+
signature.should == '5KQb7VJq4cz75cqp11JDajntCY4='
|
234
|
+
end
|
235
|
+
|
236
|
+
it "should raise ArgumentError on empty shared_secret" do
|
237
|
+
expect do
|
238
|
+
@parameters.delete(:shared_secret)
|
239
|
+
signature = Adyen::Form.calculate_billing_address_signature(@parameters)
|
240
|
+
end.to raise_error ArgumentError
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
end
|
245
|
+
|
246
|
+
describe "flatten" do
|
247
|
+
let(:parameters) do
|
248
|
+
{
|
249
|
+
:billing_address => { :street => 'My Street'}
|
250
|
+
}
|
251
|
+
end
|
252
|
+
|
253
|
+
it "returns empty hash for nil input" do
|
254
|
+
Adyen::Form.flatten(nil).should == {}
|
255
|
+
end
|
256
|
+
|
257
|
+
it "flattens hash and prefixes keys" do
|
258
|
+
Adyen::Form.flatten(parameters).should == {
|
259
|
+
'billingAddress.street' => 'My Street'
|
260
|
+
}
|
261
|
+
end
|
177
262
|
end
|
178
|
-
end
|
263
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,10 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: adyen
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 1
|
7
|
-
- 3
|
8
|
-
- 1
|
9
|
-
version: 1.3.1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.3.2
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Willem van Bergen
|
13
9
|
- Michel Barbosa
|
14
10
|
- Stefan Borsje
|
@@ -16,72 +12,67 @@ authors:
|
|
16
12
|
autorequire:
|
17
13
|
bindir: bin
|
18
14
|
cert_chain: []
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
dependencies:
|
23
|
-
- !ruby/object:Gem::Dependency
|
15
|
+
date: 2013-01-14 00:00:00.000000000 Z
|
16
|
+
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
24
18
|
name: rake
|
25
|
-
|
26
|
-
|
27
|
-
requirements:
|
28
|
-
- -
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
|
31
|
-
- 0
|
32
|
-
version: "0"
|
19
|
+
requirement: &70260598824500 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ! '>='
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: '0'
|
33
25
|
type: :development
|
34
|
-
version_requirements: *id001
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: rspec
|
37
26
|
prerelease: false
|
38
|
-
|
39
|
-
|
27
|
+
version_requirements: *70260598824500
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rspec
|
30
|
+
requirement: &70260598798280 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
40
33
|
- - ~>
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
|
43
|
-
- 2
|
44
|
-
version: "2"
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '2'
|
45
36
|
type: :development
|
46
|
-
version_requirements: *id002
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: rails
|
49
37
|
prerelease: false
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
38
|
+
version_requirements: *70260598798280
|
39
|
+
- !ruby/object:Gem::Dependency
|
40
|
+
name: rails
|
41
|
+
requirement: &70260598790820 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '2.3'
|
58
47
|
type: :development
|
59
|
-
version_requirements: *id003
|
60
|
-
- !ruby/object:Gem::Dependency
|
61
|
-
name: nokogiri
|
62
48
|
prerelease: false
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
49
|
+
version_requirements: *70260598790820
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: nokogiri
|
52
|
+
requirement: &70260598661900 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ! '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
70
58
|
type: :development
|
71
|
-
|
72
|
-
|
73
|
-
|
59
|
+
prerelease: false
|
60
|
+
version_requirements: *70260598661900
|
61
|
+
description: ! " Package to simplify including the Adyen payments services into
|
62
|
+
a Ruby on Rails application.\n The package provides functionality to create payment
|
63
|
+
forms, handling and storing notifications \n sent by Adyen and consuming the
|
64
|
+
SOAP services provided by Adyen. Moreover, it contains helper\n methods, mocks
|
65
|
+
and matchers to simpify writing tests/specs for your code.\n"
|
66
|
+
email:
|
74
67
|
- willem@vanbergen.org
|
75
68
|
- cicaboo@gmail.com
|
76
69
|
- mail@sborsje.nl
|
77
70
|
- eloy.de.enige@gmail.com
|
78
71
|
executables: []
|
79
|
-
|
80
72
|
extensions: []
|
81
|
-
|
82
|
-
extra_rdoc_files:
|
73
|
+
extra_rdoc_files:
|
83
74
|
- README.rdoc
|
84
|
-
files:
|
75
|
+
files:
|
85
76
|
- .gitignore
|
86
77
|
- .kick
|
87
78
|
- .travis.yml
|
@@ -125,42 +116,38 @@ files:
|
|
125
116
|
- spec/spec_helper.rb
|
126
117
|
- tasks/github-gem.rake
|
127
118
|
- yard_extensions.rb
|
128
|
-
has_rdoc: true
|
129
119
|
homepage: http://github.com/wvanbergen/adyen/wiki
|
130
120
|
licenses: []
|
131
|
-
|
132
121
|
post_install_message:
|
133
|
-
rdoc_options:
|
122
|
+
rdoc_options:
|
134
123
|
- --title
|
135
124
|
- adyen
|
136
125
|
- --main
|
137
126
|
- README.rdoc
|
138
127
|
- --line-numbers
|
139
128
|
- --inline-source
|
140
|
-
require_paths:
|
129
|
+
require_paths:
|
141
130
|
- lib
|
142
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
requirements:
|
151
|
-
- -
|
152
|
-
- !ruby/object:Gem::Version
|
153
|
-
|
154
|
-
|
155
|
-
version: "0"
|
156
|
-
requirements:
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
133
|
+
requirements:
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ! '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
requirements:
|
157
144
|
- Having Nokogiri installed will speed up XML handling when using the SOAP API.
|
158
145
|
rubyforge_project:
|
159
|
-
rubygems_version: 1.
|
146
|
+
rubygems_version: 1.8.16
|
160
147
|
signing_key:
|
161
148
|
specification_version: 3
|
162
149
|
summary: Integrate Adyen payment services in your Ruby on Rails application.
|
163
|
-
test_files:
|
150
|
+
test_files:
|
164
151
|
- spec/adyen_spec.rb
|
165
152
|
- spec/api/api_spec.rb
|
166
153
|
- spec/api/payment_service_spec.rb
|