Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cancelled payment check for ios users #3

Merged
merged 2 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions ecommerce/extensions/iap/processors/base_iap.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -178,8 +183,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
Expand Down
15 changes: 14 additions & 1 deletion ecommerce/extensions/iap/tests/processors/test_ios_iap.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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):
Expand Down
Loading