diff --git a/monero/include/monero_payments.php b/monero/include/monero_payments.php
index 3ba2c22..cc4a55c 100644
--- a/monero/include/monero_payments.php
+++ b/monero/include/monero_payments.php
@@ -12,6 +12,7 @@ class Monero_Gateway extends WC_Payment_Gateway
private $discount;
private $confirmed = false;
private $monero_daemon;
+ private $non_rpc = false;
function __construct()
{
@@ -30,7 +31,20 @@ class Monero_Gateway extends WC_Payment_Gateway
$this->host = $this->get_option('daemon_host');
$this->port = $this->get_option('daemon_port');
$this->address = $this->get_option('monero_address');
+ $this->viewKey = $this->get_option('viewKey');
$this->discount = $this->get_option('discount');
+
+ $this->use_viewKey = $this->get_option('use_viewKey');
+ $this->use_rpc = $this->get_option('use_rpc');
+
+ if($this->use_viewKey == 'yes')
+ {
+ $this->non_rpc = true;
+ }
+ if($this->use_rpc == 'yes')
+ {
+ $this->non_rpc = false;
+ }
// After init_settings() is called, you can get the settings and load them into variables, e.g:
// $this->title = $this->get_option('title' );
@@ -77,12 +91,32 @@ class Monero_Gateway extends WC_Payment_Gateway
'default' => __('Pay securely using XMR.', 'monero_gateway')
),
+ 'use_viewKey' => array(
+ 'title' => __('Use ViewKey', 'monero_gateway'),
+ 'label' => __(' Verify Transaction with ViewKey ', 'monero_gateway'),
+ 'type' => 'checkbox',
+ 'description' => __('Fill in the Address and ViewKey fields to verify transactions with your ViewKey', 'monero_gateway'),
+ 'default' => 'no'
+ ),
'monero_address' => array(
'title' => __('Monero Address', 'monero_gateway'),
'label' => __('Useful for people that have not a daemon online'),
'type' => 'text',
'desc_tip' => __('Monero Wallet Address', 'monero_gateway')
),
+ 'viewKey' => array(
+ 'title' => __('Secret ViewKey', 'monero_gateway'),
+ 'label' => __('Secret ViewKey'),
+ 'type' => 'text',
+ 'desc_tip' => __('Your secret ViewKey', 'monero_gateway')
+ ),
+ 'use_rpc' => array(
+ 'title' => __('Use monero-wallet-rpc', 'monero_gateway'),
+ 'label' => __(' Verify transactions with the monero-wallet-rpc ', 'monero_gateway'),
+ 'type' => 'checkbox',
+ 'description' => __('This must be setup seperatly', 'monero_gateway'),
+ 'default' => 'no'
+ ),
'daemon_host' => array(
'title' => __('Monero wallet rpc Host/ IP', 'monero_gateway'),
'type' => 'text',
@@ -100,8 +134,8 @@ class Monero_Gateway extends WC_Payment_Gateway
'desc_tip' => __('Provide a discount to your customers for making a private payment with XMR!', 'monero_gateway'),
'description' => __('Do you want to spread the word about Monero? Offer a small discount! Leave this empty if you do not wish to provide a discount', 'monero_gateway'),
- 'type' => __('text'),
- 'default' => '5%'
+ 'type' => __('number'),
+ 'default' => '5'
),
'environment' => array(
@@ -140,17 +174,19 @@ class Monero_Gateway extends WC_Payment_Gateway
public function admin_options()
{
$this->log->add('Monero_gateway', '[SUCCESS] Monero Settings OK');
-
echo "
Monero Payment Gateway ";
echo "Welcome to Monero Extension for WooCommerce. Getting started: Make a connection with daemon Contact Me ";
echo "
";
- $this->getamountinfo();
+
+ if(!$this->non_rpc) // only try to get balance data if using wallet-rpc
+ $this->getamountinfo();
+
echo "
";
echo "";
- echo "Learn more about using monero-wallet-rpc here ";
+ echo "Learn more about using monero-wallet-rpc here and viewkeys here ";
}
public function getamountinfo()
@@ -197,7 +233,15 @@ class Monero_Gateway extends WC_Payment_Gateway
public function validate_fields()
{
if ($this->check_monero() != TRUE) {
- echo "Your Monero Address doesn't seem valid. Have you checked it?
";
+ echo "Your Monero Address doesn't look valid. Have you checked it?
";
+ }
+ if(!$this->check_viewKey())
+ {
+ echo "Your ViewKey doesn't look valid. Have you checked it?
";
+ }
+ if($this->check_checkedBoxes())
+ {
+ echo "You must choose to either use monero-wallet-rpc or a ViewKey, not both
";
}
}
@@ -213,6 +257,29 @@ class Monero_Gateway extends WC_Payment_Gateway
}
return false;
}
+ public function check_viewKey()
+ {
+ if($this->use_viewKey == 'yes')
+ {
+ if (strlen($this->viewKey) == 64) {
+ return true;
+ }
+ return false;
+ }
+ return true;
+ }
+ public function check_checkedBoxes()
+ {
+ if($this->use_viewKey == 'yes')
+ {
+ if($this->use_rpc == 'yes')
+ {
+ return true;
+ }
+ }
+ else
+ return false;
+ }
public function is_virtual_in_cart($order_id)
{
@@ -231,93 +298,164 @@ class Monero_Gateway extends WC_Payment_Gateway
public function instruction($order_id)
{
- $order = wc_get_order($order_id);
- $amount = floatval(preg_replace('#[^\d.]#', '', $order->get_total()));
- $payment_id = $this->set_paymentid_cookie();
- $currency = $order->get_currency();
- $amount_xmr2 = $this->changeto($amount, $currency, $payment_id);
- $address = $this->address;
- if (!isset($address)) {
- // If there isn't address (merchant missed that field!), $address will be the Monero address for donating :)
- $address = "44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A";
+ if($this->non_rpc)
+ {
+ $order = wc_get_order($order_id);
+ $amount = floatval(preg_replace('#[^\d.]#', '', $order->get_total()));
+ $payment_id = $this->set_paymentid_cookie(32);
+ $currency = $order->get_currency();
+ $amount_xmr2 = $this->changeto($amount, $currency, $payment_id);
+ $address = $this->address;
+ if (!isset($address)) {
+ // If there isn't address (merchant missed that field!), $address will be the Monero address for donating :)
+ $address = "44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A";
+ }
+ $uri = "monero:$address?amount=$amount?payment_id=$payment_id";
+
+ if($this->verify_non_rpc($payment_id, $amount_xmr2, $order_id) == false);
+ {
+ echo " We are waiting for your transaction to be confirmed ";
+ }
+
+ echo "
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Send:
+
".$amount_xmr2."
+
Payment ID:
+
".$payment_id."
+
+
+
To this address:
+
".$address."
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ";
+
+ echo "
+ ";
}
- $uri = "monero:$address?amount=$amount?payment_id=$payment_id";
- $array_integrated_address = $this->monero_daemon->make_integrated_address($payment_id);
- if (!isset($array_integrated_address)) {
- $this->log->add('Monero_Gateway', '[ERROR] Unable get integrated address');
- // Seems that we can't connect with daemon, then set array_integrated_address, little hack
- $array_integrated_address["integrated_address"] = $address;
- }
- if($this->is_virtual_in_cart($order_id) == true){
- echo "test";
- }
- $message = $this->verify_payment($payment_id, $amount_xmr2, $order);
- if ($this->confirmed) {
- $color = "006400";
- } else {
- $color = "DC143C";
- }
- echo "" . $message . " ";
+ else
+ {
+ $order = wc_get_order($order_id);
+ $amount = floatval(preg_replace('#[^\d.]#', '', $order->get_total()));
+ $payment_id = $this->set_paymentid_cookie(8);
+ $currency = $order->get_currency();
+ $amount_xmr2 = $this->changeto($amount, $currency, $payment_id);
+ $address = $this->address;
+ if (!isset($address)) {
+ // If there isn't address (merchant missed that field!), $address will be the Monero address for donating :)
+ $address = "44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A";
+ }
+ $uri = "monero:$address?amount=$amount?payment_id=$payment_id";
+ $array_integrated_address = $this->monero_daemon->make_integrated_address($payment_id);
+ if (!isset($array_integrated_address)) {
+ $this->log->add('Monero_Gateway', '[ERROR] Unable get integrated address');
+ // Seems that we can't connect with daemon, then set array_integrated_address, little hack
+ $array_integrated_address["integrated_address"] = $address;
+ }
+ $message = $this->verify_payment($payment_id, $amount_xmr2, $order);
+ if ($this->confirmed) {
+ $color = "006400";
+ } else {
+ $color = "DC143C";
+ }
+ echo "" . $message . " ";
- echo "
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Send:
-
".$amount_xmr2."
XMR
-
-
-
To this address:
-
".$array_integrated_address['integrated_address']."
-
-
-
-
-
-
-
-
-
-
-
-
-
- ";
-
-
-
- echo "
- ";
+ echo "
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Send:
+
".$amount_xmr2."
+
+
+
To this address:
+
".$array_integrated_address['integrated_address']."
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ";
+
+ echo "
+ ";
+ }
}
- private function set_paymentid_cookie()
+ private function set_paymentid_cookie($size)
{
if (!isset($_COOKIE['payment_id'])) {
- $payment_id = bin2hex(openssl_random_pseudo_bytes(8));
+ $payment_id = bin2hex(openssl_random_pseudo_bytes($size));
setcookie('payment_id', $payment_id, time() + 2700);
}
else{
@@ -456,6 +594,41 @@ class Monero_Gateway extends WC_Payment_Gateway
}
return $message;
}
+
+ public function verify_non_rpc($payment_id, $amount, $order_id)
+ {
+ $tools = new NodeTools();
+ $bc_height = $tools->get_last_block_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
+
+ $i = 1;
+ $output_found;
+ $block_index;
+ while($i <= $tx_count)
+ {
+ $tx_hash = $txs_from_block[$i]['tx_hash'];
+ $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)
+ {
+ $this->on_verified($payment_id, $amount_atomic_units, $order_id);
+ }
+
+ return true;
+ }
+ return false;
+ }
public function do_ssl_check()
{
diff --git a/monero/library.php b/monero/library.php
index 1e3d777..774a6a1 100644
--- a/monero/library.php
+++ b/monero/library.php
@@ -319,3 +319,62 @@ class Monero_Library
return $get_bulk_payments;
}
}
+
+class NodeTools
+{
+ public function get_last_block_height()
+ {
+ $curl = curl_init();
+
+ curl_setopt_array($curl, array(
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_URL => 'https://xmrchain.net/api/networkinfo',
+ ));
+ $resp = curl_exec($curl);
+ curl_close($curl);
+
+ $array = json_decode($resp, true);
+ return $array['data']['height'] - 1;
+ }
+
+ public function get_txs_from_block($height)
+ {
+ $curl = curl_init();
+
+ curl_setopt_array($curl, array(
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_URL => 'https://xmrchain.net/api/search/' . $height,
+ ));
+ $resp = curl_exec($curl);
+ curl_close($curl);
+
+ $array = json_decode($resp, true);
+
+ return $array['data']['txs'];
+ }
+
+ public function check_tx($tx_hash, $address, $viewKey)
+ {
+ $curl = curl_init();
+ curl_setopt_array($curl, array(
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_URL => 'https://xmrchain.net/api/outputs?txhash=' .$tx_hash . '&address='. $address . '&viewkey='. $viewKey .'&txprove=0',
+ ));
+ $resp = curl_exec($curl);
+ curl_close($curl);
+ $array = json_decode($resp, true);
+ $output_count = count($array['data']['outputs']);
+ $i = 0;
+ while($i < $output_count)
+ {
+ if($array['data']['outputs'][$i]['match'])
+ {
+ return $array['data']['outputs'][$i];
+ }
+
+ $i++;
+ }
+
+ }
+
+}