Exemple #1
0
    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)
Exemple #2
0
    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)
Exemple #3
0
                filing_info.get('filingTypes')[0]['waiveFees'] = waive_fees
                if 'waiveFees' in headers:
                    del headers['waiveFees']

                # This is to support staff-payment-enabled switch to false in Launch Darkly
                if not account_info and not waive_fees:
                    headers = {}

            # Create our payment request
            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()
Exemple #4
0
    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)