From 44b8eaf1c41ff942df9ba698d95d06695e366bf1 Mon Sep 17 00:00:00 2001 From: david ruiz Date: Fri, 19 Jun 2026 14:06:44 +0200 Subject: [PATCH] GetFaceAuthenticationAttemptAssets + PaymentPlan updates --- checkout_sdk/identities/entities.py | 3 +++ .../faceauthentication_client.py | 10 ++++++++++ .../identityverification_client.py | 10 ++++++++++ checkout_sdk/payments/hosted/hosted_payments.py | 4 +++- checkout_sdk/payments/links/payments_links.py | 4 +++- checkout_sdk/payments/payments.py | 1 + checkout_sdk/payments/sessions/sessions.py | 4 +++- .../faceauthentication_client_test.py | 10 ++++++++++ .../faceauthentication_integration_test.py | 14 ++++++++++++++ .../identityverification_client_test.py | 10 ++++++++++ .../identityverification_integration_test.py | 15 +++++++++++++++ tests/oauth_integration_test.py | 2 +- 12 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 checkout_sdk/identities/entities.py diff --git a/checkout_sdk/identities/entities.py b/checkout_sdk/identities/entities.py new file mode 100644 index 00000000..f25a9930 --- /dev/null +++ b/checkout_sdk/identities/entities.py @@ -0,0 +1,3 @@ +class AttemptAssetsQueryFilter: + skip: int + limit: int diff --git a/checkout_sdk/identities/faceauthentication/faceauthentication_client.py b/checkout_sdk/identities/faceauthentication/faceauthentication_client.py index 6f623ef9..36b36f27 100644 --- a/checkout_sdk/identities/faceauthentication/faceauthentication_client.py +++ b/checkout_sdk/identities/faceauthentication/faceauthentication_client.py @@ -4,6 +4,7 @@ from checkout_sdk.authorization_type import AuthorizationType from checkout_sdk.checkout_configuration import CheckoutConfiguration from checkout_sdk.client import Client +from checkout_sdk.identities.entities import AttemptAssetsQueryFilter from checkout_sdk.identities.faceauthentication.faceauthentication import ( FaceAuthenticationRequest, FaceAuthenticationAttemptRequest ) @@ -13,6 +14,7 @@ class FaceAuthenticationClient(Client): __FACE_AUTHENTICATIONS_PATH = 'face-authentications' __ANONYMIZE_PATH = 'anonymize' __ATTEMPTS_PATH = 'attempts' + __ASSETS_PATH = 'assets' def __init__(self, api_client: ApiClient, configuration: CheckoutConfiguration): super().__init__(api_client=api_client, @@ -50,3 +52,11 @@ def get_face_authentication_attempt(self, face_authentication_id: str, attempt_i self.build_path(self.__FACE_AUTHENTICATIONS_PATH, face_authentication_id, self.__ATTEMPTS_PATH, attempt_id), self._sdk_authorization()) + + def get_face_authentication_attempt_assets(self, face_authentication_id: str, attempt_id: str, + query: AttemptAssetsQueryFilter = None): + return self._api_client.get( + self.build_path(self.__FACE_AUTHENTICATIONS_PATH, face_authentication_id, self.__ATTEMPTS_PATH, + attempt_id, self.__ASSETS_PATH), + self._sdk_authorization(), + query) diff --git a/checkout_sdk/identities/identityverification/identityverification_client.py b/checkout_sdk/identities/identityverification/identityverification_client.py index 24ac2d5e..1e4741a7 100644 --- a/checkout_sdk/identities/identityverification/identityverification_client.py +++ b/checkout_sdk/identities/identityverification/identityverification_client.py @@ -4,6 +4,7 @@ from checkout_sdk.authorization_type import AuthorizationType from checkout_sdk.checkout_configuration import CheckoutConfiguration from checkout_sdk.client import Client +from checkout_sdk.identities.entities import AttemptAssetsQueryFilter from checkout_sdk.identities.identityverification.identityverification import ( IdentityVerificationRequest, IdentityVerificationAndAttemptRequest, @@ -17,6 +18,7 @@ class IdentityVerificationClient(Client): __ANONYMIZE_PATH = 'anonymize' __ATTEMPTS_PATH = 'attempts' __PDF_REPORT_PATH = 'pdf-report' + __ASSETS_PATH = 'assets' def __init__(self, api_client: ApiClient, configuration: CheckoutConfiguration): super().__init__(api_client=api_client, @@ -60,6 +62,14 @@ def get_identity_verification_attempt(self, identity_verification_id: str, attem attempt_id), self._sdk_authorization()) + def get_identity_verification_attempt_assets(self, identity_verification_id: str, attempt_id: str, + query: AttemptAssetsQueryFilter = None): + return self._api_client.get( + self.build_path(self.__IDENTITY_VERIFICATIONS_PATH, identity_verification_id, self.__ATTEMPTS_PATH, + attempt_id, self.__ASSETS_PATH), + self._sdk_authorization(), + query) + def get_identity_verification_report(self, identity_verification_id: str): return self._api_client.get( self.build_path(self.__IDENTITY_VERIFICATIONS_PATH, identity_verification_id, self.__PDF_REPORT_PATH), diff --git a/checkout_sdk/payments/hosted/hosted_payments.py b/checkout_sdk/payments/hosted/hosted_payments.py index c4f5ed3a..19ce7520 100644 --- a/checkout_sdk/payments/hosted/hosted_payments.py +++ b/checkout_sdk/payments/hosted/hosted_payments.py @@ -3,7 +3,7 @@ from checkout_sdk.common.common import CustomerRequest, CustomerRetry from checkout_sdk.common.enums import Currency from checkout_sdk.payments.payments import BillingDescriptor, PaymentInstruction, PaymentType, ShippingDetails, \ - ThreeDsRequest, RiskRequest, PaymentRecipient, ProcessingSettings, PaymentSender + ThreeDsRequest, RiskRequest, PaymentRecipient, ProcessingSettings, PaymentSender, PaymentPlan, AuthorizationType from checkout_sdk.payments.payments_previous import BillingInformation from checkout_sdk.payments.sessions.sessions import SessionPaymentMethodConfiguration @@ -40,3 +40,5 @@ class HostedPaymentsSessionRequest: capture_on: datetime instruction: PaymentInstruction payment_method_configuration: SessionPaymentMethodConfiguration + payment_plan: PaymentPlan + authorization_type: AuthorizationType diff --git a/checkout_sdk/payments/links/payments_links.py b/checkout_sdk/payments/links/payments_links.py index c2a3623d..f20c9b34 100644 --- a/checkout_sdk/payments/links/payments_links.py +++ b/checkout_sdk/payments/links/payments_links.py @@ -3,7 +3,7 @@ from checkout_sdk.common.common import CustomerRequest, CustomerRetry from checkout_sdk.common.enums import Currency from checkout_sdk.payments.payments import BillingDescriptor, PaymentInstruction, PaymentType, ShippingDetails, \ - ThreeDsRequest, RiskRequest, PaymentRecipient, ProcessingSettings, PaymentSender + ThreeDsRequest, RiskRequest, PaymentRecipient, ProcessingSettings, PaymentSender, PaymentPlan, AuthorizationType from checkout_sdk.payments.payments_previous import BillingInformation from checkout_sdk.payments.sessions.sessions import SessionPaymentMethodConfiguration @@ -39,3 +39,5 @@ class PaymentLinkRequest: capture_on: datetime instruction: PaymentInstruction payment_method_configuration: SessionPaymentMethodConfiguration + payment_plan: PaymentPlan + authorization_type: AuthorizationType diff --git a/checkout_sdk/payments/payments.py b/checkout_sdk/payments/payments.py index a08fffdd..512e1b33 100644 --- a/checkout_sdk/payments/payments.py +++ b/checkout_sdk/payments/payments.py @@ -620,6 +620,7 @@ class ProcessingSettings: service_type: ServiceType partner_code: str processing_speed: str # 'fast' (only for unreferenced refunds / card payouts) + scheme_transaction_link_id: str class ProductSubType (str, Enum): diff --git a/checkout_sdk/payments/sessions/sessions.py b/checkout_sdk/payments/sessions/sessions.py index 1d6d546b..d41c4b99 100644 --- a/checkout_sdk/payments/sessions/sessions.py +++ b/checkout_sdk/payments/sessions/sessions.py @@ -3,7 +3,7 @@ from checkout_sdk.common.enums import Currency from checkout_sdk.payments.payments import PaymentType, BillingDescriptor, ShippingDetails, \ - PaymentRecipient, ProcessingSettings, RiskRequest, ThreeDsRequest, PaymentSender + PaymentRecipient, ProcessingSettings, RiskRequest, ThreeDsRequest, PaymentSender, PaymentPlan, AuthorizationType from checkout_sdk.sessions.sessions import SessionsBillingDescriptor @@ -252,6 +252,8 @@ class PaymentSessionsRequest: disabled_payment_methods: list # PaymentMethodsType customer_retry: CustomerRetry ip_address: str + authorization_type: AuthorizationType + payment_plan: PaymentPlan class PaymentSessionWithPaymentRequest: diff --git a/tests/identities/faceauthentication/faceauthentication_client_test.py b/tests/identities/faceauthentication/faceauthentication_client_test.py index 0809185b..3c34716f 100644 --- a/tests/identities/faceauthentication/faceauthentication_client_test.py +++ b/tests/identities/faceauthentication/faceauthentication_client_test.py @@ -1,6 +1,7 @@ import pytest from tests._assertions import assert_api_call +from checkout_sdk.identities.entities import AttemptAssetsQueryFilter from checkout_sdk.identities.faceauthentication.faceauthentication import ( FaceAuthenticationRequest, FaceAuthenticationAttemptRequest ) @@ -55,3 +56,12 @@ def test_should_get_face_authentication_attempt(self, mocker, client: FaceAuthen assert client.get_face_authentication_attempt(_FAV_ID, _ATTEMPT_ID) == 'response' assert_api_call(mock, f'face-authentications/{_FAV_ID}/attempts/{_ATTEMPT_ID}') + + def test_should_get_face_authentication_attempt_assets(self, mocker, client: FaceAuthenticationClient): + mock = mocker.patch('checkout_sdk.api_client.ApiClient.get', return_value='response') + query = AttemptAssetsQueryFilter() + query.skip = 0 + query.limit = 10 + + assert client.get_face_authentication_attempt_assets(_FAV_ID, _ATTEMPT_ID, query) == 'response' + assert_api_call(mock, f'face-authentications/{_FAV_ID}/attempts/{_ATTEMPT_ID}/assets') diff --git a/tests/identities/faceauthentication/faceauthentication_integration_test.py b/tests/identities/faceauthentication/faceauthentication_integration_test.py index fa067727..cd0e94ed 100644 --- a/tests/identities/faceauthentication/faceauthentication_integration_test.py +++ b/tests/identities/faceauthentication/faceauthentication_integration_test.py @@ -1,5 +1,6 @@ import pytest +from checkout_sdk.identities.entities import AttemptAssetsQueryFilter from checkout_sdk.identities.faceauthentication.faceauthentication import ( FaceAuthenticationRequest, FaceAuthenticationAttemptRequest, ClientInformation ) @@ -57,6 +58,19 @@ def test_should_get_face_authentication_attempt(default_api): assert retrieved.id == created_attempt.id +@pytest.mark.skip(reason='Requires valid test environment setup') +def test_should_get_face_authentication_attempt_assets(default_api): + created = default_api.face_authentication.create_face_authentication(face_authentication_request()) + created_attempt = default_api.face_authentication.create_face_authentication_attempt( + created.id, face_authentication_attempt_request()) + query = AttemptAssetsQueryFilter() + query.skip = 0 + query.limit = 10 + assets = default_api.face_authentication.get_face_authentication_attempt_assets( + created.id, created_attempt.id, query) + assert_response(assets, 'http_metadata', 'total_count', 'data') + + @pytest.mark.skip(reason='Requires valid test environment setup') def test_should_perform_face_authentication_workflow(default_api): created = default_api.face_authentication.create_face_authentication(face_authentication_request()) diff --git a/tests/identities/identityverification/identityverification_client_test.py b/tests/identities/identityverification/identityverification_client_test.py index 4600b6e5..dc95a228 100644 --- a/tests/identities/identityverification/identityverification_client_test.py +++ b/tests/identities/identityverification/identityverification_client_test.py @@ -1,6 +1,7 @@ import pytest from tests._assertions import assert_api_call +from checkout_sdk.identities.entities import AttemptAssetsQueryFilter from checkout_sdk.identities.identityverification.identityverification import ( IdentityVerificationRequest, IdentityVerificationAndAttemptRequest, IdentityVerificationAttemptRequest ) @@ -64,3 +65,12 @@ def test_should_get_identity_verification_report(self, mocker, client: IdentityV assert client.get_identity_verification_report('idv_12345') == 'response' assert_api_call(mock, 'identity-verifications/idv_12345/pdf-report') + + def test_should_get_identity_verification_attempt_assets(self, mocker, client: IdentityVerificationClient): + mock = mocker.patch('checkout_sdk.api_client.ApiClient.get', return_value='response') + query = AttemptAssetsQueryFilter() + query.skip = 0 + query.limit = 10 + + assert client.get_identity_verification_attempt_assets('idv_12345', 'attempt_67890', query) == 'response' + assert_api_call(mock, 'identity-verifications/idv_12345/attempts/attempt_67890/assets') diff --git a/tests/identities/identityverification/identityverification_integration_test.py b/tests/identities/identityverification/identityverification_integration_test.py index a69a4fbd..047c1eba 100644 --- a/tests/identities/identityverification/identityverification_integration_test.py +++ b/tests/identities/identityverification/identityverification_integration_test.py @@ -1,5 +1,6 @@ import pytest +from checkout_sdk.identities.entities import AttemptAssetsQueryFilter from checkout_sdk.identities.identityverification.identityverification import ( IdentityVerificationRequest, IdentityVerificationAndAttemptRequest, IdentityVerificationAttemptRequest, DeclaredData, ClientInformation @@ -72,6 +73,20 @@ def test_should_get_identity_verification_attempt(default_api): assert retrieved.id == created_attempt.id +@pytest.mark.skip(reason='Requires valid test environment setup') +def test_should_get_identity_verification_attempt_assets(default_api): + created = default_api.identity_verification.create_identity_verification( + identity_verification_request()) + created_attempt = default_api.identity_verification.create_identity_verification_attempt( + created.id, identity_verification_attempt_request()) + query = AttemptAssetsQueryFilter() + query.skip = 0 + query.limit = 10 + assets = default_api.identity_verification.get_identity_verification_attempt_assets( + created.id, created_attempt.id, query) + assert_response(assets, 'http_metadata', 'total_count', 'data') + + @pytest.mark.skip(reason='Requires valid test environment setup') def test_should_get_identity_verification_report(default_api): created = default_api.identity_verification.create_identity_verification( diff --git a/tests/oauth_integration_test.py b/tests/oauth_integration_test.py index 99a34410..179eab7c 100644 --- a/tests/oauth_integration_test.py +++ b/tests/oauth_integration_test.py @@ -57,4 +57,4 @@ def test_should_fail_oauth_with_subdomain_invalid_credentials(): .scopes([OAuthScopes.GATEWAY, OAuthScopes.VAULT]) \ .build() except CheckoutException as err: - assert err.args[0] == 'OAuth client_credentials authentication failed with status: (406)' + assert err.args[0] == 'OAuth client_credentials authentication failed with error: (invalid_client)'