WordPress plugin to accept HUSH payments in WooCommerce.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

291 lines
11 KiB

<?php
/**
* Plugin Name: HUSH WooCommerce Gateway
* Plugin URI: https://hush.is
* Description: Allows your WooCommerce store to accept HUSH for payment
* Version: 1.0.0
* Author: Hush Developers
* Text Domain: hush-wc-gateway
* Domain Path: /i18n/languages/
*
* Copyright: (c) 2022 Hush Developers and WooCommerce
*
* License: GNU General Public License v3.0
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
*
* @package WC-Hush-Gateway
* @author Hush Developers
* @category Admin
* @copyright Copyright (c) 2022 Hush Developers and WooCommerce
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
*
*/
defined( 'ABSPATH' ) or exit;
// Include phpqrcode lib
include_once('phpqrcode.php');
// Make sure WooCommerce is active
if ( ! in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
return;
}
/**
* Add the gateway to WC Available Gateways
*
* @since 1.0.0
* @param array $gateways all available WC gateways
* @return array $gateways all WC gateways + hush gateway
*/
add_filter( 'woocommerce_payment_gateways', 'hush_add_to_gateways' );
function hush_add_to_gateways( $gateways ) {
$gateways[] = 'Hush_WC_Gateway';
return $gateways;
}
/**
* Adds plugin page links
*
* @since 1.0.0
* @param array $links all plugin links
* @return array $links all plugin links + our custom links (i.e., "Settings")
*/
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'hush_gateway_plugin_links' );
function hush_gateway_plugin_links( $links ) {
$plugin_links = array(
'<a href="' . admin_url( 'admin.php?page=wc-settings&tab=checkout&section=hush_gateway' ) . '">' . __( 'Configure', 'hush-wc-gateway' ) . '</a>'
);
return array_merge( $plugin_links, $links );
}
/**
* Set and save expected Hush payment details when order created
*/
add_action('woocommerce_checkout_create_order', 'set_hush_payment_details', 20, 2);
function set_hush_payment_details( $order, $data ) {
// Get order amount
$orderAmt = $order->get_total();
// Get plugin options
$options = get_option('woocommerce_hush_gateway_settings', 'default text');
// Get HUSH price from CoinGecko and convert amount to send
$request = wp_remote_get('https://api.coingecko.com/api/v3/simple/price?ids=hush&vs_currencies=btc%2Cusd%2Ceur%2Ceth%2Cgbp%2Ccny%2Cjpy%2Cidr%2Crub%2Ccad%2Csgd%2Cchf%2Cinr%2Caud%2Cinr%2Ckrw%2Cthb%2Cnzd%2Czar%2Cvef%2Cxau%2Cxag%2Cvnd%2Csar%2Ctwd%2Caed%2Cars%2Cbdt%2Cbhd%2Cbmd%2Cbrl%2Cclp%2Cczk%2Cdkk%2Chuf%2Cils%2Ckwd%2Clkr%2Cpkr%2Cnok%2Ctry%2Csek%2Cmxn%2Cuah%2Chkd&include_market_cap=true&include_24hr_vol=true&include_24hr_change=true');
if( is_wp_error( $request ) ) {
return false;
}
$body = wp_remote_retrieve_body( $request );
$data = json_decode( $body, true);
if( ! empty( $data ) ) {
$hushPrice = $data['hush']['usd'];
}
// Convert addresses to an array
$hushAddressArray = explode(",", $options['hushAddresses']);
// Shuffle for random address
shuffle($hushAddressArray);
$hushAddress = trim($hushAddressArray[0]);
// Get volatility markup option
$markup = $options['volatilityMarkup'];
// Set amount that should be sent based on USD and markup
$hushAmt = $orderAmt / $hushPrice;
$hushAmt = $hushAmt + ($hushAmt * $markup);
$hushAmt = number_format((float)$hushAmt, 8, '.', '');
// Save payment instruction related meta for verifying orders later
$order->update_meta_data( '_hush_price', $hushPrice );
$order->update_meta_data( '_hush_receive_address', $hushAddress);
$order->update_meta_data( '_hush_expected', $hushAmt );
$order->save();
}
/**
* Display expected HUSH payment details on the admin order edit page
*/
add_action( 'woocommerce_admin_order_data_after_billing_address', 'hush_display_admin_order_meta', 10, 1 );
function hush_display_admin_order_meta($order){
echo "<p><strong>Receive Address:</strong> ". get_post_meta( $order->get_id(), '_hush_receive_address', true ) . "</p>";
echo "<p><strong>Expected HUSH:</strong> ". get_post_meta( $order->get_id(), '_hush_expected', true ) . "</p>";
echo "<p><strong>Exchange Rate:</strong> $". get_post_meta( $order->get_id(), '_hush_price', true ) . " USD </p>";
}
/**
* Hush Payment Gateway
* Provides simple instructions for customers to pay with Hush
* We load it later to ensure WC is loaded first since we're extending it.
*
* @class Hush_WC_Gateway
* @extends WC_Payment_Gateway
* @version 1.0.0
* @package WooCommerce/Classes/Payment
* @author Hush Developers
*/
add_action( 'plugins_loaded', 'hush_gateway_init', 11 );
function hush_gateway_init() {
class Hush_WC_Gateway extends WC_Payment_Gateway {
/**
* Constructor for the gateway.
*/
public function __construct() {
$this->id = 'hush_gateway';
$this->icon = apply_filters('woocommerce_hush_icon', '');
$this->has_fields = false;
$this->method_title = __( 'HUSH', 'hush-wc-gateway' );
$this->method_description = __( 'Provides simple instructions for customers to pay with HUSH', 'hush-wc-gateway' );
// Load the settings.
$this->init_form_fields();
$this->init_settings();
// Define user set variables
$this->title = $this->get_option( 'title' );
$this->volatilityMarkup = $this->get_option( 'volatilityMarkup' );
$this->checkoutInstructions = $this->get_option( 'checkoutInstructions' );
$this->hushAddresses = $this->get_option( 'hushAddresses' );
// Actions
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
add_action( 'woocommerce_thankyou_' . $this->id, array( $this, 'thankyou_page' ) );
}
/**
* Initialize Gateway Settings Form Fields
* This is where the Store Owners will enter all of their Hush Settings.
*/
public function init_form_fields() {
$this->form_fields = apply_filters( 'hush_form_fields', array(
'enabled' => array(
'title' => __( 'Enable/Disable:', 'hush-wc-gateway' ),
'type' => 'checkbox',
'label' => __( 'Enable HUSH', 'hush-wc-gateway' ),
'default' => 'yes'
),
'checkoutInstructions' => array(
'title' => __( 'Checkout Payment Instructions:', 'hush-wc-gateway' ),
'type' => 'textarea',
'description' => __( 'This text will be displayed on the order confirmation/thank you page, letting the customer know where to send payment.' ),
'default' => __( 'Thank you for supporting the Hush network. Manual payment instructions are below. Your order will remain on hold until payment is manually verified as being received. Please send payment as soon as possible. We reserve the right to cancel any orders due to extreme market volatility conditions.', 'hush-wc-gateway' ),
'desc_tip' => true,
),
'title' => array(
'title' => __( 'Title:', 'hush-wc-gateway' ),
'type' => 'text',
'description' => __( 'This controls the title for the payment method the customer sees during checkout.', 'hush-wc-gateway' ),
'default' => __( 'HUSH', 'hush-wc-gateway' ),
'desc_tip' => true,
),
'hushAddresses' => array(
'title' => __( 'HUSH Address:', 'hush-wc-gateway' ),
'type' => 'textarea',
'description' => __( 'Enter a comma separated list of Hush addresses to be used for receiving payments. You can enter as many as you want and update this setting as often as you like for added privacy. During checkout, 1 address from this list will be chosen randomly for the customer to send payment to. It is recommended to submit at least 10 addresses and change once a month for privacy.' ),
'default' => __( '', 'hush-wc-gateway' ),
'desc_tip' => true,
),
'volatilityMarkup' => array(
'title' => __( 'Volatility markup:', 'hush-wc-gateway' ),
'type' => 'text',
'description' => __( 'This allows setting a percentage markup to apply to current HUSH price to help with any market volatility. Enter as decimal (IE: 2% markup enter as 0.02)', 'hush-wc-gateway' ),
'default' => __( '0.02', 'hush-wc-gateway' ),
'desc_tip' => true,
),
) );
}
/**
* Output for the order received page.
*/
public function thankyou_page( $order_id ) {
// Get Hush price at time of order
$hushPrice = get_post_meta($order_id, '_hush_price', true);
// Get address to send to
$hushAddress = get_post_meta($order_id, '_hush_receive_address', true);
// Get expected amount to be received
$hushAmt = get_post_meta($order_id, '_hush_expected', true);
// Generate HUSH URI
$hushURI = "hush:".$hushAddress."?amt=".$hushAmt;
// Generate QR Code
$timestamp = $_SERVER['REQUEST_TIME'];
$upload_dir = wp_upload_dir();
$upload_dir = $upload_dir['basedir'] . '/' . "hush/";
if(!file_exists($upload_dir)) wp_mkdir_p($upload_dir);
QRcode::png($hushAddress, $upload_dir.'qr_code-'.$timestamp.'.png', QR_ECLEVEL_L, 8);
// Display instructions for customer to send payment to
$htmlOutput .= "<h2>HUSH Payment Instructions</h2>";
$htmlOutput .= $this->checkoutInstructions."<br/><br/>";
$htmlOutput .= "<strong>Address to send HUSH to: </strong><input type='text' value='".$hushAddress."' id='hushAddress' style='width:100%'/><br/><br/>";
$htmlOutput .= "<strong>Amount to send: </strong>(Exchange Rate is </strong>".$hushPrice." USD + ". $this->volatilityMarkup * 100 ."% volatility markup)<br/><input type='text' value='".$hushAmt."' id='hushAmt' style='width:100%'/><br/><br/>";
$htmlOutput .= "<strong>Memo</strong> is not required, but you may include with any message, notes, or special instructions<br/><br/>";
$htmlOutput .= "An auto-generated HUSH URI may be used instead for easier/quicker payment. In lite or full wallet, go to <strong>File > Pay HUSH URI</strong> and copy paste the URI below. Do not modify this URI. Orders will only be fulfilled if expected amount of HUSH is received.<br/><br/>";
$htmlOutput .= "<strong>Pay HUSH URI: </strong><input type='text' value='".$hushURI."' id='hushURI' style='width:100%'/><br/><br/>";
$htmlOutput .= "<strong>Silent Dragon Android QR Code: </strong><br/><img src='/wp-content/uploads/hush/qr_code-".$timestamp.".png' /><br/><br/>";
echo $htmlOutput;
}
/**
* Process the payment and return the result
* This will put the order into on-hold status, reduce inventory levels, and empty customer shopping cart.
*
* @param int $order_id
* @return array
*/
public function process_payment( $order_id ) {
$order = wc_get_order( $order_id );
// Mark as on-hold (we're awaiting the payment)
$order->update_status( 'on-hold', __( 'Awaiting HUSH payment', 'hush-wc-gateway' ) );
// Reduce stock levels
wc_reduce_stock_levels($order_id);
// Remove cart
WC()->cart->empty_cart();
// Return thankyou redirect
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order )
);
}
} // end \Hush_WC_Gateway class
}