def _update_stale_payments(cls):
        """Update stale payment records.

        This is to handle edge cases where the user has completed payment and some error occured and payment status
        is not up-to-date.
        """
        stale_transactions = PaymentTransactionModel.find_stale_records(
            minutes=30)
        if len(stale_transactions) == 0:
            current_app.logger.info(
                f'Stale Transaction Job Ran at {datetime.datetime.now()}.But No records found!'
            )
        for transaction in stale_transactions:
            try:
                current_app.logger.info(
                    'Stale Transaction Job found records.Payment Id: {}, Transaction Id : {}'
                    .format(transaction.payment_id, transaction.id))
                TransactionService.update_transaction(transaction.id,
                                                      pay_response_url=None)
                current_app.logger.info(
                    'Stale Transaction Job Updated records.Payment Id: {}, Transaction Id : {}'
                    .format(transaction.payment_id, transaction.id))
            except BusinessException as err:  # just catch and continue .Don't stop
                current_app.logger.error(
                    'Stale Transaction Error on update_transaction')
                current_app.logger.error(err)
Example #2
0
    def post(invoice_id: int = None, payment_id: int = None):
        """Create the Transaction records."""
        current_app.logger.info('<Transaction.post')
        request_json = request.get_json()

        # Validate the input request
        valid_format, errors = schema_utils.validate(request_json,
                                                     'transaction_request')

        if not valid_format:
            return error_to_response(
                Error.INVALID_REQUEST,
                invalid_params=schema_utils.serialize(errors))

        try:
            if invoice_id:
                response, status = TransactionService.create_transaction_for_invoice(
                    invoice_id, request_json).asdict(), HTTPStatus.CREATED
            elif payment_id:
                response, status = TransactionService.create_transaction_for_payment(
                    payment_id, request_json).asdict(), HTTPStatus.CREATED

        except BusinessException as exception:
            return exception.response()
        current_app.logger.debug('>Transaction.post')
        return jsonify(response), status
Example #3
0
 def get(invoice_id):
     """Get all transaction records for a invoice."""
     current_app.logger.info('<Transaction.get')
     response, status = TransactionService.find_by_invoice_id(
         invoice_id), HTTPStatus.OK
     current_app.logger.debug('>Transaction.get')
     return jsonify(response), status
Example #4
0
    def post(payment_id):
        """Create the Transaction records."""
        current_app.logger.info('<Transaction.post')
        request_json = request.get_json()

        # Validate the input request
        valid_format, errors = schema_utils.validate(request_json,
                                                     'transaction_request')

        if not valid_format:
            return jsonify({
                'code': 'PAY007',
                'message': schema_utils.serialize(errors)
            }), HTTPStatus.BAD_REQUEST

        try:
            response, status = TransactionService.create(
                payment_id, request_json).asdict(), HTTPStatus.CREATED
        except BusinessException as exception:
            response, status = {
                'code': exception.code,
                'message': exception.message
            }, exception.status
        current_app.logger.debug('>Transaction.post')
        return jsonify(response), status
Example #5
0
    def _update_stale_payments(cls):
        """Update stale payment records.

        This is to handle edge cases where the user has completed payment and some error occured and payment status
        is not up-to-date.
        """
        stale_transactions = PaymentTransactionModel.find_stale_records(
            minutes=30)
        # Find all payments which were failed due to service unavailable error.
        service_unavailable_transactions = db.session.query(PaymentTransactionModel)\
            .join(PaymentModel, PaymentModel.id == PaymentTransactionModel.payment_id) \
            .filter(PaymentModel.payment_status_code == PaymentStatus.CREATED.value)\
            .filter(PaymentTransactionModel.pay_system_reason_code == Error.SERVICE_UNAVAILABLE.name)\
            .all()

        if len(stale_transactions) == 0 and len(
                service_unavailable_transactions) == 0:
            current_app.logger.info(
                f'Stale Transaction Job Ran at {datetime.datetime.now()}.But No records found!'
            )
        for transaction in [
                *stale_transactions, *service_unavailable_transactions
        ]:
            try:
                current_app.logger.info(
                    f'Stale Transaction Job found records.Payment Id: {transaction.payment_id}, '
                    f'Transaction Id : {transaction.id}')
                TransactionService.update_transaction(transaction.id,
                                                      pay_response_url=None)
                current_app.logger.info(
                    f'Stale Transaction Job Updated records.Payment Id: {transaction.payment_id}, '
                    f'Transaction Id : {transaction.id}')
            except BusinessException as err:  # just catch and continue .Don't stop
                # If the error is for COMPLETED PAYMENT, then mark the transaction as CANCELLED
                # as there would be COMPLETED transaction in place and continue.
                if err.code == Error.COMPLETED_PAYMENT.name:
                    current_app.logger.info(
                        'Completed payment, marking transaction as CANCELLED.')
                    transaction.status_code = TransactionStatus.CANCELLED.value
                    transaction.save()
                else:
                    current_app.logger.info(
                        'Stale Transaction Error on update_transaction')
                    current_app.logger.info(err)
Example #6
0
 def get(payment_identifier, transaction_identifier):
     """Get the Transaction record."""
     current_app.logger.info(
         f'<Transaction.get for payment : {payment_identifier}, and transaction {transaction_identifier}')
     try:
         response, status = TransactionService.find_by_id(payment_identifier,
                                                          transaction_identifier).asdict(), HTTPStatus.OK
     except BusinessException as exception:
         response, status = {'code': exception.code, 'message': exception.message}, exception.status
     current_app.logger.debug('>Transaction.get')
     return jsonify(response), status
Example #7
0
 def get(payment_id, transaction_id):
     """Get the Transaction record."""
     current_app.logger.info(
         f'<Transaction.get for payment : {payment_id}, and transaction {transaction_id}'
     )
     try:
         response, status = TransactionService.find_by_id(
             payment_id, transaction_id).asdict(), HTTPStatus.OK
     except BusinessException as exception:
         return exception.response()
     current_app.logger.debug('>Transaction.get')
     return jsonify(response), status
Example #8
0
 def put(payment_identifier, transaction_identifier):
     """Update the transaction record by querying payment system."""
     current_app.logger.info(
         f'<Transaction.post for payment : {payment_identifier}, and transaction {transaction_identifier}')
     receipt_number = flask.request.args.get('receipt_number')
     try:
         response, status = TransactionService.update_transaction(payment_identifier, transaction_identifier,
                                                                  receipt_number).asdict(), HTTPStatus.OK
     except BusinessException as exception:
         response, status = {'code': exception.code, 'message': exception.message}, exception.status
     current_app.logger.debug('>Transaction.post')
     return jsonify(response), status
def run():
    application = create_app()
    application.logger.debug('Ran Batch Job--')

    application.app_context().push()
    stale_transactions = PaymentTransactionModel.find_stale_records(hours=4)
    if len(stale_transactions) == 0:
        application.logger.info(
            f' Job Ran at {datetime.datetime.now()}.But No records found!')
    for transaction in stale_transactions:
        try:
            application.logger.debug(
                'Job found records.Payment Id: {}, Transaction Id : {}'.format(
                    transaction.payment_id, transaction.id))
            TransactionService.update_transaction(transaction.payment_id,
                                                  transaction.id, '')
            application.logger.debug(
                'Job Updated records.Payment Id: {}, Transaction Id : {}'.
                format(transaction.payment_id, transaction.id))
        except BusinessException as err:  # just catch and continue .Don't stop
            application.logger.error('Error on update_transaction')
            application.logger.error(err)
Example #10
0
    def post(payment_identifier):
        """Create the Transaction records."""
        current_app.logger.info('<Transaction.post')
        redirect_uri = flask.request.args.get('redirect_uri')
        try:
            if not redirect_uri:
                raise BusinessException(Error.PAY007)

            response, status = TransactionService.create(payment_identifier, redirect_uri).asdict(), HTTPStatus.CREATED
        except BusinessException as exception:
            response, status = {'code': exception.code, 'message': exception.message}, exception.status
        current_app.logger.debug('>Transaction.post')
        return jsonify(response), status
Example #11
0
 def patch(payment_id, transaction_id):
     """Update the transaction record by querying payment system."""
     current_app.logger.info(
         f'<Transaction.post for payment : {payment_id}, and transaction {transaction_id}'
     )
     receipt_number = request.get_json().get('receipt_number', None)
     try:
         response, status = TransactionService.update_transaction(
             payment_id, transaction_id,
             receipt_number).asdict(), HTTPStatus.OK
     except BusinessException as exception:
         return exception.response()
     current_app.logger.debug('>Transaction.post')
     return jsonify(response), status
Example #12
0
    def get(invoice_id: int = None,
            payment_id: int = None,
            transaction_id=None):
        """Get the Transaction record."""
        current_app.logger.info(
            '<Transaction.get for invoice : %s, payment : %s, transaction %s',
            invoice_id, payment_id, transaction_id)
        try:
            response, status = TransactionService.find_by_id(
                transaction_id).asdict(), HTTPStatus.OK

        except BusinessException as exception:
            return exception.response()
        current_app.logger.debug('>Transaction.get')
        return jsonify(response), status
Example #13
0
    def patch(invoice_id: int = None,
              payment_id: int = None,
              transaction_id=None):
        """Update the transaction record by querying payment system."""
        current_app.logger.info(
            '<Transaction.patch for invoice : %s, payment : %s, transaction %s',
            invoice_id, payment_id, transaction_id)
        pay_response_url: str = request.get_json().get('payResponseUrl', None)

        try:
            response, status = TransactionService.update_transaction(
                transaction_id, pay_response_url).asdict(), HTTPStatus.OK
        except BusinessException as exception:
            return exception.response()
        current_app.logger.debug('>Transaction.post')
        return jsonify(response), status