Repository: fossasia/open-event-server

Issue:
Send appropriate error message on failure from Charges layer
**Is your feature request related to a problem? Please describe.**
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
Right now the server sends the HTTP 500 when something goes wrong in the processing of payments.

**Describe the solution you'd like**
<!-- A clear and concise description of what you want to happen. -->
Catch the Exception and send appropriate error message.

**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->
Parent #4852 


Discussion:

Resolving patch:
diff --git a/app/api/data_layers/ChargesLayer.py b/app/api/data_layers/ChargesLayer.py
--- a/app/api/data_layers/ChargesLayer.py
+++ b/app/api/data_layers/ChargesLayer.py
@@ -23,6 +23,7 @@ def create_object(self, data, view_kwargs):
         else:
             # when identifier is passed
             order = Order.query.filter_by(identifier=view_kwargs['order_identifier']).first()
+
         if not order:
             raise ObjectNotFound({'parameter': 'order_identifier'},
                                  "Order with identifier: {} not found".format(view_kwargs['order_identifier']))
@@ -33,19 +34,34 @@ def create_object(self, data, view_kwargs):
             raise ConflictException({'parameter': 'id'},
                                     "You cannot charge payments on a free order")
 
+        data['id'] = order.id
+
         # charge through stripe
         if order.payment_mode == 'stripe':
             if not data.get('stripe'):
                 raise UnprocessableEntity({'source': ''}, "stripe token is missing")
-            success, response = TicketingManager.charge_stripe_order_payment(order, data['stripe'])
-            if not success:
-                raise UnprocessableEntity({'source': 'stripe_token_id'}, response)
+            if not order.event.can_pay_by_stripe:
+                raise ConflictException({'': ''}, "This event doesn't accept payments by Stripe")
+            try:
+                success, response = TicketingManager.charge_stripe_order_payment(order, data['stripe'])
+                data['status'] = success
+                data['message'] = response
+            except Exception:
+                data['status'] = False
+                data['message'] = "Stripe hasn't been configured properly."
 
         # charge through paypal
         elif order.payment_mode == 'paypal':
             if not data.get('paypal'):
                 raise UnprocessableEntity({'source': ''}, "paypal token is missing")
-            success, response = TicketingManager.charge_paypal_order_payment(order, data['paypal'])
-            if not success:
-                raise UnprocessableEntity({'source': 'paypal'}, response)
-        return order
+            if not order.event.can_pay_by_paypal:
+                raise ConflictException({'': ''}, "This event doesn't accept payments by Paypal")
+            try:
+                success, response = TicketingManager.charge_paypal_order_payment(order, data['paypal'])
+                data['status'] = success
+                data['message'] = response
+            except Exception:
+                data['status'] = False
+                data['message'] = "Paypal hasn't been configured properly."
+
+        return data
diff --git a/app/api/orders.py b/app/api/orders.py
--- a/app/api/orders.py
+++ b/app/api/orders.py
@@ -357,8 +357,10 @@ class Meta:
         self_view_kwargs = {'order_identifier': '<id>'}
 
     id = fields.Str(dump_only=True)
-    stripe = fields.Str(allow_none=True)
-    paypal = fields.Str(allow_none=True)
+    stripe = fields.Str(load_only=True, allow_none=True)
+    paypal = fields.Str(load_only=True, allow_none=True)
+    status = fields.Boolean(dump_only=True)
+    message = fields.Str(dump_only=True)
 
 
 class ChargeList(ResourceList):


Test patch: