From 11429008c5c706bb2bb335fee1851d3a46e3515d Mon Sep 17 00:00:00 2001 From: Antoni Stroinski <55943882+antolo-arch@users.noreply.github.com> Date: Fri, 25 Nov 2022 15:42:31 +0100 Subject: [PATCH] separate services to different files, remove redundant HPP code --- .github/CODEOWNERS | 2 +- Adyen/__init__.py | 3 - Adyen/services.py | 449 ------------------------------------ Adyen/services/__init__.py | 7 + Adyen/services/base.py | 24 ++ Adyen/services/binLookup.py | 24 ++ Adyen/services/checkout.py | 120 ++++++++++ Adyen/services/payments.py | 103 +++++++++ Adyen/services/payouts.py | 47 ++++ Adyen/services/recurring.py | 36 +++ Adyen/services/terminal.py | 38 +++ test/DirectoryLookupTest.py | 77 ------- 12 files changed, 400 insertions(+), 530 deletions(-) delete mode 100644 Adyen/services.py create mode 100644 Adyen/services/__init__.py create mode 100644 Adyen/services/base.py create mode 100644 Adyen/services/binLookup.py create mode 100644 Adyen/services/checkout.py create mode 100644 Adyen/services/payments.py create mode 100644 Adyen/services/payouts.py create mode 100644 Adyen/services/recurring.py create mode 100644 Adyen/services/terminal.py delete mode 100644 test/DirectoryLookupTest.py diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 96d03f86..11b950d2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @AlexandrosMor @rikterbeek @acampos1916 @candemiralp @michaelpaul @jillingk +* @AlexandrosMor @rikterbeek @acampos1916 @candemiralp @michaelpaul @jillingk @antolo-arch diff --git a/Adyen/__init__.py b/Adyen/__init__.py index 888066a6..cb2ee5a7 100644 --- a/Adyen/__init__.py +++ b/Adyen/__init__.py @@ -19,7 +19,6 @@ AdyenRecurring, AdyenPayment, AdyenThirdPartyPayout, - AdyenHPP, AdyenCheckoutApi, AdyenTerminal ) @@ -33,7 +32,6 @@ def __init__(self, **kwargs): self.payment = AdyenPayment(client=self.client) self.binlookup = AdyenBinLookup(client=self.client) self.payout = AdyenThirdPartyPayout(client=self.client) - self.hpp = AdyenHPP(client=self.client) self.recurring = AdyenRecurring(client=self.client) self.checkout = AdyenCheckoutApi(client=self.client) self.terminal = AdyenTerminal(client=self.client) @@ -41,7 +39,6 @@ def __init__(self, **kwargs): _base_adyen_obj = Adyen() recurring = _base_adyen_obj.recurring -hpp = _base_adyen_obj.hpp payment = _base_adyen_obj.payment payout = _base_adyen_obj.payout checkout = _base_adyen_obj.checkout diff --git a/Adyen/services.py b/Adyen/services.py deleted file mode 100644 index a8a3f90c..00000000 --- a/Adyen/services.py +++ /dev/null @@ -1,449 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -import datetime - -from Adyen import AdyenClient - - -class AdyenBase(object): - def __setattr__(self, attr, value): - client_attr = ["username", "password", "platform"] - if attr in client_attr: - if value: - self.client[attr] = value - else: - super(AdyenBase, self).__setattr__(attr, value) - - def __getattr__(self, attr): - client_attr = ["username", "password", "platform"] - if attr in client_attr: - return self.client[attr] - - -class AdyenServiceBase(AdyenBase): - def __init__(self, client=None): - if client: - self.client = client - else: - self.client = AdyenClient() - - -class AdyenRecurring(AdyenServiceBase): - """This represents the Adyen API Recurring Service. - - API calls currently implemented: listRecurringDetails and disable. Please - refer to the Recurring Manual for specifics around the API. - https://docs.adyen.com/online-payments/tokenization - - Args: - client (AdyenAPIClient, optional): An API client for the service to - use. If not provided, a new API client will be created. - """ - - def __init__(self, client=None): - super(AdyenRecurring, self).__init__(client=client) - self.service = "Recurring" - - def list_recurring_details(self, request, **kwargs): - - action = "listRecurringDetails" - - return self.client.call_api(request, self.service, - action, **kwargs) - - def disable(self, request, **kwargs): - - action = "disable" - - if 'recurringDetailReference' not in request: - raise ValueError("Include a 'recurringDetailReference'" - " to disable a specific recurring contract.") - else: - return self.client.call_api(request, self.service, - action, **kwargs) - - -class AdyenHPP(AdyenServiceBase): - """This represents the Adyen HPP Service. - - This currently only implements the directory_lookup request which will - return the list of payment methods available for given shopper. Please - refer to the HPP manual and the directory lookup section for the specifics. - https://docs.adyen.com/online-payments/classic-integrations/hosted-payment-pages/directory-lookup - - Args: - client (AdyenAPIClient, optional): An API client for the service to - use. If not provided, a new API client will be created. - """ - - def __init__(self, client=None): - super(AdyenHPP, self).__init__(client=client) - - def directory_lookup(self, request, **kwargs): - - action = "directory" - - try: - datetime.datetime.strptime(request['sessionValidity'], - '%Y-%m-%dT%H:%M:%SZ') - except ValueError: - raise ValueError( - "Incorrect date format, should be Y-m-dH:M:SZ," - " use datetime.strftime('%Y-%m-%dT%H:%M:%SZ')" - " to format a datetime object.") - - return self.client.call_hpp(request, action) - - def hpp_payment(self, request, skip_details=None, **kwargs): - - if skip_details: - action = "skipDetails" - else: - action = "select" - - if action == "skipDetails": - if "issuerId" not in request: - request['issuerId'] = "" - if type(request['sessionValidity']) is not str: - raise TypeError( - 'HPP: sessionValidity must be type of str,' - ' use datetime.strftime to convert and format.') - if all(k in request for k in ("shopperEmail", "shopperReference", - "recurringContract")): - recc = request['recurringContract'] - if recc != 'ONECLICK' and recc != 'RECURRING' \ - and recc != 'ONECLICK,RECURRING': - raise ValueError( - "HPP: recurringContract must be on of the following" - " values: 'ONECLICK', 'RECURRING'," - " 'ONECLICK,RECURRING'") - - result = self.client.hpp_payment(request, action) - return result - - -class AdyenPayment(AdyenServiceBase): - """This represents the Adyen API Payment Service. - - API calls currently implemented: - authorise - authorise3d - adjustAuthorisation - cancel - capture - refund - cancelOrRefund - Please refer to our API Explorer for specifics around these APIs. - https://docs.adyen.com/api-explorer/ - - The AdyenPayment class, is accessible as adyen.payment.method(args) - - Args: - client (AdyenAPIClient, optional): An API client for the service to - use. If not provided, a new API client will be created. - """ - - def __init__(self, client=None): - super(AdyenPayment, self).__init__(client=client) - self.service = "Payment" - - def authorise(self, request, idempotency_key=None, **kwargs): - - action = "authorise" - - if 'shopperEmail' in request: - if request['shopperEmail'] == '': - raise ValueError( - 'shopperEmail must contain the shopper email' - ' when authorising recurring contracts.') - if 'shopperReference' in request: - if request['shopperReference'] == '': - raise ValueError( - 'shopperReference must contain the shopper' - ' name when authorising recurring contracts.') - - return self.client.call_api(request, self.service, - action, idempotency_key, **kwargs) - - def authorise3d(self, request, idempotency_key=None, **kwargs): - action = "authorise3d" - - return self.client.call_api(request, self.service, - action, idempotency_key, **kwargs) - - def adjustAuthorisation(self, request, **kwargs): - action = "adjustAuthorisation" - - return self.client.call_api(request, self.service, - action, **kwargs) - - def cancel(self, request, idempotency_key=None, **kwargs): - action = "cancel" - - return self.client.call_api(request, self.service, - action, idempotency_key, **kwargs) - - def capture(self, request, idempotency_key=None, **kwargs): - - action = "capture" - - if request['modificationAmount']["value"] == "" or \ - request['modificationAmount']['value'] == "0": - raise ValueError( - "Set the 'modificationAmount' to the original transaction" - " amount, or less for a partial capture. " - "modificationAmount should be an object with the following" - " keys: {'currency':,'value':}") - if request['originalReference'] == "": - raise ValueError("Set the 'originalReference' to the psp " - "reference of the transaction to be modified") - - response = self.client.call_api(request, self.service, - action, idempotency_key, **kwargs) - return response - - def refund(self, request, idempotency_key=None, **kwargs): - - action = "refund" - - if request['modificationAmount']['value'] == "" or \ - request['modificationAmount']['value'] == "0": - raise ValueError( - "To refund this payment, provide the original value. " - "Set the value to less than the original amount, " - "to partially refund this payment.") - else: - return self.client.call_api(request, self.service, - action, idempotency_key, **kwargs) - - def cancel_or_refund(self, request, idempotency_key=None, **kwargs): - action = "cancelOrRefund" - - return self.client.call_api( - request, self.service, action, idempotency_key, **kwargs - ) - - -class AdyenThirdPartyPayout(AdyenServiceBase): - """This represents the Adyen Payouts Service. - https://docs.adyen.com/api-explorer/#/Payout/overview - - The AdyenThirdPartyPayout class is accessible as adyen.payout.method(args) - - Args: - client (AdyenAPIClient, optional): An API client for the service to - use. If not provided, a new API client will be created. - """ - - def __init__(self, client=None): - super(AdyenThirdPartyPayout, self).__init__(client=client) - self.service = "Payout" - - def confirm(self, request=None, **kwargs): - action = "confirmThirdParty" - return self.client.call_api( - request, self.service, action, **kwargs - ) - - def decline(self, request=None, **kwargs): - action = "declineThirdParty" - return self.client.call_api( - request, self.service, action, **kwargs - ) - - def store_detail(self, request=None, **kwargs): - action = "storeDetail" - return self.client.call_api( - request, self.service, action, **kwargs - ) - - def submit(self, request=None, **kwargs): - action = "submitThirdParty" - return self.client.call_api( - request, self.service, action, **kwargs - ) - - def store_detail_and_submit(self, request=None, **kwargs): - action = "storeDetailAndSubmitThirdParty" - return self.client.call_api( - request, self.service, action, **kwargs - ) - - -class AdyenCheckoutApi(AdyenServiceBase): - """This represents the Adyen Checkout API . - - API calls currently implemented: - paymentMethods - payments - payments/details - originKeys - - Modifications: - capture - refunds - cancels - reversals - - - Please refer to the checkout documentation for specifics around the API. - https://docs.adyen.com/online-payments - - The AdyenPayment class, is accessible as adyen.payment.method(args) - - Args: - client (AdyenAPIClient, optional): An API client for the service to - use. If not provided, a new API client will be created. - """ - - def __init__(self, client=None): - super(AdyenCheckoutApi, self).__init__(client=client) - self.service = "Checkout" - - def payment_methods(self, request, **kwargs): - action = "paymentMethods" - if 'merchantAccount' in request: - if request['merchantAccount'] == '': - raise ValueError( - 'merchantAccount must contain the merchant account' - ' when retrieving payment methods.') - - return self.client.call_checkout_api(request, action, **kwargs) - - def payments(self, request, idempotency_key=None, **kwargs): - action = "payments" - return self.client.call_checkout_api(request, action, idempotency_key, - **kwargs) - - def payments_details(self, request=None, idempotency_key=None, **kwargs): - action = "paymentsDetails" - return self.client.call_checkout_api(request, action, idempotency_key, - **kwargs) - - def payment_session(self, request=None, **kwargs): - action = "paymentSession" - return self.client.call_checkout_api(request, action, **kwargs) - - 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) - - def sessions(self, request=None, **kwargs): - action = "sessions" - return self.client.call_checkout_api(request, action, **kwargs) - # Orders endpoints - - # /paymentMethods/balance - def payment_methods_balance(self, request, **kwargs): - action = "paymentMethodsBalance" - return self.client.call_checkout_api(request, action, **kwargs) - - # /orders - def orders(self, request, **kwargs): - action = "orders" - return self.client.call_checkout_api(request, action, **kwargs) - - # /orders/cancel - def orders_cancel(self, request, **kwargs): - action = "ordersCancel" - return self.client.call_checkout_api(request, action, **kwargs) - - -class AdyenBinLookup(AdyenServiceBase): - """This represents the Adyen API Bin Lookup service. - - API call currently implemented: getCostEstimate. - Please refer to the Bin Lookup Manual for specifics around the API. - https://docs.adyen.com/api-explorer/#/BinLookup/ - - Args: - client (AdyenAPIClient, optional): An API client for the service to - use. If not provided, a new API client will be created. - """ - - def __init__(self, client=None): - super(AdyenBinLookup, self).__init__(client=client) - self.service = "BinLookup" - - def get_cost_estimate(self, request="", **kwargs): - - action = "getCostEstimate" - - return self.client.call_api(request, self.service, action, **kwargs) - - -class AdyenTerminal(AdyenServiceBase): - """This represents the Adyen API Terminal service. - - API call currently implemented: - - assignTerminals - - findTerminal - - getStoreUnderAccount - - getTerminalDetails - - getTerminalsUnderAccount - Please refer to the Terminal Manual for specifics around the API. - https://docs.adyen.com/api-explorer/#/postfmapi/ - - Args: - client (AdyenAPIClient, optional): An API client for the service to - use. If not provided, a new API client will be created. - """ - - def __init__(self, client=None): - super(AdyenTerminal, self).__init__(client=client) - self.service = "terminal" - - def assign_terminals(self, request="", **kwargs): - return self.client.call_api(request, self.service, "assignTerminals", **kwargs) - - def find_terminal(self, request="", **kwargs): - return self.client.call_api(request, self.service, "findTerminal", **kwargs) - - def get_stores_under_account(self, request="", **kwargs): - return self.client.call_api(request, self.service, "getStoresUnderAccount", **kwargs) - - def get_terminal_details(self, request="", **kwargs): - return self.client.call_api(request, self.service, "getTerminalDetails", **kwargs) - - def get_terminals_under_account(self, request="", **kwargs): - return self.client.call_api(request, self.service, "getTerminalsUnderAccount", **kwargs) \ No newline at end of file diff --git a/Adyen/services/__init__.py b/Adyen/services/__init__.py new file mode 100644 index 00000000..e90c11b9 --- /dev/null +++ b/Adyen/services/__init__.py @@ -0,0 +1,7 @@ +from .base import AdyenBase +from .binLookup import AdyenBinLookup +from .checkout import AdyenCheckoutApi +from .payments import AdyenPayment +from .payouts import AdyenThirdPartyPayout +from .recurring import AdyenRecurring +from .terminal import AdyenTerminal diff --git a/Adyen/services/base.py b/Adyen/services/base.py new file mode 100644 index 00000000..bbebebfd --- /dev/null +++ b/Adyen/services/base.py @@ -0,0 +1,24 @@ +from Adyen import AdyenClient + + +class AdyenBase(object): + def __setattr__(self, attr, value): + client_attr = ["username", "password", "platform"] + if attr in client_attr: + if value: + self.client[attr] = value + else: + super(AdyenBase, self).__setattr__(attr, value) + + def __getattr__(self, attr): + client_attr = ["username", "password", "platform"] + if attr in client_attr: + return self.client[attr] + + +class AdyenServiceBase(AdyenBase): + def __init__(self, client=None): + if client: + self.client = client + else: + self.client = AdyenClient() \ No newline at end of file diff --git a/Adyen/services/binLookup.py b/Adyen/services/binLookup.py new file mode 100644 index 00000000..79d0de30 --- /dev/null +++ b/Adyen/services/binLookup.py @@ -0,0 +1,24 @@ +from .base import AdyenServiceBase + + +class AdyenBinLookup(AdyenServiceBase): + """This represents the Adyen API Bin Lookup service. + + API call currently implemented: getCostEstimate. + Please refer to the Bin Lookup Manual for specifics around the API. + https://docs.adyen.com/api-explorer/#/BinLookup/ + + Args: + client (AdyenAPIClient, optional): An API client for the service to + use. If not provided, a new API client will be created. + """ + + def __init__(self, client=None): + super(AdyenBinLookup, self).__init__(client=client) + self.service = "BinLookup" + + def get_cost_estimate(self, request="", **kwargs): + + action = "getCostEstimate" + + return self.client.call_api(request, self.service, action, **kwargs) diff --git a/Adyen/services/checkout.py b/Adyen/services/checkout.py new file mode 100644 index 00000000..e78500f9 --- /dev/null +++ b/Adyen/services/checkout.py @@ -0,0 +1,120 @@ +from .base import AdyenServiceBase + + +class AdyenCheckoutApi(AdyenServiceBase): + """This represents the Adyen Checkout API . + + API calls currently implemented: + paymentMethods + payments + payments/details + originKeys + + Modifications: + capture + refunds + cancels + reversals + + + Please refer to the checkout documentation for specifics around the API. + https://docs.adyen.com/online-payments + + The AdyenPayment class, is accessible as adyen.payment.method(args) + + Args: + client (AdyenAPIClient, optional): An API client for the service to + use. If not provided, a new API client will be created. + """ + + def __init__(self, client=None): + super(AdyenCheckoutApi, self).__init__(client=client) + self.service = "Checkout" + + def payment_methods(self, request, **kwargs): + action = "paymentMethods" + if 'merchantAccount' in request: + if request['merchantAccount'] == '': + raise ValueError( + 'merchantAccount must contain the merchant account' + ' when retrieving payment methods.') + + return self.client.call_checkout_api(request, action, **kwargs) + + def payments(self, request, idempotency_key=None, **kwargs): + action = "payments" + return self.client.call_checkout_api(request, action, idempotency_key, + **kwargs) + + def payments_details(self, request=None, idempotency_key=None, **kwargs): + action = "paymentsDetails" + return self.client.call_checkout_api(request, action, idempotency_key, + **kwargs) + + def payment_session(self, request=None, **kwargs): + action = "paymentSession" + return self.client.call_checkout_api(request, action, **kwargs) + + 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) + + def sessions(self, request=None, **kwargs): + action = "sessions" + return self.client.call_checkout_api(request, action, **kwargs) + # Orders endpoints + + # /paymentMethods/balance + def payment_methods_balance(self, request, **kwargs): + action = "paymentMethodsBalance" + return self.client.call_checkout_api(request, action, **kwargs) + + # /orders + def orders(self, request, **kwargs): + action = "orders" + return self.client.call_checkout_api(request, action, **kwargs) + + # /orders/cancel + def orders_cancel(self, request, **kwargs): + action = "ordersCancel" + return self.client.call_checkout_api(request, action, **kwargs) diff --git a/Adyen/services/payments.py b/Adyen/services/payments.py new file mode 100644 index 00000000..7b563301 --- /dev/null +++ b/Adyen/services/payments.py @@ -0,0 +1,103 @@ +from .base import AdyenServiceBase + + +class AdyenPayment(AdyenServiceBase): + """This represents the Adyen API Payment Service. + + API calls currently implemented: + authorise + authorise3d + adjustAuthorisation + cancel + capture + refund + cancelOrRefund + Please refer to our API Explorer for specifics around these APIs. + https://docs.adyen.com/api-explorer/ + + The AdyenPayment class, is accessible as adyen.payment.method(args) + + Args: + client (AdyenAPIClient, optional): An API client for the service to + use. If not provided, a new API client will be created. + """ + + def __init__(self, client=None): + super(AdyenPayment, self).__init__(client=client) + self.service = "Payment" + + def authorise(self, request, idempotency_key=None, **kwargs): + + action = "authorise" + + if 'shopperEmail' in request: + if request['shopperEmail'] == '': + raise ValueError( + 'shopperEmail must contain the shopper email' + ' when authorising recurring contracts.') + if 'shopperReference' in request: + if request['shopperReference'] == '': + raise ValueError( + 'shopperReference must contain the shopper' + ' name when authorising recurring contracts.') + + return self.client.call_api(request, self.service, + action, idempotency_key, **kwargs) + + def authorise3d(self, request, idempotency_key=None, **kwargs): + action = "authorise3d" + + return self.client.call_api(request, self.service, + action, idempotency_key, **kwargs) + + def adjustAuthorisation(self, request, **kwargs): + action = "adjustAuthorisation" + + return self.client.call_api(request, self.service, + action, **kwargs) + + def cancel(self, request, idempotency_key=None, **kwargs): + action = "cancel" + + return self.client.call_api(request, self.service, + action, idempotency_key, **kwargs) + + def capture(self, request, idempotency_key=None, **kwargs): + + action = "capture" + + if request['modificationAmount']["value"] == "" or \ + request['modificationAmount']['value'] == "0": + raise ValueError( + "Set the 'modificationAmount' to the original transaction" + " amount, or less for a partial capture. " + "modificationAmount should be an object with the following" + " keys: {'currency':,'value':}") + if request['originalReference'] == "": + raise ValueError("Set the 'originalReference' to the psp " + "reference of the transaction to be modified") + + response = self.client.call_api(request, self.service, + action, idempotency_key, **kwargs) + return response + + def refund(self, request, idempotency_key=None, **kwargs): + + action = "refund" + + if request['modificationAmount']['value'] == "" or \ + request['modificationAmount']['value'] == "0": + raise ValueError( + "To refund this payment, provide the original value. " + "Set the value to less than the original amount, " + "to partially refund this payment.") + else: + return self.client.call_api(request, self.service, + action, idempotency_key, **kwargs) + + def cancel_or_refund(self, request, idempotency_key=None, **kwargs): + action = "cancelOrRefund" + + return self.client.call_api( + request, self.service, action, idempotency_key, **kwargs + ) diff --git a/Adyen/services/payouts.py b/Adyen/services/payouts.py new file mode 100644 index 00000000..f8ad999b --- /dev/null +++ b/Adyen/services/payouts.py @@ -0,0 +1,47 @@ +from .base import AdyenServiceBase + + +class AdyenThirdPartyPayout(AdyenServiceBase): + """This represents the Adyen Payouts Service. + https://docs.adyen.com/api-explorer/#/Payout/overview + + The AdyenThirdPartyPayout class is accessible as adyen.payout.method(args) + + Args: + client (AdyenAPIClient, optional): An API client for the service to + use. If not provided, a new API client will be created. + """ + + def __init__(self, client=None): + super(AdyenThirdPartyPayout, self).__init__(client=client) + self.service = "Payout" + + def confirm(self, request=None, **kwargs): + action = "confirmThirdParty" + return self.client.call_api( + request, self.service, action, **kwargs + ) + + def decline(self, request=None, **kwargs): + action = "declineThirdParty" + return self.client.call_api( + request, self.service, action, **kwargs + ) + + def store_detail(self, request=None, **kwargs): + action = "storeDetail" + return self.client.call_api( + request, self.service, action, **kwargs + ) + + def submit(self, request=None, **kwargs): + action = "submitThirdParty" + return self.client.call_api( + request, self.service, action, **kwargs + ) + + def store_detail_and_submit(self, request=None, **kwargs): + action = "storeDetailAndSubmitThirdParty" + return self.client.call_api( + request, self.service, action, **kwargs + ) diff --git a/Adyen/services/recurring.py b/Adyen/services/recurring.py new file mode 100644 index 00000000..69087f81 --- /dev/null +++ b/Adyen/services/recurring.py @@ -0,0 +1,36 @@ +from .base import AdyenServiceBase + + +class AdyenRecurring(AdyenServiceBase): + """This represents the Adyen API Recurring Service. + + API calls currently implemented: listRecurringDetails and disable. Please + refer to the Recurring Manual for specifics around the API. + https://docs.adyen.com/online-payments/tokenization + + Args: + client (AdyenAPIClient, optional): An API client for the service to + use. If not provided, a new API client will be created. + """ + + def __init__(self, client=None): + super(AdyenRecurring, self).__init__(client=client) + self.service = "Recurring" + + def list_recurring_details(self, request, **kwargs): + + action = "listRecurringDetails" + + return self.client.call_api(request, self.service, + action, **kwargs) + + def disable(self, request, **kwargs): + + action = "disable" + + if 'recurringDetailReference' not in request: + raise ValueError("Include a 'recurringDetailReference'" + " to disable a specific recurring contract.") + else: + return self.client.call_api(request, self.service, + action, **kwargs) diff --git a/Adyen/services/terminal.py b/Adyen/services/terminal.py new file mode 100644 index 00000000..fe6f5f6d --- /dev/null +++ b/Adyen/services/terminal.py @@ -0,0 +1,38 @@ +from .base import AdyenServiceBase + + +class AdyenTerminal(AdyenServiceBase): + """This represents the Adyen API Terminal service. + + API call currently implemented: + - assignTerminals + - findTerminal + - getStoreUnderAccount + - getTerminalDetails + - getTerminalsUnderAccount + Please refer to the Terminal Manual for specifics around the API. + https://docs.adyen.com/api-explorer/#/postfmapi/ + + Args: + client (AdyenAPIClient, optional): An API client for the service to + use. If not provided, a new API client will be created. + """ + + def __init__(self, client=None): + super(AdyenTerminal, self).__init__(client=client) + self.service = "terminal" + + def assign_terminals(self, request="", **kwargs): + return self.client.call_api(request, self.service, "assignTerminals", **kwargs) + + def find_terminal(self, request="", **kwargs): + return self.client.call_api(request, self.service, "findTerminal", **kwargs) + + def get_stores_under_account(self, request="", **kwargs): + return self.client.call_api(request, self.service, "getStoresUnderAccount", **kwargs) + + def get_terminal_details(self, request="", **kwargs): + return self.client.call_api(request, self.service, "getTerminalDetails", **kwargs) + + def get_terminals_under_account(self, request="", **kwargs): + return self.client.call_api(request, self.service, "getTerminalsUnderAccount", **kwargs) \ No newline at end of file diff --git a/test/DirectoryLookupTest.py b/test/DirectoryLookupTest.py deleted file mode 100644 index dc75e962..00000000 --- a/test/DirectoryLookupTest.py +++ /dev/null @@ -1,77 +0,0 @@ -import unittest - -import Adyen - -try: - from BaseTest import BaseTest -except ImportError: - from .BaseTest import BaseTest - -import time - - -class TestDirectoryLookup(unittest.TestCase): - ady = Adyen.Adyen() - - client = ady.client - test = BaseTest(ady) - client.username = "YourWSUser" - client.password = "YourWSPassword" - client.platform = "test" - client.hmac = "DFB1EB5485895CFA84146406857104A" \ - "BB4CBCABDC8AAF103A624C8F6A3EAAB00" - - def test_get_post_parameters(self): - request = { - 'merchantAccount': "testmerchantaccount", - 'paymentAmount': "1000", - 'currencyCode': "EUR", - 'merchantReference': "Get Payment methods", - 'skinCode': "testskincode", - 'countryCode': "NL", - 'shopperLocale': "nl_NL", - 'sessionValidity': time.strftime('%Y-%m-%dT%H:%M:%SZ') - } - self.test.create_client_from_file(200, request, None) - result = self.ady.hpp.hpp_payment(request) - self.assertEqual("EUR", result["message"]["currencyCode"]) - self.assertEqual(44, len(result["message"]["merchantSig"])) - - def test_get_payment_methods(self): - request = { - 'merchantAccount': "testmerchantaccount", - 'paymentAmount': "1000", - 'currencyCode': "EUR", - 'merchantReference': "Get Payment methods", - 'skinCode': "testskincode", - 'countryCode': "NL", - 'shopperLocale': "nl_NL", - 'sessionValidity': time.strftime('%Y-%m-%dT%H:%M:%SZ') - } - self.test.create_client_from_file(200, request, - 'test/mocks/hpp/' - 'directoryLookup-success.json') - result = self.ady.hpp.directory_lookup(request) - self.assertEqual(8, len(result.message['paymentMethods'])) - ideal = result.message['paymentMethods'][0] - self.assertEqual("ideal", ideal['brandCode']) - self.assertEqual("iDEAL", ideal['name']) - self.assertEqual(3, len(ideal['issuers'])) - issuer1 = ideal['issuers'][0] - self.assertEqual("1121", issuer1['issuerId']) - self.assertEqual("Test Issuer", issuer1['name']) - visa = result.message['paymentMethods'][1] - self.assertEqual("visa", visa['brandCode']) - - -TestDirectoryLookup.client.http_force = "requests" -suite = unittest.TestLoader().loadTestsFromTestCase(TestDirectoryLookup) -unittest.TextTestRunner(verbosity=2).run(suite) -TestDirectoryLookup.client.http_force = "pycurl" -TestDirectoryLookup.client.http_init = False -suite = unittest.TestLoader().loadTestsFromTestCase(TestDirectoryLookup) -unittest.TextTestRunner(verbosity=2).run(suite) -TestDirectoryLookup.client.http_force = "other" -TestDirectoryLookup.client.http_init = False -suite = unittest.TestLoader().loadTestsFromTestCase(TestDirectoryLookup) -unittest.TextTestRunner(verbosity=2).run(suite)