adyen_jpiqueras 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|