async def process_payment(pay_msg: dict, flask_app: Flask): """Render the payment status.""" if not flask_app or not pay_msg: raise QueueException('Flask App or token not available.') with flask_app.app_context(): logger.debug('entering process payment: %s', pay_msg) # capture_message(f'Queue Issue: Unable to find payment.id={payment_id} to place on email queue') # return if pay_msg.get('paymentToken', {}).get('statusCode') == PaymentState.TRANSACTION_FAILED.value: # TODO: The customer has cancelled out of paying, so we could note this better # technically the payment for this service is still pending logger.debug('Failed transaction on queue:%s', pay_msg) return complete_payment_status = [PaymentState.COMPLETED.value, PaymentState.APPROVED.value] if pay_msg.get('paymentToken', {}).get('statusCode') in complete_payment_status: logger.debug('COMPLETED transaction on queue: %s', pay_msg) if payment_token := pay_msg.get('paymentToken', {}).get('id'): if payment := Payment.find_by_payment_token(payment_token): if update_payment := await update_payment_record(payment): payment = update_payment await furnish_receipt_message(qsm, payment) else:
async def test_update_payment_record( app, session, test_name, action_code, start_request_state, end_request_state, start_priority, end_priority, start_datetime, days_after_start_datetime, start_payment_state, end_payment_state, start_payment_date, end_payment_has_value, error): """Assert that the update_payment_record works as expected.""" from namex.models import Request, State, Payment from namex_pay.worker import update_payment_record print(test_name) now = datetime.utcnow() with freeze_time(now): # setup PAYMENT_TOKEN = 'dog' NR_NUMBER = 'NR B000001' name_request = Request() name_request.nrNum = NR_NUMBER name_request.stateCd = start_request_state name_request._source = 'NRO' name_request.expirationDate = start_datetime name_request.priorityCd = start_priority name_request.save_to_db() payment = Payment() payment.nrId = name_request.id payment._payment_token = PAYMENT_TOKEN payment._payment_status_code = start_payment_state payment.payment_action = action_code payment.furnished = False payment._payment_completion_date = start_payment_date payment.save_to_db() # run test if error: # expecting it to raise an error with pytest.raises(error): await update_payment_record(payment) else: # else it was processable if not (payment_final := await update_payment_record(payment)): payment_final = payment nr_final = Request.find_by_nr(NR_NUMBER) assert nr_final.stateCd == end_request_state assert nr_final.priorityCd == end_priority assert nr_final.expirationDate == ( start_datetime or now) + timedelta(days=days_after_start_datetime) assert eval( f'payment_final.payment_completion_date {end_payment_has_value} None' ) assert payment_final.payment_status_code == end_payment_state
def delete(self, nr_id, payment_id): try: # Find the existing name request nr_model = RequestDAO.query.get(nr_id) if not nr_model: return jsonify(message=f'No NR found with id: {nr_id}.'), 404 # Find the existing payment record payment = PaymentDAO.find_by_payment_token(payment_id) if not payment: return jsonify(message=f'No payment record with id: {payment_id}.'), 404 # check payment record state is CREATED current_payment_state = payment.payment_status_code if current_payment_state != PaymentStatusCode.CREATED.value: return jsonify(message=f'Unable to cancel a payment record in {current_payment_state} state.'), 400 try: # cancelling may change with refactor cancel_payment(payment.payment_token) payment.payment_status_code = PaymentState.CANCELLED.value payment.save_to_db() response_data = nr_model.json() # Add the list of valid Name Request actions for the given state to the response response_data['actions'] = get_nr_state_actions(nr_model.stateCd, nr_model) return jsonify(response_data), 200 except PaymentServiceError as err: # should only get here if there was a conflict (payment went through before cancel happened) return handle_exception(err, err.message, 409) except Exception as err: return handle_exception(err, repr(err), 500)
def post(nr_num): try: # TODO: Validate NR string format # if not RequestDAO.validNRFormat(nr_num): # return jsonify(message='NR number is not in a valid format \'NR 9999999\''), 400 nr_draft = RequestDAO.find_by_nr(nr_num) if not nr_draft: # Should this be a 400 or 404... hmmm return jsonify(message='{nr_num} not found'.format(nr_num=nr_num)), 400 json_input = request.get_json() if not json_input: return jsonify(message=MSG_BAD_REQUEST_NO_JSON_BODY), 400 elif isinstance(json_input, str): json_input = json.loads(json_input) # Grab the info we need off the request payment_info = json_input.get('paymentInfo') filing_info = json_input.get('filingInfo') business_info = json_input.get('businessInfo') # Create our payment request req = PaymentRequest( payment_info=payment_info, filing_info=filing_info, business_info=business_info ) payment_response = create_payment(req) if not payment_response: raise PaymentServiceError(message=MSG_ERROR_CREATING_RESOURCE) if payment_response and payment_response.status_code == PaymentStatusCode.CREATED.value: # Save the payment info to Postgres payment = PaymentDAO() payment.nrId = nr_draft.id payment.payment_token = str(payment_response.id) payment.payment_completion_date = payment_response.created_on payment.payment_status_code = PaymentState.CREATED.value payment.save_to_db() data = jsonify(payment_response.to_dict()) response = make_response(data, 200) return response except PaymentServiceError as err: return handle_exception(err, err.message, 500) except SBCPaymentException as err: return handle_exception(err, err.message, 500) except SBCPaymentError as err: return handle_exception(err, err.message, 500) except Exception as err: return handle_exception(err, err, 500)
async def furnish_receipt_message(qsm: QueueServiceManager, payment: Payment): # pylint: disable=redefined-outer-name """Send receipt info to the mail queue if it hasn't yet been done.""" if payment.furnished == 'Y': logger.debug( 'Queue Issue: Duplicate, already furnished receipt for payment.id=%s', payment.id) capture_message( f'Queue Issue: Duplicate, already furnished receipt for payment.id={payment.id}' ) return nr = None logger.debug('Start of the furnishing of receipt for payment record:%s', payment.as_dict()) try: payment.furnished = True payment.save_to_db() except Exception as err: # noqa: B902; bare exception to catch all raise Exception('Unable to alter payment record.') from err try: nr = RequestDAO.find_by_id(payment.nrId) cloud_event_msg = create_cloud_event_msg( msg_id=str(uuid.uuid4()), msg_type='bc.registry.names.request', source=f'/requests/{nr.nrNum}', time=datetime.utcfromtimestamp( time.time()).replace(tzinfo=timezone.utc).isoformat(), identifier=nr.nrNum, json_data_body={ 'request': { 'header': { 'nrNum': nr.nrNum }, 'paymentToken': payment.payment_token, 'statusCode': nr.stateCd } }) logger.debug('About to publish email for payment.id=%s', payment.id) await publish_email_message(qsm, cloud_event_msg) except Exception as err: # noqa: B902; bare exception to catch all payment.furnished = False payment.save_to_db() logger.debug('Reset payment furnish status payment.id= %s', payment.id) raise QueueException(f'Unable to furnish NR info. {err}') from err
async def test_process_payment( app, session, mocker, test_name, action_code, start_request_state, start_priority, start_datetime, start_payment_state, start_payment_date, ): from namex.models import Request, State, Payment from namex_pay.worker import process_payment, FLASK_APP nest_asyncio.apply() # setup PAYMENT_TOKEN = 'dog' NR_NUMBER = 'NR B000001' name_request = Request() name_request.nrNum = NR_NUMBER name_request.stateCd = start_request_state name_request._source = 'NRO' name_request.expirationDate = start_datetime name_request.priorityCd = start_priority name_request.save_to_db() payment = Payment() payment.nrId = name_request.id payment._payment_token = PAYMENT_TOKEN payment._payment_status_code = start_payment_state payment.payment_action = action_code payment.furnished = False payment._payment_completion_date = start_payment_date payment.save_to_db() # setup mock and patch msg = None def catch(qsm, cloud_event_msg): nonlocal msg msg = cloud_event_msg mocker.patch('namex_pay.worker.publish_email_message', side_effect=catch) # Test pay_msg = { "paymentToken": { "id": PAYMENT_TOKEN, "statusCode": "COMPLETED", "filingIdentifier": None } } await process_payment(pay_msg, FLASK_APP) print(msg) # Verify message that would be sent to the email server assert msg['type'] == 'bc.registry.names.request' assert msg['source'] == '/requests/NR B000001' assert msg['datacontenttype'] == 'application/json' assert msg['identifier'] == 'NR B000001' assert msg['data']['request']['header']['nrNum'] == NR_NUMBER assert msg['data']['request']['paymentToken'] == PAYMENT_TOKEN assert msg['data']['request']['statusCode'] == 'DRAFT'
def post(self, nr_id, payment_action=NameRequestActions.COMPLETE.value): """ At this point, the Name Request will still be using a TEMPORARY NR number. Confirming the payment on the frontend triggers this endpoint. Here, we: - Save the request to NRO which gives us a real NR. - Create the payment via SBC Pay. - If payment creation is successful, create a corresponding payment record in our system. :param nr_id: :param payment_action: :return: """ try: # Find the existing name request nr_model = RequestDAO.query.get(nr_id) if not nr_model: # Should this be a 400 or 404... hmmm return jsonify(message='Name Request {nr_id} not found'.format( nr_id=nr_id)), 400 if not payment_action: return jsonify( message='Invalid payment action, {action} not found'. format(action=payment_action)), 400 valid_payment_action = payment_action in [ NameRequestActions.COMPLETE.value, NameRequestActions.UPGRADE.value, NameRequestActions.REAPPLY.value ] if not valid_payment_action: return jsonify( message='Invalid payment action [{action}]'.format( action=payment_action)), 400 # We only handle payments if the NR is in the following states valid_payment_states = [ State.DRAFT, State.COND_RESERVE, State.RESERVED, State.CONDITIONAL, State.APPROVED ] valid_nr_state = nr_model.stateCd in valid_payment_states if not valid_nr_state: return jsonify(message='Invalid NR state'.format( action=payment_action)), 400 if valid_payment_action and valid_nr_state: if payment_action in [NameRequestActions.COMPLETE.value]: # Save the record to NRO, which swaps the NR-L Number for a real NR update_solr = True nr_model = self.add_records_to_network_services( nr_model, update_solr) json_input = request.get_json() payment_request = {} if not json_input: # return jsonify(message=MSG_BAD_REQUEST_NO_JSON_BODY), 400 # Grab the data from the NR, if it exists payment_request = build_payment_request(nr_model) elif isinstance(json_input, dict): payment_request = merge_payment_request(nr_model, json_input) elif isinstance(json_input, str): payment_request = merge_payment_request( nr_model, json.loads(json_input)) # Grab the info we need off the request payment_info = payment_request.get('paymentInfo') filing_info = payment_request.get('filingInfo') business_info = payment_request.get('businessInfo') # Create our payment request req = PaymentRequest(payment_info=payment_info, filing_info=filing_info, business_info=business_info) payment_response = create_payment(req) if not payment_response: raise PaymentServiceError(message=MSG_ERROR_CREATING_RESOURCE) if payment_response and payment_response.status_code == PaymentStatusCode.CREATED.value: # Save the payment info to Postgres payment = PaymentDAO() payment.nrId = nr_model.id payment.payment_token = str(payment_response.id) payment.payment_completion_date = payment_response.created_on payment.payment_status_code = PaymentState.CREATED.value payment.save_to_db() # Wrap the response, providing info from both the SBC Pay response and the payment we created data = jsonify({ 'id': payment.id, 'nrId': payment.nrId, 'token': payment.payment_token, 'statusCode': payment.payment_status_code, 'completionDate': payment.payment_completion_date, 'payment': payment.as_dict(), 'sbcPayment': payment_response.to_dict() }) # Record the event nr_svc = self.nr_service # EventRecorder.record(nr_svc.user, Event.PATCH + ' [payment ID: {id}]'.format(id=payment.id), nr_model, data) response = make_response(data, 201) return response except PaymentServiceError as err: return handle_exception(err, err.message, 500) except SBCPaymentException as err: return handle_exception(err, err.message, err.status_code) except SBCPaymentError as err: return handle_exception(err, err.message, 500) except Exception as err: return handle_exception(err, err, 500)
async def test_furnish_receipt_message(app, session, stan_server, event_loop, client_id, entity_stan, future): """Assert that events are placed on the email queue and the payment is marked furnished.""" from queue_common.messages import create_cloud_event_msg from queue_common.service import ServiceWorker from queue_common.service_utils import subscribe_to_queue from namex_pay.worker import APP_CONFIG, furnish_receipt_message, qsm from namex.models import Request, State, Payment print('test vars') print(app, session, stan_server, event_loop, client_id, entity_stan, future) # setup PAYMENT_TOKEN = 'dog' NR_NUMBER = 'NR B000001' name_request = Request() name_request.nrNum = NR_NUMBER name_request.stateCd = State.DRAFT name_request._source = 'NRO' name_request.save_to_db() payment = Payment() payment.nrId = name_request.id payment._payment_token = PAYMENT_TOKEN payment._payment_status_code = 'COMPLETED' payment.furnished = False payment.save_to_db() # file handler callback msgs = [] s = ServiceWorker() s.sc = entity_stan qsm.service = s async def cb_handler(msg): nonlocal msgs nonlocal future msgs.append(msg) print('call back recvd') if len(msgs) == 1: future.set_result(True) file_handler_subject = APP_CONFIG.EMAIL_PUBLISH_OPTIONS['subject'] print(f'file_handler_subject:{file_handler_subject}') await subscribe_to_queue(entity_stan, file_handler_subject, f'entity_queue.{file_handler_subject}', f'entity_durable_name.{file_handler_subject}', cb_handler) print(payment.as_dict()) # sanity check assert name_request.id assert payment.nrId == name_request.id # test await furnish_receipt_message(qsm, payment) try: await asyncio.wait_for(future, 1, loop=event_loop) except Exception as err: print(err) # results processed_payment = Payment.find_by_payment_token(PAYMENT_TOKEN) # verify assert processed_payment.furnished assert len(msgs) == 1 cloud_event = json.loads(msgs[0].data.decode('utf-8')) assert cloud_event['identifier'] == NR_NUMBER
async def update_payment_record(payment: Payment) -> Optional[Payment]: """Update the payment record in the database. Alter the NR state as required based on the payment action. Payment NR Action - One of [COMPLETE, UPGRADE, REAPPLY] COMPLETE - set NR to DRAFT IFF nr.state == PENDING_PAYMENT UPGRADE - set the nr.priority to True/'Y' REAPPLY - add REAPPLY_EXTENSION to expiry date of NR IFF it hasn't expired """ if payment.payment_completion_date: msg = f'Queue Issue: Duplicate, payment already processed for payment.id={payment.id}' logger.debug(msg) capture_message(msg) return None payment_action = payment.payment_action nr = RequestDAO.find_by_id(payment.nrId) if payment_action == Payment.PaymentActions.CREATE.value: # pylint: disable=R1705 if nr.stateCd == State.PENDING_PAYMENT: nr.stateCd = State.DRAFT payment.payment_completion_date = datetime.utcnow() payment.payment_status_code = State.COMPLETED nr.save_to_db() payment.save_to_db() return payment elif payment_action == Payment.PaymentActions.UPGRADE.value: if nr.stateCd == State.PENDING_PAYMENT: msg = f'Queue Issue: Upgrading a non-DRAFT NR for payment.id={payment.id}' logger.debug(msg) capture_message(msg) raise QueueException(msg) nr.priorityCd = 'Y' nr.priorityDate = datetime.utcnow() payment.payment_completion_date = datetime.utcnow() payment.payment_status_code = State.COMPLETED nr.save_to_db() payment.save_to_db() return payment elif payment_action == Payment.PaymentActions.REAPPLY.value: if nr.stateCd != State.APPROVED \ and nr.expirationDate + timedelta(hours=NAME_REQUEST_EXTENSION_PAD_HOURS) < datetime.utcnow(): msg = f'Queue Issue: Failed attempt to extend NR for payment.id={payment.id} '\ 'nr.state{nr.stateCd}, nr.expires:{nr.expirationDate}' logger.debug(msg) capture_message(msg) raise QueueException(msg) nr.expirationDate = nr.expirationDate + timedelta(days=NAME_REQUEST_LIFESPAN_DAYS) payment.payment_completion_date = datetime.utcnow() payment.payment_status_code = State.COMPLETED nr.save_to_db() payment.save_to_db() return payment msg = f'Queue Issue: Unknown action:{payment_action} for payment.id={payment.id}' logger.debug(msg) capture_message(msg) raise QueueException(f'Unknown action:{payment_action} for payment.id={payment.id}')
req = PaymentRequest(paymentInfo=payment_info, filingInfo=filing_info, businessInfo=business_info, accountInfo=account_info, details=details) payment_response = create_payment(req.as_dict(), headers) try: successful_status_list = [ PaymentStatusCode.APPROVED.value, PaymentStatusCode.CREATED.value, PaymentStatusCode.COMPLETED.value ] if payment_response.statusCode in successful_status_list: # Save the payment info to Postgres payment = PaymentDAO() payment.nrId = nr_model.id payment.payment_token = str(payment_response.id) # namex-pay will set payment_status_code to completed state after actioning it on the queue payment.payment_status_code = payment_response.statusCode payment.payment_action = payment_action payment.save_to_db() # happens for PAD. If completed/approved right away queue will have err'd so apply changes here # TODO: send email / furnish payment for these if payment_response.statusCode in [ PaymentStatusCode.APPROVED.value, PaymentStatusCode.COMPLETED.value ]: if payment_action == PaymentDAO.PaymentActions.CREATE.value: # pylint: disable=R1705 if nr_model.stateCd == State.PENDING_PAYMENT:
async def process_payment(pay_msg: dict, flask_app: Flask): """Render the payment status.""" if not flask_app or not pay_msg: raise QueueException('Flask App or token not available.') with flask_app.app_context(): logger.debug('entering process payment: %s', pay_msg) # capture_message(f'Queue Issue: Unable to find payment.id={payment_id} to place on email queue') # return if pay_msg.get( 'paymentToken', {}).get('statusCode') == PaymentState.TRANSACTION_FAILED.value: # TODO: The customer has cancelled out of paying, so we could note this better # technically the payment for this service is still pending logger.debug('Failed transaction on queue:%s', pay_msg) return complete_payment_status = [ PaymentState.COMPLETED.value, PaymentState.APPROVED.value ] if pay_msg.get('paymentToken', {}).get('statusCode') in complete_payment_status: # pylint: disable=R1702 logger.debug('COMPLETED transaction on queue: %s', pay_msg) if payment_token := pay_msg.get('paymentToken', {}).get('id'): if payment := Payment.find_by_payment_token(payment_token): if update_payment := await update_payment_record(payment): payment = update_payment # record event nr = RequestDAO.find_by_id(payment.nrId) # TODO: create a namex_pay user for this user = User.find_by_username( 'name_request_service_account') EventRecorder.record( user, Event.NAMEX_PAY + f' [payment completed] { payment.payment_action }', nr, nr.json()) # try to update NRO otherwise send a sentry msg for OPS if payment.payment_action in \ [payment.PaymentActions.UPGRADE.value, payment.PaymentActions.REAPPLY.value]: change_flags = { 'is_changed__request': True, 'is_changed__previous_request': False, 'is_changed__applicant': False, 'is_changed__address': False, 'is_changed__name1': False, 'is_changed__name2': False, 'is_changed__name3': False, 'is_changed__nwpta_ab': False, 'is_changed__nwpta_sk': False, 'is_changed__request_state': False, 'is_changed_consent': False } warnings = nro.change_nr(nr, change_flags) if warnings: logger.error( 'Queue Error: Unable to update NRO :%s', warnings) capture_message( f'Queue Error: Unable to update NRO for {nr} {payment.payment_action} :{warnings}', level='error') await furnish_receipt_message(qsm, payment) else:
def post(self, nr_id, payment_action=NameRequestActions.CREATE.value): """ At this point, the Name Request will still be using a TEMPORARY NR number. Confirming the payment on the frontend triggers this endpoint. Here, we: - Save the request to NRO which gives us a real NR. - Create the payment via SBC Pay. - If payment creation is successful, create a corresponding payment record in our system. :param nr_id: :param payment_action: :return: """ try: # Find the existing name request nr_model = RequestDAO.query.get(nr_id) if not nr_model: # Should this be a 400 or 404... hmmm return jsonify(message='Name Request {nr_id} not found'.format(nr_id=nr_id)), 400 if not payment_action: return jsonify(message='Invalid payment action, {action} not found'.format(action=payment_action)), 400 valid_payment_action = payment_action in [ NameRequestActions.CREATE.value, NameRequestActions.UPGRADE.value, NameRequestActions.REAPPLY.value ] if not valid_payment_action: return jsonify(message='Invalid payment action [{action}]'.format(action=payment_action)), 400 # We only handle payments if the NR is in the following states valid_payment_states = [State.DRAFT, State.COND_RESERVE, State.RESERVED, State.CONDITIONAL, State.APPROVED, State.PENDING_PAYMENT] valid_nr_state = nr_model.stateCd in valid_payment_states if not valid_nr_state: return jsonify(message='Invalid NR state'.format(action=payment_action)), 400 if valid_payment_action and valid_nr_state: if payment_action in [NameRequestActions.CREATE.value]: # Save the record to NRO, which swaps the NR-L Number for a real NR update_solr = True nr_model = self.add_records_to_network_services(nr_model, update_solr) json_input = request.get_json() payment_request = {} if not json_input: # return jsonify(message=MSG_BAD_REQUEST_NO_JSON_BODY), 400 # Grab the data from the NR, if it exists payment_request = build_payment_request(nr_model) elif isinstance(json_input, dict): payment_request = merge_payment_request(nr_model, json_input) elif isinstance(json_input, str): payment_request = merge_payment_request(nr_model, json.loads(json_input)) # Grab the info we need off the request payment_info = payment_request.get('paymentInfo', {}) filing_info = payment_request.get('filingInfo') business_info = payment_request.get('businessInfo') # Create our payment request req = PaymentRequest( paymentInfo=payment_info, filingInfo=filing_info, businessInfo=business_info ) payment_response = create_payment(req.as_dict(), json_input.get('headers')) try: successful_status_list = [ PaymentStatusCode.APPROVED.value, PaymentStatusCode.CREATED.value, PaymentStatusCode.COMPLETED.value ] if payment_response.statusCode in successful_status_list: # Save the payment info to Postgres payment = PaymentDAO() payment.nrId = nr_model.id payment.payment_token = str(payment_response.id) # namex-pay will set payment_status_code to completed state after actioning it on the queue payment.payment_status_code = payment_response.statusCode payment.payment_action = payment_action payment.save_to_db() # happens for PAD. If completed/approved right away queue will have err'd so apply changes here # TODO: send email / furnish payment for these if payment_response.statusCode in [PaymentStatusCode.APPROVED.value, PaymentStatusCode.COMPLETED.value]: if payment_action == PaymentDAO.PaymentActions.CREATE.value: # pylint: disable=R1705 if nr_model.stateCd == State.PENDING_PAYMENT: nr_model.stateCd = State.DRAFT payment.payment_completion_date = datetime.utcnow() elif payment_action == PaymentDAO.PaymentActions.UPGRADE.value: # TODO: handle this (refund payment and prevent action?) if nr_model.stateCd == State.PENDING_PAYMENT: msg = f'Upgrading a non-DRAFT NR for payment.id={payment.id}' current_app.logger.debug(msg) nr_model.priorityCd = 'Y' nr_model.priorityDate = datetime.utcnow() payment.payment_completion_date = datetime.utcnow() elif payment_action == PaymentDAO.PaymentActions.REAPPLY.value: # TODO: handle this (refund payment and prevent action?) if nr_model.stateCd != State.APPROVED \ and nr_model.expirationDate + timedelta(hours=NAME_REQUEST_EXTENSION_PAD_HOURS) < datetime.utcnow(): msg = f'Extend NR for payment.id={payment.id} nr_model.state{nr_model.stateCd}, nr_model.expires:{nr_model.expirationDate}' current_app.logger.debug(msg) nr_model.expirationDate = nr_model.expirationDate + timedelta(days=NAME_REQUEST_LIFESPAN_DAYS) payment.payment_completion_date = datetime.utcnow() nr_model.save_to_db() payment.save_to_db() # Wrap the response, providing info from both the SBC Pay response and the payment we created data = jsonify({ 'id': payment.id, 'nrId': payment.nrId, 'nrNum': nr_model.nrNum, 'token': payment.payment_token, 'statusCode': payment.payment_status_code, 'action': payment.payment_action, 'completionDate': payment.payment_completion_date, 'payment': payment.as_dict(), 'sbcPayment': payment_response.as_dict() }) # Record the event # nr_svc = self.nr_service # EventRecorder.record(nr_svc.user, Event.POST + ' [payment created]', json_input) response = make_response(data, 201) return response # something went wrong with status code above else: # log actual status code current_app.logger.debug('Error with status code. Actual status code: ' + payment_response.statusCode) # return generic error status to the front end return jsonify(message='Name Request {nr_id} encountered an error'.format(nr_id=nr_id)), 402 except Exception as err: current_app.logger.error(err.with_traceback(None)) return jsonify(message='Name Request {nr_id} encountered an error'.format(nr_id=nr_id)), 500 except PaymentServiceError as err: return handle_exception(err, err.message, 500) except SBCPaymentException as err: return handle_exception(err, err.message, err.status_code) except SBCPaymentError as err: return handle_exception(err, err.message, 500) except Exception as err: return handle_exception(err, err, 500)