SatSale

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

woo_satsale.php (7301B)


      1 <?php
      2 /*
      3  * Plugin Name: SatSale
      4  * Plugin URI: https://github.com/nickfarrow/SatSale
      5  * Description: Take Bitcoin payments on your store.
      6  * Author: Nick Farrow
      7  * Author URI: https://nickfarrow.com
      8  * Version: 1.0.1
      9  *
     10 */
     11 
     12 /* Based.
     13 * Based on https://rudrastyh.com/woocommerce/payment-gateway-plugin.html */
     14 
     15 /*
     16  * This action hook registers our PHP class as a WooCommerce payment gateway
     17  */
     18 
     19 // Debugging helper
     20 // Writes to wp-content/debug.log
     21  if (!function_exists('write_log')) {
     22      function write_log($log) {
     23          if (true) {
     24              if (is_array($log) || is_object($log)) {
     25                  error_log(print_r($log, true));
     26              } else {
     27                  error_log($log);
     28              }
     29          }
     30      }
     31  }
     32 
     33 // SatSale class
     34 add_filter( 'woocommerce_payment_gateways', 'satsale_add_gateway_class' );
     35 function satsale_add_gateway_class( $gateways ) {
     36 	$gateways[] = 'WC_Satsale_Gateway';
     37 	return $gateways;
     38 }
     39 
     40 // Extend existing payment gateway
     41 add_action( 'plugins_loaded', 'satsale_init_gateway_class' );
     42 function satsale_init_gateway_class() {
     43 	class WC_Satsale_Gateway extends WC_Payment_Gateway {
     44 
     45         public static $secret = 0;
     46  		/**
     47  		 * Class constructor
     48  		 */
     49  		public function __construct() {
     50 
     51            	$this->id = 'satsale'; // payment gateway plugin ID
     52            	$this->icon = ''; // URL of the icon that will be displayed on checkout page near your gateway name
     53            	$this->has_fields = true; // in case you need a custom credit card form
     54            	$this->method_title = 'SatSale Gateway';
     55            	$this->method_description = 'SatSale payment gateway'; // will be displayed on the options page
     56 
     57            	$this->supports = array(
     58            		'products'
     59            	);
     60 
     61            	// Method with all the options fields
     62            	$this->init_form_fields();
     63 
     64            	// Load the settings.
     65            	$this->init_settings();
     66            	$this->title = $this->get_option( 'title' );
     67            	$this->description = $this->get_option( 'description' );
     68            	$this->enabled = $this->get_option( 'enabled' );
     69             $this->satsale_server_url = $this->get_option( 'satsale_server_url' );
     70             // $this->redirect_url = $this->get_option( 'redirect_url' );
     71            	// $this->testmode = 'yes' === $this->get_option( 'testmode' );
     72            	$this->SatSale_API_Key = $this->get_option( 'SatSale_API_Key' );
     73 
     74             $this->callback_URL = str_replace( 'https:', 'http:', add_query_arg( 'wc-api', 'wc_satsale_gateway', home_url( '/' ) ) );
     75             // $this->callback_URL = home_url( '/' ) . 'wc-api/' . 'WC_SatSale_Gateway/';
     76 
     77            	// This action hook saves the settings
     78            	add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
     79 
     80            	// You can also register a webhook here
     81            	add_action( 'woocommerce_api_wc_satsale_gateway', array( $this, 'webhook' ) );
     82  		}
     83 
     84 		/**
     85  		 * Plugin options
     86  		 */
     87  		public function init_form_fields(){
     88 
     89             	$this->form_fields = array(
     90             		'enabled' => array(
     91             			'title'       => 'Enable/Disable',
     92             			'label'       => 'Enable SatSale Gateway',
     93             			'type'        => 'checkbox',
     94             			'description' => '',
     95             			'default'     => 'no'
     96             		),
     97             		'title' => array(
     98             			'title'       => 'Title',
     99             			'type'        => 'text',
    100             			'description' => 'This controls the title which the user sees during checkout.',
    101             			'default'     => 'Bitcoin',
    102             			'desc_tip'    => true,
    103             		),
    104             		'description' => array(
    105             			'title'       => 'Description',
    106             			'type'        => 'textarea',
    107             			'description' => 'This controls the description which the user sees during checkout.',
    108             			'default'     => 'Pay with Bitcoin via SatSale',
    109             		),
    110                     'satsale_server_url' => array(
    111                         'title'       => 'SatSale URL',
    112                         'type'        => 'text',
    113                         'description' => 'Points towards your instance of SatSale, should be IP or https://SERVER.com',
    114                     ),
    115             		'SatSale_API_Key' => array(
    116             			'title'       => 'SatSale_API_Key',
    117             			'type'        => 'text'
    118             		)
    119             	);
    120 	 	}
    121 
    122 		/*
    123 		 * Processing the payments
    124 		 */
    125          public function process_payment( $order_id ) {
    126 
    127          	global $woocommerce;
    128 
    129          	// we need it to get any order details
    130          	$order = wc_get_order( $order_id );
    131 
    132             // We need to store a signature of the data, and check it later during the webhook to confirm it is the same!
    133          	/*
    134           	 * Array with parameters for API interaction
    135          	 */
    136          	$args = array(
    137                 'amount' => $order->get_total(),
    138                 'w_url' => $this->callback_URL,
    139                 'id' => $order_id
    140 			);
    141 
    142             write_log($args);
    143 
    144             $key = hex2bin($this->SatSale_API_Key);
    145 
    146             $payment_url = add_query_arg(
    147                 $args,
    148                 $this->satsale_server_url . '/pay'
    149             );
    150 
    151             // Redirect to SatSale
    152             return [
    153                 'result'   => 'success',
    154                 'redirect' => $payment_url
    155             ];
    156          }
    157 
    158 		 /*
    159 		 * Webhook to confirm payment
    160 		 */
    161          public function webhook() {
    162             $order = wc_get_order( $_GET['id'] );
    163 			$headers = getallheaders();
    164 
    165 			$now = time(); // current unix timestamp
    166 			$json = json_encode($_GET, JSON_FORCE_OBJECT);
    167             $key = hex2bin($this->SatSale_API_Key);
    168 
    169             // Order secret must match to ensure inital payment url
    170             // had not been tampered when leaving the gateway.
    171             // This secret is generated within the python backend (gateways/woo_webhook.py)
    172             // For the payment to succeed, this will be provided in the success request header
    173             // once the payment has been confirmed by the python backend.
    174             // By confirming it matches the order details (amount * id) we know that
    175             // the order has not been tampered with after leaving the php payment gateway.
    176             $order_secret_seed = (int)($order->get_total() * 100.0);
    177             $order_secret_seed_str = (string)$order_secret_seed;
    178             $secret = hash_hmac('sha256', $order_secret_seed, $key);
    179 
    180             if ($headers['X-Secret'] != $secret) {
    181                 header( 'HTTP/1.1 403 Forbidden' );
    182 				return 1;
    183             }
    184 
    185             // Main Signature.
    186             // Get supplied signature
    187             $signature = $headers['X-Signature'];
    188 
    189             // Calculate expected signature
    190             $valid_signature = hash_hmac('sha256', $_GET['time'] .'.'.$json, $key);
    191 
    192             // Compare signature and timestamps
    193 			if (hash_equals($signature, $valid_signature) and (abs($now - $_GET['time']) < 5)) {
    194 	            header( 'HTTP/1.1 200 OK' );
    195                 // Complete order
    196 	         	$order->payment_complete();
    197 	         	$order->reduce_order_stock();
    198 	         	update_option('webhook_debug', $_GET);
    199 
    200 			} else {
    201 				header( 'HTTP/1.1 403 Forbidden' );
    202 				return 1;
    203 			}
    204 
    205          }
    206  	}
    207 }