From 5418b395fbee682042a10b5fd828975352834fd8 Mon Sep 17 00:00:00 2001 From: Jawad Khan Date: Fri, 26 Jul 2024 23:12:13 +0500 Subject: [PATCH 1/2] fix: Remove redundant apple date match check --- ecommerce/extensions/iap/processors/base_iap.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ecommerce/extensions/iap/processors/base_iap.py b/ecommerce/extensions/iap/processors/base_iap.py index 106a881e44e..23f8b2f986b 100644 --- a/ecommerce/extensions/iap/processors/base_iap.py +++ b/ecommerce/extensions/iap/processors/base_iap.py @@ -178,8 +178,7 @@ def parse_ios_response(self, response, product_id): """ purchases = response['receipt'].get('in_app', []) for purchase in purchases: - if purchase['product_id'] == product_id and \ - response['receipt']['original_purchase_date_ms'] == purchase['original_purchase_date_ms']: + if purchase['product_id'] == product_id: response['receipt']['in_app'] = [purchase] break From 06bc657fdedf8723e6bc865f09fe3e1b89c4f7e5 Mon Sep 17 00:00:00 2001 From: Jawad Khan Date: Mon, 29 Jul 2024 19:58:40 +0500 Subject: [PATCH 2/2] fix: Handled cancelled payment case for iOS --- ecommerce/extensions/iap/processors/base_iap.py | 5 +++++ .../iap/tests/processors/test_ios_iap.py | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ecommerce/extensions/iap/processors/base_iap.py b/ecommerce/extensions/iap/processors/base_iap.py index 23f8b2f986b..2f28d6a79db 100644 --- a/ecommerce/extensions/iap/processors/base_iap.py +++ b/ecommerce/extensions/iap/processors/base_iap.py @@ -128,6 +128,11 @@ def handle_processor_response(self, response, basket=None): if not original_transaction_id: raise PaymentError(response) + if 'cancellation_reason' in validation_response['receipt']['in_app'][0]: + error = 'iOS payment is cancelled for [%s] in basket [%d]' + logger.error(error, original_transaction_id, basket.id) + raise UserCancelled(response) + # In case of Android transaction_id is required to identify payment elif not transaction_id: logger.error('Unable to find transaction id for basket [%d]', basket.id) diff --git a/ecommerce/extensions/iap/tests/processors/test_ios_iap.py b/ecommerce/extensions/iap/tests/processors/test_ios_iap.py index b305b07282e..6ad118c021d 100644 --- a/ecommerce/extensions/iap/tests/processors/test_ios_iap.py +++ b/ecommerce/extensions/iap/tests/processors/test_ios_iap.py @@ -9,7 +9,7 @@ import mock from django.test import RequestFactory from django.urls import reverse -from oscar.apps.payment.exceptions import GatewayError, PaymentError +from oscar.apps.payment.exceptions import GatewayError, PaymentError, UserCancelled from oscar.core.loading import get_model from testfixtures import LogCapture @@ -185,6 +185,19 @@ def test_handle_processor_response_payment_error(self, mock_ios_validator): self.processor.handle_processor_response(modified_return_data, basket=self.basket) + @mock.patch.object(IOSValidator, 'validate') + def test_handle_cancelled_payment_error(self, mock_ios_validator): + """ + Verify that User cancelled exception is raised in presence of cancellation_reason parameter. + """ + modified_validation_response = self.mock_validation_response + modified_validation_response['receipt']['in_app'][2]['cancellation_reason'] = 0 + mock_ios_validator.return_value = modified_validation_response + with self.assertRaises(UserCancelled): + modified_return_data = self.RETURN_DATA + + self.processor.handle_processor_response(modified_return_data, basket=self.basket) + @mock.patch.object(IOSIAP, 'is_payment_redundant') @mock.patch.object(IOSValidator, 'validate') def test_handle_processor_response_redundant_error(self, mock_ios_validator, mock_payment_redundant):