Skip to content

Commit 2530b4d

Browse files
Merge pull request #57 from Adyen/develop
New release 1.4.0
2 parents 28eb420 + 1d94500 commit 2530b4d

26 files changed

+1771
-136
lines changed

Adyen/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
AdyenRecurring,
1919
AdyenPayment,
2020
AdyenThirdPartyPayout,
21-
AdyenHPP)
21+
AdyenHPP,
22+
AdyenCheckoutApi)
2223

2324
from .httpclient import HTTPClient
2425

@@ -30,10 +31,12 @@ def __init__(self, **kwargs):
3031
self.payout = AdyenThirdPartyPayout(client=self.client)
3132
self.hpp = AdyenHPP(client=self.client)
3233
self.recurring = AdyenRecurring(client=self.client)
34+
self.checkout = AdyenCheckoutApi(client=self.client)
3335

3436

3537
_base_adyen_obj = Adyen()
3638
recurring = _base_adyen_obj.recurring
3739
hpp = _base_adyen_obj.hpp
3840
payment = _base_adyen_obj.payment
3941
payout = _base_adyen_obj.payout
42+
checkout = _base_adyen_obj.checkout

Adyen/client.py

Lines changed: 165 additions & 32 deletions
Large diffs are not rendered by default.

Adyen/exceptions.py

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,26 @@ def __init__(self,
99
url="",
1010
psp="",
1111
headers="",
12-
status_code=""):
12+
status_code="",
13+
error_code=""):
1314
self.message = message
1415
self.raw_request = raw_request
1516
self.raw_response = raw_response
1617
self.url = url
1718
self.psp = psp
1819
self.headers = headers
1920
self.status_code = status_code
21+
self.error_code = error_code
2022

2123
def __str__(self):
2224
return repr("{}:{}".format(self.__class__.__name__, self.message))
2325

2426
def debug(self):
2527
return ("class: {}\nmessage: {}\nHTTP status_code:{}\nurl: {}"
26-
"request: {}\nresponse: {}\nheaders: {}".format(
27-
self.__class__.__name__,
28-
self.message,
29-
self.status_code,
30-
self.url,
31-
self.raw_request,
32-
self.raw_response,
33-
self.headers
34-
)
35-
)
28+
"request: {}\nresponse: {}\nheaders: {}"
29+
.format(self.__class__.__name__, self.message,
30+
self.status_code, self.url, self.raw_request,
31+
self.raw_response, self.headers))
3632

3733

3834
class AdyenInvalidRequestError(AdyenError):
@@ -42,13 +38,9 @@ class AdyenInvalidRequestError(AdyenError):
4238
class AdyenAPIResponseError(AdyenError):
4339
def __init__(self,
4440
message,
45-
result="",
46-
error_code="",
4741
*args,
4842
**kwargs):
4943
super(AdyenAPIResponseError, self).__init__(message, *args, **kwargs)
50-
self.error_code = error_code
51-
self.result = result
5244

5345

5446
class AdyenAPIAuthenticationError(AdyenAPIResponseError):
@@ -73,3 +65,7 @@ class AdyenAPIInvalidAmount(AdyenAPIResponseError):
7365

7466
class AdyenAPIInvalidFormat(AdyenAPIResponseError):
7567
pass
68+
69+
70+
class AdyenEndpointInvalidFormat(AdyenError):
71+
pass

Adyen/httpclient.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ def _requests_post(self, url,
142142
data=None,
143143
username="",
144144
password="",
145+
xapikey="",
145146
headers=None,
146147
timeout=30):
147148
"""This function will POST to the url endpoint using requests.
@@ -175,6 +176,8 @@ def _requests_post(self, url,
175176
auth = None
176177
if username and password:
177178
auth = requests.auth.HTTPBasicAuth(username, password)
179+
elif xapikey:
180+
headers['x-api-key'] = xapikey
178181

179182
# Add User-Agent header to request so that the request
180183
# can be identified as coming from the Adyen Python library.
@@ -246,12 +249,12 @@ def _urllib_post(self, url,
246249
if username and password:
247250
if sys.version_info[0] >= 3:
248251
basic_authstring = base64.encodebytes(('%s:%s' %
249-
(username, password))
250-
.encode()).decode().\
252+
(username, password))
253+
.encode()).decode(). \
251254
replace('\n', '')
252255
else:
253256
basic_authstring = base64.encodestring('%s:%s' % (username,
254-
password)).\
257+
password)). \
255258
replace('\n', '')
256259
url_request.add_header("Authorization",
257260
"Basic %s" % basic_authstring)

Adyen/services.py

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def hpp_payment(self, request="", skip_details=None, **kwargs):
117117
if all(k in request for k in ("shopperEmail", "shopperReference",
118118
"recurringContract")):
119119
recc = request['recurringContract']
120-
if recc != 'ONECLICK' and recc != 'RECURRING'\
120+
if recc != 'ONECLICK' and recc != 'RECURRING' \
121121
and recc != 'ONECLICK,RECURRING':
122122
raise ValueError(
123123
"HPP: recurringContract must be on of the following"
@@ -190,8 +190,8 @@ def capture(self, request="", **kwargs):
190190
action = "capture"
191191

192192
if validation.check_in(request, action):
193-
if request['modificationAmount']["value"] == "" or\
194-
request['modificationAmount']['value'] == "0":
193+
if request['modificationAmount']["value"] == "" or \
194+
request['modificationAmount']['value'] == "0":
195195
raise ValueError(
196196
"Set the 'modificationAmount' to the original transaction"
197197
" amount, or less for a partial capture. "
@@ -210,8 +210,8 @@ def refund(self, request="", **kwargs):
210210
action = "refund"
211211

212212
if validation.check_in(request, action):
213-
if request['modificationAmount']['value'] == "" or\
214-
request['modificationAmount']['value'] == "0":
213+
if request['modificationAmount']['value'] == "" or \
214+
request['modificationAmount']['value'] == "0":
215215
raise ValueError(
216216
"To refund this payment, provide the original value. "
217217
"Set the value to less than the original amount, "
@@ -279,3 +279,62 @@ def store_detail_and_submit(self, request=None, **kwargs):
279279
return self.client.call_api(
280280
request, self.service, action, **kwargs
281281
)
282+
283+
284+
class AdyenCheckoutApi(AdyenServiceBase):
285+
"""This represents the Adyen Checkout API .
286+
287+
API calls currently implemented:
288+
paymentMethods
289+
payments
290+
payments/details
291+
originKeys
292+
Please refer to the checkout documentation for specifics around the API.
293+
https://docs.adyen.com/developers/checkout
294+
295+
The AdyenPayment class, is accessible as adyen.payment.method(args)
296+
297+
Args:
298+
client (AdyenAPIClient, optional): An API client for the service to
299+
use. If not provided, a new API client will be created.
300+
"""
301+
302+
def __init__(self, client=""):
303+
super(AdyenCheckoutApi, self).__init__(client=client)
304+
self.service = "Checkout"
305+
306+
def payment_methods(self, request="", **kwargs):
307+
action = "paymentMethods"
308+
if validation.check_in(request, action):
309+
if 'merchantAccount' in request:
310+
if request['merchantAccount'] == '':
311+
raise ValueError(
312+
'merchantAccount must contain the merchant account'
313+
' when retrieving payment methods.')
314+
315+
return self.client.call_checkout_api(request, action, **kwargs)
316+
317+
def payments(self, request="", **kwargs):
318+
action = "payments"
319+
if validation.check_in(request, action):
320+
return self.client.call_checkout_api(request, action, **kwargs)
321+
322+
def payments_details(self, request="", **kwargs):
323+
action = "paymentsDetails"
324+
if validation.check_in(request, action):
325+
return self.client.call_checkout_api(request, action, **kwargs)
326+
327+
def payment_session(self, request="", **kwargs):
328+
action = "paymentSession"
329+
if validation.check_in(request, action):
330+
return self.client.call_checkout_api(request, action, **kwargs)
331+
332+
def payment_result(self, request="", **kwargs):
333+
action = "paymentsResult"
334+
if validation.check_in(request, action):
335+
return self.client.call_checkout_api(request, action, **kwargs)
336+
337+
def origin_keys(self, request="", **kwargs):
338+
action = "originKeys"
339+
if validation.check_in(request, action):
340+
return self.client.call_checkout_api(request, action, **kwargs)

Adyen/settings.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
#!/bin/python
2-
1+
# Those constants are used from the library only
32
BASE_PAL_URL = "https://pal-{}.adyen.com/pal/servlet"
43
BASE_HPP_URL = "https://{}.adyen.com/hpp"
5-
API_VERSION = "v30"
4+
ENDPOINT_CHECKOUT_TEST = "https://checkout-test.adyen.com"
5+
ENDPOINT_CHECKOUT_LIVE_SUFFIX = "https://{}-checkout-live" \
6+
".adyenpayments.com/checkout"
7+
API_CHECKOUT_VERSION = "v40"
8+
API_CHECKOUT_UTILITY_VERSION = "v1"
69
API_RECURRING_VERSION = "v25"
10+
API_PAYMENT_VERSION = "v40"
11+
API_PAYOUT_VERSION = "v30"

Adyen/validation.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@
1717
actions['refund'] = ["modificationAmount", "originalReference"]
1818
actions['cancelOrRefund'] = ["originalReference"]
1919

20+
actions['paymentMethods'] = ["merchantAccount"]
21+
actions['payments'] = ["amount", "reference", "paymentMethod",
22+
"merchantAccount", "returnUrl"]
23+
actions['paymentsDetails'] = ["paymentData", "details"]
24+
actions['paymentSession'] = ["amount", "reference", "shopperReference",
25+
"channel", "returnUrl", "countryCode",
26+
"shopperLocale", "sessionValidity",
27+
"merchantAccount"]
28+
actions['paymentsResult'] = ["payload"]
29+
actions['originKeys'] = ["originDomains"]
30+
2031
payout_required_fields = {
2132
'confirmThirdParty': (
2233
'merchantAccount',

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
setup(
44
name='Adyen',
55
packages=['Adyen'],
6-
version='1.3.0',
6+
version='1.4.0',
77
maintainer='Adyen',
88
maintainer_email='support@adyen.com',
99
description='Adyen Python Api',

0 commit comments

Comments
 (0)