from appservices.common.util import *
from appservices.v1.controllers.payout_apis import *
from appservices.common.payment_gateways.wowpe_payment_gateways import *
# from appservices.common.payment_gateways.fstac_payment_gateways import *
# from appservices.common.payment_gateways.payaid_payment_gateways import *
from appservices.common.payment_gateways.accurepay_payment_gateways import *

paymentgateway_integrations = Blueprint("paymentgateway_integrations",__name__)


@paymentgateway_integrations.route("/view_all_banks_list", methods=["GET"])
def view_all_banks_list():
    data_status = {"responseStatus": 0, "result": ""}
    banksList = []
    try:
        banks_queryset = MasterIFSCBank.objects(status__in=[1]).order_by("-id").all()
        for each_bank in banks_queryset:
            bankDict = {
            "id":str(each_bank.id),
            "bankName":each_bank.bankName,
            "bankCode":each_bank.bankCode,
            "status":each_bank.status
            }
            banksList.append(bankDict)
        
        data_status["responseStatus"] = 1
        data_status["result"] = "Banks data fetched successful!"
        data_status["banksList"]=banksList
        return data_status      
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to fetch banks data!!"
        return data_status


@paymentgateway_integrations.route("/merchant_based_payouts_list", methods=["POST"])
@user_required
def merchant_based_payouts_list():
    data_status = {"responseStatus": 0, "result": ""}
    payoutsList = []
    userId = request.json.get("userId","")
    paymentMode = request.json.get("paymentMode","")
    startDate = request.json.get("startDate","")
    endDate = request.json.get("endDate","")
    orderId = request.json.get("orderId","")
    beneficiaryName = request.json.get("beneficiaryName","")
    pageLimit = request.json.get("pageLimit","20")
    pageOffset = request.json.get("pageOffset","0")
    try:
        page_start=int(pageOffset)
        page_end=int(pageOffset)+int(pageLimit)

        if not startDate or not endDate:
            data_status["result"] = "Start date and end date are required!!"
            return data_status

        date_format = "%d-%m-%Y"
        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
 
            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            data_status["result"] = "Invalid date format!!"
            return data_status


        # Initial query set with the base filter
        payouts_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,userId=userId,fundTransferType="instant").order_by("-id").all()

        # Apply date filters and status filters
        if paymentMode in ["IMPS", "NEFT", "RTGS",""]:
            if (paymentMode == "IMPS") or (paymentMode == "NEFT") or (paymentMode == "RTGS"):
                payouts_queryset = payouts_queryset.filter(paymentMode=paymentMode)

        if orderId:
            payouts_queryset = payouts_queryset.filter(merchantReferenceNumber=orderId)

        if beneficiaryName:
            payouts_queryset = payouts_queryset.filter(beneficiaryName__icontains=beneficiaryName)

        for each_payout in payouts_queryset[page_start:page_end]:
            payoutDict = fetching_payouts_details(each_payout)
            payoutsList.append(payoutDict)
        data_status["responseStatus"] = 1
        data_status["result"] = "Payouts data fetched successful!"
        data_status["payoutsList"]=payoutsList
        data_status["totalPayoutsCount"]=payouts_queryset.count()
        return data_status      
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to fetch payouts data!!"
        return data_status


@paymentgateway_integrations.route("/payout_reports_list", methods=["POST"])
@user_required
def payout_reports_list():
    data_status = {"responseStatus": 0, "result": ""}
    payoutsList = []
    userId = request.json.get("userId","")
    startDate = request.json.get("startDate","")
    endDate = request.json.get("endDate","")
    payoutType = request.json.get("payoutType","")
    transferType = request.json.get("transferType","")
    orderId = request.json.get("orderId","")
    pageLimit = request.json.get("pageLimit","20")
    pageOffset = request.json.get("pageOffset","0")
    try:
        page_start=int(pageOffset)
        page_end=int(pageOffset)+int(pageLimit)

        if not startDate or not endDate:
            data_status["result"] = "Start date and end date are required!!"
            return data_status

        date_format = "%d-%m-%Y"
        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
 
            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            data_status["result"] = "Invalid date format!!"
            return data_status

        payouts_queryset = FundTransfers.objects(userId=userId,createdOn__gte=startDate,createdOn__lte=endDate).order_by("-createdOn").all()
        if payoutType == "all" or payoutType == "":
            payouts_queryset = payouts_queryset.filter(status__in=[0,1,2,4,5])
        elif payoutType == "success":
            payouts_queryset = payouts_queryset.filter(status__in=[1])
        elif payoutType == "processing":
            payouts_queryset = payouts_queryset.filter(status__in=[2])
        elif payoutType == "failed":
            payouts_queryset = payouts_queryset.filter(status__in=[0])

        if transferType:
            payouts_queryset = payouts_queryset.filter(transferType=transferType)

        if orderId:
            payouts_queryset = payouts_queryset.filter(merchantReferenceNumber=orderId)

        for each_payout in payouts_queryset[page_start:page_end]:
            payoutDict = fetching_payouts_details(each_payout)
            payoutsList.append(payoutDict)
        data_status["responseStatus"] = 1
        data_status["result"] = "Payouts data fetched successful!"
        data_status["payoutsList"]=payoutsList
        data_status["totalPayoutsCount"]=payouts_queryset.count()
        return data_status      
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to fetch payouts data!!"
        return data_status


@paymentgateway_integrations.route("/auto_collect_transactions_reports", methods=["POST"])
@user_required
def auto_collect_transactions_reports():
    data_status = {"responseStatus": 0, "result": ""}
    transactionReportList = []
    userId = request.json.get("userId","")
    startDate = request.json.get("startDate","")
    endDate = request.json.get("endDate","")
    virtualAccountNumber = request.json.get("virtualAccountNumber","")
    utr = request.json.get("utr","")
    orderId = request.json.get("orderId","")
    nofityList = []
    try:
        if not startDate or not endDate:
            data_status["result"] = "Start date and end date are required!!"
            return data_status
        try:
            if startDate and endDate:
                start_date = startDate + " 00:00:00"
                end_date = endDate + " 23:59:59"
                
                startDate = datetime.datetime.strptime(start_date, "%d-%m-%Y %H:%M:%S")
                endDate = datetime.datetime.strptime(end_date, "%d-%m-%Y %H:%M:%S")
            else:
                startDate = None
                endDate = None
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Invalid date format!!"
            return data_status

        credit_notifications_queryset = CreditNotifications.objects(
            userId=userId,createdOn__gte=startDate,createdOn__lte=endDate).order_by("-id").all()

        if virtualAccountNumber:
            credit_notifications_queryset = credit_notifications_queryset.filter(ecollectAccoutNo__icontains=virtualAccountNumber)

        if utr:
            credit_notifications_queryset = credit_notifications_queryset.filter(bankReferenceNumber__icontains=utr)

        if orderId:
            credit_notifications_queryset = credit_notifications_queryset.filter(transactionUniqueId__icontains=orderId)

        for each_cred_notify in credit_notifications_queryset:
            nofityDict = {
            "id":str(each_cred_notify.id),
            "status":each_cred_notify.status,
            "virtualAccountNumber":each_cred_notify.ecollectAccoutNo,
            "utr":each_cred_notify.bankReferenceNumber,
            "orderId":each_cred_notify.transactionUniqueId,
            "remitterName":each_cred_notify.remitterName,
            "remitterAccountNumber":mask_account_number(each_cred_notify.remitterAccountNumber),
            "remitterIfscCode":each_cred_notify.remitterIfscCode,
            "remitterNote":each_cred_notify.remitterNote,
            "transferType":each_cred_notify.transferType,
            "transactionAmount":"{:.2f}".format(float(each_cred_notify.transactionAmount)),
            "transactionDate":each_cred_notify.transactionDate.astimezone(ist_timezone).strftime("%d-%m-%Y %I:%M %p"), 
            "createdOn":each_cred_notify.createdOn.astimezone(ist_timezone).strftime("%d-%m-%Y %I:%M %p") 
            }
            nofityList.append(nofityDict)

        data_status["responseStatus"] = 1
        data_status["result"] = "Auto collect transaction reports data fetched successful!"
        data_status["nofityList"]=nofityList
        return data_status      
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to fetch auto collect transaction reports data!!"
        return data_status


@paymentgateway_integrations.route("/auto_collect_dashboard_list", methods=["POST"])
@user_required
def auto_collect_dashboard_list():
    data_status = {"responseStatus": 0, "result": ""}
    userId = request.json.get("userId","")
    notificationsList = []
    totalAutoCollectAmount = 0
    try:
        credit_notifications_queryset = CreditNotifications.objects(userId=userId).order_by("-id").limit(10)

        for each_cred_notify in credit_notifications_queryset:
            notificationDict = {
            "id":str(each_cred_notify.id),
            "status":each_cred_notify.status,
            "virtualAccountNumber":each_cred_notify.ecollectAccoutNo,
            "utr":each_cred_notify.bankReferenceNumber,
            "orderId":each_cred_notify.transactionUniqueId,
            "remitterName":each_cred_notify.remitterName,
            "remitterAccountNumber":mask_account_number(each_cred_notify.remitterAccountNumber),
            "remitterIfscCode":each_cred_notify.remitterIfscCode,
            "remitterNote":each_cred_notify.remitterNote,
            "transferType":each_cred_notify.transferType,
            "transactionAmount":"{:.2f}".format(float(each_cred_notify.transactionAmount)),
            "transactionDate":each_cred_notify.transactionDate.astimezone(ist_timezone).strftime("%d-%m-%Y %I:%M %p"), 
            "createdOn":each_cred_notify.createdOn.astimezone(ist_timezone).strftime("%d-%m-%Y %I:%M %p") 
            }
            notificationsList.append(notificationDict)

        all_credit_notifications = CreditNotifications.objects(userId=userId)
        
        for each_cred_notify in all_credit_notifications:
            totalAutoCollectAmount += float(each_cred_notify.transactionAmount)

        data_status["responseStatus"] = 1
        data_status["result"] = "Auto collect dashboard data fetched successfully!"
        data_status["notificationsList"]=notificationsList
        data_status["totalAutoCollectAmount"]="{:.2f}".format(float(totalAutoCollectAmount))
        data_status["totalAutoCollectRefundAmount"]=0
        return data_status      
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to fetch auto collect dashboard data!!"
        return data_status

@paymentgateway_integrations.route("/payin_reports_list", methods=["POST"])
@user_required
def payin_reports_list():
    data_status = {"responseStatus": 0, "result": ""}
    payInList = []
    userId = request.json.get("userId","")
    payInType = request.json.get("payInType","")
    startDate = request.json.get("startDate","")
    endDate = request.json.get("endDate","")
    pageLimit = request.json.get("pageLimit","20")
    pageOffset = request.json.get("pageOffset","0")
    transactionId = request.json.get("transactionId","")
    try:
        if not payInType:
            data_status["result"] = "Required fields are missing!!"
            return data_status

        if not startDate or not endDate:
            data_status["result"] = "Start date and end date are required!!"
            return data_status

        date_format = "%d-%m-%Y"
        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
 
            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            data_status["result"] = "Invalid date format!!"
            return data_status

        page_start=int(pageOffset)
        page_end=int(pageOffset)+int(pageLimit)


        # Initial query set with the base filter
        payin_queryset = WalletTransactions.objects(createdOn__gte=startDate,createdOn__lte=endDate,userId=userId,creditType="Credit",userType='user').order_by("-id").all()
        failed_queryset_sum = payin_queryset.filter(status__in=[0]).sum('amount')
        success_queryset_sum = payin_queryset.filter(status__in=[1]).sum('amount')
        intent_queryset_sum = payin_queryset.filter(status__in=[3]).sum('amount')
        totalSumAmount=float(failed_queryset_sum)+float(intent_queryset_sum)+float(success_queryset_sum)


        # Apply date filters and status filters
        if payInType in ["all", "success", "failed","initiated",""]:
            if payInType == "all":
                status = [0,1,2,3]
            elif payInType == "success":
                status = [1]
            elif payInType == "failed":
                status = [0]
            elif payInType == "initiated":
                status = [3]

            payin_queryset = payin_queryset.filter(status__in=status)

        # Apply transactionId filter if provided
        if transactionId:
            payin_queryset = payin_queryset.filter(Q(transactionId__icontains=transactionId)|Q(orderId__icontains=transactionId))


        # Apply the combined filter to the queryset
        length = payin_queryset.count()

        payin_queryset=payin_queryset[page_start:page_end]
        for each_pay_in in payin_queryset:
            payIndDict = fetching_payin_details(each_pay_in)
            payInList.append(payIndDict)
        data_status["responseStatus"] = 1
        data_status["result"] = "Payin data fetched successful!"
        data_status["payInList"]=payInList
        data_status["noOfRecords"]=length
        data_status["totalFailedSum"]=formatINR("{:.2f}".format(float(failed_queryset_sum)))
        data_status["totalSuccessSum"]=formatINR("{:.2f}".format(float(success_queryset_sum)))
        data_status["totalIntentSum"]=formatINR("{:.2f}".format(float(intent_queryset_sum)))
        data_status["totalSumAmount"]=formatINR("{:.2f}".format(float(totalSumAmount)))
        return data_status      
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to fetch payin data!!"
        return data_status


@paymentgateway_integrations.route("/payout_instant_transfer", methods=["POST"])
@user_required
def payout_instant_transfer():
    data_status = {"responseStatus": 0, "result":""}
    if SERVER_STATUS == "DOWN":
        data_status["result"]= SERVER_MAINTAINCE_MESSAGE
        return data_status

    random_number = str(random_digit_generate(16))

    userId = request.json.get("userId","")
    amount = request.json.get("amount",0)
    fundTransferType = request.json.get("fundTransferType","")
    accountType = request.json.get("accountType","") # "bank","upi"
    beneficiaryName = request.json.get("beneficiaryName","")
    accountNumber = request.json.get("accountNumber","")
    accountIFSCCode = request.json.get("accountIFSCCode","")
    bankId = request.json.get("bankId","")
    uniqueRequestNumber = request.json.get("uniqueRequestNumber","")
    beneficiaryMail = request.json.get("beneficiaryMail","")
    beneficiaryPhone = request.json.get("beneficiaryPhone","")
    narration = request.json.get("narration","")
    bankBranch = request.json.get("bankBranch","")
    paymentMode = request.json.get("paymentMode","") # "IMPS"
    otpCheckId = request.json.get("otpCheckId","")

    masked_account_number = mask_account_number(accountNumber)
    client_ip=""
    # Extracting client IP address
    if request.headers.getlist("X-Forwarded-For"):
        client_ip = request.headers.getlist("X-Forwarded-For")[0]
    else:
        client_ip = request.remote_addr

    loginBrowser = request.headers.get("Sec-Ch-Ua")
    if loginBrowser:
        loginBrowseData = loginBrowser.split(";")
        browser = loginBrowseData[0]
    else:
        loginBrowseData = request.headers.get('User-Agent').split(";")
        browser = loginBrowseData[0]

    transactionAPIId = ""
    requestData = [request.json]

    # Here Create Client Logs Table
    save_client_table = save_client_logs_data(userId,"payout","fund_transfer","payout_instant_transfer",transactionAPIId,requestData,client_ip,"web")

    print(request.json,"((((((((((PAYOUT))))))))))")
    
    try:
        if amount and bankId and accountType and fundTransferType and accountNumber and userId and beneficiaryName and otpCheckId:
            otpcheck_querryset=OtpChecks.objects(userId=str(userId),id=str(otpCheckId),status=1).first()
            if not otpcheck_querryset:
                data_status["result"]="Invalid Request."
                return data_status
            otpcheck_querryset.update(status=2)
            merchant_queryset = Users.objects(id=str(userId),status=1).first()
            if not merchant_queryset:
                data_status["result"]="Invalid merchant id!!"
                return data_status

            check_kyc_status = merchant_kyc_status(str(merchant_queryset.id))
            if check_kyc_status.get("responseStatus") != 1:
                data_status["result"]="Merchant KYC is not completed please contact to admin!!"
                return data_status
            kycStatus = check_kyc_status.get("merchantKycDetails", {}).get("kycStatus")
            if kycStatus == False:
                data_status["result"]="Merchant KYC is not completed please contact to admin!!"
                return data_status

            ################################################ Checking For Velocity Rule Engine Conditions Code ###################################################
            velocity_rule_check = check_payout_velocity_rule_engine_conditions(userId,amount,accountNumber)
            if velocity_rule_check.get("responseStatus") == 0:
                data_status["result"]=velocity_rule_check.get("result")
                return data_status
            ######################################################################################################################################################
            master_ifsc_queryset = MasterIFSCBank.objects(id=bankId,status__in=[1]).first()
            if not master_ifsc_queryset:
                data_status["result"]="Invalid bank id!!"
                return data_status
            user_queryset = Users.objects(id=userId,status__in=[1]).first()
            if not user_queryset.payOutPaymentGatewayId or user_queryset.enablePayout == False:
                data_status["result"]="Please contact to admin to enable payout option!!"
                return data_status
            transactionAPIId = str(user_queryset.payOutPaymentGatewayId.id)
            payout_gate_way_queryset = TransactionAPI.objects(id=transactionAPIId,status=1).first()
            if not payout_gate_way_queryset:
                data_status['result']="Payout option is diabled.Please contact to admin"
                return data_status
                
            # Here Update some data in client log
            save_client_table.update(transactionAPIId=ObjectId(transactionAPIId))

            check_transaction_limits = merchant_transaction_limit_settings("Payout",transactionAPIId,userId,amount)
            if check_transaction_limits.get("responseStatus") == 1:
                pass

            merchantUniqueNumber=str(user_queryset.merchantUniqueNumber)
            mid_extracted = merchantUniqueNumber[1:].lstrip("0")
            merchant_reference_number=str(get_epoch_milli_time())+str(random_digit_generate(2))
            pgOrderId = transaction_id_prefix + mid_extracted + merchant_reference_number

            ######################################################### Slab Calculation for Payout ###########################################################################
            payoutPaymentGatewayId = str(user_queryset.payOutPaymentGatewayId.id)
            payment_mode_queryset = PaymentMode.objects(paymentMode=paymentMode).first()
            paymentModeId = str(payment_mode_queryset.id)
            sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType=paymentMode).first()
            subPaymentModeId = str(sub_payment_mode_queryset.id)
            patternId = str(user_queryset.patternId.id)


            commissionCharges = slab_calculation_for_payout(amount,paymentModeId,subPaymentModeId,patternId,transactionAPIId)
            if commissionCharges.get("slabId") == None:
                slabId = None
                transactionAmount = amount
            else:
                slabId = commissionCharges.get("slabId")
                transactionAmount = float(commissionCharges.get("transactionAmount"))

            ##################################################################################################################################################################

            transactionId=random_digit_generate(16)
            if float(user_queryset.payoutBalance)<float(transactionAmount):
                insufficient_table = InsufficientBalanceLogs(
                    userId=userId,
                    orderId=merchant_reference_number,
                    orderAmount=amount,
                    walletAmount=float(merchant_queryset.payoutBalance),
                    createdOn=datetime.datetime.now(),
                    status=1
                    ).save()
                data_status["result"]="Insufficient balance!!"
                return data_status

            prevpayout_balance_queryset1 = PayoutBalances.objects(userId=userId,transactionAPIId=transactionAPIId).first()
            if float(prevpayout_balance_queryset1.currentBalance)<float(transactionAmount):
                insufficient_table = InsufficientBalanceLogs(
                    userId=userId,
                    orderId=merchant_reference_number,
                    orderAmount=amount,
                    walletAmount=float(merchant_queryset.payoutBalance),
                    createdOn=datetime.datetime.now(),
                    status=1
                    ).save()
                data_status["result"]="Insufficient balance!!"
                return data_status

            balanceResult=user_payout_balance_update(str(userId),float(transactionAmount),"Debit",str(transactionAPIId))
            if balanceResult.get('responseStatus')==0:
                insufficient_table = InsufficientBalanceLogs(
                    userId=userId,
                    orderId=merchant_reference_number,
                    orderAmount=amount,
                    walletAmount=float(merchant_queryset.payoutBalance),
                    createdOn=datetime.datetime.now(),
                    status=1
                    ).save()
                data_status["result"]="Insufficient balance!!"
                return data_status
            # prevuserquery_set = Users.objects(id=str(userId),payoutBalance__gte=transactionAmount).modify(dec__payoutBalance=float(transactionAmount),new=True)
            # if prevuserquery_set==None:
            #   data_status["result"]="Insufficient balance!!"
            #   return data_status
            # updateAmount = prevuserquery_set.payoutBalance
            # actuallBalance = float(updateAmount)+float(transactionAmount)
            
            # prevpayout_balance_queryset = PayoutBalances.objects(userId=userId,transactionAPIId=transactionAPIId,currentBalance__gte=transactionAmount).modify(dec__currentBalance=float(transactionAmount),new=True)
            # if prevpayout_balance_queryset==None:
            #   data_status["result"]="Insufficient balance!!"
            #   return data_status

            # payoutCurrentBalance=prevpayout_balance_queryset.currentBalance
            # previousBalance=float(payoutCurrentBalance)+float(transactionAmount)
            # prevpayout_balance_queryset.update(previousBalance=round(float(previousBalance),2),updatedOn=datetime.datetime.now())

            payoutbalancelog_queryset=PayoutBalanceLogs(
                userId =str(userId),
                transactionAPIId =str(transactionAPIId),
                previousBalance = round(float(balanceResult.get('transactionPreviousBalance')),2),
                currentBalance = round(float(balanceResult.get('transactionCurrentBalance')),2),
                amount=round(float(amount),2),
                grandTotal=round(float(transactionAmount),2),
                orderId=merchant_reference_number,
                transferType = "Debit",
                userType = "user",
                transactionId = transactionId,
                createdOn = datetime.datetime.now(),
                status = 1
                ).save()

            fund_transfer_table = FundTransfers(
                userId=userId,
                slabId=slabId,
                transactionAPIId=transactionAPIId,
                bankId=bankId,
                bankName=str(master_ifsc_queryset.bankName),
                merchantReferenceNumber=merchant_reference_number,
                fundTransferType=fundTransferType,
                accountType=accountType,
                apiType="web",
                bankBranch=bankBranch,
                accountNumber=accountNumber,
                accountIFSCCode=accountIFSCCode,
                beneficiaryName=beneficiaryName,
                uniqueRequestNumber=uniqueRequestNumber,
                amount=round(float(amount),2),
                grandTotal=round(float(transactionAmount),2),
                transferType="Debit",
                beneficiaryMail=beneficiaryMail,
                beneficiaryPhone=beneficiaryPhone,
                paymentMode=paymentMode,
                narration=narration,
                commissionCharges=commissionCharges,
                createdOn=datetime.datetime.now(),
                pgOrderId=pgOrderId,
                statusCheckId = pgOrderId,
                userType="user",
                clientIp=client_ip,
                previousBalance = round(float(balanceResult.get('userPreviousBalance')),2),
                currentBalance = round(float(balanceResult.get('userCurrentBalance')),2),
                status=2
                )
            save_table = fund_transfer_table.save()
            instantTransferId = str(save_table.id)
            fund_transfer_queryset = FundTransfers.objects(id=instantTransferId).first()

            # Here Routing Switch Table Log Save and Update
            currentDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            routing_switch_counts_queryset = RoutingSwitchCounts.objects(userId=userId,transactionAPIId=transactionAPIId,createdOn=currentDate).first()
            if routing_switch_counts_queryset:
                numberOfFails = routing_switch_counts_queryset.numberOfFails
                numberOfSuccess = routing_switch_counts_queryset.numberOfSuccess

            else:
                save_routing_switch_table=save_routing_switch_logs_data(userId,"payout",str(transactionAPIId))

            ################################### Future Routing Implementation ######################################
            # check_routing_switch_api = check_transaction_routing(userId, str(transactionAPIId), 0,amount,"payout")
            # if check_routing_switch_api.get("responseStatus") == 1:
            #     routingUserId = check_routing_switch_api.get("userId")
            #     routingApiId = check_routing_switch_api.get("apiId")

            #     currentDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            #     routing_switch_counts_queryset = RoutingSwitchCounts.objects(userId=userId,transactionAPIId=transactionAPIId,createdOn=currentDate).first()
            #     if routing_switch_counts_queryset:
            #         numberOfFails = check_routing_switch_api.get("numberOfFails")
            #         numberOfSuccess = check_routing_switch_api.get("numberOfSuccess")
                    
            #     else:
            #         routingUserId = check_routing_switch_api.get("userId")
            #         routingApiId = check_routing_switch_api.get("apiId")

            #         save_routing_switch_table=save_routing_switch_logs_data(userId,"payout",str(apiId))

            # elif check_routing_switch_api.get("responseStatus") == 2:
            #     routingUserId = check_routing_switch_api.get("userId")
            #     routingApiId = check_routing_switch_api.get("apiId")

            #     save_routing_switch_table=save_routing_switch_logs_data(userId,"payout",str(apiId))

            bank_name = master_ifsc_queryset.bankName


            if user_queryset.payOutPaymentGatewayId.code == "AccurePay_Payout":
                print(user_queryset.payOutPaymentGatewayId.paramsList,"paramslist")
                get_api_key = ""
                get_salt = ""
                get_base_url = ""

                for each_key in user_queryset.payOutPaymentGatewayId.paramsList:
                    get_key = each_key.get("key")      
                    if get_key == "api_key":
                        get_api_key = each_key.get("value").strip()
                    if get_key == "salt":
                        get_salt = each_key.get("value").strip()
                    if get_key == "base_url":
                        get_base_url = each_key.get("value").strip()
                ############################################ Accurepay Payout Fundtransfer Functionality Code #######################################################
                paymentgatewayresponseDict = accurepay_payout_fundtransfer(get_api_key,get_salt,get_base_url,userId,transactionAPIId,client_ip,amount,paymentMode,beneficiaryName,accountNumber,accountIFSCCode,bank_name,pgOrderId,"web")
                ######################################################################################################################################################

            elif user_queryset.payOutPaymentGatewayId.code == "WowPe_Payout":
                get_client = ""
                get_secret = ""
                get_base_url = ""

                for each_key in user_queryset.payOutPaymentGatewayId.paramsList:
                    get_key = each_key.get("key")        
                    if get_key == "api_key":
                        get_client = each_key.get("value").strip()
                    if get_key == "secret_key":
                        get_secret = each_key.get("value").strip()
                    if get_key == "base_url":
                        get_base_url = each_key.get("value").strip()

                ###################### Wowpe Payout Fundtransfer Functionality Code #####################################
                paymentgatewayresponseDict = wowpe_payout_fundtransfer(get_client,get_secret,get_base_url,beneficiaryPhone,amount,paymentMode,accountNumber,accountIFSCCode,beneficiaryName,pgOrderId,userId,transactionAPIId,client_ip,"web")
                ##########################################################################################################
                
                    
            else: 
                data_status["result"]="Our banking partner server is down please try after sometime!!"
                save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
                # For count update number of failures in routing switch counts table
                if routing_switch_counts_queryset:
                    existingFailuresCount = routing_switch_counts_queryset.numberOfFails
                    updateFailuresCount = existingFailuresCount+1
                    routing_switch_counts_queryset.update(numberOfFails=updateFailuresCount)
                else:
                    save_routing_switch_table.update(numberOfFails=1)
                return data_status


            ################################################## Common Code for all Payment Gateways ##########################################
            if paymentgatewayresponseDict.get("responseStatus") == 1:
                if paymentgatewayresponseDict.get("bank_reference_number"):
                    bank_reference_number = paymentgatewayresponseDict.get("bank_reference_number")
                else:
                    bank_reference_number = fund_transfer_queryset.bankReferenceNumber

                transactionData = paymentgatewayresponseDict.get("transactionData")

                latest_fund_transfer_queryset = FundTransfers.objects(id=instantTransferId).first()
                previousstatus=latest_fund_transfer_queryset.status
                if paymentgatewayresponseDict.get("transactionstatus")==0 or paymentgatewayresponseDict.get("transactionstatus")==4:
                    getrefund_record=FundTransfers.objects(transactionUniqueId=latest_fund_transfer_queryset.merchantReferenceNumber,userId=str(userId)).count()
                    if (previousstatus==1 or previousstatus==2) and getrefund_record==0:
                        balanceResult=user_payout_balance_update(str(userId),float(transactionAmount),"Credit",str(transactionAPIId))
                        if balanceResult.get('responseStatus')==0:
                            data_status["result"]="Unable to connect with server. Please Try again."
                            return data_status
                        
                        merchantReferenceNumber=random_digit_generate(16)
                        refund_transfer_table = FundTransfers(
                            userId=str(userId),
                            transactionAPIId=transactionAPIId,
                            fundTransferId=str(latest_fund_transfer_queryset.id),
                            bankId=bankId,
                            merchantReferenceNumber=merchantReferenceNumber,
                            transactionUniqueId=merchant_reference_number,
                            pgOrderId=paymentgatewayresponseDict.get("transaction_id"),
                            fundTransferType="instant",
                            accountType="bank",
                            apiType="web",
                            slabId=slabId,
                            transferType="Refund",
                            bankBranch=bankBranch,
                            accountNumber=accountNumber,
                            accountIFSCCode=accountIFSCCode,
                            beneficiaryName=beneficiaryName,
                            uniqueRequestNumber=uniqueRequestNumber,
                            amount=round(float(amount),2),
                            grandTotal=round(float(transactionAmount),2),
                            previousBalance = round(float(balanceResult.get('userPreviousBalance')),2),
                            currentBalance = round(float(balanceResult.get('userCurrentBalance')),2),
                            beneficiaryMail=beneficiaryMail,
                            bankReferenceNumber=bank_reference_number,
                            beneficiaryPhone=beneficiaryPhone,
                            paymentMode=paymentMode,
                            narration=narration,
                            createdOn=datetime.datetime.now(),
                            userType="user",
                            status=5,
                            clientIp=client_ip,
                            transactionData=transactionData,
                            commissionCharges=commissionCharges
                            )
                        save_table = refund_transfer_table.save()
                        
                        payoutbalancelog_queryset=PayoutBalanceLogs(
                            userId =str(userId),
                            transactionAPIId =str(transactionAPIId),
                            previousBalance = round(float(balanceResult.get('transactionPreviousBalance')),2),
                            currentBalance = round(float(balanceResult.get('transactionCurrentBalance')),2),
                            amount=round(float(amount),2),
                            grandTotal=round(float(transactionAmount),2),
                            orderId=merchant_reference_number,
                            transferType = "Refund",
                            userType = "user",
                            transactionId = paymentgatewayresponseDict.get("transaction_id"),
                            createdOn = datetime.datetime.now(),
                            status = 1
                            ).save()

                fund_transfer_queryset.update(
                    transactionData=transactionData,
                    errorMessage=paymentgatewayresponseDict.get("messages"),
                    transactionUniqueId=paymentgatewayresponseDict.get("transaction_id"),
                    bankReferenceNumber=bank_reference_number,
                    status=paymentgatewayresponseDict.get("transactionstatus")
                    )

                try:
                    merchantName = str(user_queryset.fullName)
                    trnsactionDate = datetime.datetime.now().astimezone(ist_timezone).strftime("%d-%m-%Y %I:%M %p")
                    mail_subject = "Instant fund transfer initiated from " + merchantName + "."
                    recipients_list = [admin_recieve_email]
                    template_name = "emails/instant_fundtransfer.html"
                    mail_data = {
                    "merchantName":merchantName,
                    "accountNumber":accountNumber,
                    "bankName":bank_name,
                    "ifscCode":accountIFSCCode,
                    "amount":formatINR("{:.2f}".format(float(amount))),
                    "transactionId":paymentgatewayresponseDict.get("transaction_id"),
                    "orderId":merchant_reference_number,
                    "transactionDate":trnsactionDate,
                    }
                    domainUrl=domain
                    mailoutputData = send_asynchronous_email(mail_subject, recipients_list, template_name, mail_data)
                except Exception as e:
                    app.logger.error(traceback.format_exc())
                    pass

                data_status["responseStatus"] = 1
                data_status["result"] = "Instant transfer was successful!"
                # For count update number of success in routing switch counts table
                if routing_switch_counts_queryset:
                    existingSuccessCount = routing_switch_counts_queryset.numberOfSuccess
                    updateSuccessCount = existingSuccessCount+1

                    existingSuccessAmount = float(routing_switch_counts_queryset.maxVolume)
                    updateSuccessAmount = float(existingSuccessAmount)+float(amount)

                    routing_switch_counts_queryset.update(numberOfSuccess=updateSuccessCount,maxVolume=updateSuccessAmount)
                else:
                    save_routing_switch_table.update(numberOfSuccess=1,maxVolume=amount)
                return data_status
            else:
                data_status["responseStatus"]=paymentgatewayresponseDict.get("responseStatus")
                data_status["result"]=paymentgatewayresponseDict.get("result")
                save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())

                # For count update number of failures in routing switch counts table
                if routing_switch_counts_queryset:
                    existingFailuresCount = routing_switch_counts_queryset.numberOfFails
                    updateFailuresCount = existingFailuresCount+1

                    routing_switch_counts_queryset.update(numberOfFails=updateFailuresCount)
                else:
                    save_routing_switch_table.update(numberOfFails=1)
                return data_status
        else:
            data_status["result"]="Required fields are missing!!"
            save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Instant transfer was unsuccessful!!"
        exceptionData = [traceback.format_exc()]
        exception_log_table = save_exception_logs_data(userId,"payout","fund_transfer","payout_instant_transfer",exceptionData,client_ip,"web")
        save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
        return data_status

@paymentgateway_integrations.route("/payin_call_back_url", methods=["POST"])
def payin_call_back_url():
    print("(((((((((Testing)))))))))")
    data_status = {"responseStatus": 0, "result": ""}
    transaction_id = request.form.get("transaction_id","")
    payment_method = request.form.get("payment_method","")
    payment_datetime = request.form.get("payment_datetime","")
    response_code = request.form.get("response_code","")
    response_message = request.form.get("response_message","")
    error_desc = request.form.get("error_desc","")
    order_id = request.form.get("order_id","")
    amount = request.form.get("amount","")
    currency = request.form.get("currency","")
    description = request.form.get("description","")
    name = request.form.get("name","")
    email = request.form.get("email","")
    phone = request.form.get("phone","")
    address_line_1 = request.form.get("address_line_1","")
    address_line_2 = request.form.get("address_line_2","")
    city = request.form.get("city","")
    state = request.form.get("state","")
    country = request.form.get("country","")
    zip_code = request.form.get("zip_code","")
    udf1 = request.form.get("udf1","") # userId
    udf2 = request.form.get("udf2","") # payment_link or button_link or payment_page
    udf3 = request.form.get("udf3","") # type of link
    udf4 = request.form.get("udf4","")
    udf5 = request.form.get("udf5","")
    hashValue = request.form.get("hash","")

    print(request.form)
    print("(((((((((((((((((Accure Pay In Call Back Response Data)))))))))))))))))")

    requestData = [
    {
    "transaction_id":transaction_id,
    "payment_method":payment_method,
    "payment_datetime":payment_datetime,
    "response_message":response_message,
    "response_code":response_code,
    "error_desc":error_desc,
    "order_id":order_id,
    "amount":amount,
    "currency":currency,
    "description":description,
    "name":name,
    "email":email,
    "phone":phone,
    "address_line_1":address_line_1,
    "address_line_2":address_line_2,
    "city":city,
    "state":state,
    "country":country,
    "zip_code":zip_code,
    "udf1":udf1,
    "udf2":udf2,
    "udf3":udf3,
    "udf4":udf4,
    "udf5":udf5,
    "hash":hashValue,
    }
    ]
    
    save_api_webhook_logs_table = save_webhook_logs_data(None,"payin","call_back","payin_call_back_url",None,requestData,"api","")

    errorMessage=""
    if error_desc!="":
        errorMessage=error_desc
    else:
        if response_message!="":
            errorMessage=response_message
        else:
            errorMessage=""

    if response_code == 0:
        transactionstatus=1
        if errorMessage=="":
            errorMessage="Success"
    else:
        transactionstatus=3
        if response_code==1000:
            transactionstatus=0
            if errorMessage=="":
                errorMessage="Failed"
        elif response_code==1031 or response_code == 1032:
            transactionstatus=4
            if errorMessage=="":
                errorMessage="Reversal"
        else:
            transactionstatus=3
            if errorMessage=="":
                errorMessage="Pending"
            
    accurepay_payin_callback_request_data={
    "transaction_id":transaction_id,
    "payment_method":payment_method,
    "payment_datetime":payment_datetime,
    "response_code":response_code,
    "response_message":response_message,
    "pgOrderId":order_id,
    "client_order_id":order_id,
    "amount":round(float(amount),2),
    "currency":currency,
    "description":description,
    "name":name,
    "email":email,
    "phone":phone,
    "address_line_1":address_line_1,
    "address_line_2":address_line_2,
    "city":city,
    "state":state,
    "country":country,
    "zip_code":zip_code,
    "udf1":udf1,
    "udf2":udf2,
    "udf3":udf3,
    "udf4":udf4,
    "udf5":udf5,
    "customer_vpa":"",
    "transactionstatus":transactionstatus,
    "errorMessage":errorMessage,
    "hash":hashValue,
    "paymentChannel":"Accurepay",
    "bank_ref_id":""
    }
    callbackUrl = "payin_call_back_url"
    try:
        callbackResponseData = payin_webhook_call_back_update(accurepay_payin_callback_request_data,save_api_webhook_logs_table)

        data_status["responseStatus"] = callbackResponseData.get("responseStatus")
        data_status["result"] = callbackResponseData.get("result")
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to get pay in call back url!!"
        return data_status

@paymentgateway_integrations.route("/wowpe_payin_call_back_url", methods=["POST"])
def wowpe_payin_call_back_url():
    data_status = {"responseStatus": 0, "result": ""}
    pgOrderId = request.json.get("OrderId","")
    payment_method = request.json.get("PaymentMode","")
    payment_datetime = request.json.get("Date","")
    bank_ref_id = request.json.get("BankRRN","")
    customer_vpa = request.json.get("PayerVPA","")
    apiMerchantId = request.json.get("MerchantId","")
    response_code = request.json.get("Status","")
    order_id = request.json.get("ClientOrderId","")
    amount = request.json.get("Amount","")
    OrderAmount = request.json.get("OrderAmount","")
    currency = request.json.get("Currency","")
    name = request.json.get("PayerName","")
    phone = request.json.get("PayerMobile","")
    transaction_id = request.json.get("RefNumber","")
    Checksum = request.json.get("Checksum","")

    print(request.json)
    print("(((((((((((((((((Wowpe Call Back Response Data)))))))))))))))))")
    requestData = [request.json]
    save_api_webhook_logs_table = save_webhook_logs_data(None,"payin","call_back","wowpe_payin_call_back_url",None,requestData,"api","")

    errorMessage=""
    if response_code == 1:
        transactionstatus=1
        errorMessage = "Success"
    else:
        transactionstatus=3
        errorMessage="Pending"
        if response_code==0:
            transactionstatus=0
            errorMessage="Failed"
        elif response_code==4:
            transactionstatus=4
            errorMessage="Reversal"
        else:
            transactionstatus=3
            errorMessage="Pending"

    wowpe_payin_callback_request_data={
    "transaction_id":transaction_id,
    "payment_method":payment_method,
    "payment_datetime":payment_datetime,
    "response_code":response_code,
    "response_message":errorMessage,
    "pgOrderId":pgOrderId,
    "client_order_id":order_id,
    "amount":round(float(amount),2),
    "OrderAmount":round(float(OrderAmount),2),
    "currency":currency,
    "description":description,
    "name":name,
    "email":email,
    "phone":phone,
    "address_line_1":address_line_1,
    "address_line_2":address_line_2,
    "city":city,
    "state":state,
    "country":country,
    "zip_code":zip_code,
    "udf1":udf1,
    "udf2":udf2,
    "udf3":udf3,
    "udf4":udf4,
    "udf5":udf5,
    "customer_vpa":customer_vpa,
    "apiMerchantId":apiMerchantId,
    "transactionstatus":transactionstatus,
    "errorMessage":errorMessage,
    "hash":Checksum,
    "paymentChannel":"Wowpe",
    "bank_ref_id":bank_ref_id
    }

    try:
        callbackResponseData = payin_webhook_call_back_update(wowpe_payin_callback_request_data,save_api_webhook_logs_table)

        data_status["responseStatus"] = callbackResponseData.get("responseStatus")
        data_status["result"] = callbackResponseData.get("result")
        return data_status
    except Exception as e:
        print("GETTING ERROR")
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to get pay in call back url!!"
        return data_status

@paymentgateway_integrations.route("/payin_intent_payment_url", methods=["POST"])
def payin_intent_payment_url():
    data_status = {"responseStatus": 0, "result": ""}
    if SERVER_STATUS == "DOWN":
        data_status["result"]= SERVER_MAINTAINCE_MESSAGE
        return data_status
    address_line_1 = request.json.get("address_line_1","")
    address_line_2 = request.json.get("address_line_2","")
    amount = request.json.get("amount","")
    city = request.json.get("city","")
    country = request.json.get("country","")
    currency = request.json.get("currency","")
    description = request.json.get("description","")
    email = request.json.get("email","")
    mode = request.json.get("mode","")
    name = request.json.get("name","")
    order_id = request.json.get("order_id","")
    phone = request.json.get("phone","")
    return_url = request.json.get("return_url","")
    return_url_cancel = request.json.get("return_url_cancel","")
    return_url_failure = request.json.get("return_url_failure","")
    state = request.json.get("state","")
    user_id = request.json.get("udf1","")
    udf2 = request.json.get("udf2","")
    udf3 = request.json.get("udf3","")
    udf4 = request.json.get("udf4","")
    udf5 = request.json.get("udf5","")
    zip_code = request.json.get("zip_code","")
    location = ""
    agent = ""
    responseDict = {}
    respnseData = {}

    # Extracting client IP address
    if request.headers.getlist("X-Forwarded-For"):
        client_ip = request.headers.getlist("X-Forwarded-For")[0]
    else:
        client_ip = request.remote_addr

    loginBrowser = request.headers.get("Sec-Ch-Ua")
    if loginBrowser:
        loginBrowseData = loginBrowser.split(";")
        browser = loginBrowseData[0]
    else:
        loginBrowseData = request.headers.get('User-Agent').split(";")
        browser = loginBrowseData[0]

    transactionAPIId = ""
    requestData = []

    # Here Create Client Logs Table
    save_client_table = save_client_logs_data(user_id,"payin","intent","payin_intent_payment_url",None,requestData,client_ip,"web")

    try:
        if user_id and order_id:
            merchant_queryset = Users.objects(id=user_id,status__in=[1]).first()
            if not merchant_queryset:
                data_status["result"]="Invalid merchant id!!"
                return data_status
            if not merchant_queryset.payInPaymentGatewayId:
                data_status['result']="Payin option is diabled.Please contact to admin."
                return data_status

            transactionAPIId=str(merchant_queryset.payInPaymentGatewayId.id)
            requestData=[request.json]

            # Here Update some data in client log
            save_client_table.update(requestData=requestData,transactionAPIId=ObjectId(transactionAPIId))

            # api_security_queryset = ApiSecurities.objects(apiKey=api_key,apiType="payment_gateway",userId=userId,status__in=[1]).first()
            # if not api_security_queryset:
            #     data_status["result"]="Invalid api key!!"
            #     return data_status

            # if client_ip != api_security_queryset.ipAddress:
            #     data_status["result"]="Your ip adress is not whitelisted please contact admin!!"
            #     return data_status

            currentDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            if merchant_queryset.payInPaymentGatewayId:
                payInPaymentGatewayId = str(merchant_queryset.payInPaymentGatewayId.id)
                payin_gate_way_queryset = TransactionAPI.objects(id=payInPaymentGatewayId,status=1).first()
                if not payin_gate_way_queryset:
                    data_status['result']="Payin option is diabled.Please contact to admin"
                    return data_status

                paymentGateWayCode = payin_gate_way_queryset.code

                routing_switch_counts_queryset = RoutingSwitchCounts.objects(userId=user_id,transactionAPIId=payInPaymentGatewayId,createdOn=currentDate).first()
                if routing_switch_counts_queryset:
                    numberOfFails = routing_switch_counts_queryset.numberOfFails
                    numberOfSuccess = routing_switch_counts_queryset.numberOfSuccess

                else:
                    save_routing_switch_table=save_routing_switch_logs_data(user_id,"payin",transactionAPIId)


                pgOrderId = merchant_queryset.merchantUniqueNumber+"-"+order_id

                if paymentGateWayCode == "AccurePay_PayIn":
                    check_order = WalletTransactions.objects(orderId=order_id).first()
                    if check_order:
                        data_status["result"]="This order id is already exisit!!"
                        return data_status

                    get_api_key = ""
                    get_salt = ""
                    get_base_url = ""

                    for each_key in payin_gate_way_queryset.paramsList:
                        
                        get_key = each_key.get("key")
                        
                        if get_key == "api_key":
                            get_api_key = each_key.get("value")
                            
                        if get_key == "salt":
                            get_salt = each_key.get("value")

                        if get_key == "base_url":
                            get_base_url = each_key.get("value")
                            
                    newEncryptedData = {
                    "api_key":get_api_key,
                    "order_id":pgOrderId,
                    "mode":mode,
                    "amount":amount,
                    "currency":currency,
                    "description":description,
                    "name":name,
                    "email":email,
                    "phone":phone,
                    "address_line_1":address_line_1,
                    "address_line_2":address_line_2,
                    "city":city,
                    "state":state,
                    "country":country,
                    "zip_code":zip_code,
                    "udf1":user_id,
                    "udf2":udf2,
                    "udf3":udf3,
                    "udf4":udf4,
                    "udf5":udf5,
                    "return_url":domain+"/api/mobile/payin_call_back_url"
                    }
                    salt = get_salt
                    hashvalue = Sha512Hash(newEncryptedData,salt)
                    
                    newEncryptedData.update({"hash": hashvalue})
                    
                    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
                    payload = "api_key="+get_api_key+"&order_id="+newEncryptedData.get('order_id')+"&mode="+newEncryptedData.get('mode')+"&amount="+str(newEncryptedData.get('amount'))+"&currency="+newEncryptedData.get('currency')+"&description="+newEncryptedData.get('description')+"&name="+newEncryptedData.get('name')+"&email="+newEncryptedData.get('email')+"&phone="+newEncryptedData.get('phone')+"&address_line_1="+newEncryptedData.get('address_line_1')+"&address_line_2="+newEncryptedData.get('address_line_2')+"&city="+newEncryptedData.get('city')+"&state="+newEncryptedData.get('state')+"&country="+newEncryptedData.get('country')+"&zip_code="+newEncryptedData.get('zip_code')+"&udf1="+newEncryptedData.get('udf1')+"&udf2="+newEncryptedData.get('udf2')+"&udf3="+newEncryptedData.get('udf3')+"&udf4="+newEncryptedData.get('udf4')+"&udf5="+newEncryptedData.get('udf5')+"&return_url="+newEncryptedData.get('return_url')+"&hash="+newEncryptedData.get('hash')

                    # API Logs Table Saving Here
                    apiCallingUrl=get_base_url+"getpaymentrequestintenturl"
                    requestData=[payload]
                    save_api_log_table = save_api_logs_data(user_id,"payin","intent",apiCallingUrl,str(transactionAPIId),requestData,client_ip,"web")
                    

                    respnseData = requests.post(get_base_url+"getpaymentrequestintenturl", data=payload, headers=headers)
                    response_text = respnseData.text
                    # Parse the JSON response
                    response_data = json.loads(response_text)
                    print(response_data,"Accure PAY IN INTENT URL RESPONSE")

                    # For update response data in api log table
                    save_api_log_table.update(responseData=[response_data],responseDate=datetime.datetime.now())

                    if "data" in response_data:
                        if response_data["data"].get("upi_intent_url")!=None:
                            responseDict={
                            'url':response_data["data"].get("upi_intent_url")
                            }
                            data_status["responseStatus"]=1
                            data_status["result"]=responseDict
                            # For update response data in client log table
                            save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())

                            # For count update number of success in routing switch counts table
                            if routing_switch_counts_queryset:
                                existingSuccessCount = routing_switch_counts_queryset.numberOfSuccess
                                updateSuccessCount = existingSuccessCount+1

                                existingSuccessAmount = float(routing_switch_counts_queryset.maxVolume)
                                updateSuccessAmount = float(existingSuccessAmount)+float(amount)

                                routing_switch_counts_queryset.update(numberOfSuccess=updateSuccessCount,maxVolume=updateSuccessAmount)
                            else:
                                save_routing_switch_table.update(numberOfSuccess=1,maxVolume=amount)

                            return data_status
                        else:
                            data_status['result'] = "Request failed with status code BadRequest"
                            # For update response data in client log table
                            save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())

                            # For count update number of failures in routing switch counts table
                            if routing_switch_counts_queryset:
                                existingFailuresCount = routing_switch_counts_queryset.numberOfFails
                                updateFailuresCount = existingFailuresCount+1

                                existingSuccessAmount = float(routing_switch_counts_queryset.maxVolume)
                                updateSuccessAmount = float(existingSuccessCount)+float(amount)

                                routing_switch_counts_queryset.update(numberOfFails=updateFailuresCount)
                            else:
                                save_routing_switch_table.update(numberOfFails=1)

                            return data_status
                    else:
                        data_status['result'] = response_data["error"].get("message")
                        # For update response data in client log table
                        save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())

                        # For count update number of failures in routing switch counts table
                        if routing_switch_counts_queryset:
                            existingFailuresCount = routing_switch_counts_queryset.numberOfFails
                            updateFailuresCount = existingFailuresCount+1

                            existingSuccessAmount = float(routing_switch_counts_queryset.maxVolume)
                            updateSuccessAmount = float(existingSuccessCount)+float(amount)

                            routing_switch_counts_queryset.update(numberOfFails=updateFailuresCount)
                        else:
                            save_routing_switch_table.update(numberOfFails=1)
                        return data_status

                elif paymentGateWayCode == "WowPe_Payin":
                    check_order = WalletTransactions.objects(orderId=order_id).first()
                    if check_order:
                        data_status["result"]="This order id is already exisit!!"
                        return data_status

                    get_client_id = ""
                    get_secret = ""
                    get_base_url = ""

                    for each_key in payin_gate_way_queryset.paramsList:
                        
                        get_key = each_key.get("key")
                        
                        if get_key == "api_key":
                            get_client_id = each_key.get("value")
                        if get_key == "secret_key":
                            get_secret = each_key.get("value")
                        if get_key == "base_url":
                            get_base_url = each_key.get("value")

                    wowpe_payin_request_body={
                    "clientId": get_client_id,
                    "secretKey": get_secret,
                    "name": name,
                    "mobileNo": phone,
                    "emailID": email,
                    "amount": amount,
                    "clientOrderId": pgOrderId
                    }

                    url = get_base_url+"/orders"

                    # API Logs Table Saving Here
                    requestData=[wowpe_payin_request_body]
                    save_wowpe_api_log_table = save_api_logs_data(user_id,"payin","create_order",url,str(transactionAPIId),requestData,client_ip,"web")

                    headers = {
                        "accept": "application/json",
                        "content-type": "application/json"
                    }
                    response = requests.post(url, json=wowpe_payin_request_body, headers=headers)
                    responseData = json.loads(response.text)

                    print(responseData,"RESPONSE FOR PAYIN WOWPE CREATE ORDER DATA")

                    # For update response data in api log table
                    save_wowpe_api_log_table.update(responseData=[responseData],responseDate=datetime.datetime.now())

                    if responseData.get("statusCode") == 1:
                        get_order_id = responseData.get("orderId")

                        # For count update number of success in routing switch counts table
                        if routing_switch_counts_queryset:
                            existingSuccessCount = routing_switch_counts_queryset.numberOfSuccess
                            updateSuccessCount = existingSuccessCount+1

                            existingSuccessAmount = float(routing_switch_counts_queryset.maxVolume)
                            updateSuccessAmount = float(existingSuccessAmount)+float(amount)

                            routing_switch_counts_queryset.update(numberOfSuccess=updateSuccessCount,maxVolume=updateSuccessAmount)
                        else:
                            save_routing_switch_table.update(numberOfSuccess=1,maxVolume=amount)

                        get_deeplink_data = {
                            "clientId": get_client_id,
                            "secretKey": get_secret,
                            "note":description,
                            "orderId":get_order_id
                            }
                        deep_link_url = get_base_url+"/intent-initiate"

                        # API Logs Table Saving Here
                        requestData=[get_deeplink_data]
                        save_wowpe_link_api_log_table = save_api_logs_data(user_id,"payin","intent",deep_link_url,transactionAPIId,requestData,client_ip,"web")

                        deep_link_response = requests.post(deep_link_url, json=get_deeplink_data, headers=headers)
                        deeplinkResponseData = json.loads(deep_link_response.text)

                        # For update response data in api log table
                        save_wowpe_link_api_log_table.update(responseData=[deeplinkResponseData],responseDate=datetime.datetime.now())

                        print(deeplinkResponseData,"RESPONSE FOR PAYIN WOWPE DEEP LINK DATA")

                        if deeplinkResponseData.get('statusCode')==1:
                            if deeplinkResponseData.get("upiurl")!=None:
                                responseDict={
                                'url':deeplinkResponseData.get("upiurl")
                                }
                                wallet_transaction_table = WalletTransactions(
                                    userId = user_id,
                                    amount = round(float(amount),2),
                                    grandTotal=round(float(amount),2),
                                    paymentGatewayId = payInPaymentGatewayId,
                                    paymentType = "UPI",
                                    creditType = "Credit",
                                    transactionId = "",
                                    transactionData = [deeplinkResponseData],
                                    orderId = order_id,
                                    walletLog="",
                                    userType="user",
                                    createdBy = None,
                                    createdOn = datetime.datetime.now(),
                                    location = location,
                                    platform = "api",
                                    agent = agent,
                                    customerEmail = email,
                                    customerName = name,
                                    customerPhonenumber = phone,
                                    previousBalance=0,
                                    currentBalance=0,
                                    paymentLinkId = None,
                                    PaymentButtonId = None,
                                    paymentPageId = None,
                                    errorMessage = "",
                                    paymentChannel = "Wowpe",
                                    bankRefId="",
                                    cardmasked="",
                                    pgOrderId=deeplinkResponseData.get("orderId"),
                                    customerVpa="",
                                    commissionCharges={},
                                    status = 3
                                    ).save()

                                data_status["responseStatus"]=1
                                data_status["result"]=responseDict
                                # For update response data in client log table
                                save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())

                                # For count update number of success in routing switch counts table
                                if routing_switch_counts_queryset:
                                    existingSuccessCount = routing_switch_counts_queryset.numberOfSuccess
                                    updateSuccessCount = existingSuccessCount+1

                                    existingSuccessAmount = float(routing_switch_counts_queryset.maxVolume)
                                    updateSuccessAmount = float(existingSuccessAmount)+float(amount)

                                    routing_switch_counts_queryset.update(numberOfSuccess=updateSuccessCount,maxVolume=updateSuccessAmount)
                                else:
                                    save_routing_switch_table.update(numberOfSuccess=1,maxVolume=amount)

                                return data_status
                            else:
                                data_status['result'] = "Request failed with status code BadRequest"
                                # For update response data in client log table
                                save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())

                                # For count update number of failures in routing switch counts table
                                if routing_switch_counts_queryset:
                                    existingFailuresCount = routing_switch_counts_queryset.numberOfFails
                                    updateFailuresCount = existingFailuresCount+1

                                    existingSuccessAmount = float(routing_switch_counts_queryset.maxVolume)
                                    updateSuccessAmount = float(existingSuccessCount)+float(amount)

                                    routing_switch_counts_queryset.update(numberOfFails=updateFailuresCount)
                                else:
                                    save_routing_switch_table.update(numberOfFails=1)

                                return data_status
                        else:
                            data_status['result'] = deeplinkResponseData.get("message")
                            # For update response data in client log table
                            save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())

                            # For count update number of failures in routing switch counts table
                            if routing_switch_counts_queryset:
                                existingFailuresCount = routing_switch_counts_queryset.numberOfFails
                                updateFailuresCount = existingFailuresCount+1

                                existingSuccessAmount = float(routing_switch_counts_queryset.maxVolume)
                                updateSuccessAmount = float(existingSuccessCount)+float(amount)

                                routing_switch_counts_queryset.update(numberOfFails=updateFailuresCount)
                            else:
                                save_routing_switch_table.update(numberOfFails=1)

                            return data_status
                    else:
                        data_status['result'] = responseData.get("message")
                        # For update response data in client log table
                        save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())

                        # For count update number of failures in routing switch counts table
                        if routing_switch_counts_queryset:
                            existingFailuresCount = routing_switch_counts_queryset.numberOfFails
                            updateFailuresCount = existingFailuresCount+1

                            existingSuccessAmount = float(routing_switch_counts_queryset.maxVolume)
                            updateSuccessAmount = float(existingSuccessCount)+float(amount)

                            routing_switch_counts_queryset.update(numberOfFails=updateFailuresCount)
                        else:
                            save_routing_switch_table.update(numberOfFails=1)

                        return data_status
                else:
                    data_status["result"]="Please contact to admin to enable payin option!!"
                    # For update response data in client log table
                    save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
                    return data_status
            else:
                data_status["result"]="Please contact to admin to enable payin option!!"
                # For update response data in client log table
                save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
            return data_status
        else:
            data_status["result"]="Required fields are missing!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to get intent data!!"
        exceptionData = [traceback.format_exc()]
        exception_log_table = save_exception_logs_data(user_id,"payin","intent","payin_intent_payment_url",exceptionData,client_ip,"web")
        return data_status

@paymentgateway_integrations.route("/payin_payment_status", methods=["POST"])
def payin_payment_status():
    data_status = {"responseStatus": 0, "result": ""}
    order_id = request.json.get("order_id","")
    user_id = request.json.get("user_id","")
    responseDict = {}
    try:
        if user_id and order_id:
            merchant_queryset = Users.objects(id=user_id,status__in=[1]).first()
            if not merchant_queryset:
                data_status["result"]="Invalid merchant id!!"
                return data_status
            merchantReferenceNumber = merchant_queryset.merchantUniqueNumber
            orderId = str(merchantReferenceNumber+"-"+order_id)
            order_queryset = WalletTransactions.objects(pgOrderId=orderId).first()
            if order_queryset:
                responseDict={
                'order_id':order_queryset.orderId,
                'amount':order_queryset.amount,
                'status':order_queryset.status,
                'errorMessage':order_queryset.errorMessage
                }
                data_status["responseStatus"]=1
                data_status['result']=responseDict
                return data_status
            else:
                data_status["result"]="Order id not found!"
                return data_status
        else:
            data_status["result"]="Required fields are missing!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to get intent data!!"
        return data_status


@paymentgateway_integrations.route("/payout_credit_notification", methods=["POST"])
def payout_credit_notification():
    print("(((((((((Testing)))))))))")
    print(request.json,"$$$$$$$$$$$$$$$$$requestjson$$$$$$$$$$$$$$$$$$$$$$$$$")
    data_status = {"responseStatus": 0, "result": ""}
    notifylist=request.json.get('notify')
    status=notifylist['status']
    ecollect_account_no=notifylist['ecollect_account_no']
    bank_reference_number=notifylist['bank_reference_number']
    transfer_type=notifylist['transfer_type']
    transaction_date=notifylist['transaction_date']
    transaction_amount=notifylist['transaction_amount']
    remitter_name=notifylist['remitter_name']
    remitter_account_number=notifylist['remitter_account_number']
    remitter_ifsc_code=notifylist['remitter_ifsc_code']
    remitter_note=notifylist['remitter_note']
    api_key=notifylist['api_key']
    hashvalue=notifylist['hash']
    transactionUniqueId = random_digit_generate(15)
    orderId = random_digit_generate(15)
    try:
        if remitter_account_number and api_key and ecollect_account_no:
            merchant_whitelist_queryset = WhiteListAccounts.objects(whiteListAccountNumber=remitter_account_number).first()
            payout_gate_way_queryset = TransactionAPI.objects(code="AccurePay_Payout").all()
            get_api_key=''
            transactionAPIId=''
            for each_payout in payout_gate_way_queryset:
                paramsList=each_payout.paramsList
                for each_param in paramsList:
                    get_key = each_param.get("key")
                    if get_key == "api_key":
                        get_api_key = each_param.get("value")
                        if get_api_key==api_key:
                            transactionAPIId=str(each_payout.id)
            print(transactionAPIId,'**************transactionAPIId*******************')
            if transactionAPIId=='':
                return False
            if not merchant_whitelist_queryset:
                resd=CreditNotifications(
                    #userId=None,
                    ecollectAccoutNo=ecollect_account_no,
                    bankReferenceNumber=bank_reference_number,
                    transferType=transfer_type,
                    transactionDate=transaction_date,
                    transactionAmount=float(transaction_amount),
                    remitterName=remitter_name,
                    remitterAccountNumber=remitter_account_number,
                    remitterIfscCode=remitter_ifsc_code,
                    remitterNote=remitter_note,
                    apiKey=api_key,
                    hashValue=hashvalue,
                    transactionUniqueId=transactionUniqueId,
                    responseStatus=status,
                    transactionAPIId=transactionAPIId,
                    createdOn=datetime.datetime.now(),
                    requestData=[notifylist],
                    status=1
                    )
                save_table=resd.save()
                save_table.update(userId=None)
            else:
                userId=str(merchant_whitelist_queryset.userId.id)
                merchant_queryset = Users.objects(id=userId).first()
                if merchant_queryset:
                    payoutBalance=0
                    currentBalance=0
                    payout_balance_queryset = PayoutBalances.objects(userId=userId,transactionAPIId=transactionAPIId).first()
                    if payout_balance_queryset:
                        payoutBalance=payout_balance_queryset.currentBalance
                        currentBalance=float(payoutBalance)+float(transaction_amount)
                        payout_balance_queryset.update(currentBalance = currentBalance,previousBalance=payoutBalance,updatedOn=datetime.datetime.now())
                    else:
                        payoutBalance=payoutBalance
                        currentBalance=float(transaction_amount)
                        save_payout_balance=PayoutBalances(
                            userId=userId,
                            transactionAPIId=transactionAPIId,
                            previousBalance=payoutBalance,
                            currentBalance=currentBalance,
                            createdOn=datetime.datetime.now(),
                            status=1
                            ).save()

                    payout_table = FundTransfers(
                        userId=userId,
                        amount=float(transaction_amount),
                        accountType=transfer_type,
                        accountNumber=remitter_account_number,
                        accountIFSCCode=remitter_ifsc_code,
                        beneficiaryName=remitter_name,
                        transferType="Credit",
                        transactionAPIId=transactionAPIId,
                        merchantReferenceNumber=orderId,
                        userType = "api",
                        apiType = "api",
                        transactionData = [notifylist],
                        payoutResponseCallBackData = [notifylist],
                        narration=remitter_note,
                        responseCallBackTime=transaction_date,
                        transactionUniqueId = transactionUniqueId,
                        createdOn = datetime.datetime.now(),
                        previousBalance=payoutBalance,
                        currentBalance=currentBalance,
                        errorMessage=status,
                        pgOrderId=str(merchant_queryset.merchantUniqueNumber)+'-'+str(orderId),
                        status = 1
                        )

                    save_payout_table = payout_table.save()
                    merchantPayoutBalance=merchant_queryset.payoutBalance
                    merchantCurrentBalance=float(merchantPayoutBalance)+float(transaction_amount)
                    merchant_queryset.update(payoutBalance = merchantCurrentBalance)

                    resd=CreditNotifications(
                        #userId=userId,
                        ecollectAccoutNo=ecollect_account_no,
                        bankReferenceNumber=bank_reference_number,
                        transferType=transfer_type,
                        transactionDate=transaction_date,
                        transactionAmount=float(transaction_amount),
                        remitterName=remitter_name,
                        remitterAccountNumber=remitter_account_number,
                        remitterIfscCode=remitter_ifsc_code,
                        remitterNote=remitter_note,
                        apiKey=api_key,
                        hashValue=hashvalue,
                        transactionUniqueId=transactionUniqueId,
                        responseStatus=status,
                        transactionAPIId=transactionAPIId,
                        createdOn=datetime.datetime.now(),
                        requestData=[notifylist],
                        status=1
                        )
                    save_table=resd.save()
                    save_table.update(userId=ObjectId(userId))
                else:
                    resd=CreditNotifications(
                        #userId=None,
                        ecollectAccoutNo=ecollect_account_no,
                        bankReferenceNumber=bank_reference_number,
                        transferType=transfer_type,
                        transactionDate=transaction_date,
                        transactionAmount=float(transaction_amount),
                        remitterName=remitter_name,
                        remitterAccountNumber=remitter_account_number,
                        remitterIfscCode=remitter_ifsc_code,
                        remitterNote=remitter_note,
                        apiKey=api_key,
                        hashValue=hashvalue,
                        transactionUniqueId=transactionUniqueId,
                        responseStatus=status,
                        transactionAPIId=transactionAPIId,
                        createdOn=datetime.datetime.now(),
                        requestData=[notifylist],
                        status=1
                        )
                    save_table=resd.save()
                    save_table.update(userId=None)
        return "Success"
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to pay in call back url!!"
        return "False"



@paymentgateway_integrations.route("/check_payout_fundtransfer_status",methods=["POST"])
def check_payout_fundtransfer_status():
    data_status = {"responseStatus":0,"result":""}
    merchant_reference_number = request.json.get("merchant_reference_number","")

    if not merchant_reference_number:
        data_status["result"]="Required fields are missing!!"
        return data_status

    try:
        order_queryset = FundTransfers.objects(merchantReferenceNumber=merchant_reference_number).first()
        if not order_queryset:
            data_status["result"]="Invalid order id!!"
            return data_status
        check_payment_status = get_fundtransfer_payment_status(merchant_reference_number,str(order_queryset.userId.id))
        print(check_payment_status,"CHECK Payment FundTransfer Status")

        data_status["responseStatus"]=1
        data_status["result"]="Success"
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to get payment status!!"
        return data_status

@paymentgateway_integrations.route("/gst_tds_reports", methods=["POST"])
@user_required
def gst_tds_reports():
    data_status = {"responseStatus": 0, "result": ""}
    gstTdsReportList = []

    userId = request.json.get("userId", "")
    selectYear = request.json.get("selectYear", "")
    selectMonth = request.json.get("selectMonth", "")
    pageLimit = request.json.get("pageLimit","20")
    pageOffset = request.json.get("pageOffset","0")

    try:
        page_start=int(pageOffset)
        page_end=int(pageOffset)+int(pageLimit)

        if not selectYear or not selectMonth:
            data_status["result"] = "Year and month are required!!"
            return data_status

        # Convert selectYear and selectMonth to datetime objects
        try:
            start_date = datetime.datetime(int(selectYear), int(selectMonth), 1)
            if selectMonth == '12':
                end_date = datetime.datetime(int(selectYear) + 1, 1, 1)
            else:
                end_date = datetime.datetime(int(selectYear), int(selectMonth) + 1, 1)
        except ValueError as e:
            data_status["result"] = "Invalid year or month format!!"
            return data_status


        # Query the FundTransfers collection
        payouts_credit_queryset = FundTransfers.objects(userId=userId,status__in=[1,2]).order_by("-id").all()

        # Filter the querysets based on the start and end dates
        credits_queryset_filter = payouts_credit_queryset.filter(
            transferType="Credit",
            createdOn__gte=start_date,
            createdOn__lt=end_date
        )
        debits_queryset_filter = payouts_credit_queryset.filter(
            transferType__nin=["Credit"],
            createdOn__gte=start_date,
            createdOn__lt=end_date
        )
        if credits_queryset_filter:
            transactionCreditCount = credits_queryset_filter.count()
            totalChargeAmount = 0
            totalAmount = 0
            totalGstAmount = 0
            totalTdsAmount = 0
            totalCommissionAmount = 0

            totalAmount=credits_queryset_filter.sum("amount")
            totalChargeAmount=credits_queryset_filter.sum("commissionCharges.chargeAmount")
            totalGstAmount=credits_queryset_filter.sum("commissionCharges.gstAmount")
            totalTdsAmount=credits_queryset_filter.sum("commissionCharges.tdsAmount")
            totalCommissionAmount=credits_queryset_filter.sum("commissionCharges.commissionAmount")

            # Iterate through each transaction to accumulate totals
            # for transaction in credits_queryset_filter:
            #     commissionCharges = transaction.commissionCharges
            #     if commissionCharges:
            #         totalChargeAmount += commissionCharges.get("chargeAmount", 0)
            #         totalGstAmount += commissionCharges.get("gstAmount", 0)
            #         totalTdsAmount += commissionCharges.get("tdsAmount", 0)
            #         totalCommissionAmount += commissionCharges.get("commissionAmount", 0)

            creditDict = {
                "serviceName": "Auto Collect",
                "transactionCount": transactionCreditCount,
                "totalAmount": round(float(totalAmount),2),
                "totalChargeAmount": round(float(totalChargeAmount),2),
                "totalGstAmount": round(float(totalGstAmount),2),
                "totalTdsAmount": round(float(totalTdsAmount),2),
                "totalCommissionAmount": round(float(totalCommissionAmount),2),
            }
            gstTdsReportList.append(creditDict)

        if debits_queryset_filter:
            transactionDebitCount = debits_queryset_filter.count()
            totalChargeAmount = 0
            totalGstAmount = 0
            totalTdsAmount = 0
            totalCommissionAmount = 0
            totalAmount = 0

            totalAmount=debits_queryset_filter.sum("amount")
            totalChargeAmount=debits_queryset_filter.sum("commissionCharges.chargeAmount")
            totalGstAmount=debits_queryset_filter.sum("commissionCharges.gstAmount")
            totalTdsAmount=debits_queryset_filter.sum("commissionCharges.tdsAmount")
            totalCommissionAmount=debits_queryset_filter.sum("commissionCharges.commissionAmount")
            
            # Iterate through each transaction to accumulate totals
            # for transaction in debits_queryset_filter:
            #     commissionCharges = transaction.commissionCharges
            #     if commissionCharges:
            #         totalChargeAmount += commissionCharges.get("chargeAmount", 0)
            #         totalGstAmount += commissionCharges.get("gstAmount", 0)
            #         totalTdsAmount += commissionCharges.get("tdsAmount", 0)
            #         totalCommissionAmount += commissionCharges.get("commissionAmount", 0)

            debitDict = {
                "serviceName": "Payout",
                "transactionCount": transactionDebitCount,
                "totalAmount": round(float(totalAmount),2),
                "totalChargeAmount": round(float(totalChargeAmount),2),
                "totalGstAmount": round(float(totalGstAmount),2),
                "totalTdsAmount": round(float(totalTdsAmount),2),
                "totalCommissionAmount": round(float(totalCommissionAmount),2),
            }
            gstTdsReportList.append(debitDict)

        data_status["responseStatus"] = 1
        data_status["result"] = "Gst/tds reports data fetched successfully!"
        data_status["gstTdsReportList"] = gstTdsReportList
        return data_status

    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to fetch gst/tds reports data!!"
        return data_status

@paymentgateway_integrations.route("/getpayoutfundtransferstatus",methods=["POST"])
@user_required
def getpayoutfundtransferstatus():
    data_status = {"responseStatus":0,"result":""}
    print(SERVER_STATUS,"(((((((((((SERVER_STATUS)))))))))))")
    if SERVER_STATUS == "DOWN":
        data_status["result"]= SERVER_MAINTAINCE_MESSAGE
        return data_status
    userId = request.json.get("userId","")
    orderId = request.json.get("orderId","")
    get_fundtransfer_status = {}
    try:
        if not orderId:
            data_status["result"]="Required fields are missing!!"
            return data_status
        merchant_queryset = Users.objects(id=str(userId),status=1).first()
        if not merchant_queryset:
            data_status["result"]="Invalid merchant id!!"
                
        order_queryset = FundTransfers.objects(merchantReferenceNumber=orderId,userId=userId).first()
        if not order_queryset:
            data_status["result"]="Invalid order id!!"
            return data_status


        get_fundtransfer_status = get_fundtransfer_payment_status(orderId,userId)
        print(get_fundtransfer_status,"((((((((((((GET Payout FundTransfer Status In Frontend))))))))))))")

        if get_fundtransfer_status.get("error"):
            data_status["status"]= "Failed"
            data_status["errorMessage"]=get_fundtransfer_status.get("error")

        elif get_fundtransfer_status.get("status") == "SUCCESS":
            data_status["status"]=get_fundtransfer_status.get("status")
            data_status["errorMessage"]=get_fundtransfer_status.get("status")
        elif get_fundtransfer_status.get("status") == "PROCESSING":
            data_status["status"]=get_fundtransfer_status.get("status")
            data_status["errorMessage"]=get_fundtransfer_status.get("status")
        else:
            data_status["status"]=get_fundtransfer_status.get("status")
            data_status["errorMessage"]=get_fundtransfer_status.get("error_message")

        data_status["responseStatus"]=1
        data_status["result"]="FundTransfer payout status fetched successfully!"
        return data_status

    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to get fundtransfer status data!!"
        return data_status


################################## WOWPE Payout Call Back URL API ######################################
@paymentgateway_integrations.route("/wowpe_payout_call_back_url",methods=["POST"])
def wowpe_payout_call_back_url():
    data_status = {"responseStatus":0,"result":""}
    StatusCode = request.json.get("StatusCode")
    Message = request.json.get("Message","")
    OrderId = request.json.get("OrderId","")
    Status = request.json.get("Status")
    ClientOrderId = request.json.get("ClientOrderId","")
    PaymentMode = request.json.get("PaymentMode","")
    amount = request.json.get("Amount","")
    Date = request.json.get("Date","")
    UTR = request.json.get("UTR","")
    Checksum = request.json.get("Checksum","")
    print(request.json,"wowpe payout call back response result")

    requestData = [request.json]
    save_api_webhook_logs_table = save_webhook_logs_data(None,"payout","call_back","wowpe_payout_call_back_url",None,requestData,"api","")

    statusText = "FAILED"
    if StatusCode!=1:
        data_status["responseStatus"] = 1
        data_status["result"] = "Wowpe payout status no update"
        return data_status
    else:
        transactionstatus=2
        if Status==1:
            transactionstatus=1
            statusText="SUCCESS"
        elif Status == 0:
            transactionstatus=0
            statusText="FAILED"
        elif Status == 4:
            transactionstatus=4
            statusText="REVERSAL"
        else:
            transactionstatus=2
            statusText="PROCESSING"

    wowpe_payout_callback_request_data={
    "statusCode":StatusCode,
    "message":Message,
    "orderId":OrderId,
    "pgOrderId":ClientOrderId,
    "paymentMode":PaymentMode,
    "amount":round(float(amount),2),
    "transaction_date":Date,
    "bank_reference_number":UTR,
    "transactionstatus":transactionstatus,
    "statusText":statusText,
    "hash":Checksum,
    "paymentChannel":"Wowpe"
    }
    try:
        callbackResponseData = payout_webhook_call_back_update(wowpe_payout_callback_request_data,save_api_webhook_logs_table)

        data_status["responseStatus"] = callbackResponseData.get("responseStatus")
        data_status["result"] = callbackResponseData.get("result")
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to get payout call back url data!!"
        return data_status


@paymentgateway_integrations.route("/payout_call_back_url", methods=["POST"])
def payout_call_back_url():
    data_status = {"responseStatus": 0, "result": ""}
    transaction_reference_number = request.form.get("transaction_reference_number","")
    status = request.form.get("status","")
    error_message = request.form.get("error_message","")
    bank_reference_number = request.form.get("bank_reference_number","")
    merchant_reference_number = request.form.get("merchant_reference_number","")
    transaction_date = request.form.get("transaction_date","")
    transaction_amount = request.form.get("transaction_amount","")
    api_key = request.form.get("api_key","")
    hashValue = request.form.get("hash","")

    print(request.form,"(((((((((((((((((((((Accurepay Payout Call Back request.form Response)))))))))))))))))))))")
    print("(((((((((((((((((((((Accurepay Payout Call Back Response)))))))))))))))))))))")
    log_request_data={
        "error_message":error_message,
        "transaction_reference_number":transaction_reference_number,
        "merchant_reference_number":merchant_reference_number,
        "transaction_amount":transaction_amount,
        "transaction_date":transaction_date,
        "bank_reference_number":bank_reference_number,
        "hash":hashValue,
        "status":status,
        "api_key":api_key
        }
    requestData = [log_request_data]
    save_api_webhook_logs_table = save_webhook_logs_data(None,"payout","call_back","payout_call_back_url",None,requestData,"api","")

    try:
        statusText = "PROCESSING"
        transactionstatus=2
        if status=="SUCCESS":
            transactionstatus=1
            statusText="SUCCESS"
        elif status == "FAILED" or status == "FAILURE":
            transactionstatus=0
            statusText="FAILED"
        elif status == "RETURNED_FROM_BENEFICIARY":
            transactionstatus=4
            statusText="REVERSAL"
        else:
            transactionstatus=2
            statusText="PROCESSING"

        accure_payout_callback_request_data={
        "statusCode":"",
        "message":error_message,
        "orderId":transaction_reference_number,
        "pgOrderId":merchant_reference_number,
        "paymentMode":"",
        "amount":transaction_amount,
        "transaction_date":transaction_date,
        "bank_reference_number":bank_reference_number,
        "transactionstatus":transactionstatus,
        "statusText":statusText,
        "hash":hashValue,
        "paymentChannel":"Accurepay",
        "status":status,
        "api_key":api_key
        }
        callbackResponseData = payout_webhook_call_back_update(accure_payout_callback_request_data,save_api_webhook_logs_table)

        data_status["responseStatus"] = callbackResponseData.get("responseStatus")
        data_status["result"] = callbackResponseData.get("result")
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to get payout call back url!!"
        return data_status


@paymentgateway_integrations.route("/fstac_payin_call_back_url", methods=["POST"])
def fstac_payin_call_back_url():
    data_status = {"responseStatus": 0, "result": ""}
    print(request.json,"fstac request.json")
    pgOrderId = request.json.get("transID","")
    payment_method = request.json.get("mop","")
    payment_datetime = request.json.get("tdate","")
    bank_ref_id = request.json.get("utr","")
    response_code = request.json.get("orderStatus","")
    order_id = request.json.get("orderId","")
    message = request.json.get("response","")
    amount = request.json.get("amount","")
    OrderAmount = request.json.get("amount","")
    currency = request.json.get("billCurrency","")
    transaction_id = request.json.get("refId","")
    ref_id = request.json.get("refId","")


    print(request.json)
    print("(((((((((((((((((Fstac Call Back Response Data)))))))))))))))))")
    requestData = [request.json]
    save_api_webhook_logs_table = save_webhook_logs_data(None,"payin","call_back","fstac_payin_call_back_url",None,requestData,"api","")

    if response_code==11:
        return data_status
        
    errorMessage=""
    if response_code == 1:
        transactionstatus=1
        errorMessage = "Success"
    elif response_code==11:
        return data_status
    else:
        transactionstatus=3
        errorMessage="Pending"
        if response_code==2:
            transactionstatus=0
            errorMessage="Failed"
        elif response_code==3 or response_code==7 or response_code==8:
            transactionstatus=4
            errorMessage="Reversal"
        else:
            transactionstatus=3
            errorMessage="Pending"

    payin_callback_request_data={
    "transaction_id":transaction_id,
    "payment_method":payment_method,
    "payment_datetime":payment_datetime,
    "response_code":response_code,
    "response_message":errorMessage,
    "pgOrderId":pgOrderId,
    "client_order_id":order_id,
    "amount":round(float(amount),2),
    "OrderAmount":round(float(OrderAmount),2),
    "currency":currency,
    "description":"",
    "name":"",
    "email":"",
    "phone":"",
    "address_line_1":"",
    "address_line_2":"",
    "city":"",
    "state":"",
    "country":"",
    "zip_code":"",
    "udf1":"",
    "udf2":"",
    "udf3":"",
    "udf4":'',
    "udf5":"",
    "customer_vpa":"",
    "apiMerchantId":"",
    "transactionstatus":transactionstatus,
    "errorMessage":message,
    "paymentChannel":"Fstac",
    "bank_ref_id":bank_ref_id
    }

    try:
        callbackResponseData = payin_webhook_call_back_update(payin_callback_request_data,save_api_webhook_logs_table)

        data_status["responseStatus"] = callbackResponseData.get("responseStatus")
        data_status["result"] = callbackResponseData.get("result")
        return data_status
    except Exception as e:
        print("GETTING ERROR")
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to get pay in call back url!!"
        return data_status
    



@paymentgateway_integrations.route("/lyra_payin_call_back_url", methods=["POST"])
def lyra_payin_call_back_url():
    print("(((Testing pay)))")
    data_status = {"responseStatus": 0, "result": ""}


    response_data = request.json
    print("((((((((((((((((Data))))))))))))))))", response_data)

    transaction_id = response_data["transactions"][0]["uuid"]
    payment_method = response_data["transactions"][0]["family"]
    payment_datetime = response_data["transactions"][0]["date"]
    response_code = response_data["transactions"][0]["status"]
   
   
    order_id = response_data["orderId"]
    amount = response_data["amount"]
    currency = response_data["currency"]
    description = "Payment for order " + order_id
    name = response_data["customer"]["name"]
    email = response_data["customer"]["email"]
    phone = response_data["customer"]["phone"]

    udf2 = response_data["paymentLink"]
    udf3 = "payment"
 
    
    print("(((((((((((((((((Lyra Pay In Call Back Response Data)))))))))))))))))")

    requestData = [
        {
            "transaction_id": transaction_id,
            "payment_method": payment_method,
            "payment_datetime": payment_datetime,
           
            "response_code": response_code,
      
            "order_id": order_id,
            "amount": amount,
            "currency": currency,
            "description": description,
            "name": name,
            "email": email,
            "phone": phone,
            "address_line_1": "",
            "address_line_2": "",
            "city": "",
            "state": "",
            "country": "",
            "zip_code": "",
            "udf1": "",
            "udf2": "",
            "udf3": "",
            "udf4": "",
            "udf5": "",
            "hash": "",
        }
    ]

    print("(((((((((((requestData)))))))))))",requestData)

    save_api_webhook_logs_table = save_webhook_logs_data(None, "payin", "call_back", "lyra_payin_call_back_url", None, requestData, "api", "")

    errorMessage = ""
    if response_code == "ACCEPTED":
        transactionstatus = 1
        errorMessage = "Success"
    else:
        transactionstatus = 3
        errorMessage = "Pending"

    if response_code == "DECLINED":
        transactionstatus = 0
        errorMessage = "Failed"
    elif response_code in [3, 7, 8]:
        transactionstatus = 4
        errorMessage = "Reversal"

   

    lyra_payin_callback_request_data = {
            "transaction_id": transaction_id,
            "payment_method": payment_method,
            "payment_datetime": payment_datetime,
            "response_code": response_code,
            
            "pgOrderId": order_id,
            "client_order_id": order_id,
            "amount": round(float(amount), 2),
            "currency": currency,
            "description": description,
            "name": name,
            "email": email,
            "phone": phone,
            "address_line_1": "",
            "address_line_2": "",
            "city": "",
            "state": "",
            "country": "",
            "zip_code": "",
            "udf1": "",
            "udf2": "",
            "udf3": "",
            "udf4": "",
            "udf5": "",
            "customer_vpa": "",
            "transactionstatus": transactionstatus,
            "errorMessage": errorMessage,
            "hash": "",
            "paymentChannel": "Lyra",
            "bank_ref_id": ""
        }

    callbackUrl = "payin_call_back_url"
    print("_______lyra_payin_callback_request_data_______",lyra_payin_callback_request_data)
    
    try:
        if lyra_payin_callback_request_data: 
            callbackResponseData = payin_webhook_call_back_update(lyra_payin_callback_request_data, save_api_webhook_logs_table)

            data_status["responseStatus"] = callbackResponseData.get("responseStatus")
            data_status["result"] = callbackResponseData.get("result")
        else:
            data_status["result"] = "Payment not successful, no callback data."
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to get pay in call back url!!"
        
        app.logger.debug("Received data for processing: %s", data)    
        return data_status
