diff --git a/ecommerce/extensions/dashboard/orders/tests.py b/ecommerce/extensions/dashboard/orders/tests.py
index cfd96bcc429..8e8aea0b0eb 100644
--- a/ecommerce/extensions/dashboard/orders/tests.py
+++ b/ecommerce/extensions/dashboard/orders/tests.py
@@ -1,5 +1,5 @@
-
+import json
import os
from unittest import SkipTest, skipIf
@@ -16,6 +16,8 @@
from ecommerce.extensions.dashboard.tests import DashboardViewTestMixin
from ecommerce.extensions.fulfillment.signals import SHIPPING_EVENT_NAME
from ecommerce.extensions.fulfillment.status import LINE, ORDER
+from ecommerce.extensions.iap.constants import MOBILE_PAYMENT_PROCESSORS
+from ecommerce.extensions.payment.models import PaymentProcessorResponse
from ecommerce.extensions.refund.tests.mixins import RefundTestMixin
from ecommerce.extensions.test.factories import create_order
from ecommerce.tests.factories import UserFactory
@@ -240,6 +242,24 @@ def test_create_refund_error(self):
'A refund cannot be created for these lines. They may have already been refunded.',
MSG.ERROR)
+ def test_mobile_refund_error(self):
+ """Verify the view creates a Refund for the Order and selected Lines."""
+ # Create Order and Lines
+ order = self.create_order(user=self.user)
+ PaymentProcessorResponse.objects.create(basket=order.basket,
+ transaction_id="test-transaction",
+ processor_name=MOBILE_PAYMENT_PROCESSORS[0],
+ response=json.dumps({'state': 'approved'}))
+
+ self.assertFalse(order.refunds.exists())
+ # Validate the Refund
+ response = self._request_refund(order)
+ self.assertFalse(order.refunds.exists())
+
+ self.assert_message_equals(response,
+ "Mobile payment refunds aren't allowed in ecommerce.",
+ MSG.ERROR)
+
class OrderDetailViewBrowserTests(OrderViewTestsMixin, RefundTestMixin, OrderViewBrowserTestBase):
diff --git a/ecommerce/extensions/dashboard/orders/views.py b/ecommerce/extensions/dashboard/orders/views.py
index 55113e198ab..2b4e00323a8 100644
--- a/ecommerce/extensions/dashboard/orders/views.py
+++ b/ecommerce/extensions/dashboard/orders/views.py
@@ -9,6 +9,7 @@
from oscar.core.loading import get_model
from ecommerce.extensions.dashboard.views import FilterFieldsMixin
+from ecommerce.extensions.iap.constants import MOBILE_PAYMENT_PROCESSORS
Order = get_model('order', 'Order')
Partner = get_model('partner', 'Partner')
@@ -62,20 +63,30 @@ class OrderDetailView(CoreOrderDetailView):
line_actions = ('change_line_statuses', 'create_shipping_event', 'create_payment_event', 'create_refund')
def create_refund(self, request, order, lines, _quantities): # pylint: disable=unused-argument
- refund = Refund.create_with_lines(order, lines)
-
- if refund:
- data = {
- 'link_start': ''.format(
- reverse('dashboard:refunds-detail', kwargs={'pk': refund.pk})),
- 'link_end': '',
- 'refund_id': refund.pk
- }
- message = _('{link_start}Refund #{refund_id}{link_end} created! '
- 'Click {link_start}here{link_end} to view it.').format(**data)
- messages.success(request, mark_safe(message))
- else:
- message = _('A refund cannot be created for these lines. They may have already been refunded.')
+ if self._is_order_from_mobile(order):
+ message = _("Mobile payment refunds aren't allowed in ecommerce.")
messages.error(request, message)
+ else:
+ refund = Refund.create_with_lines(order, lines)
+
+ if refund:
+ data = {
+ 'link_start': ''.format(
+ reverse('dashboard:refunds-detail', kwargs={'pk': refund.pk})),
+ 'link_end': '',
+ 'refund_id': refund.pk
+ }
+ message = _('{link_start}Refund #{refund_id}{link_end} created! '
+ 'Click {link_start}here{link_end} to view it.').format(**data)
+ messages.success(request, mark_safe(message))
+ else:
+ message = _('A refund cannot be created for these lines. They may have already been refunded.')
+ messages.error(request, message)
+
return self.reload_page()
+
+ def _is_order_from_mobile(self, order):
+ processor_responses = order.basket.paymentprocessorresponse_set.all()
+ return any(response.processor_name in MOBILE_PAYMENT_PROCESSORS
+ for response in processor_responses)
diff --git a/ecommerce/extensions/iap/constants.py b/ecommerce/extensions/iap/constants.py
index 1efcd8d319d..2847da95e90 100644
--- a/ecommerce/extensions/iap/constants.py
+++ b/ecommerce/extensions/iap/constants.py
@@ -1,3 +1,4 @@
+MOBILE_PAYMENT_PROCESSORS = ['android-iap', 'ios-iap']
ANDROID_SKU_PREFIX = 'android'
IOS_SKU_PREFIX = 'ios'
MISSING_WEB_SEAT_ERROR = "Couldn't find existing web seat for course [%s]"