adyen 0.3.7 → 0.3.8
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.rdoc +12 -5
- data/TODO +10 -0
- data/adyen.gemspec +13 -7
- data/lib/adyen.rb +3 -3
- data/lib/adyen/form.rb +28 -26
- data/lib/adyen/matchers.rb +6 -7
- data/lib/adyen/notification.rb +3 -3
- data/spec/adyen_spec.rb +1 -1
- data/spec/form_spec.rb +1 -1
- data/spec/notification_spec.rb +1 -1
- data/spec/soap_spec.rb +77 -77
- data/spec/spec_helper.rb +2 -1
- data/tasks/github-gem.rake +65 -22
- metadata +93 -10
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
@@ -15,14 +15,20 @@ automated test suite to assert the integration is working correctly.
|
|
15
15
|
|
16
16
|
== Installation
|
17
17
|
|
18
|
-
Add the following line to your <tt>
|
18
|
+
<b>Bundler / Rails 3</b>: Add the following line to your <tt>Gemfile</tt>:
|
19
|
+
|
20
|
+
gem 'adyen'
|
21
|
+
|
22
|
+
<b>Rails 2.x</b>: Add the following line to your <tt>environment.rb</tt> and run <tt>rake gems:install</tt>
|
19
23
|
to make the Adyen functionality available in your Rails project:
|
20
24
|
|
21
|
-
|
25
|
+
config.gem 'adyen'
|
22
26
|
|
23
27
|
You can also install it as a Rails plugin (*deprecated*):
|
24
28
|
|
25
|
-
|
29
|
+
script/plugin install git://github.com/wvanbergen/adyen.git
|
30
|
+
|
31
|
+
Depending on your use case, you may also need the following gems: activerecord, handsoap and nokogiri.
|
26
32
|
|
27
33
|
== Usage
|
28
34
|
|
@@ -36,5 +42,6 @@ RDoc documentation for the project can be found on http://rdoc.info/projects/wva
|
|
36
42
|
== About
|
37
43
|
|
38
44
|
This package is written by Michel Barbosa and Willem van Bergen for Floorplanner.com, and
|
39
|
-
made public under the MIT license (see LICENSE).
|
40
|
-
|
45
|
+
made public under the MIT license (see LICENSE). Its is currently maintained by Willem van
|
46
|
+
Bergen, Stefan Borsje and Eloy Duran. We are not affiliated with Adyen B.V. The software
|
47
|
+
comes without warranty of any kind, so use at your own risk.
|
data/TODO
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
* Use require/autoload instead of const_missing
|
2
|
+
* Make sure Japansese yens work as expected (this is the only currency Adyen does not expect to be in cents)
|
3
|
+
* Ditch SOAP library dependency.
|
4
|
+
* Complete SOAP API.
|
5
|
+
* Add ActiveMerchant integration
|
6
|
+
|
7
|
+
* Split up gem to have more explicit dependency requirements, e.g.:
|
8
|
+
* adyen-soap
|
9
|
+
* adyen-railtie
|
10
|
+
* adyen-activemerchant
|
data/adyen.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'adyen'
|
3
|
-
s.version = "0.3.
|
4
|
-
s.date = "2010-
|
3
|
+
s.version = "0.3.8"
|
4
|
+
s.date = "2010-09-23"
|
5
5
|
|
6
|
-
s.summary = "Integrate Adyen payment services in
|
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
|
@@ -11,20 +11,26 @@ Gem::Specification.new do |s|
|
|
11
11
|
methods, mocks and matchers to simpify writing tests/specsfor your code.
|
12
12
|
EOS
|
13
13
|
|
14
|
-
s.authors = ['Willem van Bergen', 'Michel Barbosa']
|
15
|
-
s.email = ['willem@vanbergen.org', 'cicaboo@gmail.com']
|
14
|
+
s.authors = ['Willem van Bergen', 'Michel Barbosa', 'Stefan Borsje', 'Eloy Duran']
|
15
|
+
s.email = ['willem@vanbergen.org', 'cicaboo@gmail.com', 'mail@sborsje.nl', 'eloy.de.enige@gmail.com']
|
16
16
|
s.homepage = 'http://wiki.github.com/wvanbergen/adyen'
|
17
17
|
|
18
|
+
s.add_development_dependency('rake')
|
18
19
|
s.add_development_dependency('rspec', '>= 1.1.4')
|
19
20
|
s.add_development_dependency('git', '>= 1.1.0')
|
21
|
+
s.add_development_dependency('gemcutter')
|
22
|
+
|
23
|
+
# Drop or make runtime dependency.
|
24
|
+
s.add_development_dependency('activerecord')
|
25
|
+
s.add_development_dependency('handsoap')
|
26
|
+
s.add_development_dependency('nokogiri')
|
20
27
|
|
21
28
|
s.requirements << 'Handsoap is required for accessing the SOAP services. See http://github.com/troelskn/handsoap.'
|
22
|
-
s.requirements << 'LibXML is required for using the RSpec matchers.'
|
23
29
|
s.requirements << 'ActiveRecord is required for storing the notifications in your database.'
|
24
30
|
|
25
31
|
s.rdoc_options << '--title' << s.name << '--main' << 'README.rdoc' << '--line-numbers' << '--inline-source'
|
26
32
|
s.extra_rdoc_files = ['README.rdoc']
|
27
33
|
|
28
|
-
s.files = %w(spec/spec_helper.rb spec/adyen_spec.rb lib/adyen/form.rb .gitignore spec/notification_spec.rb lib/adyen/soap.rb LICENSE spec/soap_spec.rb init.rb adyen.gemspec Rakefile spec/form_spec.rb README.rdoc lib/adyen/notification.rb lib/adyen/formatter.rb tasks/github-gem.rake lib/adyen/encoding.rb lib/adyen/matchers.rb lib/adyen.rb)
|
34
|
+
s.files = %w(spec/spec_helper.rb spec/adyen_spec.rb lib/adyen/form.rb .gitignore spec/notification_spec.rb lib/adyen/soap.rb LICENSE spec/soap_spec.rb init.rb adyen.gemspec Rakefile spec/form_spec.rb README.rdoc lib/adyen/notification.rb lib/adyen/formatter.rb tasks/github-gem.rake lib/adyen/encoding.rb TODO lib/adyen/matchers.rb lib/adyen.rb)
|
29
35
|
s.test_files = %w(spec/adyen_spec.rb spec/notification_spec.rb spec/soap_spec.rb spec/form_spec.rb)
|
30
36
|
end
|
data/lib/adyen.rb
CHANGED
@@ -13,7 +13,7 @@ module Adyen
|
|
13
13
|
# Version constant for the Adyen plugin.
|
14
14
|
# DO NOT CHANGE THIS VALUE BY HAND. It will be updated automatically by
|
15
15
|
# the gem:release rake task.
|
16
|
-
VERSION = "0.3.
|
16
|
+
VERSION = "0.3.8"
|
17
17
|
|
18
18
|
# Loads configuration settings from a Hash.
|
19
19
|
#
|
@@ -47,9 +47,9 @@ module Adyen
|
|
47
47
|
#
|
48
48
|
# It will return the +override+ value if set, it will return the value set
|
49
49
|
# using {Adyen.environment=} otherwise. If this value also isn't set, the
|
50
|
-
#
|
50
|
+
# environment is determined with {Adyen.autodetect_environment}.
|
51
51
|
#
|
52
|
-
# @param ['test', 'live'] override An
|
52
|
+
# @param ['test', 'live'] override An environment to override the default with.
|
53
53
|
# @return ['test', 'live'] The Adyen environment that is currently being used.
|
54
54
|
def self.environment(override = nil)
|
55
55
|
override || @environment || Adyen.autodetect_environment
|
data/lib/adyen/form.rb
CHANGED
@@ -21,8 +21,8 @@ module Adyen
|
|
21
21
|
# @see Adyen::Form.redirect_url
|
22
22
|
# @see Adyen::Form.redirect_signature_check
|
23
23
|
module Form
|
24
|
-
|
25
|
-
extend
|
24
|
+
include ActionView::Helpers::TagHelper
|
25
|
+
extend self
|
26
26
|
|
27
27
|
######################################################
|
28
28
|
# SKINS
|
@@ -30,7 +30,7 @@ module Adyen
|
|
30
30
|
|
31
31
|
# Returns all registered skins and their accompanying skin code and shared secret.
|
32
32
|
# @return [Hash] The hash of registered skins.
|
33
|
-
def
|
33
|
+
def skins
|
34
34
|
@skins ||= {}
|
35
35
|
end
|
36
36
|
|
@@ -38,7 +38,7 @@ module Adyen
|
|
38
38
|
# @param [Hash<Symbol, Hash>] hash A hash with the skin name as key and the skin parameter hash
|
39
39
|
# (which should include +:skin_code+ and +:shared_secret+) as value.
|
40
40
|
# @see Adyen::Form.register_skin
|
41
|
-
def
|
41
|
+
def skins=(hash)
|
42
42
|
@skins = hash.inject({}) do |skins, (name, skin)|
|
43
43
|
skins[name.to_sym] = skin.merge(:name => name.to_sym)
|
44
44
|
skins
|
@@ -58,28 +58,28 @@ module Adyen
|
|
58
58
|
# @param [String] skin_code The skin code for this skin, as defined by Adyen.
|
59
59
|
# @param [String] shared_secret The shared secret used for signature calculation.
|
60
60
|
# @see Adyen.load_config
|
61
|
-
def
|
62
|
-
|
61
|
+
def register_skin(name, skin_code, shared_secret)
|
62
|
+
skins[name.to_sym] = {:name => name.to_sym, :skin_code => skin_code, :shared_secret => shared_secret }
|
63
63
|
end
|
64
64
|
|
65
65
|
# Returns skin information given a skin name.
|
66
66
|
# @param [Symbol] skin_name The name of the skin
|
67
67
|
# @return [Hash, nil] A hash with the skin information, or nil if not found.
|
68
|
-
def
|
69
|
-
|
68
|
+
def skin_by_name(skin_name)
|
69
|
+
skins[skin_name.to_sym]
|
70
70
|
end
|
71
71
|
|
72
72
|
# Returns skin information given a skin code.
|
73
73
|
# @param [String] skin_code The skin code of the skin
|
74
74
|
# @return [Hash, nil] A hash with the skin information, or nil if not found.
|
75
|
-
def
|
76
|
-
|
75
|
+
def skin_by_code(skin_code)
|
76
|
+
skins.detect { |(name, skin)| skin[:skin_code] == skin_code }.last rescue nil
|
77
77
|
end
|
78
78
|
|
79
79
|
# Returns the shared secret belonging to a skin code.
|
80
80
|
# @param [String] skin_code The skin code of the skin
|
81
81
|
# @return [String, nil] The shared secret for the skin, or nil if not found.
|
82
|
-
def
|
82
|
+
def lookup_shared_secret(skin_code)
|
83
83
|
skin = skin_by_code(skin_code)[:shared_secret] rescue nil
|
84
84
|
end
|
85
85
|
|
@@ -90,14 +90,14 @@ module Adyen
|
|
90
90
|
# Returns the default parameters to use, unless they are overridden.
|
91
91
|
# @see Adyen::Form.default_parameters
|
92
92
|
# @return [Hash] The hash of default parameters
|
93
|
-
def
|
93
|
+
def default_parameters
|
94
94
|
@default_arguments ||= {}
|
95
95
|
end
|
96
96
|
|
97
97
|
# Sets the default parameters to use.
|
98
98
|
# @see Adyen::Form.default_parameters
|
99
99
|
# @param [Hash] hash The hash of default parameters
|
100
|
-
def
|
100
|
+
def default_parameters=(hash)
|
101
101
|
@default_arguments = hash
|
102
102
|
end
|
103
103
|
|
@@ -117,7 +117,7 @@ module Adyen
|
|
117
117
|
# for payment forms or redirects.
|
118
118
|
# @see Adyen::Form.environment
|
119
119
|
# @see Adyen::Form.redirect_url
|
120
|
-
def
|
120
|
+
def url(environment = nil)
|
121
121
|
environment ||= Adyen.environment
|
122
122
|
Adyen::Form::ACTION_URL % environment.to_s
|
123
123
|
end
|
@@ -133,7 +133,7 @@ module Adyen
|
|
133
133
|
#
|
134
134
|
# @private
|
135
135
|
# @param [Hash] parameters The payment parameters hash to transform
|
136
|
-
def
|
136
|
+
def do_parameter_transformations!(parameters = {})
|
137
137
|
raise "YENs are not yet supported!" if parameters[:currency_code] == 'JPY' # TODO: fixme
|
138
138
|
|
139
139
|
parameters.replace(default_parameters.merge(parameters))
|
@@ -160,7 +160,7 @@ module Adyen
|
|
160
160
|
# is provided as the +:shared_secret+ parameter.
|
161
161
|
# @return [Hash] The payment parameters with the +:merchant_signature+ parameter set.
|
162
162
|
# @raise [StandardError] Thrown if some parameter health check fails.
|
163
|
-
def
|
163
|
+
def payment_parameters(parameters = {}, shared_secret = nil)
|
164
164
|
do_parameter_transformations!(parameters)
|
165
165
|
|
166
166
|
raise "Cannot generate form: :currency code attribute not found!" unless parameters[:currency_code]
|
@@ -204,8 +204,8 @@ module Adyen
|
|
204
204
|
#
|
205
205
|
# @param [Hash] parameters The payment parameters to include in the payment request.
|
206
206
|
# @return [String] An absolute URL to redirect to the Adyen payment system.
|
207
|
-
def
|
208
|
-
|
207
|
+
def redirect_url(parameters = {})
|
208
|
+
url + '?' + payment_parameters(parameters).map { |(k, v)|
|
209
209
|
"#{k.to_s.camelize(:lower)}=#{CGI.escape(v.to_s)}" }.join('&')
|
210
210
|
end
|
211
211
|
|
@@ -230,12 +230,14 @@ module Adyen
|
|
230
230
|
# @param [Hash] parameters The payment parameters to include in the payment request.
|
231
231
|
# @return [String] An HTML snippet that can be included in a form that POSTs to the
|
232
232
|
# Adyen payment system.
|
233
|
-
def
|
233
|
+
def hidden_fields(parameters = {})
|
234
234
|
|
235
235
|
# Generate a hidden input tag per parameter, join them by newlines.
|
236
|
-
payment_parameters(parameters).map { |key, value|
|
237
|
-
|
236
|
+
form_str = payment_parameters(parameters).map { |key, value|
|
237
|
+
tag(:input, :type => 'hidden', :name => key.to_s.camelize(:lower), :value => value)
|
238
238
|
}.join("\n")
|
239
|
+
|
240
|
+
form_str.respond_to?(:html_safe) ? form_str.html_safe : form_str
|
239
241
|
end
|
240
242
|
|
241
243
|
######################################################
|
@@ -246,7 +248,7 @@ module Adyen
|
|
246
248
|
# is used by Adyen to check whether the request is genuinely originating from you.
|
247
249
|
# @param [Hash] parameters The parameters that will be included in the payment request.
|
248
250
|
# @return [String] The string for which the siganture is calculated.
|
249
|
-
def
|
251
|
+
def calculate_signature_string(parameters)
|
250
252
|
merchant_sig_string = ""
|
251
253
|
merchant_sig_string << parameters[:payment_amount].to_s << parameters[:currency_code].to_s <<
|
252
254
|
parameters[:ship_before_date].to_s << parameters[:merchant_reference].to_s <<
|
@@ -270,7 +272,7 @@ module Adyen
|
|
270
272
|
# It should correspond with the skin_code parameter. This parameter can be
|
271
273
|
# left out if the shared_secret is included as key in the parameters.
|
272
274
|
# @return [String] The signature of the payment request
|
273
|
-
def
|
275
|
+
def calculate_signature(parameters, shared_secret = nil)
|
274
276
|
shared_secret ||= parameters.delete(:shared_secret)
|
275
277
|
Adyen::Encoding.hmac_base64(shared_secret, calculate_signature_string(parameters))
|
276
278
|
end
|
@@ -282,7 +284,7 @@ module Adyen
|
|
282
284
|
# Generates the string for which the redirect signature is calculated, using the request paramaters.
|
283
285
|
# @param [Hash] params A hash of HTTP GET parameters for the redirect request.
|
284
286
|
# @return [String] The signature string.
|
285
|
-
def
|
287
|
+
def redirect_signature_string(params)
|
286
288
|
params[:authResult].to_s + params[:pspReference].to_s + params[:merchantReference].to_s + params[:skinCode].to_s
|
287
289
|
end
|
288
290
|
|
@@ -294,7 +296,7 @@ module Adyen
|
|
294
296
|
# the original payment form. You can leave this out of the skin is registered
|
295
297
|
# using the {Adyen::Form.register_skin} method.
|
296
298
|
# @return [String] The redirect signature
|
297
|
-
def
|
299
|
+
def redirect_signature(params, shared_secret = nil)
|
298
300
|
shared_secret ||= lookup_shared_secret(params[:skinCode])
|
299
301
|
Adyen::Encoding.hmac_base64(shared_secret, redirect_signature_string(params))
|
300
302
|
end
|
@@ -329,7 +331,7 @@ module Adyen
|
|
329
331
|
# the original payment form. You can leave this out of the skin is registered
|
330
332
|
# using the {Adyen::Form.register_skin} method.
|
331
333
|
# @return [true, false] Returns true only if the signature in the parameters is correct.
|
332
|
-
def
|
334
|
+
def redirect_signature_check(params, shared_secret = nil)
|
333
335
|
params[:merchantSig] == redirect_signature(params, shared_secret)
|
334
336
|
end
|
335
337
|
end
|
data/lib/adyen/matchers.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
require '
|
1
|
+
require 'rexml/document'
|
2
|
+
require 'rexml/xpath'
|
2
3
|
|
3
4
|
module Adyen
|
4
5
|
module Matchers
|
@@ -31,12 +32,10 @@ module Adyen
|
|
31
32
|
|
32
33
|
def self.document(subject)
|
33
34
|
if String === subject
|
34
|
-
|
35
|
+
REXML::Document.new(subject.to_s)
|
35
36
|
elsif subject.respond_to?(:body)
|
36
|
-
|
37
|
-
elsif
|
38
|
-
subject
|
39
|
-
elsif XML::Document === subject
|
37
|
+
REXML::Document.new(subject.body.to_s)
|
38
|
+
elsif REXML::Document === subject
|
40
39
|
subject
|
41
40
|
else
|
42
41
|
raise "Cannot handle this XML input type"
|
@@ -44,7 +43,7 @@ module Adyen
|
|
44
43
|
end
|
45
44
|
|
46
45
|
def self.check(subject, checks = {})
|
47
|
-
document(subject)
|
46
|
+
!!REXML::XPath.first(document(subject), build_xpath_query(checks))
|
48
47
|
end
|
49
48
|
end
|
50
49
|
|
data/lib/adyen/notification.rb
CHANGED
@@ -105,15 +105,15 @@ module Adyen
|
|
105
105
|
end
|
106
106
|
|
107
107
|
def live=(value)
|
108
|
-
|
108
|
+
super([true, 1, '1', 'true'].include?(value))
|
109
109
|
end
|
110
110
|
|
111
111
|
def success=(value)
|
112
|
-
|
112
|
+
super([true, 1, '1', 'true'].include?(value))
|
113
113
|
end
|
114
114
|
|
115
115
|
def value=(value)
|
116
|
-
|
116
|
+
super(Adyen::Formatter::Price.from_cents(value)) unless value.blank?
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
data/spec/adyen_spec.rb
CHANGED
data/spec/form_spec.rb
CHANGED
data/spec/notification_spec.rb
CHANGED
data/spec/soap_spec.rb
CHANGED
@@ -1,31 +1,31 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Adyen::SOAP::PaymentService do
|
4
4
|
|
5
5
|
describe '#authorise' do
|
6
6
|
before(:all) do
|
7
|
-
setup_mock_driver(
|
8
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
9
|
-
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
</soap:Envelope>
|
28
|
-
|
7
|
+
setup_mock_driver(<<-XML)
|
8
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
9
|
+
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
10
|
+
<soap:Body>
|
11
|
+
<ns1:authoriseResponse xmlns:ns1="http://payment.services.adyen.com">
|
12
|
+
<ns1:paymentResult>
|
13
|
+
<additionalData xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
|
14
|
+
<authCode xmlns="http://payment.services.adyen.com">1234</authCode>
|
15
|
+
<dccAmount xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
|
16
|
+
<dccSignature xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
|
17
|
+
<fraudResult xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
|
18
|
+
<issuerUrl xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
|
19
|
+
<md xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
|
20
|
+
<paRequest xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
|
21
|
+
<pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
|
22
|
+
<refusalReason xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
|
23
|
+
<resultCode xmlns="http://payment.services.adyen.com">Authorised</resultCode>
|
24
|
+
</ns1:paymentResult>
|
25
|
+
</ns1:authoriseResponse>
|
26
|
+
</soap:Body>
|
27
|
+
</soap:Envelope>
|
28
|
+
XML
|
29
29
|
|
30
30
|
@response = Adyen::SOAP::PaymentService.authorise({
|
31
31
|
:selected_recurring_detail_reference => '6543210987654321',
|
@@ -93,19 +93,19 @@ EOF
|
|
93
93
|
|
94
94
|
describe '#capture' do
|
95
95
|
before(:all) do
|
96
|
-
setup_mock_driver(
|
97
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
98
|
-
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
</soap:Envelope>
|
108
|
-
|
96
|
+
setup_mock_driver(<<-XML)
|
97
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
98
|
+
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
99
|
+
<soap:Body>
|
100
|
+
<ns1:captureResponse xmlns:ns1="http://payment.services.adyen.com">
|
101
|
+
<ns1:captureResult>
|
102
|
+
<pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
|
103
|
+
<response xmlns="http://payment.services.adyen.com">[capture-received]</response>
|
104
|
+
</ns1:captureResult>
|
105
|
+
</ns1:captureResponse>
|
106
|
+
</soap:Body>
|
107
|
+
</soap:Envelope>
|
108
|
+
XML
|
109
109
|
|
110
110
|
@response = Adyen::SOAP::PaymentService.capture({
|
111
111
|
:merchant_account => 'YourMerchantAccount',
|
@@ -154,19 +154,19 @@ EOF
|
|
154
154
|
|
155
155
|
describe "#cancel" do
|
156
156
|
before(:all) do
|
157
|
-
setup_mock_driver(
|
158
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
159
|
-
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
</soap:Envelope>
|
169
|
-
|
157
|
+
setup_mock_driver(<<-XML)
|
158
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
159
|
+
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
160
|
+
<soap:Body>
|
161
|
+
<ns1:cancelResponse xmlns:ns1="http://payment.services.adyen.com">
|
162
|
+
<ns1:cancelResult>
|
163
|
+
<pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
|
164
|
+
<response xmlns="http://payment.services.adyen.com">[cancel-received]</response>
|
165
|
+
</ns1:cancelResult>
|
166
|
+
</ns1:cancelResponse>
|
167
|
+
</soap:Body>
|
168
|
+
</soap:Envelope>
|
169
|
+
XML
|
170
170
|
|
171
171
|
@response = Adyen::SOAP::PaymentService.cancel({
|
172
172
|
:merchant_account => 'YourMerchantAccount',
|
@@ -205,19 +205,19 @@ EOF
|
|
205
205
|
|
206
206
|
describe "#refund" do
|
207
207
|
before(:all) do
|
208
|
-
setup_mock_driver(
|
209
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
210
|
-
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
</soap:Envelope>
|
220
|
-
|
208
|
+
setup_mock_driver(<<-XML)
|
209
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
210
|
+
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
211
|
+
<soap:Body>
|
212
|
+
<ns1:refundResponse xmlns:ns1="http://payment.services.adyen.com">
|
213
|
+
<ns1:refundResult>
|
214
|
+
<pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
|
215
|
+
<response xmlns="http://payment.services.adyen.com">[refund-received]</response>
|
216
|
+
</ns1:refundResult>
|
217
|
+
</ns1:refundResponse>
|
218
|
+
</soap:Body>
|
219
|
+
</soap:Envelope>
|
220
|
+
XML
|
221
221
|
|
222
222
|
@response = Adyen::SOAP::PaymentService.refund({
|
223
223
|
:merchant_account => 'YourMerchantAccount',
|
@@ -261,20 +261,20 @@ EOF
|
|
261
261
|
|
262
262
|
describe "#cancel_or_refund" do
|
263
263
|
before(:all) do
|
264
|
-
setup_mock_driver(
|
265
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
266
|
-
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
</soap:Envelope>
|
276
|
-
|
277
|
-
|
264
|
+
setup_mock_driver(<<-XML)
|
265
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
266
|
+
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
267
|
+
<soap:Body>
|
268
|
+
<ns1:cancelOrRefundResponse xmlns:ns1="http://payment.services.adyen.com">
|
269
|
+
<ns1:cancelOrRefundResult>
|
270
|
+
<pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
|
271
|
+
<response xmlns="http://payment.services.adyen.com">[cancelOrRefund-received]</response>
|
272
|
+
</ns1:cancelOrRefundResult>
|
273
|
+
</ns1:cancelOrRefundResponse>
|
274
|
+
</soap:Body>
|
275
|
+
</soap:Envelope>
|
276
|
+
XML
|
277
|
+
|
278
278
|
@response = Adyen::SOAP::PaymentService.cancel_or_refund({
|
279
279
|
:merchant_account => 'YourMerchantAccount',
|
280
280
|
:original_reference => '1234567890123456'
|
@@ -320,7 +320,7 @@ private
|
|
320
320
|
'Server: Apache',
|
321
321
|
'Content-Type: text/xml;charset=UTF-8'
|
322
322
|
].join("\r\n"),
|
323
|
-
:content => content
|
323
|
+
:content => content.strip
|
324
324
|
})
|
325
325
|
Handsoap.http_driver = :mock
|
326
326
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'spec'
|
@@ -6,6 +6,7 @@ require 'spec/autorun'
|
|
6
6
|
require 'active_support'
|
7
7
|
|
8
8
|
require 'adyen'
|
9
|
+
require 'adyen/matchers'
|
9
10
|
|
10
11
|
Spec::Runner.configure do |config|
|
11
12
|
config.include Adyen::Matchers
|
data/tasks/github-gem.rake
CHANGED
@@ -119,24 +119,43 @@ module GithubGem
|
|
119
119
|
checks = [:check_current_branch, :check_clean_status, :check_not_diverged, :check_version]
|
120
120
|
checks.unshift('spec:basic') if has_specs?
|
121
121
|
checks.unshift('test:basic') if has_tests?
|
122
|
-
checks.push << [:check_rubyforge] if gemspec.rubyforge_project
|
122
|
+
# checks.push << [:check_rubyforge] if gemspec.rubyforge_project
|
123
123
|
|
124
124
|
desc "Perform all checks that would occur before a release"
|
125
125
|
task(:release_checks => checks)
|
126
126
|
|
127
127
|
release_tasks = [:release_checks, :set_version, :build, :github_release, :gemcutter_release]
|
128
|
-
release_tasks << [:rubyforge_release] if gemspec.rubyforge_project
|
128
|
+
# release_tasks << [:rubyforge_release] if gemspec.rubyforge_project
|
129
129
|
|
130
|
-
desc "Release a new
|
130
|
+
desc "Release a new version of the gem using the VERSION environment variable"
|
131
131
|
task(:release => release_tasks) { release_task }
|
132
|
+
|
133
|
+
namespace(:release) do
|
134
|
+
desc "Release the next version of the gem, by incrementing the last version segment by 1"
|
135
|
+
task(:next => [:next_version] + release_tasks) { release_task }
|
132
136
|
|
133
|
-
|
134
|
-
|
137
|
+
desc "Release the next version of the gem, using a patch increment (0.0.1)"
|
138
|
+
task(:patch => [:next_patch_version] + release_tasks) { release_task }
|
139
|
+
|
140
|
+
desc "Release the next version of the gem, using a minor increment (0.1.0)"
|
141
|
+
task(:minor => [:next_minor_version] + release_tasks) { release_task }
|
142
|
+
|
143
|
+
desc "Release the next version of the gem, using a major increment (1.0.0)"
|
144
|
+
task(:major => [:next_major_version] + release_tasks) { release_task }
|
145
|
+
end
|
146
|
+
|
147
|
+
# task(:check_rubyforge) { check_rubyforge_task }
|
148
|
+
# task(:rubyforge_release) { rubyforge_release_task }
|
135
149
|
task(:gemcutter_release) { gemcutter_release_task }
|
136
150
|
task(:github_release => [:commit_modified_files, :tag_version]) { github_release_task }
|
137
151
|
task(:tag_version) { tag_version_task }
|
138
152
|
task(:commit_modified_files) { commit_modified_files_task }
|
139
153
|
|
154
|
+
task(:next_version) { next_version_task }
|
155
|
+
task(:next_patch_version) { next_version_task(:patch) }
|
156
|
+
task(:next_minor_version) { next_version_task(:minor) }
|
157
|
+
task(:next_major_version) { next_version_task(:major) }
|
158
|
+
|
140
159
|
desc "Updates the gem release tasks with the latest version on Github"
|
141
160
|
task(:update_tasks) { update_tasks_task }
|
142
161
|
end
|
@@ -160,6 +179,32 @@ module GithubGem
|
|
160
179
|
sh "mv #{gemspec.name}-#{gemspec.version}.gem pkg/#{gemspec.name}-#{gemspec.version}.gem"
|
161
180
|
end
|
162
181
|
|
182
|
+
def newest_version
|
183
|
+
git.tags.map { |tag| tag.name.split('-').last }.compact.map { |v| Gem::Version.new(v) }.max || Gem::Version.new('0.0.0')
|
184
|
+
end
|
185
|
+
|
186
|
+
def next_version(increment = nil)
|
187
|
+
next_version = newest_version.segments
|
188
|
+
increment_index = case increment
|
189
|
+
when :micro then 3
|
190
|
+
when :patch then 2
|
191
|
+
when :minor then 1
|
192
|
+
when :major then 0
|
193
|
+
else next_version.length - 1
|
194
|
+
end
|
195
|
+
|
196
|
+
next_version[increment_index] ||= 0
|
197
|
+
next_version[increment_index] = next_version[increment_index].succ
|
198
|
+
((increment_index + 1)...next_version.length).each { |i| next_version[i] = 0 }
|
199
|
+
|
200
|
+
Gem::Version.new(next_version.join('.'))
|
201
|
+
end
|
202
|
+
|
203
|
+
def next_version_task(increment = nil)
|
204
|
+
ENV['VERSION'] = next_version(increment).version
|
205
|
+
puts "Releasing version #{ENV['VERSION']}..."
|
206
|
+
end
|
207
|
+
|
163
208
|
# Updates the version number in the gemspec file, the VERSION constant in the main
|
164
209
|
# include file and the contents of the VERSION file.
|
165
210
|
def version_task
|
@@ -172,10 +217,8 @@ module GithubGem
|
|
172
217
|
|
173
218
|
def check_version_task
|
174
219
|
raise "#{ENV['VERSION']} is not a valid version number!" if ENV['VERSION'] && !Gem::Version.correct?(ENV['VERSION'])
|
175
|
-
proposed_version = Gem::Version.new(ENV['VERSION'] || gemspec.version)
|
176
|
-
#
|
177
|
-
newest_version = git.tags.map { |tag| tag.name.split('-').last }.compact.map { |v| Gem::Version.new(v) }.max
|
178
|
-
raise "This version (#{proposed_version}) is not higher than the highest tagged version (#{newest_version})" if newest_version && newest_version >= proposed_version
|
220
|
+
proposed_version = Gem::Version.new(ENV['VERSION'].dup || gemspec.version)
|
221
|
+
raise "This version (#{proposed_version}) is not higher than the highest tagged version (#{newest_version})" if newest_version >= proposed_version
|
179
222
|
end
|
180
223
|
|
181
224
|
# Checks whether the current branch is not diverged from the remote branch
|
@@ -216,19 +259,19 @@ module GithubGem
|
|
216
259
|
git.push(remote, remote_branch, true)
|
217
260
|
end
|
218
261
|
|
219
|
-
# Checks whether Rubyforge is configured properly
|
220
|
-
def check_rubyforge_task
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
end
|
227
|
-
|
228
|
-
# Task to release the .gem file toRubyforge.
|
229
|
-
def rubyforge_release_task
|
230
|
-
|
231
|
-
end
|
262
|
+
# # Checks whether Rubyforge is configured properly
|
263
|
+
# def check_rubyforge_task
|
264
|
+
# # Login no longer necessary when using rubyforge 2.0.0 gem
|
265
|
+
# # raise "Could not login on rubyforge!" unless `rubyforge login 2>&1`.strip.empty?
|
266
|
+
# output = `rubyforge names`.split("\n")
|
267
|
+
# raise "Rubyforge group not found!" unless output.any? { |line| %r[^groups\s*\:.*\b#{Regexp.quote(gemspec.rubyforge_project)}\b.*] =~ line }
|
268
|
+
# raise "Rubyforge package not found!" unless output.any? { |line| %r[^packages\s*\:.*\b#{Regexp.quote(gemspec.name)}\b.*] =~ line }
|
269
|
+
# end
|
270
|
+
|
271
|
+
# # Task to release the .gem file toRubyforge.
|
272
|
+
# def rubyforge_release_task
|
273
|
+
# sh 'rubyforge', 'add_release', gemspec.rubyforge_project, gemspec.name, gemspec.version.to_s, "pkg/#{gemspec.name}-#{gemspec.version}.gem"
|
274
|
+
# end
|
232
275
|
|
233
276
|
def gemcutter_release_task
|
234
277
|
sh "gem push pkg/#{gemspec.name}-#{gemspec.version}.gem"
|
metadata
CHANGED
@@ -1,55 +1,134 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adyen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 3
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
9
|
+
- 8
|
10
|
+
version: 0.3.8
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Willem van Bergen
|
13
14
|
- Michel Barbosa
|
15
|
+
- Stefan Borsje
|
16
|
+
- Eloy Duran
|
14
17
|
autorequire:
|
15
18
|
bindir: bin
|
16
19
|
cert_chain: []
|
17
20
|
|
18
|
-
date: 2010-
|
21
|
+
date: 2010-09-23 00:00:00 +02:00
|
19
22
|
default_executable:
|
20
23
|
dependencies:
|
21
24
|
- !ruby/object:Gem::Dependency
|
22
|
-
name:
|
25
|
+
name: rake
|
23
26
|
prerelease: false
|
24
27
|
requirement: &id001 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
hash: 3
|
33
|
+
segments:
|
34
|
+
- 0
|
35
|
+
version: "0"
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id001
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: rspec
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
25
43
|
requirements:
|
26
44
|
- - ">="
|
27
45
|
- !ruby/object:Gem::Version
|
46
|
+
hash: 27
|
28
47
|
segments:
|
29
48
|
- 1
|
30
49
|
- 1
|
31
50
|
- 4
|
32
51
|
version: 1.1.4
|
33
52
|
type: :development
|
34
|
-
version_requirements: *
|
53
|
+
version_requirements: *id002
|
35
54
|
- !ruby/object:Gem::Dependency
|
36
55
|
name: git
|
37
56
|
prerelease: false
|
38
|
-
requirement: &
|
57
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
39
59
|
requirements:
|
40
60
|
- - ">="
|
41
61
|
- !ruby/object:Gem::Version
|
62
|
+
hash: 19
|
42
63
|
segments:
|
43
64
|
- 1
|
44
65
|
- 1
|
45
66
|
- 0
|
46
67
|
version: 1.1.0
|
47
68
|
type: :development
|
48
|
-
version_requirements: *
|
69
|
+
version_requirements: *id003
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: gemcutter
|
72
|
+
prerelease: false
|
73
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
type: :development
|
83
|
+
version_requirements: *id004
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: activerecord
|
86
|
+
prerelease: false
|
87
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
hash: 3
|
93
|
+
segments:
|
94
|
+
- 0
|
95
|
+
version: "0"
|
96
|
+
type: :development
|
97
|
+
version_requirements: *id005
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: handsoap
|
100
|
+
prerelease: false
|
101
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
hash: 3
|
107
|
+
segments:
|
108
|
+
- 0
|
109
|
+
version: "0"
|
110
|
+
type: :development
|
111
|
+
version_requirements: *id006
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: nokogiri
|
114
|
+
prerelease: false
|
115
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
hash: 3
|
121
|
+
segments:
|
122
|
+
- 0
|
123
|
+
version: "0"
|
124
|
+
type: :development
|
125
|
+
version_requirements: *id007
|
49
126
|
description: " Package to simplify including the Adyen payments services into a Ruby on Rails application.\n The package provides functionality to create payment forms, handling and storing notifications \n sent by Adyen and consuming the SOAP services provided by Adyen. Moreover, it contains helper\n methods, mocks and matchers to simpify writing tests/specsfor your code.\n"
|
50
127
|
email:
|
51
128
|
- willem@vanbergen.org
|
52
129
|
- cicaboo@gmail.com
|
130
|
+
- mail@sborsje.nl
|
131
|
+
- eloy.de.enige@gmail.com
|
53
132
|
executables: []
|
54
133
|
|
55
134
|
extensions: []
|
@@ -74,6 +153,7 @@ files:
|
|
74
153
|
- lib/adyen/formatter.rb
|
75
154
|
- tasks/github-gem.rake
|
76
155
|
- lib/adyen/encoding.rb
|
156
|
+
- TODO
|
77
157
|
- lib/adyen/matchers.rb
|
78
158
|
- lib/adyen.rb
|
79
159
|
has_rdoc: true
|
@@ -91,28 +171,31 @@ rdoc_options:
|
|
91
171
|
require_paths:
|
92
172
|
- lib
|
93
173
|
required_ruby_version: !ruby/object:Gem::Requirement
|
174
|
+
none: false
|
94
175
|
requirements:
|
95
176
|
- - ">="
|
96
177
|
- !ruby/object:Gem::Version
|
178
|
+
hash: 3
|
97
179
|
segments:
|
98
180
|
- 0
|
99
181
|
version: "0"
|
100
182
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
183
|
+
none: false
|
101
184
|
requirements:
|
102
185
|
- - ">="
|
103
186
|
- !ruby/object:Gem::Version
|
187
|
+
hash: 3
|
104
188
|
segments:
|
105
189
|
- 0
|
106
190
|
version: "0"
|
107
191
|
requirements:
|
108
192
|
- Handsoap is required for accessing the SOAP services. See http://github.com/troelskn/handsoap.
|
109
|
-
- LibXML is required for using the RSpec matchers.
|
110
193
|
- ActiveRecord is required for storing the notifications in your database.
|
111
194
|
rubyforge_project:
|
112
|
-
rubygems_version: 1.3.
|
195
|
+
rubygems_version: 1.3.7
|
113
196
|
signing_key:
|
114
197
|
specification_version: 3
|
115
|
-
summary: Integrate Adyen payment services in
|
198
|
+
summary: Integrate Adyen payment services in your Ruby on Rails application.
|
116
199
|
test_files:
|
117
200
|
- spec/adyen_spec.rb
|
118
201
|
- spec/notification_spec.rb
|