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)
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
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
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
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)
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
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
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)
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
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
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
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