adyen 2.0.0.pre1 → 2.0.0.pre2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fd5a2022e170a6376459b9fa48062f85ac05ce97
4
- data.tar.gz: dc37f35aa6a2265d467c5ae1dd3d6860cc959894
3
+ metadata.gz: 65289d682bc415347ec65ea427c0d6e7943cb3d3
4
+ data.tar.gz: e3a11edb4ac752b412721f3bdf61a0a04b4bf85e
5
5
  SHA512:
6
- metadata.gz: 6928bc0115a69ed05d2be6cd1deccce983bb3bcb53ff34a8e068505bc8d09b82930df245fc96c6e5bd058830e4a92f2f12df352724285b4bab5f7a3684bf11f2
7
- data.tar.gz: bcc9cd8995fd9c299a71dcc20ec2415b87038bdf1b8d6eb05177303d1470e38f08ee1e72d54fb1dbbaa3813aa8839b67c3bbabd4f16f3eeba6bc5b73358378d7
6
+ metadata.gz: fb6eb78b5a9748124fa432b7105f88d1b0d358ad7fe13817d36ae97036968ebb9514e7986aa8ee071a0210331d16782b67db5179ef90a04733c9d08835b07fcb
7
+ data.tar.gz: db40c3ff10543755bbe055f6f2ac677cbba179aea097ea175389d0c39b9958e6434118ff646deba9cb2ce2dd5096bca23ae869ae1ce45766a738e79f4c5ca4bb
@@ -2,13 +2,13 @@ language: ruby
2
2
  cache: bundler
3
3
  script: bundle exec rake
4
4
  rvm:
5
- - 1.9.3
6
- - 2.0.0
7
- - 2.1.1
8
- - ruby-head
9
- - rbx-2
10
- - jruby-19mode
11
- - jruby-head
5
+ - "2.0"
6
+ - "2.1"
7
+ - "2.2"
8
+ - "ruby-head"
9
+ - "rbx-2"
10
+ - "jruby-19mode"
11
+ - "jruby-head"
12
12
  matrix:
13
13
  allow_failures:
14
14
  - rvm: jruby-head
@@ -51,11 +51,11 @@ So follow good engineering practices:
51
51
 
52
52
  ### Contributors
53
53
 
54
- - Willem van Bergen
55
- - Michel Barbosa
56
- - Stefan Borsje
57
- - Eloy Durán
58
- - Tobias Bielohlawek
54
+ - [Willem van Bergen](https://github.com/wvanbergen)
55
+ - [Michel Barbosa](https://github.com/mbarb0sa)
56
+ - [Stefan Borsje](https://github.com/sborsje)
57
+ - [Eloy Durán](https://github.com/alloy)
58
+ - [Tobias Bielohlawek](https://github.com/rngtng)
59
59
  - Dimitri Sinitsa
60
60
  - Rinaldi Fonseca
61
61
  - Joost Hietbrink
@@ -73,6 +73,7 @@ So follow good engineering practices:
73
73
  - Thibaut Assus
74
74
  - Vinicius Ferriani
75
75
  - Timo Rößner
76
+ - [Enzo Finidori](https://github.com/tiredenzo)
76
77
 
77
78
  ## Release process
78
79
 
data/Rakefile CHANGED
@@ -2,26 +2,35 @@ require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
3
  require "rake/testtask"
4
4
 
5
- Rake::TestTask.new do |t|
6
- t.libs << "test"
7
- t.test_files = FileList['test/**/*_test.rb']
8
- end
5
+ namespace(:test) do
6
+ Rake::TestTask.new(:all) do |t|
7
+ t.description = "Run all tests"
8
+ t.libs << "test"
9
+ t.test_files = FileList['test/**/*_test.rb']
10
+ end
9
11
 
10
- Rake::TestTask.new('test:unit') do |t|
11
- t.libs << "test"
12
- t.test_files = FileList['test/*_test.rb']
13
- end
12
+ Rake::TestTask.new(:unit) do |t|
13
+ t.description = "Run unit tests"
14
+ t.libs << "test"
15
+ t.test_files = FileList['test/*_test.rb']
16
+ end
14
17
 
15
- Rake::TestTask.new('test:functional') do |t|
16
- t.libs << "test"
17
- t.test_files = FileList['test/functional/**/*_test.rb']
18
- end
18
+ Rake::TestTask.new(:functional) do |t|
19
+ t.description = "Run functional tests"
20
+ t.libs << "test"
21
+ t.test_files = FileList['test/functional/**/*_test.rb']
22
+ end
19
23
 
20
- Rake::TestTask.new('test:integration') do |t|
21
- t.libs << "test"
22
- t.test_files = FileList['test/integration/**/*_test.rb']
24
+ Rake::TestTask.new(:integration) do |t|
25
+ t.description = "Run integration tests"
26
+ t.libs << "test"
27
+ t.test_files = FileList['test/integration/**/*_test.rb']
28
+ end
23
29
  end
24
30
 
31
+ desc "Run unit and functional tests"
32
+ task :test => %w{test:unit test:functional}
33
+
25
34
  RSpec::Core::RakeTask.new(:spec) do |task|
26
35
  task.pattern = "./spec/**/*_spec.rb"
27
36
  task.rspec_opts = ['--color']
@@ -42,14 +51,4 @@ end
42
51
  # sh "git diff-index --quiet HEAD #{CACERT_PATH} || (git add #{CACERT_PATH} && git commit -m '[API] Update CA root certificates file.')"
43
52
  # end
44
53
 
45
- begin
46
- require 'rubygems'
47
- require 'yard'
48
- require File.expand_path('../yard_extensions', __FILE__)
49
- YARD::Rake::YardocTask.new do |y|
50
- y.options << '--no-private' << '--title' << "The 'Adyen payment service' library for Ruby"
51
- end
52
- rescue LoadError
53
- end
54
-
55
- task :default => [:test, :spec]
54
+ task :default => %w{test spec}
@@ -1,14 +1,18 @@
1
- # The Adyen module is the container module for all Adyen related functionality,
2
- # which is implemented in submodules. This module only contains some global
1
+ # The Adyen module is the container module for all Adyen related functionality,
2
+ # which is implemented in submodules. This module only contains some global
3
3
  # configuration methods.
4
4
  #
5
5
  # The most important submodules are:
6
- # * {Adyen::Form} for generating payment form fields, generating redirect URLs
6
+ # * {Adyen::Form} for generating payment form fields, generating redirect URLs
7
7
  # to the Adyen payment system, and generating and checking of signatures.
8
8
  # * {Adyen::API} for communicating with the Adyen SOAP services for issuing
9
9
  # (recurring) payments and recurring contract maintenance.
10
10
  module Adyen
11
11
 
12
+ # Basic exception class for Adyen
13
+ class Error < ::StandardError
14
+ end
15
+
12
16
  # @return [Configuration] The configuration singleton.
13
17
  def self.configuration
14
18
  @configuration ||= Adyen::Configuration.new
@@ -14,7 +14,7 @@ module Adyen
14
14
  def set_encrypted_card_data(source)
15
15
  encrypted_json = if source.respond_to?(:params)
16
16
  source.params['adyen-encrypted-data']
17
- elsif source.respond_to?(:[]) && source.key?('adyen-encrypted-data')
17
+ elsif source.is_a?(Hash) && source.key?('adyen-encrypted-data')
18
18
  source['adyen-encrypted-data']
19
19
  else
20
20
  source
@@ -139,10 +139,106 @@ module Adyen
139
139
  execute_request(request)
140
140
  end
141
141
 
142
+ # Generates <tt>Payment.authorise</tt> request with recurring for Adyen's webservice.
143
+ # @param (see #authorise_recurring_payment)
144
+ # @return [Adyen::REST::Request] The request to send
145
+ # @see #authorise_recurring_payment
146
+ def authorise_recurring_payment_request(attributes={})
147
+ Adyen::REST::AuthoriseRecurringPayment::Request.new('Payment.authorise', attributes,
148
+ prefix: 'payment_request',
149
+ response_class: Adyen::REST::AuthorisePayment::Response,
150
+ response_options: { prefix: 'payment_result' })
151
+ end
152
+
153
+ # Sends an authorise recurring payment request to Adyen's webservice.
154
+ # @param attributes [Hash] The attributes to include in the request.
155
+ # @return [Adyen::REST::AuthorisePayment::Response] The response from Adyen.
156
+ # The response responds to <tt>.authorised?</tt> to check whether the
157
+ # authorization was successful.
158
+ # @see Adyen::REST::AuthorisePayment::Response#authorised?
159
+ def authorise_recurring_payment(attributes)
160
+ request = authorise_recurring_payment_request(attributes)
161
+ execute_request(request)
162
+ end
163
+
164
+ # Generates <tt>Payment.authorise</tt> request with recurring for Adyen's webservice.
165
+ # This method can be called if a previous contract was established with #authorise_recurring_payment
166
+ # @param (see #authorise_recurring_payment)
167
+ # @return [Adyen::REST::Request] The request to send
168
+ # @see #authorise_recurring_payment
169
+ def reauthorise_recurring_payment_request(attributes={})
170
+ Adyen::REST::ReauthoriseRecurringPayment::Request.new('Payment.authorise', attributes,
171
+ prefix: 'payment_request',
172
+ response_class: Adyen::REST::AuthorisePayment::Response,
173
+ response_options: { prefix: 'payment_result' })
174
+ end
175
+
176
+ # Sends an authorise recurring payment request to Adyen's webservice.
177
+ # This method can be called if a previous contract was established with #authorise_recurring_payment
178
+ # @param attributes [Hash] The attributes to include in the request.
179
+ # @return [Adyen::REST::AuthorisePayment::Response] The response from Adyen.
180
+ # The response responds to <tt>.authorised?</tt> to check whether the
181
+ # authorization was successful.
182
+ # @see Adyen::REST::AuthorisePayment::Response#authorised?
183
+ def reauthorise_recurring_payment(attributes)
184
+ request = reauthorise_recurring_payment_request(attributes)
185
+ execute_request(request)
186
+ end
187
+
188
+ # The Response class implements some extensions for the list recurring details call.
189
+ # @see Adyen::REST::Response
190
+ class ListRecurringDetailsResponse < Adyen::REST::Response
191
+ # Returns a list of recurring details
192
+ # @return [Array] A not empty array if there is at least a recurring detail
193
+ def details
194
+ mapped_attributes = {
195
+ :recurring_detail_reference => "recurringDetailReference",
196
+ :creation_date => "creationDate",
197
+ :variant => "variant",
198
+ :card_holder_name => "card.holderName",
199
+ :card_expiry_month => "card.expiryMonth",
200
+ :card_expiry_year => "card.expiryYear",
201
+ :card_number => "card.number"
202
+ }
203
+
204
+ map_response_list("recurringDetailsResult.details", mapped_attributes)
205
+ end
206
+
207
+ # Returns a list of recurring details references
208
+ # @return [Array] A not empty array if there is at least a recurring detail reference
209
+ def references
210
+ details.map { |detail| detail[:recurring_detail_reference] }
211
+ end
212
+ end
213
+
214
+ # Generates <tt>Recurring.listRecurringDetails</tt> request for Adyen's webservice.
215
+ # @param (see #list_recurring_details)
216
+ # @return [Adyen::REST::ListRecurringDetailsPayment::Request] The request to send
217
+ # @see #list_recurring_details
218
+ def list_recurring_details_request(attributes = {})
219
+ Adyen::REST::ListRecurringDetailsPayment::Request.new('Recurring.listRecurringDetails', attributes,
220
+ prefix: 'recurring_details_request',
221
+ response_class: Adyen::REST::AuthorisePayment::ListRecurringDetailsResponse,
222
+ response_options: { prefix: 'recurring_details_result' })
223
+ end
224
+
225
+ # Sends an list recurring details request to Adyen's webservice.
226
+ # @param attributes [Hash] The attributes to include in the request.
227
+ # @return [Adyen::REST::AuthorisePayment::ListRecurringDetailsResponse] The response from Adyen.
228
+ # The response responds to <tt>.details</tt> and <tt>.references</tt> with recurring data.
229
+ # @see Adyen::REST::AuthorisePayment::ListRecurringDetailsResponse#references
230
+ # @see Adyen::REST::AuthorisePayment::ListRecurringDetailsResponse#details
231
+ def list_recurring_details(attributes)
232
+ request = list_recurring_details_request(attributes)
233
+ execute_request(request)
234
+ end
235
+
142
236
  alias_method :authorize_payment_request, :authorise_payment_request
143
237
  alias_method :authorize_payment, :authorise_payment
144
238
  alias_method :authorize_payment_3dsecure_request, :authorise_payment_3dsecure_request
145
239
  alias_method :authorize_payment_3dsecure, :authorise_payment_3dsecure
240
+ alias_method :reauthorize_recurring_payment_request, :reauthorise_recurring_payment_request
241
+ alias_method :reauthorize_recurring_payment, :reauthorise_recurring_payment
146
242
  end
147
243
  end
148
244
  end
@@ -0,0 +1,47 @@
1
+ module Adyen
2
+ module REST
3
+
4
+ # This modules implements the recurring requests using<b>Payment.authorise</b> by subclassing Adyen::REST::AuthorisePayment::Request it only adds mandatory fields to it
5
+ # Those requests can be called using #Adyen::Rest::AuthorisePayment.authorise_recurring_payment and #Adyen::Rest::AuthorisePayment.reauthorise_recurring_payment
6
+ module AuthoriseRecurringPayment
7
+ class Request < Adyen::REST::AuthorisePayment::Request
8
+ def initialize(action, attributes, options)
9
+ attributes[:recurring] ||= { contract: 'RECURRING' }
10
+ super(action, attributes, options)
11
+ @required_attributes += ['paymentRequest.shopperEmail',
12
+ 'paymentRequest.recurring.contract',
13
+ 'paymentRequest.shopperReference',
14
+ ]
15
+ end
16
+ end
17
+ end
18
+
19
+ module ReauthoriseRecurringPayment
20
+ class Request < Adyen::REST::AuthorisePayment::Request
21
+ def initialize(action, attributes, options)
22
+ attributes[:recurring] ||= { contract: 'RECURRING' }
23
+ attributes[:shopper_interaction] ||= 'ContAuth'
24
+ attributes[:selected_recurring_detail_reference] ||= 'LATEST'
25
+ super(action, attributes, options)
26
+ @required_attributes += ['paymentRequest.shopperEmail',
27
+ 'paymentRequest.shopperReference',
28
+ 'paymentRequest.recurring.contract',
29
+ 'paymentRequest.shopperInteraction'
30
+ ]
31
+ end
32
+ end
33
+ end
34
+
35
+ module ListRecurringDetailsPayment
36
+ class Request < Adyen::REST::Request
37
+ def initialize(action, attributes, options)
38
+ attributes[:recurring] ||= { contract: 'RECURRING' }
39
+ super(action, attributes, options)
40
+ @required_attributes += ['recurringDetailsRequest.merchantAccount',
41
+ 'recurringDetailsRequest.recurring.contract',
42
+ 'recurringDetailsRequest.shopperReference']
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -5,6 +5,7 @@ require 'adyen/rest/errors'
5
5
  require 'adyen/rest/request'
6
6
  require 'adyen/rest/response'
7
7
  require 'adyen/rest/authorise_payment'
8
+ require 'adyen/rest/authorise_recurring_payment'
8
9
  require 'adyen/rest/modify_payment'
9
10
 
10
11
  module Adyen
@@ -2,11 +2,11 @@ module Adyen
2
2
  module REST
3
3
 
4
4
  # The main exception class for error reporting when using the REST API Client.
5
- class Error < ::StandardError
5
+ class Error < Adyen::Error
6
6
  end
7
7
 
8
8
  # Exception class for errors on requests
9
- class RequestValidationFailed < Error
9
+ class RequestValidationFailed < Adyen::REST::Error
10
10
  end
11
11
 
12
12
  # Exception class for error responses from the Adyen API.
@@ -17,7 +17,7 @@ module Adyen
17
17
  # @return [Integer, nil]
18
18
  # @!attribute description
19
19
  # @return [String, nil]
20
- class ResponseError < Error
20
+ class ResponseError < Adyen::REST::Error
21
21
  attr_accessor :category, :code, :description
22
22
 
23
23
  def initialize(response_body)
@@ -41,6 +41,25 @@ module Adyen
41
41
 
42
42
  protected
43
43
 
44
+ def map_response_list(response_prefix, mapped_attributes)
45
+ list = []
46
+ index = 0
47
+
48
+ loop do
49
+ response = {}
50
+ mapped_attributes.each do |key, value|
51
+ new_value = attributes["#{response_prefix}.#{index.to_s}.#{value}"]
52
+ response[key] = new_value unless new_value.empty?
53
+ end
54
+
55
+ index += 1
56
+ break unless response.any?
57
+ list << response
58
+ end
59
+
60
+ list
61
+ end
62
+
44
63
  def canonical_name(name)
45
64
  Adyen::Util.camelize(apply_prefix(name))
46
65
  end
@@ -1,5 +1,5 @@
1
1
  module Adyen
2
2
  # Version constant for the Adyen plugin.
3
3
  # Set it & commit the change before running rake release.
4
- VERSION = "2.0.0.pre1"
4
+ VERSION = "2.0.0.pre2"
5
5
  end
@@ -51,4 +51,56 @@ class PaymentAuthorisationAPITest < Minitest::Test
51
51
  assert response.has_attribute?(:md)
52
52
  assert_equal "https://test.adyen.com/hpp/3d/validate.shtml", response['issuer_url']
53
53
  end
54
+
55
+ def test_initial_recurring_payment_api_request
56
+ response = @client.authorise_recurring_payment(
57
+ merchant_account: 'VanBergenORG',
58
+ shopper_email: 'willem@van-bergen.org',
59
+ shopper_reference: 'willem42',
60
+ amount: { currency: 'EUR', value: 1234 },
61
+ reference: 'Test initial recurring payment order #1',
62
+ card: Adyen::TestCards::VISA
63
+ )
64
+
65
+ assert response.authorised?
66
+ assert response.psp_reference
67
+ end
68
+
69
+ def test_recurring_payment_api_request
70
+ response = @client.reauthorise_recurring_payment(
71
+ merchant_account: 'VanBergenORG',
72
+ shopper_email: 'willem@van-bergen.org',
73
+ shopper_reference: 'willem42',
74
+ amount: { currency: 'EUR', value: 1234 },
75
+ reference: 'Test recurring payment order #1'
76
+ )
77
+
78
+ assert response.authorised?
79
+ assert response.psp_reference
80
+ end
81
+
82
+ def test_list_recurring_details_api_request
83
+ response = @client.list_recurring_details(
84
+ recurring: { contract: "RECURRING" },
85
+ merchant_account: 'VanBergenORG',
86
+ shopper_reference: 'willem42',
87
+ )
88
+
89
+ assert !response.details.first[:recurring_detail_reference].empty?
90
+ assert_equal response.details.first[:card_holder_name], Adyen::TestCards::VISA[:holder_name]
91
+ assert_equal response.details.first[:card_expiry_month].to_i, Adyen::TestCards::VISA[:expiry_month].to_i
92
+ assert_equal response.details.first[:card_expiry_year], Adyen::TestCards::VISA[:expiry_year]
93
+ assert_equal response.details.first[:card_number], Adyen::TestCards::VISA[:number][-4..-1]
94
+ end
95
+
96
+
97
+ def test_list_recurring_references_api_request
98
+ response = @client.list_recurring_details(
99
+ recurring: { contract: "RECURRING" },
100
+ merchant_account: 'VanBergenORG',
101
+ shopper_reference: 'willem42',
102
+ )
103
+
104
+ assert_equal response.references.first, response.details.first[:recurring_detail_reference]
105
+ end
54
106
  end
@@ -100,6 +100,12 @@ class Adyen::ExampleServer < Sinatra::Base
100
100
  auth_code: api_response[:auth_code],
101
101
  }
102
102
 
103
- erb :authorized
103
+ if api_response.authorised?
104
+ erb :authorized
105
+
106
+ else
107
+ status 400
108
+ body api_response[:refusal_reason]
109
+ end
104
110
  end
105
111
  end
@@ -0,0 +1,21 @@
1
+ require 'test_helper'
2
+
3
+ class ListRecurringDetailsResponse < Minitest::Test
4
+
5
+ def setup
6
+ @http_response = mock
7
+ @recurring_detail_reference = "8314231570619177"
8
+ @body = "recurringDetailsResult.shopperReference=lup%40lup.com%23555&recurringDetailsResult.details.0.variant=mc&recurringDetailsResult.details.0.card.number=1111&recurringDetailsResult.details.0.recurringDetailReference=#{@recurring_detail_reference}&recurringDetailsResult.details.0.card.expiryMonth=6&recurringDetailsResult.creationDate=2015-02-05T18%3A24%3A21%2B01%3A00&recurringDetailsResult.lastKnownShopperEmail=lup%40lup.com&recurringDetailsResult.details.0.creationDate=2015-02-05T18%3A24%3A21%2B01%3A00&recurringDetailsResult.details.0.card.expiryYear=2016&recurringDetailsResult.details.0.card.holderName=jose"
9
+ @expected_details = [{ recurring_detail_reference: @recurring_detail_reference, creation_date: "2015-02-05T18:24:21+01:00", variant: "mc", card_holder_name: "jose", card_expiry_month: "6", card_expiry_year: "2016", card_number: "1111" }]
10
+ @http_response.stubs(body: @body)
11
+ @response = Adyen::REST::AuthorisePayment::ListRecurringDetailsResponse.new(@http_response, prefix: 'recurring_details_result')
12
+ end
13
+
14
+ def test_getting_details
15
+ assert_equal @response.details, @expected_details
16
+ end
17
+
18
+ def test_getting_references
19
+ assert_equal @response.references, [@recurring_detail_reference]
20
+ end
21
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adyen
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre1
4
+ version: 2.0.0.pre2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Willem van Bergen
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2015-01-15 00:00:00.000000000 Z
14
+ date: 2015-03-06 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rake
@@ -170,6 +170,7 @@ files:
170
170
  - lib/adyen/railtie.rb
171
171
  - lib/adyen/rest.rb
172
172
  - lib/adyen/rest/authorise_payment.rb
173
+ - lib/adyen/rest/authorise_recurring_payment.rb
173
174
  - lib/adyen/rest/client.rb
174
175
  - lib/adyen/rest/errors.rb
175
176
  - lib/adyen/rest/modify_payment.rb
@@ -206,6 +207,7 @@ files:
206
207
  - test/integration/hpp_integration_test.rb
207
208
  - test/integration/payment_using_3d_secure_integration_test.rb
208
209
  - test/integration/payment_with_client_side_encryption_integration_test.rb
210
+ - test/rest_list_recurring_details_response_test.rb
209
211
  - test/rest_request_test.rb
210
212
  - test/rest_response_test.rb
211
213
  - test/test_helper.rb
@@ -270,6 +272,7 @@ test_files:
270
272
  - test/integration/hpp_integration_test.rb
271
273
  - test/integration/payment_using_3d_secure_integration_test.rb
272
274
  - test/integration/payment_with_client_side_encryption_integration_test.rb
275
+ - test/rest_list_recurring_details_response_test.rb
273
276
  - test/rest_request_test.rb
274
277
  - test/rest_response_test.rb
275
278
  - test/test_helper.rb