kodun devamı
    public static function processPayPal()
    {
        // Amount user would like to deposit to account balance
        $price = Request::post('price', true);
        $paypalsettings = self::paypalsettings();
        if (empty($price)) {
            Session::add('feedback_negative', Text::get('Amountisemptyenteravalidvalue'));
            return false;
        } elseif (!filter_var($price, FILTER_VALIDATE_FLOAT)) {
            Session::add('feedback_negative', Text::get('Amountisnotfloatnumber'));
            return false;
        } elseif ($price > $paypalsettings->maxlimit) {
            Session::add('feedback_negative', Text::get('Specifiedamountismorethanmaxlimit')." $$paypalsettings->maxlimit, try again.");
            return false;
        } elseif ($price < $paypalsettings->minlimit) {
            Session::add('feedback_negative', Text::get('Specifiedamountislessthanminlimit')." $$paypalsettings->minlimit, try again.");
            return false;
        } elseif ($paypalsettings->enabled == 0) {
            Session::add('feedback_negative', Text::get('PayPalPaymentMethodisdisabled'));
            return false;
        } else {
            $customData = ['addfunds', Session::get('user_id')];
            SubscriptionModel::processPayPal(
                $paypalsettings->field1,
                Config::get('URL').'page/paypal',
                Config::get('URL').'addfunds',
                Config::get('URL').'addfunds?paypal=success',
                Text::get('Addfundstoaccount').': '.Session::get('user_name').' - '.SiteSettingsModel::sitesettings()->sitename,
                Text::get('Backto').' '.SiteSettingsModel::sitesettings()->sitename,
                $price,
                json_encode($customData)
            );
        }
    }

    // PAYZA START

    public static function payzaSettings()
    {
        $database = DatabaseFactory::getFactory()->getConnection();
        $get = $database->prepare('SELECT * FROM payment_methods WHERE id = 7');
        $get->execute();
        return $get->fetchObject();
    }

    public static function processPayza() {
        // Amount user would like to deposit to account balance
        $price = Request::post('price', true);
        $payzaSettings = self::payzaSettings();
        if (empty($price)) {
            Session::add('feedback_negative', Text::get('Amountisemptyenteravalidvalue'));
            return false;
        } elseif (!filter_var($price, FILTER_VALIDATE_FLOAT)) {
            Session::add('feedback_negative', Text::get('Amountisnotfloatnumber'));
            return false;
        } elseif ($price > $payzaSettings->maxlimit) {
            Session::add('feedback_negative', Text::get('Specifiedamountismorethanmaxlimit')." $$payzaSettings->maxlimit, try again.");
            return false;
        } elseif ($price < $payzaSettings->minlimit) {
            Session::add('feedback_negative', Text::get('Specifiedamountislessthanminlimit')." $$payzaSettings->minlimit, try again.");
            return false;
        } elseif ($payzaSettings->enabled == 0) {
            Session::add('feedback_negative', Text::get('PayzaPaymentMethodisdisabled'));
            return false;
        } else {
            Session::set('ap_merchant', $payzaSettings->field1);
            Session::set('ap_purchasetype', 'service');
            Session::set('ap_itemname', SiteSettingsModel::sitesettings()->sitename);
            Session::set('ap_amount', $price);
            Session::set('ap_currency', 'USD');
            Session::set('ap_quantity', 1);
            Session::set('ap_description', Text::get('Addfundstoaccount').': '.Session::get('user_name').' - '.SiteSettingsModel::sitesettings()->sitename);
            Session::set('apc_1', Session::get('user_id'));
            Session::set('ap_ipnversion', 2);
            Session::set('ap_testmode', 0);
            Session::set('ap_returnurl', Config::get('URL').'addfunds?payza=success');
            Session::set('ap_cancelurl', Config::get('URL').'addfunds');
            Session::set('ap_alerturl', Config::get('URL').'page/payza');

            Redirect::to('addfunds/processpayza');
        }
    }

    // Payza will send us a token that we need to send back to verify that this request is valid and from payza to prevent hackers.
    public static function payza() {
        $IPN_V2_HANDLER = 'https://secure.payza.com/ipn2.ashx';
        $TOKEN_IDENTIFIER = 'token=';

        $token = urlencode($_POST['token']);

        $token = $TOKEN_IDENTIFIER . $token;

        $response = '';
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $IPN_V2_HANDLER);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $token);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        $response = curl_exec($ch);
        curl_close($ch);

        if (strlen($response) > 0) {
            if (urldecode($response) == "INVALID TOKEN") {
                die();
            } else {
                $response = urldecode($response);
                $aps = explode("&", $response);
                $info = array();
                foreach ($aps as $ap) {
                    $ele = explode("=", $ap);
                    $info[$ele[0]] = $ele[1];
                }

                $receivedMerchantEmailAddress = $info['ap_merchant'];
                $transactionStatus = $info['ap_status'];
                $testModeStatus = $info['ap_test'];
                $purchaseType = $info['ap_purchasetype'];
                $totalAmountReceived = $info['ap_totalamount'];
                $feeAmount = $info['ap_feeamount'];
                $netAmount = $info['ap_netamount'];
                $transactionReferenceNumber = $info['ap_referencenumber'];
                $currency = $info['ap_currency'];
                $transactionDate = $info['ap_transactiondate'];
                $transactionType = $info['ap_transactiontype'];
                $customerFirstName = $info['ap_custfirstname'];
                $customerLastName = $info['ap_custlastname'];
                $customerAddress = $info['ap_custaddress'];
                $customerCity = $info['ap_custcity'];
                $customerState = $info['ap_custstate'];
                $customerCountry = $info['ap_custcountry'];
                $customerZipCode = $info['ap_custzip'];
                $customerEmailAddress = $info['ap_custemailaddress'];
                $myItemName = $info['ap_itemname'];
                $myItemCode = $info['ap_itemcode'];
                $myItemDescription = $info['ap_description'];
                $myItemQuantity = $info['ap_quantity'];
                $myItemAmount = $info['ap_amount'];
                $additionalCharges = $info['ap_additionalcharges'];
                $shippingCharges = $info['ap_shippingcharges'];
                $taxAmount = $info['ap_taxamount'];
                $discountAmount = $info['ap_discountamount'];
                // USER ID BELOW
                $myCustomField_1 = $info['apc_1'];
                if ($transactionStatus == 'Success') {
                    // Transaction is successfully paid, now lets do our thing
                    $database = DatabaseFactory::getFactory()->getConnection();

                    AffiliateModel::rewardReferrer($myCustomField_1, $totalAmountReceived);

                    // Add balance
                    $add = $database->prepare('UPDATE users SET balance = balance + :amount WHERE user_id = :userid');
                    $add->execute(array(
                        ':userid' => $myCustomField_1,
                        ':amount' => $totalAmountReceived
                    ));

                    // Add transaction history
                    $addtran = $database->prepare('INSERT INTO transactions (user_id, payment_id, complete, created, amount, method) VALUES (:userid, :payment, :complete, :created, :amount, :method)');
                    $addtran->execute(array(
                        ':userid' => $myCustomField_1,
                        ':payment' => $transactionReferenceNumber,
                        ':complete' => 1,
                        ':created' => date('Y-m-d H:i:s'),
                        ':amount' => $totalAmountReceived,
                        ':method' => 'Payza'
                    ));
                } else {
                    die();
                }
            }
        } else {
            //something is wrong, no response is received from Payza
            die();
        }
    }

    // PAYZA END

    /**
     * @param int $userID
     * @return array    stdClass array of all the payments methods that is turned on
     *                          enabled member tells whether payment method is user enabled or not
     */
    public static function getUserPaymentMethods(int $userID): array
    {
        $defaults = self::getUserCustomDefaults();
        $userValues = UserModel::getPersonalPaymentMethods($userID);

        $returnValue = [];
        foreach ($defaults as $d) {
            if ($d->enabled) {
                $paymentMethod = new stdClass();
                $paymentMethod->id = $d->id;

                foreach ($userValues as $u) {
                    if ($u->payment_id == $d->id) {
                        $paymentMethod->enabled = $u->enabled;
                    }
                }
                if (!isset($paymentMethod->enabled)) {
                    $paymentMethod->enabled = $d->user_default_enabled;
                }
                $returnValue[] = $paymentMethod;
            }

        }
        return $returnValue;
    }

    public static function getEnabledUserPaymentMethods(int $userID): array
    {
        $values = self::getUserPaymentMethods($userID);
        $returnValue = [];

        foreach ($values as $v) {
            if ($v->enabled) {
                $returnValue[] = $v->id;
            }
        }
        return $returnValue;
    }

    // Skrill
    /*
        public static function skrillSettings()
        {
            $database = DatabaseFactory::getFactory()->getConnection();
            $get = $database->prepare('SELECT * FROM pm_skrill');
            $get->execute();
            return $get->fetchObject();
        }

        public static function skrill()
        {
            // Validate the Moneybookers signature
            $concatFields = $_POST['merchant_id']
                .$_POST['transaction_id']
                .strtoupper(md5(self::skrillSettings()->secret))
                .$_POST['mb_amount']
                .$_POST['mb_currency']
                .$_POST['status'];

            // Ensure the signature is valid, the status code == 2,
            // and that the money is going to you
            if (strtoupper(md5($concatFields)) == $_POST['md5sig']
                && $_POST['status'] == 2
                && $_POST['pay_to_email'] == self::skrillSettings()->email)
            {
                // Valid transaction.
                $database = DatabaseFactory::getFactory()->getConnection();

                // Add balance
                $add = $database->prepare('UPDATE users SET balance = balance + :amount WHERE user_id = :userid');
                $add->execute(array(
                    ':userid' => $_POST['PAYMENT_ID'],
                    ':amount' => $_POST['PAYMENT_AMOUNT']
                ));

                // Add transaction history
                $addtran = $database->prepare('INSERT INTO transactions (user_id, payment_id, complete, created, amount, method) VALUES (:userid, :payment, :complete, :created, :amount, :method)');
                $addtran->execute(array(
                    ':userid' => $_POST['PAYMENT_ID'],
                    ':payment' => '',
                    ':complete' => 1,
                    ':created' => date('Y-m-d H:i:s'),
                    ':amount' => $_POST['PAYMENT_AMOUNT'],
                    ':method' => 'Perfect Money'
                ));
            }
            else
            {
                // Invalid transaction. Bail out
                exit;
            }

        }

        public static function processSkrill()
        {
            // Amount user would like to deposit to account balance
            $price = Request::post('price', true);
            $skrillsettings = self::skrillSettings();
            if (empty($price)) {
                Session::add('feedback_negative', "Amount is empty, enter a valid value and try again.");
                return false;
            } elseif (!filter_var($price, FILTER_VALIDATE_FLOAT)) {
                Session::add('feedback_negative', "Amount is not valid, please try again.");
                return false;
            } elseif ($price > $skrillsettings->maxlimit) {
                Session::add('feedback_negative', "Specified amount is more than max limit $$skrillsettings->maxlimit, try again.");
                return false;
            } elseif ($price < $skrillsettings->minlimit) {
                Session::add('feedback_negative', "Specified amount is less than min limit $$skrillsettings->minlimit, try again.");
                return false;
            } elseif ($skrillsettings->enabled == 0) {
                Session::add('feedback_negative', 'Skrill Payment Method is disabled at the moment, try again later.');
                return false;
            } else {

                $request = new \Skrill\Quick\SkrillRequest();
                $request->pay_to_email = $skrillsettings->email;
                $request->amount = $price;
                $request->currency = 'USD';
                $request->language = 'EN';
                $request->prepare_only = '1';

                $client = new \Skrill\Quick\SkrillClient($request);
                $sessionid = $client->generateSID(); //return SESSION ID
                $redirecturl = $client->getRedirectUrl(); //return redirect url

                Session::set('processSkrill', 1);
                Session::set('skrill_amount', $price);
                Session::set('skrill_sessionid', $redirecturl);

                Redirect::to('addfunds/processskrill');

            }
        }
       */

    public static function redeemCode($code, $userid)
    {
        if (!self::redeemBlocked($userid)) {
            return false;
        }
        $dbc = DatabaseFactory::getFactory()->getConnection();
        $codeExists = $dbc->prepare("SELECT *FROM balance_code WHERE balance_key = :code");
        $codeExists->execute([':code' => $code]);
        if ($codeExists->rowCount() == 0) {
            self::redeemFailed($userid);
            Session::add('feedback_negative', Text::get('Codewasnotfound'));
            return false;
        }
        $codeObj = $codeExists->fetchObject();
        if (isset($codeObj->user_id)) {
            self::redeemFailed($userid);
            Session::add('feedback_negative', Text::get('Thiscodehasbeenused'));
            return false;
        }

        AffiliateModel::rewardReferrer(Session::get('user_id'), $codeObj->amount, $codeObj->balance_key);

        $userBalance = $dbc->prepare("UPDATE users SET balance = (balance + :amount) WHERE users.user_id = :userid");
        $userBalance->execute([
            ':amount' => $codeObj->amount,
            ':userid' => $userid
        ]);
        if ($userBalance->rowCount() == 1) {
            $addtran = $dbc->prepare('INSERT INTO transactions (user_id, payment_id, complete, created, amount, method) VALUES (:userid, :payment, :complete, :created, :amount, :method)');
            $addtran->execute(array(
                ':userid' => $userid,
                ':payment' => $codeObj->balance_key,
                ':complete' => 1,
                ':created' => date('Y-m-d H:i:s'),
                ':amount' => $codeObj->amount,
                ':method' => 'Redeem'
            ));
            $usedCode = $dbc->prepare("UPDATE balance_code SET user_id = :userid WHERE balance_key = :code");
            $usedCode->execute([
                ':userid' => $userid,
                ':code' => $codeObj->balance_key
            ]);
            $resetFailed = $dbc->prepare("UPDATE redeem_block SET failed_times = 0 WHERE user_id = :userid");
            $resetFailed->execute(['userid' => $userid]);
            return $codeObj->amount;
        }
        return false;
    }

    public static function redeemFailed($userid)
    {
        $dbc = DatabaseFactory::getFactory()->getConnection();
        $stmt = $dbc->prepare("INSERT INTO redeem_block(user_id, failed_times, last_failed) VALUES (:userid, 1, NOW()) ON DUPLICATE KEY UPDATE failed_times = (failed_times + 1), last_failed = NOW()");
        return $stmt->execute([
            ':userid' => $userid
        ]);
    }

    public static function redeemBlocked($user_id)
    {
        $dbc = DatabaseFactory::getFactory()->getConnection();
        $stmt = $dbc->prepare("SELECT failed_times, UNIX_TIMESTAMP(last_failed) AS last_failed FROM redeem_block WHERE user_id = :userid");
        $stmt->execute([':userid' => $user_id]);
        $user = $stmt->fetchObject();
        if ($user->failed_times >= 3 AND ($user->last_failed > (time() - 30))) {
            Session::add('feedback_negative', Text::get('Toomanyfailedattemptswait').' ' . (30 - (time() - $user->last_failed)) . ' '.Text::get('seconds'));
            return false;
        }

        return true;
    }

    public static function addRedeemCodes($code_value, $code_number = 1)
    {
        if ($code_value <= 0){
            return 0;
        }
        $dbc = DatabaseFactory::getFactory()->getConnection();
        $stmt = $dbc->prepare("INSERT INTO balance_code(balance_key, amount) VALUES (:code, :amount)");
        $added = [];
        while (sizeof($added) < $code_number){
            $code = Text::random_str(10);
            $stmt->execute([
                ':code' => $code,
                ':amount' => $code_value
            ]);
            if($stmt->rowCount() == 1){
                $added[] = $code;
            }
        }
        if (sizeof($added) == 0){
            return 'No codes';
        }
        return $added;
    }

    public static function removeCode($code)
    {
        $dbc = DatabaseFactory::getFactory()->getConnection();
        $stmt = $dbc->prepare("DELETE FROM balance_code WHERE balance_key = :code");
        $stmt->execute([
            ':code' => $code
        ]);
        return ($stmt->rowCount() > 0) ? true : false;
    }

    public static function getRedeemCodes($page = 0, $IPP = 25, $query = "")
    {
        $dbc = DatabaseFactory::getFactory()->getConnection();
        $sql = "SELECT balance_code.*, users.user_name as username FROM balance_code LEFT JOIN users ON balance_code.user_id = users.user_id";
        $data = [];
        if (strlen($query) > 0){
            $sql .= (strlen($query) > 0 ? ' WHERE balance_key = :query' : '');
            $data[':query']  = $query;
        }
        $sql .= " ORDER BY user_id ASC, amount ASC LIMIT " . ($page * $IPP) . ', ' . $IPP;
        $stmt = $dbc->prepare($sql);
        $stmt->execute($data);
        return $stmt->fetchAll();
    }

    public static function getRedeemCode($code)
    {
        $dbc = DatabaseFactory::getFactory()->getConnection();
        $stmt = $dbc->prepare("SELECT balance_code.*, users.user_name as username FROM balance_code LEFT JOIN users ON balance_code.user_id = users.user_id WHERE balance_key = :code");
        $stmt->execute([':code' => $code]);
        return $stmt->fetchObject();
    }

    public static function setRedeemGiven($code, $given)
    {
        $dbc = DatabaseFactory::getFactory()->getConnection();
        $stmt = $dbc->prepare("UPDATE balance_code SET given = :given WHERE balance_key = :code");
        $stmt->execute([':given' => $given, ':code' => $code]);
        return $stmt->rowCount() == 1 ? true : false;
    }

    // PAYTM START
    public static function paytmSettings()
    {
        $database = DatabaseFactory::getFactory()->getConnection();
        $get = $database->prepare('SELECT * FROM payment_methods WHERE id = 8');
        $get->execute();
        return $get->fetchObject();
    }

    public static function processPaytm() {
        // Amount user would like to deposit to account balance
        $price = Request::post('price', true);
        $settings = self::paytmSettings();

        if (!self::paymentFilterCheck($price, $settings)) return false;

        $orderid = Session::get('user_id').'_'.self::randomNumber(8);
        $paramList = [];
        $paramList["ORDER_ID"] = $orderid;
        $paramList["CUST_ID"] = Session::get('user_id');
        $paramList["INDUSTRY_TYPE_ID"] = 'Retail';
        $paramList["CHANNEL_ID"] = 'WEB';
        $paramList["TXN_AMOUNT"] = $price;
        $paramList["MID"] = $settings->field1;
        $paramList["WEBSITE"] = $settings->field3;
        $paramList["EMAIL"] = Session::get('user_email');
        $paramList["CALLBACK_URL"] = Config::get('URL').'page/paytm';

        Session::set('ORDER_ID', $orderid);
        Session::set('CUST_ID', Session::get('user_id'));
        Session::set('INDUSTRY_TYPE_ID', 'Retail');
        Session::set('CHANNEL_ID', 'WEB');
        Session::set('TXN_AMOUNT', $price);
        Session::set('MID', $settings->field1);
        Session::set('WEBSITE', $settings->field3);
        Session::set('EMAIL', Session::get('user_email'));
        Session::set('CALLBACK_URL', Config::get('URL').'page/paytm');

        Session::set('CHECKSUMHASH', Paytm::getChecksumFromArray($paramList,$settings->field2));

        Redirect::to('addfunds/processpaytm');
    }

    public static function paymentFilterCheck($price, $settings) {
        if (empty($price)) {
            Session::add('feedback_negative', Text::get('Amountisemptyenteravalidvalue'));
            return false;
        } elseif (!filter_var($price, FILTER_VALIDATE_FLOAT)) {
            Session::add('feedback_negative', Text::get('Amountisnotfloatnumber'));
            return false;
        } elseif ($price > $settings->maxlimit) {
            Session::add('feedback_negative', Text::get('Specifiedamountismorethanmaxlimit')." $$settings->maxlimit, try again.");
            return false;
        } elseif ($price < $settings->minlimit) {
            Session::add('feedback_negative', Text::get('Specifiedamountislessthanminlimit')." $$settings->minlimit, try again.");
            return false;
        } elseif ($settings->enabled == 0) {
            Session::add('feedback_negative', Text::get('ChosenPaymentMethodisdisabled'));
            return false;
        }
        return true;
    }

    public static function paytm() {
        $paramList = $_POST;
        $paytmChecksum = isset($_POST["CHECKSUMHASH"]) ? $_POST["CHECKSUMHASH"] : ""; //Sent by Paytm pg
        // Verify all parameters received from Paytm pg to your application. Like MID received from paytm pg is same as your application’s MID, TXN_AMOUNT and ORDER_ID
        // are same as what was sent by you to Paytm PG for initiating transaction etc.
        $isValidChecksum = Paytm::verifychecksum_e($paramList, self::paytmSettings()->field2, $paytmChecksum); //will return TRUE or FALSE string.
        if($isValidChecksum == "TRUE") {
            if ($_POST["STATUS"] == "TXN_SUCCESS") {
                // Transaction is successfully paid, now lets do our thing
                $database = DatabaseFactory::getFactory()->getConnection();
                $userid = strtok(Request::post('ORDERID', true), '_');
                $amountinUSD = Request::post('TXNAMOUNT', true);
                // If currency is in INR, we need to convert to USD.
                if (Request::post('CURRENCY', true) == 'INR') {
                    $amountinUSD = PaymentModel::convertCurrency('INR', 'USD', Request::post('TXNAMOUNT', true));
                }

                AffiliateModel::rewardReferrer($userid, $amountinUSD);

                // Add balance
                $add = $database->prepare('UPDATE users SET balance = balance + :amount WHERE user_id = :userid');
                $add->execute(array(
                    ':userid' => $userid,
                    ':amount' => $amountinUSD
                ));

                // Add transaction history
                $addtran = $database->prepare('INSERT INTO transactions (user_id, payment_id, complete, created, amount, method) VALUES (:userid, :payment, :complete, :created, :amount, :method)');
                $addtran->execute(array(
                    ':userid' => $userid,
                    ':payment' => Request::post('TXNID', true),
                    ':complete' => 1,
                    ':created' => date('Y-m-d H:i:s'),
                    ':amount' => $amountinUSD,
                    ':method' => 'Paytm'
                ));
                Session::add('feedback_positive', Text::get('Yourpaymenthasbeenprocessed'));
                !empty(Session::get('user_id')) ? Redirect::to('addfunds') : Redirect::to('index');
                die();
            } else {
                Session::add('feedback_negative', Text::get('Yourpaymentfailed'));
                !empty(Session::get('user_id')) ? Redirect::to('addfunds') : Redirect::to('index');
                die();
            }
        } else {
            !empty(Session::get('user_id')) ? Redirect::to('addfunds') : Redirect::to('index');
            die();
            //Process transaction as suspicious.
        }
    }
    // PAYTM END

    public static function randomNumber($length) {
        $result = '';

        for($i = 0; $i < $length; $i++) {
            $result .= mt_rand(0, 9);
        }

        return $result;
    }

    public static function convertCurrency($from,$to,$amount)
    {
        $data = file_get_contents("https://api.fixer.io/latest?base=$from");
        $data = json_decode($data);
        $to = $data->rates->$to;
        return $amount*$to;
    }

    // COINPAYMENTS START

    public static function coinPaymentsSettings()
    {
        $database = DatabaseFactory::getFactory()->getConnection();
        $get = $database->prepare('SELECT * FROM payment_methods WHERE id = 9');
        $get->execute();
        return $get->fetchObject();
    }

    public static function processCoinpayments() {
        // Amount user would like to deposit to account balance
        $price = Request::post('price', true);
        $settings = self::coinPaymentsSettings();

        if (!self::paymentFilterCheck($price, $settings)) return false;

        Session::set('merchant', $settings->field1);
        Session::set('cmd', '_pay');
        Session::set('reset', 1);

        Session::set('currency', 'USD');
        Session::set('allow_currencies', $settings->field3);
        Session::set('amountf', $price);
        Session::set('item_name', Text::get('Addfundstoaccount').': '.Session::get('user_name').' - '.SiteSettingsModel::sitesettings()->sitename);
        Session::set('allow_quantity', 0);
        Session::set('want_shipping', 0);
        Session::set('cancel_url', Config::get('URL').'addfunds');
        Session::set('custom', Session::get('user_id'));
        Session::set('ipn_url', Config::get('URL').'page/coinpayments');

        Redirect::to('addfunds/processcoinpayments');
    }

    private static function checkIfPaymentAlreadyCompleted($transaction_id, $userid) {
        $database = DatabaseFactory::getFactory()->getConnection();
        $check = $database->prepare('SELECT * FROM transactions WHERE payment_id = :transid AND user_id = :userid AND complete = 1');
        $check->execute([
            ':transid' => $transaction_id,
            ':userid' => $userid
        ]);
        return $check->rowCount() > 0 ? true : false;
    }

    public static function coinpayments() {
        // Fill these in with the information from your CoinPayments.net account.
        $cp_merchant_id = self::coinPaymentsSettings()->field1;
        $cp_ipn_secret = self::coinPaymentsSettings()->field2;

        if (!isset($_POST['ipn_mode']) || $_POST['ipn_mode'] != 'hmac') {
            die('IPN Mode is not HMAC');
        }

        if (!isset($_SERVER['HTTP_HMAC']) || empty($_SERVER['HTTP_HMAC'])) {
            die('No HMAC signature sent.');
        }

        $request = file_get_contents('php://input');
        if ($request === FALSE || empty($request)) {
            die('Error reading POST data');
        }

        if (!isset($_POST['merchant']) || $_POST['merchant'] != trim($cp_merchant_id)) {
            die('No or incorrect Merchant ID passed');
        }

        $hmac = hash_hmac("sha512", $request, trim($cp_ipn_secret));
        if (!hash_equals($hmac, $_SERVER['HTTP_HMAC'])) {
            //if ($hmac != $_SERVER['HTTP_HMAC']) { <-- Use this if you are running a version of PHP below 5.6.0 without the hash_equals function
            die('HMAC signature does not match');
        }

        // HMAC Signature verified at this point, load some variables.

        $txn_id = Request::post('txn_id', true);
        $amount1 = Request::post('amount1', true);
        $currency1 = Request::post('currency1', true);
        $status = Request::post('status', true);

        //These would normally be loaded from your database, the most common way is to pass the Order ID through the 'custom' POST field.
        $order_currency = 'USD';
        $userid = Request::post('custom', true);

        // see if the transaction ID $txn_id has already been handled before at this point
        if (self::checkIfPaymentAlreadyCompleted($txn_id, $userid)) die('Transaction has already been handled.');

        // Check the original currency to make sure the buyer didn't change it.
        if ($currency1 != $order_currency) {
            die('Original currency mismatch!');
        }

        if ($status >= 100 || $status == 2) {
            // payment is complete or queued for nightly payout, success
            $database = DatabaseFactory::getFactory()->getConnection();
            AffiliateModel::rewardReferrer($userid, $amount1);

            // Add balance
            $add = $database->prepare('UPDATE users SET balance = balance + :amount WHERE user_id = :userid');
            $add->execute(array(
                ':userid' => $userid,
                ':amount' => $amount1
            ));

            // Add transaction history
            $addtran = $database->prepare('INSERT INTO transactions (user_id, payment_id, complete, created, amount, method) VALUES (:userid, :payment, :complete, :created, :amount, :method)');
            $addtran->execute(array(
                ':userid' => $userid,
                ':payment' => $txn_id,
                ':complete' => 1,
                ':created' => date('Y-m-d H:i:s'),
                ':amount' => $amount1,
                ':method' => 'Coinpayments'
            ));
        }
        die('IPN OK');
    }

    // COINPAYMENTS END
}