";
echo "
";
}
}
private function set_paymentid_cookie($size)
{
if (!isset($_COOKIE['payment_id'])) {
$payment_id = bin2hex(openssl_random_pseudo_bytes($size));
setcookie('payment_id', $payment_id, time() + 2700);
}
else{
$payment_id = $this->sanatize_id($_COOKIE['payment_id']);
}
return $payment_id;
}
public function sanatize_id($payment_id)
{
// Limit payment id to alphanumeric characters
$sanatized_id = preg_replace("/[^a-zA-Z0-9]+/", "", $payment_id);
return $sanatized_id;
}
public function changeto($amount, $currency, $payment_id)
{
global $wpdb;
// This will create a table named whatever the payment id is inside the database "WordPress"
$create_table = "CREATE TABLE IF NOT EXISTS $payment_id (
rate INT
)";
$wpdb->query($create_table);
$rows_num = $wpdb->get_results("SELECT count(*) as count FROM $payment_id");
if ($rows_num[0]->count > 0) // Checks if the row has already been created or not
{
$stored_rate = $wpdb->get_results("SELECT rate FROM $payment_id");
$stored_rate_transformed = $stored_rate[0]->rate / 100; //this will turn the stored rate back into a decimaled number
if (isset($this->discount)) {
$sanatized_discount = preg_replace('/[^0-9]/', '', $this->discount);
$discount_decimal = $sanatized_discount / 100;
$new_amount = $amount / $stored_rate_transformed;
$discount = $new_amount * $discount_decimal;
$final_amount = $new_amount - $discount;
$rounded_amount = round($final_amount, 12);
} else {
$new_amount = $amount / $stored_rate_transformed;
$rounded_amount = round($new_amount, 12); //the moneo wallet can't handle decimals smaller than 0.000000000001
}
} else // If the row has not been created then the live exchange rate will be grabbed and stored
{
$xmr_live_price = $this->retriveprice($currency);
$live_for_storing = $xmr_live_price * 100; //This will remove the decimal so that it can easily be stored as an integer
$wpdb->query("INSERT INTO $payment_id (rate) VALUES ($live_for_storing)");
if(isset($this->discount))
{
$new_amount = $amount / $xmr_live_price;
$discount = $new_amount * $this->discount / 100;
$discounted_price = $new_amount - $discount;
$rounded_amount = round($discounted_price, 12);
}
else
{
$new_amount = $amount / $xmr_live_price;
$rounded_amount = round($new_amount, 12);
}
}
return $rounded_amount;
}
// Check if we are forcing SSL on checkout pages
// Custom function not required by the Gateway
public function retriveprice($currency)
{
$xmr_price = file_get_contents('https://min-api.cryptocompare.com/data/price?fsym=XMR&tsyms=BTC,USD,EUR,CAD,INR,GBP,COP,SGD&extraParams=monero_woocommerce');
$price = json_decode($xmr_price, TRUE);
if (!isset($price)) {
$this->log->add('Monero_Gateway', '[ERROR] Unable to get the price of Monero');
}
switch ($currency) {
case 'USD':
return $price['USD'];
case 'EUR':
return $price['EUR'];
case 'CAD':
return $price['CAD'];
case 'GBP':
return $price['GBP'];
case 'INR':
return $price['INR'];
case 'COP':
return $price['COP'];
case 'SGD':
return $price['SGD'];
case 'XMR':
$price = '1';
return $price;
}
}
private function on_verified($payment_id, $amount_atomic_units, $order_id)
{
$message = "Payment has been received and confirmed. Thanks!";
$this->log->add('Monero_gateway', '[SUCCESS] Payment has been recorded. Congratulations!');
$this->confirmed = true;
$order = wc_get_order($order_id);
if($this->is_virtual_in_cart($order_id) == true){
$order->update_status('completed', __('Payment has been received.', 'monero_gateway'));
}
else{
$order->update_status('processing', __('Payment has been received.', 'monero_gateway')); // Show payment id used for order
}
global $wpdb;
$wpdb->query("DROP TABLE $payment_id"); // Drop the table from database after payment has been confirmed as it is no longer needed
$this->reloadTime = 3000000000000; // Greatly increase the reload time as it is no longer needed
return $message;
}
public function verify_payment($payment_id, $amount, $order_id)
{
/*
* function for verifying payments
* Check if a payment has been made with this payment id then notify the merchant
*/
$message = "We are waiting for your payment to be confirmed";
$amount_atomic_units = $amount * 1000000000000;
$get_payments_method = $this->monero_daemon->get_payments($payment_id);
if (isset($get_payments_method["payments"][0]["amount"])) {
if ($get_payments_method["payments"][0]["amount"] >= $amount_atomic_units)
{
$message = $this->on_verified($payment_id, $amount_atomic_units, $order_id);
}
if ($get_payments_method["payments"][0]["amount"] < $amount_atomic_units)
{
$totalPayed = $get_payments_method["payments"][0]["amount"];
$outputs_count = count($get_payments_method["payments"]); // number of outputs recieved with this payment id
$output_counter = 1;
while($output_counter < $outputs_count)
{
$totalPayed += $get_payments_method["payments"][$output_counter]["amount"];
$output_counter++;
}
if($totalPayed >= $amount_atomic_units)
{
$message = $this->on_verified($payment_id, $amount_atomic_units, $order_id);
}
}
}
return $message;
}
public function last_block_seen($height) // sometimes 2 blocks are mined within a few seconds of eacher. Make sure we don't miss one
{
if (!isset($_COOKIE['last_seen_block']))
{
setcookie('last_seen_block', $height, time() + 2700);
return 0;
}
else{
$cookie_block = $_COOKIE['last_seen_block'];
$difference = $height - $cookie_block;
setcookie('last_seen_block', $height, time() + 2700);
return $difference;
}
}
public function verify_non_rpc($payment_id, $amount, $order_id)
{
$tools = new NodeTools();
$bc_height = $tools->get_last_block_height();
$block_difference = $this->last_block_seen($bc_height);
$txs_from_block = $tools->get_txs_from_block($bc_height);
$tx_count = count($txs_from_block) - 1; // The tx at index 0 is a coinbase tx so it can be ignored
$output_found;
$block_index;
if($block_difference != 0)
{
if($block_difference >= 2){
$this->log->add('[WARNING] Block difference is greater or equal to 2');
}
$txs_from_block_2 = $tools->get_txs_from_block($bc_height - 1);
$tx_count_2 = count($txs_from_block_2) - 1;
$i = 1;
while($i <= $tx_count_2)
{
$tx_hash = $txs_from_block_2[$i]['tx_hash'];
if(strlen($txs_from_block_2[$i]['payment_id']) != 0)
{
$result = $tools->check_tx($tx_hash, $this->address, $this->viewKey);
if($result)
{
$output_found = $result;
$block_index = $i;
$i = $tx_count_2; // finish loop
}
}
$i++;
}
}
$i = 1;
while($i <= $tx_count)
{
$tx_hash = $txs_from_block[$i]['tx_hash'];
if(strlen($txs_from_block[$i]['payment_id']) != 0)
{
$result = $tools->check_tx($tx_hash, $this->address, $this->viewKey);
if($result)
{
$output_found = $result;
$block_index = $i;
$i = $tx_count; // finish loop
}
}
$i++;
}
if(isset($output_found))
{
$amount_atomic_units = $amount * 1000000000000;
if($txs_from_block[$block_index]['payment_id'] == $payment_id && $output_found['amount'] >= $amount_atomic_units)
{
$this->on_verified($payment_id, $amount_atomic_units, $order_id);
}
if($txs_from_block_2[$block_index]['payment_id'] == $payment_id && $output_found['amount'] >= $amount_atomic_units)
{
$this->on_verified($payment_id, $amount_atomic_units, $order_id);
}
return true;
}
return false;
}
public function verify_zero_conf($payment_id, $amount, $order_id)
{
$tools = new NodeTools();
$txs_from_mempool = $tools->get_mempool_txs();;
$tx_count = count($txs_from_mempool['data']['txs']);
$i = 0;
$output_found;
while($i <= $tx_count)
{
$tx_hash = $txs_from_mempool['data']['txs'][$i]['tx_hash'];
if(strlen($txs_from_mempool['data']['txs'][$i]['payment_id']) != 0)
{
$result = $tools->check_tx($tx_hash, $this->address, $this->viewKey);
if($result)
{
$output_found = $result;
$tx_i = $i;
$i = $tx_count; // finish loop
}
}
$i++;
}
if(isset($output_found))
{
$amount_atomic_units = $amount * 1000000000000;
if($txs_from_mempool['data']['txs'][$tx_i]['payment_id'] == $payment_id && $output_found['amount'] >= $amount_atomic_units)
{
$this->on_verified($payment_id, $amount_atomic_units, $order_id);
}
return true;
}
else
return false;
}
public function do_ssl_check()
{
if ($this->enabled == "yes" && !$this->get_option('onion_service')) {
if (get_option('woocommerce_force_ssl_checkout') == "no") {
echo "
" . sprintf(__("%s is enabled and WooCommerce is not forcing the SSL certificate on your checkout page. Please ensure that you have a valid SSL certificate and that you are forcing the checkout pages to be secured."), $this->method_title, admin_url('admin.php?page=wc-settings&tab=checkout')) . "
";
}
}
}
public function connect_daemon()
{
$host = $this->settings['daemon_host'];
$port = $this->settings['daemon_port'];
$monero_library = new Monero($host, $port);
if ($monero_library->works() == true) {
echo "
Everything works! Congratulations and welcome to Monero.
";
} else {
$this->log->add('Monero_gateway', '[ERROR] Plugin can not reach wallet rpc.');
echo "
Error with connection of daemon, see documentation!