Skip to content

Commit 9361510

Browse files
authored
Merge pull request #158 from TierMobility/add-modifications-to-checkout-api
Add Modifications to Python Library For Checkout Api
2 parents ff06864 + 9006c95 commit 9361510

File tree

7 files changed

+287
-3
lines changed

7 files changed

+287
-3
lines changed

Adyen/client.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,14 @@ def _determine_hpp_url(platform, action):
157157
result = '/'.join([base_uri, service])
158158
return result
159159

160-
def _determine_checkout_url(self, platform, action):
160+
def _determine_checkout_url(self, platform, action, path_param=None):
161161
"""This returns the Adyen API endpoint based on the provided platform,
162162
service and action.
163163
164164
Args:
165165
platform (str): Adyen platform, ie 'live' or 'test'.
166166
action (str): the API action to perform.
167+
path_param Optional[(str)]: a generic id that can be used to modify a payment e.g. paymentPspReference.
167168
"""
168169
api_version = self.api_checkout_version
169170
if platform == "test":
@@ -183,6 +184,16 @@ def _determine_checkout_url(self, platform, action):
183184
action = "payments/details"
184185
if action == "paymentsResult":
185186
action = "payments/result"
187+
if action == "cancels":
188+
action = "/cancels"
189+
if action == "paymentsCancelsWithReference":
190+
action = f"payments/{path_param}/cancels"
191+
if action == "paymentsCapture":
192+
action = f"/payments/{path_param}/captures"
193+
if action == "paymentsReversals":
194+
action = f"payments/{path_param}/reversals"
195+
if action == "payments/Refunds":
196+
action = f"payments/{path_param}/refunds"
186197
if action == "originKeys":
187198
api_version = self.api_checkout_utility_version
188199
if action == "paymentMethodsBalance":
@@ -449,7 +460,7 @@ class instance.
449460
status_code, headers, message)
450461
return adyen_result
451462

452-
def call_checkout_api(self, request_data, action, idempotency_key=None,
463+
def call_checkout_api(self, request_data, action, idempotency_key=None, path_param=None,
453464
**kwargs):
454465
"""This will call the checkout adyen api. xapi key merchant_account,
455466
and platform are pulled from root module level and or self object.
@@ -464,6 +475,7 @@ def call_checkout_api(self, request_data, action, idempotency_key=None,
464475
https://docs.adyen.com/api-explorer/#/CheckoutService
465476
service (str): This is the API service to be called.
466477
action (str): The specific action of the API service to be called
478+
path_param (str): This is used to pass the id or referenceID to the API sercie
467479
"""
468480
if not self.http_init:
469481
self._init_http_client()
@@ -530,7 +542,7 @@ def call_checkout_api(self, request_data, action, idempotency_key=None,
530542
headers = {}
531543
if idempotency_key:
532544
headers[self.IDEMPOTENCY_HEADER_NAME] = idempotency_key
533-
url = self._determine_checkout_url(platform, action)
545+
url = self._determine_checkout_url(platform, action, path_param)
534546

535547
raw_response, raw_request, status_code, headers = \
536548
self.http_client.request(url, json=request_data,

Adyen/services.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,13 @@ class AdyenCheckoutApi(AdyenServiceBase):
279279
payments/details
280280
originKeys
281281
282+
Modifications:
283+
capture
284+
refunds
285+
cancels
286+
reversals
287+
288+
282289
Please refer to the checkout documentation for specifics around the API.
283290
https://docs.adyen.com/online-payments
284291
@@ -321,6 +328,42 @@ def payment_result(self, request=None, **kwargs):
321328
action = "paymentsResult"
322329
return self.client.call_checkout_api(request, action, **kwargs)
323330

331+
def payments_captures(self, request, idempotency_key=None, path_param=None, **kwargs):
332+
if path_param == "":
333+
raise ValueError(
334+
'must contain a pspReference in the path_param, path_param cannot be empty'
335+
)
336+
action = "paymentsCapture"
337+
return self.client.call_checkout_api(request, action, idempotency_key, path_param, **kwargs)
338+
339+
def payments_cancels_without_reference(self, request, idempotency_key=None, **kwargs):
340+
action = "cancels"
341+
return self.client.call_checkout_api(request, action, idempotency_key, **kwargs)
342+
343+
def payments_cancels_with_reference(self, request, idempotency_key=None, path_param=None, **kwargs):
344+
if path_param == "":
345+
raise ValueError(
346+
'must contain a pspReference in the path_param, path_param cannot be empty'
347+
)
348+
action = "paymentsCancelsWithReference"
349+
return self.client.call_checkout_api(request, action, idempotency_key, path_param, **kwargs)
350+
351+
def payments_reversals(self, request, idempotency_key=None, path_param=None, **kwargs):
352+
if path_param == "":
353+
raise ValueError(
354+
'must contain a pspReference in the path_param, path_param cannot be empty'
355+
)
356+
action = "paymentsReversals"
357+
return self.client.call_checkout_api(request, action, idempotency_key, path_param, **kwargs)
358+
359+
def payments_refunds(self, request, idempotency_key=None, path_param=None, **kwargs):
360+
if path_param == "":
361+
raise ValueError(
362+
'must contain a pspReference in the path_param, path_param cannot be empty'
363+
)
364+
action = "paymentsRefunds"
365+
return self.client.call_checkout_api(request, action, idempotency_key, path_param, **kwargs)
366+
324367
def origin_keys(self, request=None, **kwargs):
325368
action = "originKeys"
326369
return self.client.call_checkout_api(request, action, **kwargs)

test/CheckoutTest.py

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,203 @@ def test_payments_result_error_mocked(self):
236236
self.assertEqual("Invalid payload provided", result.message['message'])
237237
self.assertEqual("validation", result.message['errorType'])
238238

239+
def test_payments_cancels_without_reference(self):
240+
requests = {
241+
"paymentReference": "Payment123",
242+
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
243+
"reference": "YourCancelReference",
244+
}
245+
self.adyen.client = self.test.create_client_from_file(200, requests,
246+
"test/mocks/"
247+
"checkout/"
248+
"paymentscancel-"
249+
"withoutreference-succes.json")
250+
results = self.adyen.checkout.payments_cancels_without_reference(request=requests)
251+
self.assertIsNotNone(results.message['paymentReference'])
252+
self.assertEqual("8412534564722331", results.message['pspReference'])
253+
self.assertEqual("received", results.message['status'])
254+
255+
def test_payments_cancels_without_reference_error_mocked(self):
256+
requests = {
257+
"paymentReference": "Payment123",
258+
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
259+
"reference": "YourCancelReference",
260+
}
261+
self.adyen.client = self.test.create_client_from_file(200, requests,
262+
"test/mocks/"
263+
"checkout/"
264+
"paymentsresult"
265+
"-error-invalid-"
266+
"data-payload-"
267+
"422.json")
268+
269+
result = self.adyen.checkout.payments_cancels_without_reference(requests)
270+
self.assertEqual(422, result.message['status'])
271+
self.assertEqual("14_018", result.message['errorCode'])
272+
self.assertEqual("Invalid payload provided", result.message['message'])
273+
self.assertEqual("validation", result.message['errorType'])
274+
275+
def test_payments_cancels_success_mocked(self):
276+
requests = {"reference": "Your wro order number", "merchantAccount": "YOUR_MERCHANT_ACCOUNT"}
277+
278+
reference_id = "8836183819713023"
279+
self.adyen.client = self.test.create_client_from_file(200, requests,
280+
"test/mocks/"
281+
"checkout/"
282+
"paymentscancels"
283+
"-success.json")
284+
result = self.adyen.checkout.payments_cancels_with_reference(request=requests, path_param=reference_id)
285+
self.assertEqual(reference_id, result.message["paymentPspReference"])
286+
self.assertEqual("received", result.message['status'])
287+
288+
def test_payments_cancels_error_mocked(self):
289+
requests = {"reference": "Your wro order number"}
290+
psp_reference = "8836183819713023"
291+
self.adyen.client = self.test.create_client_from_file(200, requests,
292+
"test/mocks/"
293+
"checkout/"
294+
"paymentsresult-error-invalid-"
295+
"data-payload-422.json")
296+
result = self.adyen.checkout.payments_cancels_with_reference(request=requests, path_param=psp_reference)
297+
self.assertEqual(422, result.message['status'])
298+
self.assertEqual("14_018", result.message['errorCode'])
299+
self.assertEqual("Invalid payload provided", result.message['message'])
300+
self.assertEqual("validation", result.message['errorType'])
301+
302+
def test_payments_refunds_success_mocked(self):
303+
requests = {
304+
"paymentReference": "Payment123",
305+
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
306+
"reference": "YourCancelReference",
307+
}
308+
psp_reference = "Payment123"
309+
self.adyen.client = self.test.create_client_from_file(200, requests,
310+
"test/mocks/"
311+
"checkout/"
312+
"paymentscancel-"
313+
"withoutreference-succes.json")
314+
315+
result = self.adyen.checkout.payments_refunds(request=requests, path_param=psp_reference)
316+
self.assertEqual(psp_reference, result.message["paymentReference"])
317+
self.assertIsNotNone(result.message["pspReference"])
318+
self.assertEqual("received", result.message['status'])
319+
320+
def test_payments_refunds_error_mocked(self):
321+
requests = {
322+
"paymentReference": "Payment123",
323+
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
324+
"reference": "YourCancelReference",
325+
}
326+
reference_id = "Payment123"
327+
self.adyen.client = self.test.create_client_from_file(200, requests,
328+
"test/mocks/"
329+
"checkout/"
330+
"paymentsresult-error-invalid-"
331+
"data-payload-422.json")
332+
333+
result = self.adyen.checkout.payments_refunds(request=requests, path_param=reference_id)
334+
self.assertEqual(422, result.message['status'])
335+
self.assertEqual("14_018", result.message['errorCode'])
336+
self.assertEqual("Invalid payload provided", result.message['message'])
337+
self.assertEqual("validation", result.message['errorType'])
338+
339+
def test_payments_refunds_raises_value_error(self):
340+
requests = {
341+
"paymentReference": "Payment123",
342+
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
343+
"reference": "YourCancelReference",
344+
}
345+
self.adyen.client = self.test.create_client_from_file(200, requests,
346+
"test/mocks/"
347+
"checkout/"
348+
"paymentscancel-"
349+
"withoutreference-succes.json")
350+
with self.assertRaises(ValueError) as exc:
351+
self.adyen.checkout.payments_refunds(request=requests, path_param="")
352+
self.assertEqual(exc.exception.__class__, ValueError)
353+
self.assertEqual(exc.exception.__str__(), 'must contain a pspReference in the path_param, path_param cannot '
354+
'be empty')
355+
356+
def test_reversals_success_mocked(self):
357+
requests = {
358+
"reference": "YourReversalReference",
359+
"merchantAccount": "YOUR_MERCHANT_ACCOUNT"
360+
}
361+
psp_reference = "8836183819713023"
362+
self.adyen.client = self.test.create_client_from_file(200, requests,
363+
"test/mocks/"
364+
"checkout/"
365+
"paymentsreversals-"
366+
"success.json")
367+
368+
result = self.adyen.checkout.payments_reversals(request=requests, path_param=psp_reference)
369+
self.assertEqual(psp_reference, result.message["paymentPspReference"])
370+
self.assertIsNotNone(result.message["pspReference"])
371+
self.assertEqual("received", result.message['status'])
372+
373+
def test_payments_reversals_failure_mocked(self):
374+
requests = {
375+
"reference": "YourReversalReference",
376+
"merchantAccount": "YOUR_MERCHANT_ACCOUNT"
377+
}
378+
psp_reference = "8836183819713023"
379+
380+
self.adyen.client = self.test.create_client_from_file(200, requests,
381+
"test/mocks/"
382+
"checkout/"
383+
"paymentsresult-error-invalid-"
384+
"data-payload-422.json")
385+
386+
result = self.adyen.checkout.payments_reversals(request=requests, path_param=psp_reference)
387+
self.assertEqual(422, result.message['status'])
388+
self.assertEqual("14_018", result.message['errorCode'])
389+
self.assertEqual("Invalid payload provided", result.message['message'])
390+
self.assertEqual("validation", result.message['errorType'])
391+
392+
def test_payments_capture_success_mocked(self):
393+
request = {
394+
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
395+
"amount": {
396+
"value": 2500,
397+
"currency": "EUR"
398+
},
399+
"reference": "YOUR_UNIQUE_REFERENCE"
400+
}
401+
psp_reference = "8536214160615591"
402+
self.adyen.client = self.test.create_client_from_file(200, request,
403+
"test/mocks/"
404+
"checkout/"
405+
"paymentcapture-"
406+
"success.json")
407+
408+
result = self.adyen.checkout.payments_captures(request=request, path_param=psp_reference)
409+
self.assertEqual(psp_reference, result.message["paymentPspReference"])
410+
self.assertIsNotNone(result.message["pspReference"])
411+
self.assertEqual("received", result.message['status'])
412+
self.assertEqual(2500, result.message['amount']['value'])
413+
414+
def test_payments_capture_error_mocked(self):
415+
request = {
416+
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
417+
"amount": {
418+
"value": 2500,
419+
"currency": "EUR"
420+
},
421+
"reference": "YOUR_UNIQUE_REFERENCE"
422+
}
423+
psp_reference = "8536214160615591"
424+
self.adyen.client = self.test.create_client_from_file(200, request,
425+
"test/mocks/"
426+
"checkout/"
427+
"paymentsresult-error-invalid-"
428+
"data-payload-422.json")
429+
430+
result = self.adyen.checkout.payments_captures(request=request, path_param=psp_reference)
431+
self.assertEqual(422, result.message['status'])
432+
self.assertEqual("14_018", result.message['errorCode'])
433+
self.assertEqual("Invalid payload provided", result.message['message'])
434+
self.assertEqual("validation", result.message['errorType'])
435+
239436
def test_orders_success(self):
240437
request = {'merchantAccount': "YourMerchantAccount"}
241438
self.adyen.client = self.test.create_client_from_file(200, request,
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
3+
"paymentPspReference": "8536214160615591",
4+
"pspReference": "8836226171638872",
5+
"reference": "YOUR_UNIQUE_REFERENCE",
6+
"status": "received",
7+
"amount": {
8+
"currency": "EUR",
9+
"value": 2500
10+
}
11+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
3+
"paymentReference": "Payment123",
4+
"pspReference" : "8412534564722331",
5+
"reference": "YourCancelReference",
6+
"status" : "received"
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
3+
"paymentPspReference": "8836183819713023",
4+
"pspReference" : "8412534564722331",
5+
"reference": "Cancel123",
6+
"status" : "received"
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
3+
"paymentPspReference": "8836183819713023",
4+
"pspReference" : "8863534564726784",
5+
"reference": "YourReversalReference",
6+
"status" : "received"
7+
}

0 commit comments

Comments
 (0)