diff --git a/commerce_coordinator/apps/commercetools/catalog_info/edx_utils.py b/commerce_coordinator/apps/commercetools/catalog_info/edx_utils.py index 1240ab5a..64b6acad 100644 --- a/commerce_coordinator/apps/commercetools/catalog_info/edx_utils.py +++ b/commerce_coordinator/apps/commercetools/catalog_info/edx_utils.py @@ -10,8 +10,6 @@ from commercetools.platform.models import TransactionType from commerce_coordinator.apps.commercetools.catalog_info.constants import ( - EDX_STRIPE_PAYMENT_INTERFACE_NAME, - EDX_PAYPAL_PAYMENT_INTERFACE_NAME, PAYMENT_STATUS_INTERFACE_CODE_SUCCEEDED, EdXFieldNames, TwoUKeys @@ -49,17 +47,6 @@ def get_edx_lms_user_name(customer: CTCustomer): return customer.custom.fields[EdXFieldNames.LMS_USER_NAME] -def get_edx_successful_stripe_payment(order: CTOrder) -> Union[CTPayment, None]: - for pr in order.payment_info.payments: - pmt = pr.obj - if pmt.payment_status.interface_code == PAYMENT_STATUS_INTERFACE_CODE_SUCCEEDED \ - and pmt.payment_method_info.payment_interface == EDX_STRIPE_PAYMENT_INTERFACE_NAME and \ - pmt.interface_id: - return pmt - return None - - -# TODO remove get_edx_successful_stripe_payment if there is no more use. def get_edx_successful_payment_info(order: CTOrder): for pr in order.payment_info.payments: pmt = pr.obj @@ -90,9 +77,7 @@ def get_edx_refund_info(payment: CTPayment) -> decimal: refund_amount = decimal.Decimal(0.00) interaction_id = None for transaction in payment.transactions: - print('\n\n\n\n\n\nget_edx_refund_amount transaction.type = ', transaction.type) if transaction.type == TransactionType.CHARGE: # pragma no cover - print('\n\n\n\n\n\nget_edx_refund_amount transaction.amount = ', transaction.amount) refund_amount += decimal.Decimal(typed_money_to_string(transaction.amount, money_as_decimal_string=True)) interaction_id = transaction.interaction_id return refund_amount, interaction_id diff --git a/commerce_coordinator/apps/commercetools/pipeline.py b/commerce_coordinator/apps/commercetools/pipeline.py index 93f5be41..70cd3a0d 100644 --- a/commerce_coordinator/apps/commercetools/pipeline.py +++ b/commerce_coordinator/apps/commercetools/pipeline.py @@ -13,8 +13,8 @@ from requests import HTTPError from commerce_coordinator.apps.commercetools.catalog_info.constants import ( - EDX_STRIPE_PAYMENT_INTERFACE_NAME, - EDX_PAYPAL_PAYMENT_INTERFACE_NAME + EDX_PAYPAL_PAYMENT_INTERFACE_NAME, + EDX_STRIPE_PAYMENT_INTERFACE_NAME ) from commerce_coordinator.apps.commercetools.catalog_info.edx_utils import ( get_edx_refund_info, @@ -337,7 +337,6 @@ def run_filter( payment_on_order = ct_api_client.get_payment_by_key(payment_key) elif psp == EDX_PAYPAL_PAYMENT_INTERFACE_NAME: payment_on_order = ct_api_client.get_payment_by_key(payment_intent_id) - print('\n\n\n paypal payment_on_order = ', payment_on_order) updated_payment = ct_api_client.create_return_payment_transaction( payment_id=payment_on_order.id, diff --git a/commerce_coordinator/apps/commercetools/tests/test_pipeline.py b/commerce_coordinator/apps/commercetools/tests/test_pipeline.py index 2c330604..b5a74bff 100644 --- a/commerce_coordinator/apps/commercetools/tests/test_pipeline.py +++ b/commerce_coordinator/apps/commercetools/tests/test_pipeline.py @@ -3,12 +3,12 @@ from unittest import TestCase from unittest.mock import patch -from commerce_coordinator.apps.commercetools.catalog_info.constants import EDX_STRIPE_PAYMENT_INTERFACE_NAME from commercetools.platform.models import ReturnInfo, ReturnPaymentState, ReturnShipmentState, TransactionType from django.contrib.auth import get_user_model from django.test import RequestFactory from rest_framework.test import APITestCase +from commerce_coordinator.apps.commercetools.catalog_info.constants import EDX_STRIPE_PAYMENT_INTERFACE_NAME from commerce_coordinator.apps.commercetools.constants import COMMERCETOOLS_ORDER_MANAGEMENT_SYSTEM from commerce_coordinator.apps.commercetools.pipeline import ( AnonymizeRetiredUser, @@ -148,6 +148,7 @@ def test_commercetools_transaction_create(self, mock_returned_payment, mock_paym refund_response={"payment_intent": "mock_payment_intent"}, active_order_management_system=COMMERCETOOLS_ORDER_MANAGEMENT_SYSTEM, has_been_refunded=False, + payment_intent_id="pi_4MtwBwLkdIwGlenn28a3tqPa", psp=EDX_STRIPE_PAYMENT_INTERFACE_NAME ) mock_payment_result = ret['returned_payment'] @@ -170,6 +171,7 @@ def test_commercetools_transaction_create_no_payment_data(self, mock_returned_pa refund_response={"payment_intent": "mock_payment_intent"}, active_order_management_system=COMMERCETOOLS_ORDER_MANAGEMENT_SYSTEM, has_been_refunded=False, + payment_intent_id="pi_4MtwBwLkdIwGlenn28a3tqPa", psp=EDX_STRIPE_PAYMENT_INTERFACE_NAME ) mock_payment_result = ret['returned_payment'] @@ -188,6 +190,7 @@ def test_commercetools_transaction_create_has_refund(self, mock_logger, mock_has refund_response="charge_already_refunded", active_order_management_system=COMMERCETOOLS_ORDER_MANAGEMENT_SYSTEM, has_been_refunded=True, + payment_intent_id="pi_4MtwBwLkdIwGlenn28a3tqPa", psp=EDX_STRIPE_PAYMENT_INTERFACE_NAME ) mock_logger.assert_called_once_with('[CreateReturnPaymentTransaction] refund has already been processed, ' diff --git a/commerce_coordinator/apps/commercetools/views.py b/commerce_coordinator/apps/commercetools/views.py index 44999587..f159248a 100644 --- a/commerce_coordinator/apps/commercetools/views.py +++ b/commerce_coordinator/apps/commercetools/views.py @@ -127,8 +127,6 @@ def post(self, request): **request.data } - print('\n\n\n\n\n\nrequest.data', request.data) - logger.debug(f'[CT-{tag}] Message received from commercetools with details: {input_data}') message_details = OrderReturnedViewMessageInputSerializer(data=input_data) diff --git a/commerce_coordinator/apps/paypal/clients.py b/commerce_coordinator/apps/paypal/clients.py index 4ab243e3..8369c5a9 100644 --- a/commerce_coordinator/apps/paypal/clients.py +++ b/commerce_coordinator/apps/paypal/clients.py @@ -1,12 +1,17 @@ +"""PayPal client""" import json from django.conf import settings +from paypalserversdk.api_helper import ApiHelper +from paypalserversdk.controllers.payments_controller import PaymentsController from paypalserversdk.http.auth.o_auth_2 import ClientCredentialsAuthCredentials from paypalserversdk.paypalserversdk_client import PaypalserversdkClient -from paypalserversdk.controllers.payments_controller import PaymentsController -from paypalserversdk.api_helper import ApiHelper + class PayPalClient: + """ + PayPal SDK client to call PayPal APIs. + """ def __init__(self): self.paypal_client: PaypalserversdkClient = PaypalserversdkClient( client_credentials_auth_credentials=ClientCredentialsAuthCredentials( @@ -17,16 +22,24 @@ def __init__(self): def refund_order(self, capture_id): + """ + Capture PayPal refund. + + Args: + capture_id (str): The identifier of the PayPal order to cpture refund. + + Returns: + The response from PayPal. + """ + paypal_client = self.paypal_client payments_controller: PaymentsController = paypal_client.payments collect = {"capture_id": capture_id, "prefer": "return=representation"} refund_response = payments_controller.captures_refund(collect) - print('\n\n\n\n\n refund_response.body = ', refund_response.body) + if refund_response.body: response = json.loads(ApiHelper.json_serialize(refund_response.body)) - print('\n\n\n\n\n refund_order response serialized = ', response) - return { "id": response.get("id"), "created": response.get("create_time"), diff --git a/commerce_coordinator/apps/paypal/pipeline.py b/commerce_coordinator/apps/paypal/pipeline.py index 222a1926..db74b7e9 100644 --- a/commerce_coordinator/apps/paypal/pipeline.py +++ b/commerce_coordinator/apps/paypal/pipeline.py @@ -6,12 +6,12 @@ from urllib.parse import urlencode from django.conf import settings -from commerce_coordinator.apps.paypal.clients import PayPalClient -from commerce_coordinator.apps.core.constants import PipelineCommand from openedx_filters import PipelineStep from requests import RequestException from commerce_coordinator.apps.commercetools.catalog_info.constants import EDX_PAYPAL_PAYMENT_INTERFACE_NAME +from commerce_coordinator.apps.core.constants import PipelineCommand +from commerce_coordinator.apps.paypal.clients import PayPalClient logger = logging.getLogger(__name__) @@ -71,7 +71,7 @@ def run_filter( try: paypal_client = PayPalClient() paypal_refund_response = paypal_client.refund_order(capture_id=ct_transaction_interaction_id) - print('\n\n\n\n\n paypal_refund_response = ', paypal_refund_response) + return { 'refund_response': paypal_refund_response, } @@ -81,6 +81,4 @@ def run_filter( f'message_id: {kwargs["message_id"]} ' f'exception: {ex}') - raise RequestException(str(ex)) - - + raise RequestException(str(ex)) from ex diff --git a/commerce_coordinator/apps/paypal/tests/__init__.py b/commerce_coordinator/apps/paypal/tests/__init__.py index 2e06d004..e69de29b 100644 --- a/commerce_coordinator/apps/paypal/tests/__init__.py +++ b/commerce_coordinator/apps/paypal/tests/__init__.py @@ -1 +0,0 @@ -"""Constants for PayPal app tests.""" diff --git a/commerce_coordinator/apps/stripe/pipeline.py b/commerce_coordinator/apps/stripe/pipeline.py index 32ed8a1e..132c7461 100644 --- a/commerce_coordinator/apps/stripe/pipeline.py +++ b/commerce_coordinator/apps/stripe/pipeline.py @@ -263,9 +263,6 @@ def run_filter( """ tag = type(self).__name__ - print('\n\n\n\n\n\nRefundPaymentIntent psp = ', psp) - print('\n\n\n\n\n\nRefundPaymentIntent payment_intent_id = ', payment_intent_id) - print('\n\n\n\n\n\nRefundPaymentIntent amount_in_cents = ', amount_in_cents) if psp != EDX_STRIPE_PAYMENT_INTERFACE_NAME or not payment_intent_id or not amount_in_cents: # pragma: no cover logger.info(f'[{tag}] payment_intent_id or amount_in_cents not set, skipping.') diff --git a/commerce_coordinator/settings/base.py b/commerce_coordinator/settings/base.py index 74b6095f..3d183c00 100644 --- a/commerce_coordinator/settings/base.py +++ b/commerce_coordinator/settings/base.py @@ -439,8 +439,8 @@ def root(*path_fragments): 'paypal': { 'user_activity_page_url': '', 'paypal_webhook_id': PAYPAL_WEBHOOK_ID, - 'client_id': 'ASoOt8z1BmLEzJGLV-N_gWP083ghlpWaj9eOj4BxQ9k8rQ-jDoSO5e_5-gRR3uzwp-hOt_YmfzKsnrFV', - 'client_secret': 'EL_StzjNHS0lUbtVLPOUxC-fa27E4x12WIAN4XRHjYNNYM3kkUNxXoaFd_XextoDC1h3TvF9vuC74J1Z', + 'client_id': '', + 'client_secret': '', }, }, } diff --git a/commerce_coordinator/settings/local.py b/commerce_coordinator/settings/local.py index 07d10cf7..ff2d1174 100644 --- a/commerce_coordinator/settings/local.py +++ b/commerce_coordinator/settings/local.py @@ -147,8 +147,8 @@ 'paypal': { 'user_activity_page_url': 'https://sandbox.paypal.com/myaccount/activities/', 'paypal_webhook_id': 'SET-ME-PLEASE', - 'client_id': 'ASoOt8z1BmLEzJGLV-N_gWP083ghlpWaj9eOj4BxQ9k8rQ-jDoSO5e_5-gRR3uzwp-hOt_YmfzKsnrFV', - 'client_secret': 'EL_StzjNHS0lUbtVLPOUxC-fa27E4x12WIAN4XRHjYNNYM3kkUNxXoaFd_XextoDC1h3TvF9vuC74J1Z', + 'client_id': '', + 'client_secret': '', }, }, } diff --git a/commerce_coordinator/settings/test.py b/commerce_coordinator/settings/test.py index 11e80417..b44ce027 100644 --- a/commerce_coordinator/settings/test.py +++ b/commerce_coordinator/settings/test.py @@ -18,6 +18,8 @@ 'paypal': { 'user_activity_page_url': 'https://test.paypal.com/myaccount/activities/', 'paypal_webhook_id': PAYPAL_WEBHOOK_ID, + 'client_id': '', + 'client_secret': '', }, }, } diff --git a/commerce_coordinator/urls.py b/commerce_coordinator/urls.py index 6bd3409b..4d5a0bc9 100644 --- a/commerce_coordinator/urls.py +++ b/commerce_coordinator/urls.py @@ -43,9 +43,6 @@ from commerce_coordinator.apps.titan import urls as titan_urls from commerce_coordinator.settings.base import FAVICON_URL -from commerce_coordinator.apps.paypal.clients import PayPalClient - -paypal_client = PayPalClient() admin.autodiscover() @@ -74,7 +71,6 @@ re_path(r'^$', lambda r: JsonResponse(data=[ "Welcome to Commerce Coordinator", "This is an API app that provides a backend for Commerce.", - str(paypal_client), ], status=status.HTTP_200_OK, safe=False), name='root'), path('favicon.ico', RedirectView.as_view(url=FAVICON_URL), name='favicon'), @@ -89,4 +85,3 @@ import debug_toolbar urlpatterns.append(re_path(r'^__debug__/', include(debug_toolbar.urls))) - diff --git a/requirements/base.in b/requirements/base.in index c9985da9..d36494ba 100644 --- a/requirements/base.in +++ b/requirements/base.in @@ -25,6 +25,7 @@ edx-rest-api-client mysqlclient openedx-filters Pillow +paypal-server-sdk==0.5.1 pytz segment-analytics-python stripe diff --git a/requirements/base.txt b/requirements/base.txt index 62ca0518..f1484a6b 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -147,8 +147,6 @@ openedx-filters==1.11.0 # via -r requirements/base.in packaging==24.1 # via marshmallow -paypal-server-sdk==0.5.1 - # via -r requirements/base.in pbr==6.1.0 # via stevedore pillow==11.0.0 diff --git a/requirements/common_constraints.txt b/requirements/common_constraints.txt index c54963e0..f40aa200 100644 --- a/requirements/common_constraints.txt +++ b/requirements/common_constraints.txt @@ -1,4 +1,8 @@ + + + + # A central location for most common version constraints # (across edx repos) for pip-installation. #