Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions Adyen/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,14 @@ def _determine_hpp_url(platform, action):
result = '/'.join([base_uri, service])
return result

def _determine_checkout_url(self, platform, action):
def _determine_checkout_url(self, platform, action, path_param=None):
"""This returns the Adyen API endpoint based on the provided platform,
service and action.

Args:
platform (str): Adyen platform, ie 'live' or 'test'.
action (str): the API action to perform.
path_param Optional[(str)]: a generic id that can be used to modify a payment e.g. paymentPspReference.
"""
api_version = settings.API_CHECKOUT_VERSION
if platform == "test":
Expand All @@ -171,6 +172,16 @@ def _determine_checkout_url(self, platform, action):
action = "payments/details"
if action == "paymentsResult":
action = "payments/result"
if action == "cancels":
action = "/cancels"
if action == "paymentsCancelsWithReference":
action = f"payments/{path_param}/cancels"
if action == "paymentsCapture":
action = f"/payments/{path_param}/captures"
if action == "paymentsReversals":
action = f"payments/{path_param}/reversals"
if action == "payments/Refunds":
action = f"payments/{path_param}/refunds"
if action == "originKeys":
api_version = settings.API_CHECKOUT_UTILITY_VERSION
if action == "paymentMethodsBalance":
Expand Down Expand Up @@ -437,7 +448,7 @@ class instance.
status_code, headers, message)
return adyen_result

def call_checkout_api(self, request_data, action, idempotency_key=None,
def call_checkout_api(self, request_data, action, idempotency_key=None, path_param=None,
**kwargs):
"""This will call the checkout adyen api. xapi key merchant_account,
and platform are pulled from root module level and or self object.
Expand All @@ -452,6 +463,7 @@ def call_checkout_api(self, request_data, action, idempotency_key=None,
https://docs.adyen.com/developers/checkout/api-integration
service (str): This is the API service to be called.
action (str): The specific action of the API service to be called
path_param (str): This is used to pass the id or referenceID to the API sercie
"""
if not self.http_init:
self.http_client = HTTPClient(self.USER_AGENT_SUFFIX,
Expand Down Expand Up @@ -520,7 +532,7 @@ def call_checkout_api(self, request_data, action, idempotency_key=None,
headers = {}
if idempotency_key:
headers[self.IDEMPOTENCY_HEADER_NAME] = idempotency_key
url = self._determine_checkout_url(platform, action)
url = self._determine_checkout_url(platform, action, path_param)

raw_response, raw_request, status_code, headers = \
self.http_client.request(url, json=request_data,
Expand Down
43 changes: 43 additions & 0 deletions Adyen/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,13 @@ class AdyenCheckoutApi(AdyenServiceBase):
payments/details
originKeys

Modifications:
capture
refunds
cancels
reversals


Please refer to the checkout documentation for specifics around the API.
https://docs.adyen.com/developers/checkout

Expand Down Expand Up @@ -322,6 +329,42 @@ def payment_result(self, request=None, **kwargs):
action = "paymentsResult"
return self.client.call_checkout_api(request, action, **kwargs)

def payments_captures(self, request, idempotency_key=None, path_param=None, **kwargs):
if path_param == "":
raise ValueError(
'must contain a pspReference in the path_param, path_param cannot be empty'
)
action = "paymentsCapture"
return self.client.call_checkout_api(request, action, idempotency_key, path_param, **kwargs)

def payments_cancels_without_reference(self, request, idempotency_key=None, **kwargs):
action = "cancels"
return self.client.call_checkout_api(request, action, idempotency_key, **kwargs)

def payments_cancels_with_reference(self, request, idempotency_key=None, path_param=None, **kwargs):
if path_param == "":
raise ValueError(
'must contain a pspReference in the path_param, path_param cannot be empty'
)
action = "paymentsCancelsWithReference"
return self.client.call_checkout_api(request, action, idempotency_key, path_param, **kwargs)

def payments_reversals(self, request, idempotency_key=None, path_param=None, **kwargs):
if path_param == "":
raise ValueError(
'must contain a pspReference in the path_param, path_param cannot be empty'
)
action = "paymentsReversals"
return self.client.call_checkout_api(request, action, idempotency_key, path_param, **kwargs)

def payments_refunds(self, request, idempotency_key=None, path_param=None, **kwargs):
if path_param == "":
raise ValueError(
'must contain a pspReference in the path_param, path_param cannot be empty'
)
action = "paymentsRefunds"
return self.client.call_checkout_api(request, action, idempotency_key, path_param, **kwargs)

def origin_keys(self, request=None, **kwargs):
action = "originKeys"
return self.client.call_checkout_api(request, action, **kwargs)
Expand Down
197 changes: 197 additions & 0 deletions test/CheckoutTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,203 @@ def test_payments_result_error_mocked(self):
self.assertEqual("Invalid payload provided", result.message['message'])
self.assertEqual("validation", result.message['errorType'])

def test_payments_cancels_without_reference(self):
requests = {
"paymentReference": "Payment123",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"reference": "YourCancelReference",
}
self.adyen.client = self.test.create_client_from_file(200, requests,
"test/mocks/"
"checkout/"
"paymentscancel-"
"withoutreference-succes.json")
results = self.adyen.checkout.payments_cancels_without_reference(request=requests)
self.assertIsNotNone(results.message['paymentReference'])
self.assertEqual("8412534564722331", results.message['pspReference'])
self.assertEqual("received", results.message['status'])

def test_payments_cancels_without_reference_error_mocked(self):
requests = {
"paymentReference": "Payment123",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"reference": "YourCancelReference",
}
self.adyen.client = self.test.create_client_from_file(200, requests,
"test/mocks/"
"checkout/"
"paymentsresult"
"-error-invalid-"
"data-payload-"
"422.json")

result = self.adyen.checkout.payments_cancels_without_reference(requests)
self.assertEqual(422, result.message['status'])
self.assertEqual("14_018", result.message['errorCode'])
self.assertEqual("Invalid payload provided", result.message['message'])
self.assertEqual("validation", result.message['errorType'])

def test_payments_cancels_success_mocked(self):
requests = {"reference": "Your wro order number", "merchantAccount": "YOUR_MERCHANT_ACCOUNT"}

reference_id = "8836183819713023"
self.adyen.client = self.test.create_client_from_file(200, requests,
"test/mocks/"
"checkout/"
"paymentscancels"
"-success.json")
result = self.adyen.checkout.payments_cancels_with_reference(request=requests, path_param=reference_id)
self.assertEqual(reference_id, result.message["paymentPspReference"])
self.assertEqual("received", result.message['status'])

def test_payments_cancels_error_mocked(self):
requests = {"reference": "Your wro order number"}
psp_reference = "8836183819713023"
self.adyen.client = self.test.create_client_from_file(200, requests,
"test/mocks/"
"checkout/"
"paymentsresult-error-invalid-"
"data-payload-422.json")
result = self.adyen.checkout.payments_cancels_with_reference(request=requests, path_param=psp_reference)
self.assertEqual(422, result.message['status'])
self.assertEqual("14_018", result.message['errorCode'])
self.assertEqual("Invalid payload provided", result.message['message'])
self.assertEqual("validation", result.message['errorType'])

def test_payments_refunds_success_mocked(self):
requests = {
"paymentReference": "Payment123",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"reference": "YourCancelReference",
}
psp_reference = "Payment123"
self.adyen.client = self.test.create_client_from_file(200, requests,
"test/mocks/"
"checkout/"
"paymentscancel-"
"withoutreference-succes.json")

result = self.adyen.checkout.payments_refunds(request=requests, path_param=psp_reference)
self.assertEqual(psp_reference, result.message["paymentReference"])
self.assertIsNotNone(result.message["pspReference"])
self.assertEqual("received", result.message['status'])

def test_payments_refunds_error_mocked(self):
requests = {
"paymentReference": "Payment123",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"reference": "YourCancelReference",
}
reference_id = "Payment123"
self.adyen.client = self.test.create_client_from_file(200, requests,
"test/mocks/"
"checkout/"
"paymentsresult-error-invalid-"
"data-payload-422.json")

result = self.adyen.checkout.payments_refunds(request=requests, path_param=reference_id)
self.assertEqual(422, result.message['status'])
self.assertEqual("14_018", result.message['errorCode'])
self.assertEqual("Invalid payload provided", result.message['message'])
self.assertEqual("validation", result.message['errorType'])

def test_payments_refunds_raises_value_error(self):
requests = {
"paymentReference": "Payment123",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"reference": "YourCancelReference",
}
self.adyen.client = self.test.create_client_from_file(200, requests,
"test/mocks/"
"checkout/"
"paymentscancel-"
"withoutreference-succes.json")
with self.assertRaises(ValueError) as exc:
self.adyen.checkout.payments_refunds(request=requests, path_param="")
self.assertEqual(exc.exception.__class__, ValueError)
self.assertEqual(exc.exception.__str__(), 'must contain a pspReference in the path_param, path_param cannot '
'be empty')

def test_reversals_success_mocked(self):
requests = {
"reference": "YourReversalReference",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT"
}
psp_reference = "8836183819713023"
self.adyen.client = self.test.create_client_from_file(200, requests,
"test/mocks/"
"checkout/"
"paymentsreversals-"
"success.json")

result = self.adyen.checkout.payments_reversals(request=requests, path_param=psp_reference)
self.assertEqual(psp_reference, result.message["paymentPspReference"])
self.assertIsNotNone(result.message["pspReference"])
self.assertEqual("received", result.message['status'])

def test_payments_reversals_failure_mocked(self):
requests = {
"reference": "YourReversalReference",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT"
}
psp_reference = "8836183819713023"

self.adyen.client = self.test.create_client_from_file(200, requests,
"test/mocks/"
"checkout/"
"paymentsresult-error-invalid-"
"data-payload-422.json")

result = self.adyen.checkout.payments_reversals(request=requests, path_param=psp_reference)
self.assertEqual(422, result.message['status'])
self.assertEqual("14_018", result.message['errorCode'])
self.assertEqual("Invalid payload provided", result.message['message'])
self.assertEqual("validation", result.message['errorType'])

def test_payments_capture_success_mocked(self):
request = {
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"amount": {
"value": 2500,
"currency": "EUR"
},
"reference": "YOUR_UNIQUE_REFERENCE"
}
psp_reference = "8536214160615591"
self.adyen.client = self.test.create_client_from_file(200, request,
"test/mocks/"
"checkout/"
"paymentcapture-"
"success.json")

result = self.adyen.checkout.payments_captures(request=request, path_param=psp_reference)
self.assertEqual(psp_reference, result.message["paymentPspReference"])
self.assertIsNotNone(result.message["pspReference"])
self.assertEqual("received", result.message['status'])
self.assertEqual(2500, result.message['amount']['value'])

def test_payments_capture_error_mocked(self):
request = {
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"amount": {
"value": 2500,
"currency": "EUR"
},
"reference": "YOUR_UNIQUE_REFERENCE"
}
psp_reference = "8536214160615591"
self.adyen.client = self.test.create_client_from_file(200, request,
"test/mocks/"
"checkout/"
"paymentsresult-error-invalid-"
"data-payload-422.json")

result = self.adyen.checkout.payments_captures(request=request, path_param=psp_reference)
self.assertEqual(422, result.message['status'])
self.assertEqual("14_018", result.message['errorCode'])
self.assertEqual("Invalid payload provided", result.message['message'])
self.assertEqual("validation", result.message['errorType'])

def test_orders_success(self):
request = {'merchantAccount': "YourMerchantAccount"}
self.adyen.client = self.test.create_client_from_file(200, request,
Expand Down
11 changes: 11 additions & 0 deletions test/mocks/checkout/paymentcapture-success.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"paymentPspReference": "8536214160615591",
"pspReference": "8836226171638872",
"reference": "YOUR_UNIQUE_REFERENCE",
"status": "received",
"amount": {
"currency": "EUR",
"value": 2500
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"paymentReference": "Payment123",
"pspReference" : "8412534564722331",
"reference": "YourCancelReference",
"status" : "received"
}
7 changes: 7 additions & 0 deletions test/mocks/checkout/paymentscancels-success.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"paymentPspReference": "8836183819713023",
"pspReference" : "8412534564722331",
"reference": "Cancel123",
"status" : "received"
}
7 changes: 7 additions & 0 deletions test/mocks/checkout/paymentsreversals-success.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"paymentPspReference": "8836183819713023",
"pspReference" : "8863534564726784",
"reference": "YourReversalReference",
"status" : "received"
}