diff --git a/Adyen/client.py b/Adyen/client.py index 969614e7..0cf7c858 100644 --- a/Adyen/client.py +++ b/Adyen/client.py @@ -142,41 +142,44 @@ def __init__( self.api_session_authentication_version = api_session_authentication_version self.api_capital_version = api_capital_version + def _require_live_endpoint_prefix(self): + if self.live_endpoint_prefix is None: + error_string = ( + "Please set your live suffix. You can set it by running " + "adyen.client.live_endpoint_prefix = 'Your live suffix'" + ) + raise AdyenEndpointInvalidFormat(error_string) + return self.live_endpoint_prefix + def _determine_api_url(self, platform, endpoint): if platform == "test": # Replace live with test in base url is configured with live url by default return endpoint.replace("-live", "-test") if "pal-" in endpoint: - if self.live_endpoint_prefix is None: - error_string = ( - "Please set your live suffix. You can set it by running " - "adyen.client.live_endpoint_prefix = 'Your live suffix'" - ) - raise AdyenEndpointInvalidFormat(error_string) + live_endpoint_prefix = self._require_live_endpoint_prefix() endpoint = endpoint.replace( "https://pal-test.adyen.com/pal/servlet/", - "https://" + self.live_endpoint_prefix + "-pal-live.adyenpayments.com/pal/servlet/", + f"https://{live_endpoint_prefix}-pal-live.adyenpayments.com/pal/servlet/", + ) + elif "paltokenization-" in endpoint: + live_endpoint_prefix = self._require_live_endpoint_prefix() + endpoint = endpoint.replace( + "https://paltokenization-test.adyen.com/paltokenization/servlet/", + f"https://{live_endpoint_prefix}-paltokenization-live.adyenpayments.com/paltokenization/servlet/", ) elif "checkout-" in endpoint: - if self.live_endpoint_prefix is None: - error_string = ( - "Please set your live suffix. You can set it by running " - "adyen.client.live_endpoint_prefix = 'Your live suffix'" - ) - raise AdyenEndpointInvalidFormat(error_string) + live_endpoint_prefix = self._require_live_endpoint_prefix() if "possdk" in endpoint: endpoint = endpoint.replace( "https://checkout-test.adyen.com/", - "https://" + self.live_endpoint_prefix + "-checkout-live.adyenpayments.com/", + f"https://{live_endpoint_prefix}-checkout-live.adyenpayments.com/", ) else: endpoint = endpoint.replace( "https://checkout-test.adyen.com/", - "https://" - + self.live_endpoint_prefix - + "-checkout-live.adyenpayments.com/checkout/", + f"https://{live_endpoint_prefix}-checkout-live.adyenpayments.com/checkout/", ) elif "authe/api" in endpoint: endpoint = endpoint.replace("https://test.adyen.com", "https://authe-live.adyen.com") diff --git a/test/BalancePlatformTest.py b/test/BalancePlatformTest.py index 401d6ae8..71378712 100644 --- a/test/BalancePlatformTest.py +++ b/test/BalancePlatformTest.py @@ -238,3 +238,108 @@ def test_update_network_token(self): json=request, xapikey="YourXapikey", ) + + def test_get_list_of_mandates(self): + request = {} + self.adyen.client = self.test.create_client_from_file( + 200, request, "test/mocks/configuration/get-mandates-success.json" + ) + result = self.adyen.balancePlatform.direct_debit_mandates_api.get_list_of_mandates() + self.assertEqual(1, len(result.message["mandates"])) + self.assertEqual("MD00000000000000000000001", result.message["mandates"][0]["id"]) + self.adyen.client.http_client.request.assert_called_once_with( + "GET", + f"{self.balance_platform_url}/mandates", + headers={ + "adyen-library-name": "adyen-python-api-library", + "adyen-library-version": settings.LIB_VERSION, + "User-Agent": "adyen-python-api-library/" + settings.LIB_VERSION, + }, + json=None, + xapikey="YourXapikey", + ) + + def test_get_mandate_by_id(self): + request = {} + mandate_id = "MD00000000000000000000001" + self.adyen.client = self.test.create_client_from_file( + 200, request, "test/mocks/configuration/get-mandate-success.json" + ) + result = self.adyen.balancePlatform.direct_debit_mandates_api.get_mandate_by_id(mandate_id) + self.assertEqual(mandate_id, result.message["id"]) + self.adyen.client.http_client.request.assert_called_once_with( + "GET", + f"{self.balance_platform_url}/mandates/{mandate_id}", + headers={ + "adyen-library-name": "adyen-python-api-library", + "adyen-library-version": settings.LIB_VERSION, + "User-Agent": "adyen-python-api-library/" + settings.LIB_VERSION, + }, + json=None, + xapikey="YourXapikey", + ) + + def test_cancel_mandate(self): + mandate_id = "MD00000000000000000000001" + self.adyen.client = self.test.create_client_from_file(202, None) + result = self.adyen.balancePlatform.direct_debit_mandates_api.cancel_mandate(mandate_id) + + self.assertEqual(202, result.status_code) + self.assertEqual({}, result.message) + self.assertEqual("", result.raw_response) + self.adyen.client.http_client.request.assert_called_once_with( + "POST", + f"{self.balance_platform_url}/mandates/{mandate_id}/cancel", + headers={ + "adyen-library-name": "adyen-python-api-library", + "adyen-library-version": settings.LIB_VERSION, + "User-Agent": "adyen-python-api-library/" + settings.LIB_VERSION, + }, + json=None, + xapikey="YourXapikey", + ) + + def test_update_mandate(self): + request = {"status": "active"} + mandate_id = "MD00000000000000000000001" + self.adyen.client = self.test.create_client_from_file( + 200, request, "test/mocks/configuration/update-mandate-success.json" + ) + result = self.adyen.balancePlatform.direct_debit_mandates_api.update_mandate( + request, mandate_id + ) + self.assertEqual(mandate_id, result.message["id"]) + self.assertEqual("active", result.message["status"]) + self.adyen.client.http_client.request.assert_called_once_with( + "PATCH", + f"{self.balance_platform_url}/mandates/{mandate_id}", + headers={ + "adyen-library-name": "adyen-python-api-library", + "adyen-library-version": settings.LIB_VERSION, + "User-Agent": "adyen-python-api-library/" + settings.LIB_VERSION, + }, + json=request, + xapikey="YourXapikey", + ) + + def test_get_tax_form_summary(self): + request = {} + account_holder_id = "AH00000000000000000000001" + self.adyen.client = self.test.create_client_from_file( + 200, request, "test/mocks/configuration/get-tax-form-summary-success.json" + ) + result = self.adyen.balancePlatform.account_holders_api.get_tax_form_summary( + account_holder_id + ) + self.assertEqual("available", result.message["taxForms"][0]["status"]) + self.adyen.client.http_client.request.assert_called_once_with( + "GET", + f"{self.balance_platform_url}/accountHolders/{account_holder_id}/taxFormSummary", + headers={ + "adyen-library-name": "adyen-python-api-library", + "adyen-library-version": settings.LIB_VERSION, + "User-Agent": "adyen-python-api-library/" + settings.LIB_VERSION, + }, + json=None, + xapikey="YourXapikey", + ) diff --git a/test/CapitalTest.py b/test/CapitalTest.py index f39906ab..5bc82fd5 100644 --- a/test/CapitalTest.py +++ b/test/CapitalTest.py @@ -103,3 +103,36 @@ def test_get_grant_offer(self): ) result = self.adyen.capital.grant_offers_api.get_grant_offer(id="GO00000000000000000000001") self.assertEqual("GO00000000000000000000001", result.message["id"]) + + def test_get_all_dynamic_offers(self): + request = {} + self.adyen.client = self.test.create_client_from_file( + 200, request, "test/mocks/capital/get-dynamic-offers-success.json" + ) + result = self.adyen.capital.dynamic_offers_api.get_all_dynamic_offers() + self.assertEqual(1, len(result.message["dynamicOffers"])) + self.assertEqual("DO00000000000000000000001", result.message["dynamicOffers"][0]["id"]) + + def test_calculate_preliminary_offer_from_dynamic_offer(self): + request = {"amount": {"currency": "EUR", "value": 10000}} + self.adyen.client = self.test.create_client_from_file( + 200, request, "test/mocks/capital/calculate-dynamic-offer-success.json" + ) + result = ( + self.adyen.capital.dynamic_offers_api.calculate_preliminary_offer_from_dynamic_offer( + request, id="DO00000000000000000000001" + ) + ) + self.assertEqual("DO00000000000000000000001", result.message["id"]) + self.assertEqual(1000, result.message["repayment"]["basisPoints"]) + + def test_create_static_offer_from_dynamic_offer(self): + request = {"amount": {"currency": "EUR", "value": 10000}} + self.adyen.client = self.test.create_client_from_file( + 200, request, "test/mocks/capital/create-static-offer-from-dynamic-success.json" + ) + result = self.adyen.capital.dynamic_offers_api.create_static_offer_from_dynamic_offer( + request, id="DO00000000000000000000001" + ) + self.assertEqual("GO00000000000000000000002", result.message["id"]) + self.assertEqual("cashAdvance", result.message["contractType"]) diff --git a/test/DetermineEndpointTest.py b/test/DetermineEndpointTest.py index 80299d9b..9ecf7864 100644 --- a/test/DetermineEndpointTest.py +++ b/test/DetermineEndpointTest.py @@ -3,6 +3,8 @@ import Adyen from Adyen.services.posMobile import AdyenPosMobileApi +RECURRING_DETAILS = "/listRecurringDetails" + try: from BaseTest import BaseTest except ImportError: @@ -25,6 +27,8 @@ class TestDetermineUrl(unittest.TestCase): management_url = adyen.management.account_merchant_level_api.baseUrl sessionauth_url = adyen.sessionAuthentication.session_authentication_api.baseUrl sessionauth_version = sessionauth_url.split("/")[-1] + recurring_url = adyen.recurring.recurring_api.baseUrl + recurring_version = recurring_url.split("/")[-1] capital_url = adyen.capital.grants_api.baseUrl capital_version = capital_url.split("/")[-1] @@ -154,3 +158,38 @@ def test_live_capital_api_url(self): self.assertEqual( url, f"https://balanceplatform-api-live.adyen.com/capital/{self.capital_version}" ) + + def test_recurring_api_base_url(self): + self.assertTrue( + self.recurring_url.startswith( + "https://paltokenization-test.adyen.com/paltokenization/servlet/Recurring/" + ) + ) + + def test_recurring_api_url_test_platform(self): + self.client.live_endpoint_prefix = None + url = self.adyen.client._determine_api_url( + "test", self.recurring_url + RECURRING_DETAILS + ) + self.assertEqual(url, f"{self.recurring_url}{RECURRING_DETAILS}") + + def test_recurring_api_url_live_with_prefix(self): + self.client.live_endpoint_prefix = "1797a841fbb37ca7-AdyenDemo" + url = self.adyen.client._determine_api_url( + "live", self.recurring_url + RECURRING_DETAILS + ) + self.assertEqual( + url, + "https://1797a841fbb37ca7-AdyenDemo-paltokenization-live.adyenpayments.com" + f"/paltokenization/servlet/Recurring/{self.recurring_version}{RECURRING_DETAILS}", + ) + + def test_recurring_api_url_live_no_prefix_raises(self): + self.client.live_endpoint_prefix = None + self.assertRaisesRegex( + AdyenEndpointInvalidFormat, + "Please set your live suffix", + self.adyen.client._determine_api_url, + "live", + self.recurring_url + "RECURRING_DETAILS", + ) diff --git a/test/mocks/capital/calculate-dynamic-offer-success.json b/test/mocks/capital/calculate-dynamic-offer-success.json new file mode 100644 index 00000000..b363c085 --- /dev/null +++ b/test/mocks/capital/calculate-dynamic-offer-success.json @@ -0,0 +1,16 @@ +{ + "id": "DO00000000000000000000001", + "amount": { + "currency": "EUR", + "value": 10000 + }, + "fee": { + "amount": { + "currency": "EUR", + "value": 1000 + } + }, + "repayment": { + "basisPoints": 1000 + } +} diff --git a/test/mocks/capital/create-static-offer-from-dynamic-success.json b/test/mocks/capital/create-static-offer-from-dynamic-success.json new file mode 100644 index 00000000..a77c712d --- /dev/null +++ b/test/mocks/capital/create-static-offer-from-dynamic-success.json @@ -0,0 +1,9 @@ +{ + "id": "GO00000000000000000000002", + "accountHolderId": "AH00000000000000000000001", + "contractType": "cashAdvance", + "amount": { + "currency": "EUR", + "value": 10000 + } +} diff --git a/test/mocks/capital/get-dynamic-offers-success.json b/test/mocks/capital/get-dynamic-offers-success.json new file mode 100644 index 00000000..7ed00f92 --- /dev/null +++ b/test/mocks/capital/get-dynamic-offers-success.json @@ -0,0 +1,18 @@ +{ + "dynamicOffers": [ + { + "id": "DO00000000000000000000001", + "accountHolderId": "AH00000000000000000000001", + "financing": { + "minimum": { + "currency": "EUR", + "value": 5000 + }, + "maximum": { + "currency": "EUR", + "value": 25000 + } + } + } + ] +} diff --git a/test/mocks/configuration/get-mandate-success.json b/test/mocks/configuration/get-mandate-success.json new file mode 100644 index 00000000..03efaa7e --- /dev/null +++ b/test/mocks/configuration/get-mandate-success.json @@ -0,0 +1,7 @@ +{ + "id": "MD00000000000000000000001", + "status": "active", + "accountHolderId": "AH00000000000000000000001", + "balanceAccountId": "BA00000000000000000000001", + "paymentInstrumentId": "PI00000000000000000000001" +} diff --git a/test/mocks/configuration/get-mandates-success.json b/test/mocks/configuration/get-mandates-success.json new file mode 100644 index 00000000..6f84db07 --- /dev/null +++ b/test/mocks/configuration/get-mandates-success.json @@ -0,0 +1,9 @@ +{ + "mandates": [ + { + "id": "MD00000000000000000000001", + "status": "active" + } + ], + "itemsTotal": 1 +} diff --git a/test/mocks/configuration/get-tax-form-summary-success.json b/test/mocks/configuration/get-tax-form-summary-success.json new file mode 100644 index 00000000..df8ec99f --- /dev/null +++ b/test/mocks/configuration/get-tax-form-summary-success.json @@ -0,0 +1,8 @@ +{ + "taxForms": [ + { + "year": 2025, + "status": "available" + } + ] +} diff --git a/test/mocks/configuration/update-mandate-success.json b/test/mocks/configuration/update-mandate-success.json new file mode 100644 index 00000000..83773be2 --- /dev/null +++ b/test/mocks/configuration/update-mandate-success.json @@ -0,0 +1,5 @@ +{ + "id": "MD00000000000000000000001", + "status": "active", + "accountHolderId": "AH00000000000000000000001" +}