adyen_jpiqueras 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.travis.yml +30 -0
- data/CHANGELOG.md +128 -0
- data/CONTRIBUTING.md +85 -0
- data/Gemfile +11 -0
- data/LICENSE +21 -0
- data/README.md +31 -0
- data/Rakefile +54 -0
- data/adyen_jpiqueras.gemspec +44 -0
- data/config.ru +5 -0
- data/lib/adyen.rb +16 -0
- data/lib/adyen/api.rb +424 -0
- data/lib/adyen/api/cacert.pem +3894 -0
- data/lib/adyen/api/payment_service.rb +374 -0
- data/lib/adyen/api/recurring_service.rb +188 -0
- data/lib/adyen/api/response.rb +61 -0
- data/lib/adyen/api/simple_soap_client.rb +134 -0
- data/lib/adyen/api/templates/payment_service.rb +159 -0
- data/lib/adyen/api/templates/recurring_service.rb +71 -0
- data/lib/adyen/api/test_helpers.rb +133 -0
- data/lib/adyen/api/xml_querier.rb +137 -0
- data/lib/adyen/base.rb +17 -0
- data/lib/adyen/configuration.rb +179 -0
- data/lib/adyen/form.rb +419 -0
- data/lib/adyen/hpp.rb +27 -0
- data/lib/adyen/hpp/request.rb +192 -0
- data/lib/adyen/hpp/response.rb +52 -0
- data/lib/adyen/hpp/signature.rb +34 -0
- data/lib/adyen/matchers.rb +92 -0
- data/lib/adyen/notification_generator.rb +30 -0
- data/lib/adyen/railtie.rb +13 -0
- data/lib/adyen/rest.rb +67 -0
- data/lib/adyen/rest/authorise_payment.rb +234 -0
- data/lib/adyen/rest/authorise_recurring_payment.rb +46 -0
- data/lib/adyen/rest/client.rb +127 -0
- data/lib/adyen/rest/errors.rb +33 -0
- data/lib/adyen/rest/modify_payment.rb +89 -0
- data/lib/adyen/rest/payout.rb +89 -0
- data/lib/adyen/rest/request.rb +104 -0
- data/lib/adyen/rest/response.rb +80 -0
- data/lib/adyen/rest/signature.rb +27 -0
- data/lib/adyen/signature.rb +76 -0
- data/lib/adyen/templates/notification_migration.rb +29 -0
- data/lib/adyen/templates/notification_model.rb +69 -0
- data/lib/adyen/util.rb +147 -0
- data/lib/adyen/version.rb +5 -0
- data/spec/api/api_spec.rb +231 -0
- data/spec/api/payment_service_spec.rb +505 -0
- data/spec/api/recurring_service_spec.rb +236 -0
- data/spec/api/response_spec.rb +59 -0
- data/spec/api/simple_soap_client_spec.rb +133 -0
- data/spec/api/spec_helper.rb +463 -0
- data/spec/api/test_helpers_spec.rb +84 -0
- data/spec/functional/api_spec.rb +117 -0
- data/spec/functional/initializer.rb.ci +3 -0
- data/spec/functional/initializer.rb.sample +3 -0
- data/spec/spec_helper.rb +8 -0
- data/test/form_test.rb +303 -0
- data/test/functional/payment_authorisation_api_test.rb +107 -0
- data/test/functional/payment_modification_api_test.rb +58 -0
- data/test/functional/payout_api_test.rb +93 -0
- data/test/helpers/capybara.rb +12 -0
- data/test/helpers/configure_adyen.rb +6 -0
- data/test/helpers/example_server.rb +136 -0
- data/test/helpers/public/adyen.encrypt.js +679 -0
- data/test/helpers/public/adyen.encrypt.min.js +14 -0
- data/test/helpers/test_cards.rb +20 -0
- data/test/helpers/views/authorized.erb +7 -0
- data/test/helpers/views/hpp.erb +20 -0
- data/test/helpers/views/index.erb +6 -0
- data/test/helpers/views/pay.erb +36 -0
- data/test/helpers/views/redirect_shopper.erb +18 -0
- data/test/hpp/signature_test.rb +37 -0
- data/test/hpp_test.rb +250 -0
- data/test/integration/hpp_integration_test.rb +52 -0
- data/test/integration/payment_using_3d_secure_integration_test.rb +41 -0
- data/test/integration/payment_with_client_side_encryption_integration_test.rb +26 -0
- data/test/rest/signature_test.rb +36 -0
- data/test/rest_list_recurring_details_response_test.rb +22 -0
- data/test/rest_request_test.rb +43 -0
- data/test/rest_response_test.rb +19 -0
- data/test/signature_test.rb +76 -0
- data/test/test_helper.rb +45 -0
- data/test/util_test.rb +78 -0
- data/yard_extensions.rb +16 -0
- metadata +308 -0
data/lib/adyen/rest.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'adyen/base'
|
2
|
+
require 'adyen/rest/client'
|
3
|
+
require 'adyen/rest/signature'
|
4
|
+
|
5
|
+
module Adyen
|
6
|
+
|
7
|
+
# The Adyen::REST module allows you to interact with Adyen's REST API.
|
8
|
+
#
|
9
|
+
# The primary method here is {Adyen::REST.session}, which will yield a
|
10
|
+
# {Adyen::REST::Client} which you can use to send API requests.
|
11
|
+
#
|
12
|
+
# If you need more than one client instance, for instance because you
|
13
|
+
# have multiple acounts set up with different permissions, you can instantiate
|
14
|
+
# clients yourself using {Adyen::REST::Client.new}
|
15
|
+
#
|
16
|
+
# @example Using the singleton Client instance
|
17
|
+
#
|
18
|
+
# Adyen::REST.session do |client|
|
19
|
+
# client.http.read_timeout = 5
|
20
|
+
# response = client.api_request(...)
|
21
|
+
# # ...
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# @example Using a your own Client instance
|
25
|
+
#
|
26
|
+
# Adyen::REST::Client.new('test', 'username', 'password').session do |client|
|
27
|
+
# client.http.read_timeout = 5
|
28
|
+
# response = client.api_request(...)
|
29
|
+
# # ...
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
#
|
33
|
+
# @see Adyen::REST.session Use Adyen::REST.session to run code against the API.
|
34
|
+
# @see Adyen::REST::Client Adyen::REST::Client implements the actual API calls.
|
35
|
+
module REST
|
36
|
+
|
37
|
+
# Provides a singelton REST API client this is configured using the values in
|
38
|
+
# <tt>Adyen.configuration</tt>.
|
39
|
+
#
|
40
|
+
# @param options [Hash] (see Adyen::REST::Client#initialize)
|
41
|
+
# @return [Adyen::REST::Client] A configured client instance
|
42
|
+
# @see .session
|
43
|
+
# @see Adyen::REST::Client.new To instantiate Clients yourself, in case you need more than one.
|
44
|
+
def self.client
|
45
|
+
Adyen::REST::Client.new(
|
46
|
+
Adyen.configuration.environment,
|
47
|
+
Adyen.configuration.api_username,
|
48
|
+
Adyen.configuration.api_password
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Exectutes a session against the Adyen REST API.
|
53
|
+
#
|
54
|
+
# It will use a standard client from {Adyen::REST.client}, or it uses a provided client.
|
55
|
+
# The client will be yielded to the block, and will be closed after the block is finisged
|
56
|
+
#
|
57
|
+
# @param client [Adyen::REST::Client] A custom API client if a default one won't do.
|
58
|
+
# @yield The provided block will be called in which you can interact with the API using
|
59
|
+
# the provided client. The client will be closed after the block returns.
|
60
|
+
# @yieldparam client [Adyen::REST::Client] The REST client to use for the session.
|
61
|
+
# @return [void]
|
62
|
+
# @see Adyen::REST::Client#session
|
63
|
+
def self.session(client = self.client, &block)
|
64
|
+
client.session(&block)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,234 @@
|
|
1
|
+
module Adyen
|
2
|
+
module REST
|
3
|
+
|
4
|
+
# This module implements the <b>Payment.authorise</b>, and <b>Payment.authorise3d</b>
|
5
|
+
# API calls, and includes a custom response class to make handling the response easier.
|
6
|
+
module AuthorisePayment
|
7
|
+
|
8
|
+
class Request < Adyen::REST::Request
|
9
|
+
|
10
|
+
def set_amount(currency, value)
|
11
|
+
self['amount'] = { currency: currency, value: value }
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_encrypted_card_data(source)
|
15
|
+
encrypted_json = if source.respond_to?(:params)
|
16
|
+
source.params['adyen-encrypted-data']
|
17
|
+
elsif source.is_a?(Hash) && source.key?('adyen-encrypted-data')
|
18
|
+
source['adyen-encrypted-data']
|
19
|
+
else
|
20
|
+
source
|
21
|
+
end
|
22
|
+
|
23
|
+
self['additional_data.card.encrypted.json'] = encrypted_json
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_browser_info(request)
|
27
|
+
self['shopper_ip'] = request.ip
|
28
|
+
self['browser_info.accept_header'] = request['Accept'] || "text/html;q=0.9,*/*",
|
29
|
+
self['browser_info.user_agent'] = request.user_agent
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_3d_secure_parameters(request)
|
33
|
+
set_browser_info(request)
|
34
|
+
self['pa_response'] = request.params['PaRes']
|
35
|
+
self['md'] = request.params['MD']
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# The Response class implements some extensions for the authorise payment call.
|
40
|
+
# @see Adyen::REST::Response
|
41
|
+
class Response < Adyen::REST::Response
|
42
|
+
|
43
|
+
# Checks whether the authorisation was successful.
|
44
|
+
# @return [Boolean] <tt>true</tt> iff the authorisation was successful, and the
|
45
|
+
# authorised amount can be captured.
|
46
|
+
def authorised?
|
47
|
+
result_code == AUTHORISED
|
48
|
+
end
|
49
|
+
|
50
|
+
alias_method :authorized?, :authorised?
|
51
|
+
|
52
|
+
# Check whether the payment was refused.
|
53
|
+
# @return [Boolean] <tt>true</tt> iff the authorisation was not successful.
|
54
|
+
def refused?
|
55
|
+
result_code == REFUSED
|
56
|
+
end
|
57
|
+
|
58
|
+
# Checks whether the result of the authorization call was RedirectShopper,
|
59
|
+
# which means that the customer has to be redirected away from your site to
|
60
|
+
# complete the 3Dsecure transaction.
|
61
|
+
# @return [Boolean] <tt>true</tt> iff the shopper has to be redirected,
|
62
|
+
# <tt>false</tt> in any other case.
|
63
|
+
def redirect_shopper?
|
64
|
+
result_code == REDIRECT_SHOPPER
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns the result code from the transaction.
|
68
|
+
# @return [String] The result code.
|
69
|
+
# @see #authorised?
|
70
|
+
# @see #refused?
|
71
|
+
# @see #redirect_shopper?
|
72
|
+
def result_code
|
73
|
+
self[:result_code]
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
AUTHORISED = 'Authorised'.freeze
|
79
|
+
REFUSED = 'Refused'.freeze
|
80
|
+
REDIRECT_SHOPPER = 'RedirectShopper'.freeze
|
81
|
+
private_constant :AUTHORISED, :REFUSED, :REDIRECT_SHOPPER
|
82
|
+
end
|
83
|
+
|
84
|
+
# Generates <tt>Payment.authorise</tt> request for Adyen's webservice.
|
85
|
+
# @param (see #authorise_payment)
|
86
|
+
# @return [Adyen::REST::Request] The request to send
|
87
|
+
# @see #authorise_payment
|
88
|
+
def authorise_payment_request(attributes = {})
|
89
|
+
Adyen::REST::AuthorisePayment::Request.new('Payment.authorise', attributes,
|
90
|
+
response_class: Adyen::REST::AuthorisePayment::Response)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Sends an authorise payment request to Adyen's webservice.
|
94
|
+
# @param attributes [Hash] The attributes to include in the request.
|
95
|
+
# @return [Adyen::REST::AuthorisePayment::Response] The response from Adyen.
|
96
|
+
# The response responds to <tt>.authorised?</tt> to check whether the
|
97
|
+
# authorization was successful.
|
98
|
+
# @see Adyen::REST::AuthorisePayment::Response#authorised?
|
99
|
+
def authorise_payment(attributes)
|
100
|
+
request = authorise_payment_request(attributes)
|
101
|
+
execute_request(request)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Generates a <tt>Payment.authorise3d</tt> request to Adyen's webservice.
|
105
|
+
#
|
106
|
+
# The response differs based on the credit card uses in the transaction.
|
107
|
+
# For some credit cards, an additional offsite step may be required to complete
|
108
|
+
# the transaction. Check <tt>.redirect_shopper?</tt> to see if this is the case.
|
109
|
+
# Other cards are not 3DSecure-enabled, and may immediately authorise the
|
110
|
+
# transaction. Check <tt>.authorised?</tt> to see if this is the case.
|
111
|
+
#
|
112
|
+
# @param attributes [Hash] The attributes to include in the request.
|
113
|
+
# @return [Adyen::REST::AuthorisePayment::Response] The response from Adyen.
|
114
|
+
# @see Adyen::REST::AuthorisePayment::Response#redirect_shopper?
|
115
|
+
# @see Adyen::REST::AuthorisePayment::Response#authorised?
|
116
|
+
def authorise_payment_3dsecure_request(attributes = {})
|
117
|
+
Adyen::REST::AuthorisePayment::Request.new('Payment.authorise3d', attributes,
|
118
|
+
response_class: Adyen::REST::AuthorisePayment::Response)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Sends a 3Dsecure-enabled authorise payment request to Adyen's webservice.
|
122
|
+
#
|
123
|
+
# The response differs based on the credit card uses in the transaction.
|
124
|
+
# For some credit cards, an additional offsite step may be required to complete
|
125
|
+
# the transaction. Check <tt>.redirect_shopper?</tt> to see if this is the case.
|
126
|
+
# Other cards are not 3DSecure-enabled, and may immediately authorise the
|
127
|
+
# transaction. Check <tt>.authorised?</tt> to see if this is the case.
|
128
|
+
#
|
129
|
+
# @param attributes [Hash] The attributes to include in the request.
|
130
|
+
# @return [Adyen::REST::AuthorisePayment::Response] The response from Adyen.
|
131
|
+
# @see Adyen::REST::AuthorisePayment::Response#redirect_shopper?
|
132
|
+
# @see Adyen::REST::AuthorisePayment::Response#authorised?
|
133
|
+
def authorise_payment_3dsecure(attributes)
|
134
|
+
request = authorise_payment_3dsecure_request(attributes)
|
135
|
+
execute_request(request)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Generates <tt>Payment.authorise</tt> request with recurring for Adyen's webservice.
|
139
|
+
# @param (see #authorise_recurring_payment)
|
140
|
+
# @return [Adyen::REST::Request] The request to send
|
141
|
+
# @see #authorise_recurring_payment
|
142
|
+
def authorise_recurring_payment_request(attributes={})
|
143
|
+
Adyen::REST::AuthoriseRecurringPayment::Request.new('Payment.authorise', attributes,
|
144
|
+
response_class: Adyen::REST::AuthorisePayment::Response)
|
145
|
+
end
|
146
|
+
|
147
|
+
# Sends an authorise recurring payment request to Adyen's webservice.
|
148
|
+
# @param attributes [Hash] The attributes to include in the request.
|
149
|
+
# @return [Adyen::REST::AuthorisePayment::Response] The response from Adyen.
|
150
|
+
# The response responds to <tt>.authorised?</tt> to check whether the
|
151
|
+
# authorization was successful.
|
152
|
+
# @see Adyen::REST::AuthorisePayment::Response#authorised?
|
153
|
+
def authorise_recurring_payment(attributes)
|
154
|
+
request = authorise_recurring_payment_request(attributes)
|
155
|
+
execute_request(request)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Generates <tt>Payment.authorise</tt> request with recurring for Adyen's webservice.
|
159
|
+
# This method can be called if a previous contract was established with #authorise_recurring_payment
|
160
|
+
# @param (see #authorise_recurring_payment)
|
161
|
+
# @return [Adyen::REST::Request] The request to send
|
162
|
+
# @see #authorise_recurring_payment
|
163
|
+
def reauthorise_recurring_payment_request(attributes={})
|
164
|
+
Adyen::REST::ReauthoriseRecurringPayment::Request.new('Payment.authorise', attributes,
|
165
|
+
response_class: Adyen::REST::AuthorisePayment::Response)
|
166
|
+
end
|
167
|
+
|
168
|
+
# Sends an authorise recurring payment request to Adyen's webservice.
|
169
|
+
# This method can be called if a previous contract was established with #authorise_recurring_payment
|
170
|
+
# @param attributes [Hash] The attributes to include in the request.
|
171
|
+
# @return [Adyen::REST::AuthorisePayment::Response] The response from Adyen.
|
172
|
+
# The response responds to <tt>.authorised?</tt> to check whether the
|
173
|
+
# authorization was successful.
|
174
|
+
# @see Adyen::REST::AuthorisePayment::Response#authorised?
|
175
|
+
def reauthorise_recurring_payment(attributes)
|
176
|
+
request = reauthorise_recurring_payment_request(attributes)
|
177
|
+
execute_request(request)
|
178
|
+
end
|
179
|
+
|
180
|
+
# The Response class implements some extensions for the list recurring details call.
|
181
|
+
# @see Adyen::REST::Response
|
182
|
+
class ListRecurringDetailsResponse < Adyen::REST::Response
|
183
|
+
# Returns a list of recurring details
|
184
|
+
# @return [Array] A not empty array if there is at least a recurring detail
|
185
|
+
def details
|
186
|
+
mapped_attributes = {
|
187
|
+
:recurring_detail_reference => "recurringDetailReference",
|
188
|
+
:creation_date => "creationDate",
|
189
|
+
:variant => "variant",
|
190
|
+
:card_holder_name => "card.holderName",
|
191
|
+
:card_expiry_month => "card.expiryMonth",
|
192
|
+
:card_expiry_year => "card.expiryYear",
|
193
|
+
:card_number => "card.number"
|
194
|
+
}
|
195
|
+
|
196
|
+
map_response_list("details", mapped_attributes)
|
197
|
+
end
|
198
|
+
|
199
|
+
# Returns a list of recurring details references
|
200
|
+
# @return [Array] A not empty array if there is at least a recurring detail reference
|
201
|
+
def references
|
202
|
+
details.map { |detail| detail[:recurring_detail_reference] }
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# Generates <tt>Recurring.listRecurringDetails</tt> request for Adyen's webservice.
|
207
|
+
# @param (see #list_recurring_details)
|
208
|
+
# @return [Adyen::REST::ListRecurringDetailsPayment::Request] The request to send
|
209
|
+
# @see #list_recurring_details
|
210
|
+
def list_recurring_details_request(attributes = {})
|
211
|
+
Adyen::REST::ListRecurringDetailsPayment::Request.new('Recurring.listRecurringDetails', attributes,
|
212
|
+
response_class: Adyen::REST::AuthorisePayment::ListRecurringDetailsResponse)
|
213
|
+
end
|
214
|
+
|
215
|
+
# Sends an list recurring details request to Adyen's webservice.
|
216
|
+
# @param attributes [Hash] The attributes to include in the request.
|
217
|
+
# @return [Adyen::REST::AuthorisePayment::ListRecurringDetailsResponse] The response from Adyen.
|
218
|
+
# The response responds to <tt>.details</tt> and <tt>.references</tt> with recurring data.
|
219
|
+
# @see Adyen::REST::AuthorisePayment::ListRecurringDetailsResponse#references
|
220
|
+
# @see Adyen::REST::AuthorisePayment::ListRecurringDetailsResponse#details
|
221
|
+
def list_recurring_details(attributes)
|
222
|
+
request = list_recurring_details_request(attributes)
|
223
|
+
execute_request(request)
|
224
|
+
end
|
225
|
+
|
226
|
+
alias_method :authorize_payment_request, :authorise_payment_request
|
227
|
+
alias_method :authorize_payment, :authorise_payment
|
228
|
+
alias_method :authorize_payment_3dsecure_request, :authorise_payment_3dsecure_request
|
229
|
+
alias_method :authorize_payment_3dsecure, :authorise_payment_3dsecure
|
230
|
+
alias_method :reauthorize_recurring_payment_request, :reauthorise_recurring_payment_request
|
231
|
+
alias_method :reauthorize_recurring_payment, :reauthorise_recurring_payment
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
@@ -0,0 +1,46 @@
|
|
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 += ['shopperEmail',
|
12
|
+
'recurring.contract',
|
13
|
+
'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 += ['shopperEmail',
|
27
|
+
'shopperReference',
|
28
|
+
'recurring.contract',
|
29
|
+
'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 += ['recurring.contract',
|
41
|
+
'shopperReference']
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
require 'adyen/rest/errors'
|
5
|
+
require 'adyen/rest/request'
|
6
|
+
require 'adyen/rest/response'
|
7
|
+
require 'adyen/rest/authorise_payment'
|
8
|
+
require 'adyen/rest/authorise_recurring_payment'
|
9
|
+
require 'adyen/rest/modify_payment'
|
10
|
+
require 'adyen/rest/payout'
|
11
|
+
|
12
|
+
module Adyen
|
13
|
+
module REST
|
14
|
+
|
15
|
+
# The Client class acts as a client to Adyen's REST webservice.
|
16
|
+
#
|
17
|
+
# @!attribute environment [r]
|
18
|
+
# The adyen environment to interact with. Either <tt>'live'</tt> or <tt>'test'</tt>.
|
19
|
+
# @return [String]
|
20
|
+
class Client
|
21
|
+
include AuthorisePayment
|
22
|
+
include ModifyPayment
|
23
|
+
include Payout
|
24
|
+
|
25
|
+
attr_reader :environment
|
26
|
+
|
27
|
+
# @param environment [String] The Adyen environment to interface with. Either
|
28
|
+
# <tt>'live'</tt> or <tt>'test'</tt>.
|
29
|
+
# @param username [String] The webservice username, e.g. <tt>ws@Company.Account</tt>
|
30
|
+
# @param password [String] The password associated with the username
|
31
|
+
# @param default_api_params [Hash] Default arguments that will be used for every API call
|
32
|
+
def initialize(environment, username, password)
|
33
|
+
@environment, @username, @password = environment, username, password
|
34
|
+
end
|
35
|
+
|
36
|
+
# Closes the client.
|
37
|
+
#
|
38
|
+
# - This will terminate the HTTP connection.
|
39
|
+
# - After calling this method, the behavior of any further method calls against
|
40
|
+
# this client instance is undefined.
|
41
|
+
#
|
42
|
+
# @return [void]
|
43
|
+
def close
|
44
|
+
@http.finish if @http && @http.started?
|
45
|
+
@http = nil
|
46
|
+
end
|
47
|
+
|
48
|
+
# Runs a client session against the Adyen REST service for the duration of the block,
|
49
|
+
# and closes the connection afterwards.
|
50
|
+
#
|
51
|
+
# @yield The provided block will be called in which you can interact with the API using
|
52
|
+
# the provided client. The client will be closed after the block returns.
|
53
|
+
# @return [void]
|
54
|
+
def session
|
55
|
+
yield(self)
|
56
|
+
ensure
|
57
|
+
close
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
# The underlying <tt>Net::HTTP</tt> instance that is used to execute HTTP
|
62
|
+
# request against the API.
|
63
|
+
#
|
64
|
+
# You can use this to set options on the Net::HTTP instance, like <tt>read_timeout</tt>.
|
65
|
+
# Many of these options will only work if you set them before the HTTP connection is
|
66
|
+
# opened, i.e. before doing the first API call.
|
67
|
+
#
|
68
|
+
# @return [Net::HTTP] The underlying Net::HTTP instance the client uses to perform HTTP request.
|
69
|
+
def http
|
70
|
+
@http ||= Net::HTTP.new(endpoint.host, endpoint.port).tap do |http|
|
71
|
+
http.use_ssl = endpoint.scheme == 'https'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Executes an API request, and returns a reponse of the given type.
|
76
|
+
#
|
77
|
+
# @param request [Adyen::REST::Request] The API request to execute.
|
78
|
+
# <tt>validate!</tt> will be called on the this object before the
|
79
|
+
# request is made.
|
80
|
+
# @param response_type [Class] The response type to use. Use either
|
81
|
+
# <tt>Adyen::REST::Response</tt> or a subclass.
|
82
|
+
# @return [Adyen::REST::Response] A response instance of the provided type
|
83
|
+
# @see execute_http_request The <tt>execute_http_request</tt> takes care
|
84
|
+
# of executing the underlying HTTP request.
|
85
|
+
def execute_request(request)
|
86
|
+
request.validate!
|
87
|
+
http_response = execute_http_request(request)
|
88
|
+
request.build_response(http_response)
|
89
|
+
end
|
90
|
+
|
91
|
+
protected
|
92
|
+
|
93
|
+
# Executes a HTTP request against Adyen's REST webservice.
|
94
|
+
# @param request [Adyen::REST::Request] The request to execute.
|
95
|
+
# @return [Net::HTTPResponse] The response from the server.
|
96
|
+
# @raise [Adyen::REST::Error] if the HTTP response code was not 200.
|
97
|
+
# @see #http Use the <tt>http</tt> method to set options on the underlying
|
98
|
+
# <tt>Net::HTTP</tt> object, like timeouts.
|
99
|
+
def execute_http_request(request)
|
100
|
+
http_request = Net::HTTP::Post.new(request.path)
|
101
|
+
http_request.basic_auth(@username, @password)
|
102
|
+
http_request.set_form_data(request.form_data)
|
103
|
+
|
104
|
+
case response = http.request(http_request)
|
105
|
+
when Net::HTTPOK
|
106
|
+
return response
|
107
|
+
when Net::HTTPInternalServerError
|
108
|
+
raise Adyen::REST::ResponseError.new(response.body)
|
109
|
+
when Net::HTTPUnauthorized
|
110
|
+
raise Adyen::REST::Error.new("Webservice credentials are incorrect")
|
111
|
+
else
|
112
|
+
raise Adyen::REST::Error.new("Unexpected HTTP response code: #{response.code} | response body: #{response.body}")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# The endpoint URI for this client.
|
117
|
+
# @return [URI] The endpoint to use for the environment.
|
118
|
+
def endpoint
|
119
|
+
@endpoint ||= URI(ENDPOINT % [environment])
|
120
|
+
end
|
121
|
+
|
122
|
+
# @see Adyen::REST::Client#endpoint
|
123
|
+
ENDPOINT = 'https://pal-%s.adyen.com/'
|
124
|
+
private_constant :ENDPOINT
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|