<?php
//  app/api/payments/pagomovil/sendpayments.php
    header("Content-Type:application/json");
    include("../../../../settings/dbconn.php");
    include("../../../../settings/utils.php");
    
    //Definicion de variables
    $out = new stdClass();
    // Columna por la cual ordenar
    $orderby = "datecreated";
    // Direccion de ordenamiento
    $orderdir = "ASC";
    // Cantidad de operaciones a validar por proceso
    $maxquantityop = 1;
    // Cantidad de operaciones validadas
    $quantityvalidated = 0;
    // Cantidad maxima de intentos
    $maxfails = 0;
    // Hora que se reinicia el envio
    $hourresetsend = 1;
    
    // Tiempo en el que inicio
    $time_start = new DateTime(); 
    
    // Obtenemos primerito la interfaz
    $bankinterface = getActiveBank($db, 2, 1);
    
    // Validamos cual es el ID
    switch($bankinterface){
        case 0:
            badEnd("204", array("msg"=>"Servicio inactivo, intente más tarde"));
            break;
        case 1:
            break;
        case 2:
            break;
    }
    
    // Limpiamos primero las que no han sido validadas
    $sql = "SELECT * ".
    "       FROM payments_pagomovil ".
    "       WHERE status = 2 ".
    "       AND TIMESTAMP(sendat) <= TIMESTAMP(NOW()) ".
    //"       AND id = 155 ".
    "       ORDER BY ".$orderby." ".$orderdir;
    if (!$resPago=$db->query($sql))
        badEnd("500", array("msg"=>determinateDBError($db)));
        
    for($i = 0; $i < $maxquantityop; $i++){
        $txdata = $resPago->fetch_assoc();
        
        // Finalizamos por si acaso
        if($quantityvalidated >= $maxquantityop || !$txdata){
            $out->msg = "Completado";
    
            header("HTTP/1.1 200");
            echo(json_encode($out));
            die();
        }
        
        // Obtenemos los datos de la cuenta del usuario
        $sql = "SELECT * FROM accounts ".
        "       WHERE id = ".$txdata['accountid'];
        if (!$rs=$db->query($sql))
            badEnd("500", array("a"=>$txdata,"msg"=>determinateDBError($db)));
            
        $accountdata = $rs->fetch_assoc();
        $currencyid = $accountdata['currencyid'];
        $userid = $accountdata['userid'];
        
        // Obtenemos los datos de la cuenta del usuario FIAT
        $sql = "SELECT * FROM accounts ".
        "       WHERE currencyid = 1".
        "       AND userid = ".$userid;
        if (!$rs=$db->query($sql))
            badEnd("500", array("msg"=>determinateDBError($db)));
            
        $accountfiat = $rs->fetch_assoc();
        $accountfiatid = $accountfiat['id'];
        
        // Obtenemos los datos de la moneda
        $sql = "SELECT * ".
        "       FROM currencies ".
        "       WHERE id = ".$currencyid;
        if (!$rs=$db->query($sql))
            badEnd("500", array("msg"=>determinateDBError($db)));
            
        $currency = $rs->fetch_assoc();
        
        // Obtenemos los datos del BS
        $sql = "SELECT * ".
        "       FROM currencies ".
        "       WHERE id = 1";
        if (!$rs=$db->query($sql))
            badEnd("500", array("msg"=>determinateDBError($db)));
            
        $currencyfiat = $rs->fetch_assoc();
        
        // Obtenemos el rate de la moneda para VES para la descripcion
        $rate1 = determinateRate($db, $currencyfiat["id"], $currency['id'], $currencyfiat['decimals']); //se volteó las monedas y se cambiaron los decimals 
        $amountReal = number_format($txdata['amount']*$rate1->number, $currency['decimals'], '.', '');
        $showedAmountVes  = number_format($txdata['amount'], $currencyfiat['decimals'], '.', '');
        
        $txid = '';
        if($txdata['txid'] == null){
            // Consultamos de la vista ya creada con el balance
            $sql = "SELECT * FROM accountbalances WHERE accountid = ".$accountdata['id'];
            if (!$res=$db->query($sql))
                badEnd("500", array("msg"=>determinateDBError($db)));
            
            $balancetx = $res->fetch_assoc();
            
            if(
                number_format($balancetx["balance"], $currency['decimals'], '.', '') <= 0 ||
                number_format($balancetx["balance"], $currency['decimals'], '.', '') < $amountReal
            ){
                insertStatusCanceled($db, $txdata['id'], "Saldo insuficiente", "403");
                $time_end_bad = new DateTime();
    
                $interval = $time_start->diff($time_end_bad);
            
                setAudit($db, "CRIPTO PAGOS", "", "APP", "Se rechazó  el cripto pago ".$txdata['id'].". Duración: ".$interval->format('%h').":".$interval->format('%i').":".$interval->format('%s') );
            }
            
            //Obtenemos el nivel de usuario para determinar su fee
            $sql = "SELECT * FROM users WHERE id = ".$userid;
            if (!$rs=$db->query($sql))
                badEnd("500", array("msg"=>determinateDBError($db)));
            
            //Guardamos la data de la cuenta
            $userdata = $rs->fetch_assoc();
            
            $level = 1;
            if($userdata["level"] == 0){
                $level = 1;
            }else{
                $level = $userdata["level"];
            }
            
            //Consultamos la cuenta que tiene los saldos de los pago moviles
            $sql = "SELECT * FROM accounts ".
            "       WHERE userid = -1".
            "       AND currencyid = ".$currency["id"].
            "       AND paymentmethodid = -7";
            if (!$rs=$db->query($sql))
                badEnd("500", array("msg"=>determinateDBError($db)));
            
            //Guardamos la data de la cuenta AFX
            $afxdatabalances = $rs->fetch_assoc();
            
            //Consultamos la cuenta que tiene la moneda del retiro de AFX
            $sql = "SELECT * FROM accounts ".
            "       WHERE userid = -1".
            "       AND currencyid = ".$currency["id"].
            "       AND paymentmethodid = -6";
            if (!$rs=$db->query($sql))
                badEnd("500", array("msg"=>determinateDBError($db)));
            
            //Guardamos la data de la cuenta AFX
            $afxdata = $rs->fetch_assoc();
            
            // Buscamos la cuenta de comision de AFX para retiros
            $sql = "SELECT * FROM accounts ".
            "       WHERE userid = -1".
            "       AND currencyid = ".$currency["id"].
            "       AND paymentmethodid = -2";
            if (!$rs=$db->query($sql))
                badEnd("500", array("msg"=>determinateDBError($db)));
            
            //Guardamos la data de la cuenta AFX
            $afxdatawithdrawal = $rs->fetch_assoc();
            
            //Obtenemos el fee de cada operacion por la moneda de la cuenta
            $sql = "SELECT * FROM cmspreffees WHERE currencyid = ".$currencyfiat["id"].
            "       AND levelid = ".$level.
            "       AND usertype = ".$userdata["type"];
            if (!$rs=$db->query($sql))
                badEnd("500", array("msg"=>determinateDBError($db)));
            
            //Guardamos la data de la cuenta
            $fee = $rs->fetch_assoc();
            
            //Validamos que el monto sea mas que el minimo aceptado para transferencia
            if(validateMin(1,$userdata["type"], 3, $db, $showedAmountVes)){
                insertStatusCanceled($db, $txdata['id'], "Monto m&iacute;nimo autorizado: ".numberFormatt($fee['minwithdraw'], $currency['decimals']), "403");
                $time_end_bad = new DateTime();
    
                $interval = $time_start->diff($time_end_bad);
            
                setAudit($db, "CRIPTO PAGOS", "", "APP", "Se rechazó  el cripto pago ".$txdata['id'].". Duración: ".$interval->format('%h').":".$interval->format('%i').":".$interval->format('%s') );
            }
            
            // SACAMOS LA COMISION PARA PAGO MOVIL PRIMERO
            $feepagomovil = 0;
            if($fee["pagomovilpct"] != null){
                // Obtenemos el exonerado para depositos si posee
                $sql = "SELECT IF(exonerated IS NULL, 0, exonerated) AS exonerated FROM userportfolioprefs ".
                "       WHERE currencyid = ".$currencyfiat["id"].
                "       AND userid = ".$userdata['id'].
                "       AND preffeesfield = 'pagomovilpct'";
                if (!$res=$db->query($sql))
                    badEnd("500", array("msg"=>determinateDBError($db)));
                
                $userExg = $res->fetch_assoc();
                
                $feepagomovil = number_format((($fee["pagomovilpct"] - ($fee["pagomovilpct"]/100 * $userExg['exonerated']) )*$amountReal)/100, $currency['decimals'], '.', '');
            }
            
            // SACAMOS LA COMISION PARA RETIRO PORCENTAJE FIAT
            $sql = "SELECT * FROM cmspreffees WHERE currencyid = ".$currencyfiat["id"].
            "       AND levelid = ".$level.
            "       AND usertype = ".$userdata["type"];
            if (!$rs=$db->query($sql))
                badEnd("500", array("msg"=>determinateDBError($db)));
                
            //Guardamos la data de la cuenta
            $fee = $rs->fetch_assoc();
                
            $feewithdrawal = 0;
            if($fee["pctfeewithdrawals"] != null || $fee["nmlfeewithdrawals"] != null ){
                if($fee["pctfeewithdrawals"] == null){
                    
                    // Obtenemos el exonerado para depositos si podee
                    $sql = "SELECT IF(exonerated IS NULL, 0, exonerated) AS exonerated FROM userportfolioprefs ".
                    "       WHERE currencyid = ".$currencyfiat["id"].
                    "       AND userid = ".$userdata['id'].
                    "       AND preffeesfield = 'nmlfeewithdrawals'";
                    if (!$res=$db->query($sql))
                        badEnd("500", array("msg"=>determinateDBError($db)));
                    
                    $userExg = $res->fetch_assoc();
                    
                    // Cambiamos a la moneda que es
                    $userExgRated = number_format($userExg['exonerated']*$rate1->number, $currency['decimals'], '.', '');
                    $feeRated = number_format($fee["nmlfeewithdrawals"]*$rate1->number, $currency['decimals'], '.', '');
            
                    $feewithdrawal = number_format($amountReal - ($amountReal - ($feeRated - ($feeRated/100 * $userExgRated) )), $currency['decimals'], '.', '');
                }else{
                    
                    // Obtenemos el exonerado para depositos si podee
                    $sql = "SELECT IF(exonerated IS NULL, 0, exonerated) AS exonerated FROM userportfolioprefs ".
                    "       WHERE currencyid = ".$currencyfiat["id"].
                    "       AND userid = ".$userdata['id'].
                    "       AND preffeesfield = 'pctfeewithdrawals'";
                    if (!$res=$db->query($sql))
                        badEnd("500", array("msg"=>determinateDBError($db)));
                    
                    $userExg = $res->fetch_assoc();
                    
                    $feewithdrawal = number_format((($fee["pctfeewithdrawals"] - ($fee["pctfeewithdrawals"]/100 * $userExg['exonerated']) )*$amountReal)/100, $currency['decimals'], '.', '');
                }
            }
            
            // AHORA VEMOS SI TIENE SUFICIENTE SALDO CON LAS COMISIONES
            if(
                number_format($balancetx["balance"], $currency['decimals'], '.', '') < number_format($amountReal + $feewithdrawal + $feepagomovil, $currency['decimals'], '.', '')
            ){
                insertStatusCanceled($db, $txdata['id'], "Saldo insuficiente", "403");
                $time_end_bad = new DateTime();
    
                $interval = $time_start->diff($time_end_bad);
            
                setAudit($db, "CRIPTO PAGOS", "", "APP", "Se rechazó  el cripto pago ".$txdata['id'].". Duración: ".$interval->format('%h').":".$interval->format('%i').":".$interval->format('%s') );
            }
            
            // validamos el monto diario
            
            // Validfamos el maximo
            //Consultamos los datos maximos
            $sql = "SELECT cmspreffees.* ".
            "       FROM cmspreffees, users, accounts ".
            "       WHERE cmspreffees.levelid = users.level ".
            "       AND cmspreffees.usertype = users.type ".
            "       AND users.id = ".$userid.
            "       AND accounts.userid = users.id ".
            "       AND accounts.id = ".$accountfiatid.
            "       AND accounts.currencyid = cmspreffees.currencyid";
            if (!$rs = $db->query($sql)){
                badEnd("500", array("msg"=>$db->error));
            }
            
            $maxRows = $rs->fetch_assoc();
            
            // Validamos el monto diario criptopagos
            //Consultamos los datos maximos para pago movil
            $sql = "SELECT cmspreffees.* ".
            "       FROM cmspreffees, users, accounts ".
            "       WHERE cmspreffees.levelid = users.level ".
            "       AND cmspreffees.usertype = users.type ".
            "       AND users.id = ".$userid.
            "       AND accounts.userid = users.id ".
            "       AND accounts.id = ".$accountid.
            "       AND cmspreffees.currencyid = 1";
            if (!$rs = $db->query($sql)){
                badEnd("500", array("msg"=>$db->error));
            }
            
            $rowCriptopagos = $rs->fetch_assoc();
        
            // Sumamos los ves de los criptopagos
            $sql = "SELECT IF(SUM(p.amounttx) IS NULL, 0, SUM(p.amounttx)) AS qty
               FROM pagomovildetails p, accounts acc, transactions tx, users usr
               WHERE tx.accountid = acc.id 
               AND usr.id = ".$accountfiatid."
               AND acc.userid = usr.id
               AND tx.id = p.transactionid ".
            "       AND DAY(tx.datecreated) = DAY(NOW()) AND MONTH(tx.datecreated) = MONTH(NOW()) AND YEAR(tx.datecreated) = YEAR(NOW())";
            if (!$res = $db->query($sql)){
                badEnd("500", array("msg"=>$db->error));
            }
            
            $movementData = $res->fetch_assoc();
            
            //Validamos si el monto total + monto operacion actual no excede el limite DIARIO
            if((abs($movementData["qty"]) + $showedAmountVes) >= $rowCriptopagos["pagomovilmaxsend"]){
                // Obtenemos la moneda de la cuenta
                $sql = "SELECT currencies.symbol AS symbol, currencies.decimals AS decimals ".
                "       FROM currencies, accounts".
                "       WHERE accounts.id = ".$accountfiatid.
                "       AND accounts.currencyid = currencies.id";
                if (!$res = $db->query($sql)){
                    badEnd("500", array("msg"=>determinateDBError($db)));
                }
            
                $currdata = $res->fetch_assoc();
            
                createAlert($db, 2, $userid, 'Criptopago, '.$currdata['symbol']." ".numberFormatt($showedAmountVes, $currdata['decimals']));
            }
            
            //Validamos primero el monto de las operaciones
            $sql = "SELECT SUM(withdrawals.amount) AS qty ".
            "       FROM withdrawals, transactions t, accounts, users ".
            "       WHERE t.id = withdrawals.transactionid ".
            "       AND t.accountid = accounts.id ".
            "       AND accounts.userid = users.id ".
            "       AND accounts.id = ".$accountfiatid.
            "       AND (withdrawals.valid IS NOT NULL ".
            "       OR withdrawals.valid IS NULL) ".
            "       AND withdrawals.rejected IS NULL".
            "       AND MONTH(t.datecreated) = MONTH(NOW())".
            "       AND YEAR(t.datecreated) = YEAR(NOW())";
            if (!$res = $db->query($sql)){
                badEnd("500", array("msg"=>$db->error));
            }
        
            $movementData = $res->fetch_assoc();
            
            //Validamos si el monto total + monto operacion actual no excede el limite
            if((abs($movementData["qty"]) + $showedAmountVes) > $maxRows["maxamountmonthlyopwithdrawals"]){
                // Obtenemos la moneda de la cuenta
                $sql = "SELECT currencies.symbol AS symbol, currencies.decimals AS decimals ".
                "       FROM currencies, accounts".
                "       WHERE accounts.id = ".$accountfiatid.
                "       AND accounts.currencyid = currencies.id";
                if (!$res = $db->query($sql)){
                    badEnd("500", array("msg"=>determinateDBError($db)));
                }
            
                $currdata = $res->fetch_assoc();
            
                createAlert($db, 2, $userid, 'Retiro, '.$currdata['symbol']." ".numberFormatt($showedAmountVes, $currdata['decimals']));
                
                insertStatusCanceled($db, $txdata['id'], "Monto maximo superado", "403");
                $time_end_bad = new DateTime();
    
                $interval = $time_start->diff($time_end_bad);
            
                setAudit($db, "CRIPTO PAGOS", "", "APP", "Se rechazó  el cripto pago ".$txdata['id'].". Duración: ".$interval->format('%h').":".$interval->format('%i').":".$interval->format('%s') );
            }
            
            //Validamos la cantidad de operaciones
            $sql = "SELECT COUNT(withdrawals.amount) AS qty ".
            "       FROM withdrawals, transactions t, accounts, users ".
            "       WHERE t.id = withdrawals.transactionid ".
            "       AND t.accountid = accounts.id ".
            "       AND accounts.userid = users.id ".
            "       AND accounts.id = ".$accountfiatid.
            "       AND (withdrawals.valid IS NOT NULL ".
            "       OR withdrawals.valid IS NULL) ".
            "       AND withdrawals.rejected IS NULL".
            "       AND MONTH(t.datecreated) = MONTH(NOW())".
            "       AND YEAR(t.datecreated) = YEAR(NOW())";
            if (!$res = $db->query($sql)){
                badEnd("500", array("msg"=>$db->error));
            }
        
            $movementData = $res->fetch_assoc();
            
            //Validamos si el monto total + monto operacion actual no excede el limite
            if($movementData["qty"] + 1 > $maxRows["maxqtymonthlyopwithdrawals"]){
                // Obtenemos la moneda de la cuenta
                $sql = "SELECT currencies.symbol AS symbol, currencies.decimals AS decimals ".
                "       FROM currencies, accounts".
                "       WHERE accounts.id = ".$accountfiatid.
                "       AND accounts.currencyid = currencies.id";
                if (!$res = $db->query($sql)){
                    badEnd("500", array("msg"=>determinateDBError($db)));
                }
            
                $currdata = $res->fetch_assoc();
            
                createAlert($db, 2, $userid, 'Retiro, '.$currdata['symbol']." ".($movementData["qty"] + 1)." operaciones");
                
                insertStatusCanceled($db, $txdata['id'], "Operaciones maximas superadas", "403");
                $time_end_bad = new DateTime();
    
                $interval = $time_start->diff($time_end_bad);
            
                setAudit($db, "CRIPTO PAGOS", "", "APP", "Se rechazó  el cripto pago ".$txdata['id'].". Duración: ".$interval->format('%h').":".$interval->format('%i').":".$interval->format('%s') );
            }
            
            //insertamos el retiro desde el origen
            $sql = "INSERT INTO transactions".
            "       (".
            "       datecreated, ".
            "       dsc, ".
            "       accountid, ".
            "       accountorigin, ".
            "       amount, ".
            "       amountghost, ".
            "       accountdestination, ".
            "       validator, ".
            "       validthru, ".
            "       paypending ".
            "       )".
            "       VALUES(".
            "       NOW(), ".
            "       'Venta de ".$currency['symbol']." por servicio Cripto Pago de ".$showedAmountVes." ".$currencyfiat['symbol']."', ".
            "       ".$accountdata["id"].", ".
            "       NULL, ".
            "       -".$amountReal.", ".
            "       0, ".
            "       ".$afxdatabalances['id'].", ".
            "       NULL, ".
            "       NULL, ".
            "       0".
            "       )";
            if (!$db->query($sql)){
                $error = $db->error.$sql;
                badEnd("500", array("msg"=>$error));
            }
            
            //Guardamos el id de la transaccion
            $txid = (int)$db->insert_id;
            
            //Le colocamos el primer movimiento el txid
            $sql = "UPDATE transactions SET".
            "       txid= ".$txid.
            "       WHERE id = ".$txid;
            if (!$db->query($sql)){
                $error = $db->error.$sql;
                badEnd("500", array("msg"=>$error));
            }
            
            //insertamos el fee del retiro del origen pago movil y sumamos a la comision de pago movil
            $sql = "INSERT INTO transactions".
            "       (".
            "       datecreated, ".
            "       dsc, ".
            "       accountid, ".
            "       txid, ".
            "       accountorigin, ".
            "       amount, ".
            "       amountghost, ".
            "       accountdestination, ".
            "       validator, ".
            "       validthru, ".
            "       paypending ".
            "       )".
            "       VALUES(".
            "       NOW(), ".
            "       'Comisión de Servicio Cripto Pago de ".$showedAmountVes." ".$currencyfiat['symbol']."', ".
            "       ".$accountdata["id"].", ".
            "       ".$txid.", ".
            "       NULL, ".
            "       -".$feepagomovil.", ".
            "       0, ".
            "       ".$afxdata['id'].", ".
            "       NULL, ".
            "       NULL, ".
            "       0".
            "       )";
            if (!$db->query($sql)){
                $error = $db->error.$sql;
                badEnd("500", array("msg"=>$error));
            }
            
            //insertamos el fee del retiro del origen comision de retiro a la cuenta de comision retiro
            $sql = "INSERT INTO transactions".
            "       (".
            "       datecreated, ".
            "       dsc, ".
            "       accountid, ".
            "       txid, ".
            "       accountorigin, ".
            "       amount, ".
            "       amountghost, ".
            "       accountdestination, ".
            "       validator, ".
            "       validthru, ".
            "       paypending ".
            "       )".
            "       VALUES(".
            "       NOW(), ".
            "       'Comisión de Retiro Cripto Pago de ".$showedAmountVes." ".$currencyfiat['symbol']."', ".
            "       ".$accountdata["id"].", ".
            "       ".$txid.", ".
            "       NULL, ".
            "       -".$feewithdrawal.", ".
            "       0, ".
            "       ".$afxdatawithdrawal['id'].", ".
            "       NULL, ".
            "       NULL, ".
            "       0".
            "       )";
            if (!$db->query($sql)){
                $error = $db->error.$sql;
                badEnd("500", array("msg"=>$error));
            }
            
            // Ingresamos el dinero de AFX
            $sql = "INSERT INTO transactions".
            "       (".
            "       datecreated, ".
            "       dsc, ".
            "       accountid, ".
            "       txid, ".
            "       accountorigin, ".
            "       amount, ".
            "       amountghost, ".
            "       accountdestination, ".
            "       validator, ".
            "       validthru, ".
            "       paypending ".
            "       )".
            "       VALUES(".
            "       NOW(), ".
            "       'Venta de ".$currency['symbol']." por servicio Cripto Pago de ".$showedAmountVes." ".$currencyfiat['symbol']."', ".
            "       ".$afxdatabalances["id"].", ".
            "       ".$txid.", ".
            "       ".$accountdata["id"].", ".
            "       ".$amountReal.", ".
            "       0, ".
            "       ".$afxdatabalances['id'].", ".
            "       NULL, ".
            "       NULL, ".
            "       0".
            "       )";
            if (!$db->query($sql)){
                $error = $db->error.$sql;
                badEnd("500", array("msg"=>$error));
            }
            
            // Ingresamos la comision de pago movil que recibe AFX
            $sql = "INSERT INTO transactions".
            "       (".
            "       datecreated, ".
            "       dsc, ".
            "       accountid, ".
            "       txid, ".
            "       accountorigin, ".
            "       amount, ".
            "       amountghost, ".
            "       accountdestination, ".
            "       validator, ".
            "       validthru, ".
            "       paypending ".
            "       )".
            "       VALUES(".
            "       NOW(), ".
            "       'Comisión de Servicio Cripto Pago de ".$showedAmountVes." ".$currencyfiat['symbol']."', ".
            "       ".$afxdata["id"].", ".
            "       ".$txid.", ".
            "       ".$accountdata["id"].", ".
            "       ".$feepagomovil.", ".
            "       0, ".
            "       ".$afxdata['id'].", ".
            "       NULL, ".
            "       NULL, ".
            "       0".
            "       )";
            if (!$db->query($sql)){
                $error = $db->error.$sql;
                badEnd("500", array("msg"=>$error));
            }
            
            // Ingresamos la comision de retiro que recibe AFX
            $sql = "INSERT INTO transactions".
            "       (".
            "       datecreated, ".
            "       dsc, ".
            "       accountid, ".
            "       txid, ".
            "       accountorigin, ".
            "       amount, ".
            "       amountghost, ".
            "       accountdestination, ".
            "       validator, ".
            "       validthru, ".
            "       paypending ".
            "       )".
            "       VALUES(".
            "       NOW(), ".
            "       'Comisión de Servicio Cripto Pago de ".$showedAmountVes." ".$currencyfiat['symbol']."', ".
            "       ".$afxdatawithdrawal["id"].", ".
            "       ".$txid.", ".
            "       ".$accountdata["id"].", ".
            "       ".$feewithdrawal.", ".
            "       0, ".
            "       ".$afxdatawithdrawal['id'].", ".
            "       NULL, ".
            "       NULL, ".
            "       0".
            "       )";
            if (!$db->query($sql)){
                $error = $db->error.$sql;
                badEnd("500", array("msg"=>$error));
            }
        } else {
            $txid = $txdata['txid'];
        }
        
        // Traemos el listado de los bancos
        $reference = '';
        // Necesitamos
        $ci = $txdata['recipientrif'];
        $phone = $txdata['recipientphone'];
        $amount = $txdata['amount'];
        
        // Buscamos la config de los bancos
        $sql = "SELECT pagomovilbanks ".
        "       FROM cmspreferences";
        if (!$res=$db->query($sql))
            badEnd("500", array("msg"=>determinateDBError($db)));
            
        $rowConfig = $res->fetch_assoc();
        
        // Nos traemos los objetos
        $banksConfig = json_decode($rowConfig['pagomovilbanks'], true);
        $banksConfig = $banksConfig['banks'];
        
        // Validamos que las interfaz fue la usada
        $bankInterface = null;
        foreach($banksConfig as $bank){
            if($bank['id'] == $bankinterface){
                $bankInterface = $bank;
            }
        }
        
        $words = explode(" ",$bankInterface['name']);
        $initialsBank = "";
        
        foreach ($words as $w) {
          $initialsBank .= mb_substr($w, 0, 1);
        }
            
        switch($bankinterface){
            case 0:
                badEnd("204", array("msg"=>determinateMsgFail(array(
                    "esp"=>'Servicio inactivo, intente más tarde',
                    "eng"=>'Service down, please try again later'), $lang, "Servicio inactivo, intente más tarde")));
                break;
            case 1:
                // EJECUTAMOS EL PAGO MOVIL
                $nonce = generateNonce();
                
                // Llamamos a la api primerito
                $request = array(
                    'banco'=>$bankid,
                    'idBeneficiario'=>$ci,
                    'telefono'=>$phone,
                    'monto'=>(float)number_format($amount, $currency['decimals'], '.', ''),
                    'motivo'=>'Retiro AFX',
                    'canal'=>'23',
                    'id-externo'=>$id
                );
            
               $headers = array('Content-Type:application/json', 
                    "api-key: $BP_C2P_KEY", 
                    "api-signature: ".
                    (
                        generateApiSignature("/".$BP_VERSION_P2P."/pagos/p2p".$nonce.json_encode($request),$BP_C2P_KEY_SECRET)
                    ),
                    "nonce: ".$nonce,
                );
                
                // obtenemos respuesta
                $rest = queryApiBP($BP_URL_QA, "pagos/p2p", $BP_VERSION_P2P, "POST", $headers, $request);
            
                // IMPORTANTE CAMBIAR LA VALIDACION DE LA APIKEY A004
                if(($rest['bodyres']->referencia == null || $rest['bodyres']->referencia == '') && $rest['httpres'] != 200 && $rest['httpres'] != 201 /*&& $rest['headerres']['codigorespuesta'] !== 'A004'*/){
                    $msg_esp = "";
                    $msg_eng = "";
                    $common = 0;
                    
                    switch($rest['headerres']['codigorespuesta']){
                        case 'E028':
                            $msg_esp = "El código de operaciones ingresado es inválido. Por favor intente de nuevo";
                            $msg_eng = "The operations code is invalid. Please try again";
                            $common = 1;
                            break;
                        case 'E010':
                            $msg_esp = "Monto no válido";
                            $msg_eng = "Invalid amount";
                            $common = 1;
                            break;
                        case 'E012':
                            $msg_esp = "Teléfono no habilitado para pagar";
                            $msg_eng = "Phone not enabled to pay";
                            $common = 1;
                            break;
                        case 'E013':
                            $msg_esp = "Excede cantidad de pagos diarios";
                            $msg_eng = "Exceeds amount of daily payments";
                            $common = 1;
                            break;
                        case 'E014':
                            $msg_esp = "Excede monto total de pagos diarios";
                            $msg_eng = "Exceeds total amount of daily payments";
                            $common = 1;
                            break;
                        case 'E015':
                            $msg_esp = "Excede monto máximo para un pago";
                            $msg_eng = "Exceeds maximum amount for a payment";
                            $common = 1;
                            break;
                        case 'E016':
                            $msg_esp = "Excede cantidad de pagos diarios";
                            $msg_eng = "Exceeds amount of daily payments";
                            $common = 1;
                            break;
                        case 'E017':
                            $msg_esp = "Excede monto total de pagos diarios";
                            $msg_eng = "Exceeds total amount of daily payments";
                            $common = 1;
                            break;
                        case 'E018':
                            $msg_esp = "Error en número de banco";
                            $msg_eng = "Bank number error";
                            $common = 1;
                            break;
                        case 'E021':
                            $msg_esp = "Teléfono receptor no registrado";
                            $msg_eng = "Receiving phone not registered";
                            $common = 1;
                            break;
                        case 'E022':
                            $msg_esp = "Teléfono receptor no acepta pagos";
                            $msg_eng = "Receiving phone does not accept payments";
                            $common = 1;
                            break;
                        case 'E023':
                            $msg_esp = "Identificación del beneficiario no coincide";
                            $msg_eng = "Beneficiary ID does not match";
                            $common = 1;
                            break;
                        case 'E024':
                            $msg_esp = "Cliente bloqueado";
                            $msg_eng = "Client blocked";
                            $common = 1;
                            break;
                        case 'E030':
                            $msg_esp = "Banco no activo en pago móvil";
                            $msg_eng = "Bank not active in mobile payment";
                            $common = 1;
                            break;
                        case 'A001':
                            $msg_esp = "Firma digital inválida";
                            $msg_eng = "Invalid digital signature";
                            $common = 1;
                            break;
                        case 'A004':
                            $msg_esp = "Api-key invalida o revocado";
                            $msg_eng = "Api-key invalid";
                            $common = 1;
                            break;
                        default:
                            $msg_esp = $rest['headerres']['descripcioncliente'];
                            $msg_eng = $rest['headerres']['descripcioncliente'];
                            $common = 0;
                    }
                    
                    // Si es 1 el error lo conocemos
                    if($common == 1){
                        // Cambiamos el status y todo del pagomovil
                        // Si llegamos aqui esta todo bien, guardamos lo que llevamos
                        $sql = "UPDATE payments_pagomovil SET ".
                        "       txid = ".$txid.", ".
                        "       status = 4, ".
                        "       ref = '".$msg_esp." - ".$initialsBank." - ".$rest['headerres']['codigorespuesta']."'".
                        "       WHERE id = ".$txdata['id'];
                        if (!$db->query($sql))
                            badEnd("500", array("msg"=>determinateDBError($db)));
                            
                        // Revertimos el movimiento
                        $sql = "UPDATE transactions SET ".
                        "       amountghost = amount + amountghost, ".
                        "       amount = 0 ".
                        "       WHERE id = ".$txid.
                        "       OR txid = ".$txid;
                        if (!$db->query($sql))
                            badEnd("500", array("msg"=>determinateDBError($db)));
                            
                        $time_end_bad = new DateTime();
    
                        $interval = $time_start->diff($time_end_bad);
                        
                        setAudit($db, "CRIPTO PAGOS", "", "APP", "Se rechazó  el cripto pago ".$txdata['id'].". Duración: ".$interval->format('%h').":".$interval->format('%i').":".$interval->format('%s') );
                        
                    } else {
                        // Cualquier otra cosa no sabemos que es
                        
                        // Validamos los intentos que lleva, si es mayor o igual al maximo cancelamos el pagomovil
                        if($txdata['retry'] >= $maxfails){
                            $sql = "UPDATE payments_pagomovil SET ".
                            "       txid = ".$txid.", ".
                            "       status = 4, ".
                            "       ref = 'Transacción rechazada - ".$msg_esp." - ".$initialsBank." - ".$rest['headerres']['codigorespuesta']."'".
                            "       WHERE id = ".$txdata['id'];
                            if (!$db->query($sql))
                                badEnd("500", array("msg"=>determinateDBError($db)));
                                
                            // Revertimos el movimiento
                            $sql = "UPDATE transactions SET ".
                            "       amountghost = amount + amountghost, ".
                            "       amount = 0 ".
                            "       WHERE id = ".$txid.
                            "       OR txid = ".$txid;
                            if (!$db->query($sql))
                                badEnd("500", array("msg"=>determinateDBError($db)));
                                
                            $time_end_bad = new DateTime();
    
                            $interval = $time_start->diff($time_end_bad);
                            
                            setAudit($db, "CRIPTO PAGOS", "", "APP", "Se rechazó  el cripto pago ".$txdata['id'].". Duración: ".$interval->format('%h').":".$interval->format('%i').":".$interval->format('%s') );
                        } else {
                            // si no paso el maximo, solo actualizamos la hora de envio y los intentos
                            $sql = "UPDATE payments_pagomovil SET ".
                            "       txid = ".$txid.", ".
                            "       retry = retry + 1, ".
                            "       sendat = DATE_ADD(sendat, INTERVAL ".$hourresetsend." HOUR)".
                            "       WHERE id = ".$txdata['id'];
                            if (!$db->query($sql))
                                badEnd("500", array("msg"=>determinateDBError($db)));
                        }
                        
                    }
                    
                    continue 2;
                }
                
                if($rest['headerres']['codigorespuesta'] == '0084'){
                    $reference = '0000';
                    // QUITAR A004 CUANDO SE SOLUCIONE LO DE LA APIKEY
                }else{
                    $reference = $rest['bodyres']->numeroReferencia;
                }
            
                break;
            case 2:
                // Llamamos a la api primerito
                $request = array(
                    'usuario'=>$rifafxAPI, // Usuario
                    'cedula_pagador'=>$rifafxAPI,
                    'telefono_pagador'=>intval("58".$BA_phoneAFX),
                    'tipo_cuenta'=> '0001',
                    'bco_benef'=>$txdata['bankcode'],
                    'cedula_benef'=>$ci,
                    'telefono_benef'=>intval("58".$phone),
                    'monto'=>number_format($amount, $currencydata['decimals'], ',', ''),
                    'motivo'=>'Retiro AFX',
                    'area_origen'=>'01',
                );
                
                // Consultamos la api de banco activo
                $headers = array('Content-Type:application/json','apikey: '.$BA_API_KEY);
                $rest = queryApiBA($BA_URL_QA."pago/p2p/1.0.0/p2p", "POST", $headers, $request);
                
                if(($rest['bodyres']->nroReferencia == null || $rest['bodyres']->nroReferencia == '') && $rest['httpres'] != 200 && $rest['httpres'] != 201){
                    
                    $msgs = validateErrorBancoActivo($rest['bodyres']->code, $rest['bodyres']->descripcion, $rest['bodyres']->descripcion);
                    $msg_esp = $msgs->msg_esp;
                    $msg_eng = $msgs->msg_eng;
                    $common = $msgs->common;
                    
                    // Si es 1 el error lo conocemos
                    if($common == 1){
                        // Cambiamos el status y todo del pagomovil
                        // Si llegamos aqui esta todo bien, guardamos lo que llevamos
                        $sql = "UPDATE payments_pagomovil SET ".
                        "       txid = ".$txid.", ".
                        "       status = 4, ".
                        "       ref = '".$msg_esp." - ".$initialsBank." - ".$rest['bodyres']->code."'".
                        "       WHERE id = ".$txdata['id'];
                        if (!$db->query($sql))
                            badEnd("500", array("msg"=>determinateDBError($db)));
                            
                        // Revertimos el movimiento
                        $sql = "UPDATE transactions SET ".
                        "       amountghost = amount + amountghost, ".
                        "       amount = 0 ".
                        "       WHERE id = ".$txid.
                        "       OR txid = ".$txid;
                        if (!$db->query($sql))
                            badEnd("500", array("msg"=>determinateDBError($db)));
                            
                        $time_end_bad = new DateTime();
    
                        $interval = $time_start->diff($time_end_bad);
                        
                        setAudit($db, "CRIPTO PAGOS", "", "APP", "Se rechazó  el cripto pago ".$txdata['id'].". Duración: ".$interval->format('%h').":".$interval->format('%i').":".$interval->format('%s') );
                        
                    } else {
                        // Cualquier otra cosa no sabemos que es
                        
                        // Validamos los intentos que lleva, si es mayor o igual al maximo cancelamos el pagomovil
                        if($txdata['retry'] >= $maxfails){
                            $sql = "UPDATE payments_pagomovil SET ".
                            "       txid = ".$txid.", ".
                            "       status = 4, ".
                            "       ref = 'Transacción rechazada - ".$msg_esp." - ".$initialsBank." - ".$rest['bodyres']->code."'".
                            "       WHERE id = ".$txdata['id'];
                            if (!$db->query($sql))
                                badEnd("500", array("msg"=>determinateDBError($db)));
                                
                            // Revertimos el movimiento
                            $sql = "UPDATE transactions SET ".
                            "       amountghost = amount + amountghost, ".
                            "       amount = 0 ".
                            "       WHERE id = ".$txid.
                            "       OR txid = ".$txid;
                            if (!$db->query($sql))
                                badEnd("500", array("msg"=>determinateDBError($db)));
                                
                            $time_end_bad = new DateTime();
    
                            $interval = $time_start->diff($time_end_bad);
                            
                            setAudit($db, "CRIPTO PAGOS", "", "APP", "Se rechazó  el cripto pago ".$txdata['id'].". Duración: ".$interval->format('%h').":".$interval->format('%i').":".$interval->format('%s') );
                        } else {
                            // si no paso el maximo, solo actualizamos la hora de envio y los intentos
                            $sql = "UPDATE payments_pagomovil SET ".
                            "       txid = ".$txid.", ".
                            "       retry = retry + 1, ".
                            "       sendat = DATE_ADD(sendat, INTERVAL ".$hourresetsend." HOUR)".
                            "       WHERE id = ".$txdata['id'];
                            if (!$db->query($sql))
                                badEnd("500", array("msg"=>determinateDBError($db)));
                        }
                        
                    }
                    
                    continue 2;
                }
                
                $reference = $rest['bodyres']->nroReferencia;
                
            break;
        }
        
        $quantityvalidated++;
        
        // Si llegamos aqui esta todo bien, guardamos lo que llevamos
        $sql = "UPDATE payments_pagomovil SET ".
        "       txid = ".$txid.", ".
        "       status = 3, ".
        "       sentat = NOW(), ".
        "       ref = '".$reference."'".
        "       WHERE id = ".$txdata['id'];
        if (!$db->query($sql))
            badEnd("500", array("msg"=>determinateDBError($db)));
            
        // Insertamos el movimiento en la tabla de pago moviles
        $sql = "INSERT INTO pagomovildetails ".
        "       (".
        "           transactionid, ".
        "           bankname, ".
        "           docid, ".
        "           phone, ".
        "           notes, ".
        "           amounttx, ".
        "           currencytx, ".
        "           ref, ".
        "           pagomovilbankid ".
        "       ) ".
        "       VALUES ".
        "       (".
        "           ".$txid.", ".
        "           '".$txdata['bankname']."', ".
        "           '".$ci."', ".
        "           '".$phone."', ".
        "           '".$txdata['note']."', ".
        "           ".$amount.", ".
        "           ".$currencyfiat['id'].", ".
        "           '".$reference."', ".
        "           ".$bankinterface." ".
        "       )";
        if (!$db->query($sql))
            badEnd("500", array("msg"=>determinateDBError($db)));
            
        $time_end_good = new DateTime();
    
        $interval = $time_start->diff($time_end_good);
        
        setAudit($db, "CRIPTO PAGOS", "", "APP", "Se aprobó el cripto pago ".$txdata['id'].". Duración: ".$interval->format('%h').":".$interval->format('%i').":".$interval->format('%s') );
    }
    
    $out->msg = "Completado";
    
    $time_end = new DateTime();
    
    $interval = $time_start->diff($time_end);
    
    setAudit($db, "CRIPTO PAGOS", "", "CMS", "Se ejecutaron ".$maxquantityop." transacciones y ".$quantityvalidated." fueron exitosas. Duración: ".$interval->format('%h').":".$interval->format('%i').":".$interval->format('%s') );
    
    header("HTTP/1.1 200");
    echo(json_encode($out));
    die();
    
    function insertStatusCanceled($db, $id, $msg, $code, $txid = '') {
        $sql = "UPDATE payments_pagomovil SET ".
        "       ".($txid ? " txid = ".$txid.", " : "").
        "       status = 4, ".
        "       ref = '".$msg."'".
        "       WHERE id = ".$id;
        if (!$db->query($sql))
            badEnd("500", array("msg"=>determinateDBError($db)));
                        
        if($txid){
            // Revertimos el movimiento
            $sql = "UPDATE transactions SET ".
            "       amountghost = amount + amountghost, ".
            "       amount = 0 ".
            "       WHERE id = ".$txid.
            "       OR txid = ".$txid;
            if (!$db->query($sql))
                badEnd("500", array("msg"=>determinateDBError($db)));
        }
        
        badEnd($code, array("msg"=>$msg));
    }
?>