id = "monero_gateway"; $this->method_title = __("Monero GateWay", 'monero_gateway'); $this->method_description = __("Monero Payment Gateway Plug-in for WooCommerce. You can find more information about this payment gateway on our website. You'll need a daemon online for your address.", 'monero_gateway'); $this->title = __("Monero Gateway", 'monero_gateway'); $this->version = "0.2"; // $this->icon = apply_filters('woocommerce_offline_icon', ''); $this->has_fields = false; $this->log = new WC_Logger(); $this->init_form_fields(); $this->host = $this->get_option('daemon_host'); $this->port = $this->get_option('daemon_port'); $this->address = $this->get_option('monero_address'); $this->username = $this->get_option('username'); $this->password = $this->get_option('password'); $this->discount = $this->get_option('discount'); // After init_settings() is called, you can get the settings and load them into variables, e.g: // $this->title = $this->get_option('title' ); $this->init_settings(); // Turn these settings into variables we can use foreach ($this->settings as $setting_key => $value) { $this->$setting_key = $value; } add_action('admin_notices', array($this,'do_ssl_check')); add_action('admin_notices', array($this,'validate_fields')); add_action('woocommerce_thankyou_' . $this->id, array($this,'instruction')); if (is_admin()) { /* Save Settings */ add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this,'process_admin_options' )); add_filter( 'woocommerce_currencies', array($this,'add_my_currency') ); add_filter('woocommerce_currency_symbol', 'add_my_currency_symbol', 10, 2); add_action('woocommerce_email_before_order_table', array($this, 'email_instructions'), 10, 2); } $this->monero_daemon = new Monero_Library($this->host . ':' . $this->port . '/json_rpc', $this->username, $this->password); } public function add_my_currency( $currencies ) { $currencies['XMR'] = __('Monero','woocommerce'); return $currencies; } public function add_my_currency_symbol( $currency_symbol, $currency ) { switch( $currency ) { case 'XMR': $currency_symbol = 'XMR'; break; } return $currency_symbol; } 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(); echo "
"; echo ""; $this->generate_settings_html(); echo "
"; echo "

Learn more about using a password with the monero wallet-rpc here

"; } public function init_form_fields() { $this->form_fields = array( 'enabled' => array( 'title' => __('Enable / Disable', 'monero_gateway'), 'label' => __('Enable this payment gateway', 'monero_gateway'), 'type' => 'checkbox', 'default' => 'no' ), 'title' => array( 'title' => __('Title', 'monero_gateway'), 'type' => 'text', 'desc_tip' => __('Payment title the customer will see during the checkout process.', 'monero_gateway'), 'default' => __('Monero XMR Payment', 'monero_gateway') ), 'description' => array( 'title' => __('Description', 'monero_gateway'), 'type' => 'textarea', 'desc_tip' => __('Payment description the customer will see during the checkout process.', 'monero_gateway'), 'default' => __('Pay securely using XMR.', 'monero_gateway') ), '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') ), 'daemon_host' => array( 'title' => __('Daemon Host/ IP', 'monero_gateway'), 'type' => 'text', 'desc_tip' => __('This is the Daemon Host/IP to authorize the payment with port', 'monero_gateway'), 'default' => 'localhost', ), 'daemon_port' => array( 'title' => __('Daemon PORT', 'monero_gateway'), 'type' => 'text', 'desc_tip' => __('This is the Daemon Host/IP to authorize the payment with port', 'monero_gateway'), 'default' => '18080', ), 'username' => array( 'title' => __('Daemon username', 'monero_gateway'), 'desc_tip' => __('This is the username that you used with your monero wallet-rpc', 'monero_gateway'), 'type' => __('text'), 'default' => __('username','monero_gateway'), ), 'password' => array( 'title' => __('Daemon password', 'monero_gateway'), 'desc_tip' => __('This is the password that you used with your monero wallet-rpc', 'monero_gateway'), 'description' => __('you can leave these fields empty if you did not set', 'monero_gateway'), 'type' => __('text'), 'default' => '' ), 'discount' => array( 'title' => __('% discount for using XMR', 'monero_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%' ), 'environment' => array( 'title' => __(' Test Mode', 'monero_gateway'), 'label' => __('Enable Test Mode', 'monero_gateway'), 'type' => 'checkbox', 'description' => __('Check this box if you are using testnet', 'monero_gateway'), 'default' => 'no' ), ); } 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&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'); } if ($currency == 'USD') { return $price['USD']; } if ($currency == 'EUR') { return $price['EUR']; } if ($currency == 'CAD'){ return $price['CAD']; } if ($currency == 'GBP'){ return $price['GBP']; } if ($currency == 'INR'){ return $price['INR']; } if($currency == 'XMR'){ $price = '1'; return $price; } } 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)) { $discount_decimal = $this->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 $new_amount = $amount / $xmr_live_price; $rounded_amount = round($new_amount, 12); $wpdb->query("INSERT INTO $payment_id (rate) VALUES ($live_for_storing)"); } return $rounded_amount; } // Submit payment and handle response public function process_payment($order_id) { $order = wc_get_order($order_id); $order->update_status('on-hold', __('Awaiting offline payment', 'monero_gateway')); // Reduce stock levels $order->reduce_order_stock(); // Remove cart WC()->cart->empty_cart(); // Return thankyou redirect return array( 'result' => 'success', 'redirect' => $this->get_return_url($order) ); } // Validate fields public function validate_fields() { if ($this->check_monero() != TRUE) { echo "

Your Monero Address doesn't seem valid. Have you checked it?

"; } } public function check_monero() { $monero_address = $this->settings['monero_address']; if (strlen($monero_address) == 95 && substr($monero_address, 1)) { return true; } return false; } private function set_paymentid_cookie() { if(!isset($_COOKIE['payment_id'])) { $payment_id = bin2hex(openssl_random_pseudo_bytes(8)); setcookie('payment_id', $payment_id, time()+2700); } else $payment_id = $_COOKIE['payment_id']; return $payment_id; } 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"; } $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 to getting 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 ""; echo "

Monero Payment Box

Send " . $amount_xmr2 . " XMR to
or scan QR Code with your mobile device

If you need help with how to pay with Monero or want to learn more about it, please go to the Monerosite.
"; } // Check if we are forcing SSL on checkout pages // Custom function not required by the Gateway public function do_ssl_check() { if ($this->enabled == "yes") { 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!

"; } } 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 */ $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 = "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); $order->update_status('completed', __('Payment has been received', 'monero_gateway')); 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 } } else { $message = "We are waiting for your payment to be confirmed"; } return $message; } public function getamountinfo(){ $wallet_amount = $this->monero_daemon->getbalance(); if(!isset($wallet_amount)){ $this->log->add('Monero_gateway','[ERROR] No connection with daemon'); $wallet_amount['balance'] = "0"; $wallet_amount['unlocked_balance'] = "0"; } $real_wallet_amount = $wallet_amount['balance'] / 1000000000000; $real_amount_rounded = round($real_wallet_amount, 6); $unlocked_wallet_amount = $wallet_amount['unlocked_balance'] / 1000000000000; $unlocked_amount_rounded = round($unlocked_wallet_amount, 6); echo "Your balance is: ".$real_amount_rounded. " XMR
"; echo "Unlocked balance: ".$unlocked_amount_rounded." XMR
"; } }