SatSale

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

commit a0318a23769596ec5b883a9304d302e250fe7cf7
parent 8cd335f913792895f77ea323f18a99cbc87ac4b2
Author: Nick Farrow <nick@nickfarrow.com>
Date:   Mon, 17 May 2021 18:48:51 +1000

Rename to SatSale from BTCPyment

Diffstat:
MREADME.md | 33+++++++++++++++++----------------
Mconfig.py | 2+-
Mdocs/HTTPS.md | 6+++---
Mdocs/lightning.md | 2+-
Mdocs/woocommerce.md | 12++++++------
Dgateways/woo_btcpyment.php | 206-------------------------------------------------------------------------------
Agateways/woo_satsale.php | 206+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mgateways/woo_webhook.py | 6+++---
Mpay/lnd.py | 19+++++++++----------
Mserver.py | 17+++++++++++------
Mtemplates/donate.html | 6+++---
Mtemplates/index.html | 4++--
12 files changed, 262 insertions(+), 257 deletions(-)

diff --git a/README.md b/README.md @@ -1,16 +1,17 @@ -# BTCPyment +# SatSale +## (previously called BTCPyment) <!---Existing self-custody Bitcoin payment processors are bloated, difficult to install, and not easily customisable.---> -BTCPyment is a simple, easily deployable, lightweight Bitcoin payment processor that connects to your own Bitcoin node or Lightning network node. +SatSale is a simple, easily deployable, lightweight Bitcoin payment processor that connects to your own Bitcoin node or Lightning network node. Donation Button -----> | Bitcoin Payment Gateway :-------------------------:|:-------------------------: [![Donate demo](https://user-images.githubusercontent.com/24557779/108210832-22e33400-7180-11eb-884a-5dbad3cd8f5f.png)](https://try.btcpyment.com/) <br />(Click for embed demo)<br /> Initiates payment -----> | [![Store demo](https://user-images.githubusercontent.com/24557779/108210961-43ab8980-7180-11eb-88e6-cc90d313076d.png)](https://store.btcpyment.com/) <br />(Click for WordPress payments demo) -BTCPyment currently serves as +SatSale currently serves as 1. Donation button for your website that you can easily embed/link to anywhere. 2. A Bitcoin payment gateway, including a Woocommerce plugin that easily turns ANY Wordpress site into a Bitcoin accepting store. -BTCPyment makes donation buttons simple - easy copy paste the one line HTML iframe into your site. With a simple Python backend to talk to your own Bitcoin node, BTCPyment uses RPC to generate new addresses, and monitors the payment status with your own copy of the blockchain. +SatSale makes donation buttons simple - easy copy paste the one line HTML iframe into your site. With a simple Python backend to talk to your own Bitcoin node, SatSale uses RPC to generate new addresses, and monitors the payment status with your own copy of the blockchain. # Features * Process payments with your own Bitcoin node via RPC and SSH. Bitcoin core, or any other node software that supports RPC calls. @@ -21,12 +22,12 @@ BTCPyment makes donation buttons simple - easy copy paste the one line HTML ifra * No shitcoin bloat. Bitcoin only. # Installation (short!) -You require a Raspberry Pi / server (VPS) to host an instance of BTCPyment on, and a connection to a Bitcoin node. If you don't have a Bitcoin node, you should [install one](https://bitcoincore.org/en/download/). +You require a Raspberry Pi / server (VPS) to host an instance of SatSale on, and a connection to a Bitcoin node. If you don't have a Bitcoin node, you should [install one](https://bitcoincore.org/en/download/). ### Install Clone and install dependencies ``` -git clone https://github.com/nickfarrow/BTCPyment -cd BTCPyment/ +git clone https://github.com/nickfarrow/SatSale +cd SatSale/ pip3 install -r requirements.txt ``` ### Connect to your Bitcoin Node @@ -39,16 +40,16 @@ password = "RPCPASSWORD" ``` (You can find these in `~/.bitcoin/bitcoin.conf`). If your node is remote to your server, you can specify an SSH `tunnel_host = "pi@192.168.0.252"` that will forward `rpcport`. You may also need to set `rpcallowip=YOUR_SERVER_IP` in your `~/.bitcoin/bitcoin.conf`. If you want to use lightning network payments, see [Lightning instructions](docs/lightning.md)]. -### Run BTCPyment -Run BTCPyment with +### Run SatSale +Run SatSale with ``` gunicorn --worker-class eventlet -w 1 -b 0.0.0.0:8000 server:app ``` Gunicorn is a lightweight python HTTP server, alternatively you can run with just `python server.py` though this is not recommended for production. -That's it! You should now be able to view your BTCPyment server at `http://YOUR_SERVER_IP:8000/`. If running locally, this will be `127.0.0.1:8000`. +That's it! You should now be able to view your SatSale server at `http://YOUR_SERVER_IP:8000/`. If running locally, this will be `127.0.0.1:8000`. -If running on a Raspberry Pi, you will want to [forward port 8000 in your router settings](https://user-images.githubusercontent.com/24557779/105681219-f0f5fd80-5f44-11eb-942d-b574367a161f.png) so that BTCPYment is also visible at your external IP address. You might have to allow gunicorn through your firewall with `sudo ufw allow 8000`. +If running on a Raspberry Pi, you will want to [forward port 8000 in your router settings](https://user-images.githubusercontent.com/24557779/105681219-f0f5fd80-5f44-11eb-942d-b574367a161f.png) so that SatSale is also visible at your external IP address. You might have to allow gunicorn through your firewall with `sudo ufw allow 8000`. You will want to run gunicorn with nohup so it continues serving in the background: ``` @@ -61,7 +62,7 @@ Now embed the donation button into your website HTML: ```html <iframe src="http://YOUR_SERVER_IP:8000/" style="margin: 0 auto;display:block;width:420px;height:240px;border:none;overflow:hidden;" scrolling="no"></iframe> ``` -Changing `YOUR_SERVER_IP` to the IP address of the machine you're running BTCPyment on. Optionally, you can redirect a domain to that IP and use that instead. +Changing `YOUR_SERVER_IP` to the IP address of the machine you're running SatSale on. Optionally, you can redirect a domain to that IP and use that instead. ### Using HTTPS & Domains Embedded iframes are easy if your site only uses HTTP. But if your site uses HTTPS, then you can see your donation button at `http://YOUR_SERVER_IP:8000/` but will not be able to in an embedded iframe. See [HTTPS instructions](docs/HTTPS.md). @@ -71,11 +72,11 @@ For maximum security, we recommend hosting on a machine where your node only has # Payment Gateway (Woocommerce) -Currently we have a plugin for Woocommerce in Wordpress that makes Bitcoin webstores extremely easy, [please click here for installation instructions](docs/woocommerce.md). BTCPyment acts as a custom payment gateway for Woocommerce via the php plugin found in `/gateways`. We have plans to extend to other web stores in the future. +Currently we have a plugin for Woocommerce in Wordpress that makes Bitcoin webstores extremely easy, [please click here for installation instructions](docs/woocommerce.md). SatSale acts as a custom payment gateway for Woocommerce via the php plugin found in `/gateways`. We have plans to extend to other web stores in the future. # Contributions welcomed ### You only need a little python! -The main code can be found in [server.py](server.py). The client-side logic for the donation button sits in [static/server_connection.js](static/server_connection.js), invoice structure and bitcoind interface in [invoice/](invoice/), button appearance in [template/index.html](template/index.html), and Woocommerce plugin in [gateways/woo_btcpyment.php](gateways/woo_btcpyment.php). Please have ago at implementing some of the things below! +The main code can be found in [server.py](server.py). The client-side logic for the donation button sits in [static/server_connection.js](static/server_connection.js), invoice structure and bitcoind interface in [invoice/](invoice/), button appearance in [template/index.html](template/index.html), and Woocommerce plugin in [gateways/woo_satsale.php](gateways/woo_satsale.php). Please have ago at implementing some of the things below! ![docs/diagram.png](docs/diagram.png) @@ -88,7 +89,7 @@ The main code can be found in [server.py](server.py). The client-side logic for * Variety or easily customisable price feeds # Disclaimer -BTCPyment is in very early development. As such, we are not responsible for any loss of funds, vulnerabilities with software, or any other grievances which may arise. Always confirm large payments manually. +SatSale is in very early development. As such, we are not responsible for any loss of funds, vulnerabilities with software, or any other grievances which may arise. Always confirm large payments manually. # Sponsor -Please consider [supporting me](https://btcpyment.nickfarrow.com) via my own instance of BTCPyment :). Corporate/whale support would greatly assist my ability to give 100% of my attention to BTCPyment and other Bitcoin projects, please email `baseddepartment@nickfarrow.com`. +Please consider [supporting me](https://btcpyment.nickfarrow.com) via my own instance of SatSale :). Corporate/whale support would greatly assist my ability to give 100% of my attention to SatSale and other Bitcoin projects, please email `baseddepartment@nickfarrow.com`. diff --git a/config.py b/config.py @@ -1,7 +1,7 @@ # Bitcoin node connection settings # This should point to your bitcoin/lnd node, # with the correct RPC port as set in your config. -# Connecting through local host as i'm running BTCPyment on the node +# Connecting through local host as i'm running SatSale on my node host = "127.0.0.1" rpcport = "8332" diff --git a/docs/HTTPS.md b/docs/HTTPS.md @@ -1,9 +1,9 @@ ## Using a Subdomain with nginx & certbot (HTTPS) -Embedded iframes are easy if your site only uses HTTP. But if your site uses HTTPS, then you can likely see your donation button at `http://YOUR_SERVER_IP:8000/` but not in the embeded iframe. It is best that we create a new subdomain like `btcpyment.yoursite.com` from which we can serve payments. If you use nginx, you can create a new file `/etc/nginx/sites-enabled/BTCpyment`: +Embedded iframes are easy if your site only uses HTTP. But if your site uses HTTPS, then you can likely see your donation button at `http://YOUR_SERVER_IP:8000/` but not in the embeded iframe. It is best that we create a new subdomain like `satsale.yoursite.com` from which we can serve payments. If you use nginx, you can create a new file `/etc/nginx/sites-enabled/satsale`: ``` server { listen 80; - server_name btcpyment.YOURWEBSITE.com; + server_name satsale.YOURWEBSITE.com; location / { proxy_pass http://localhost:8000; @@ -14,6 +14,6 @@ server { } } ``` -we can now point our domain `btcpyment.YOURWEBSITE.com` DNS to our server IP and create HTTPS certificates by runnining the `certbot` command (or whatever else you use). +we can now point our domain `satsale.YOURWEBSITE.com` DNS to our server IP and create HTTPS certificates by runnining the `certbot` command (or whatever else you use). You could also try provide Gunicorn with your website's HTTPS certificate with the flags `--certfile=cert.pem --keyfile=key.key`. If you use certbot for SSL, your keys are probably in `/etc/letsencrypt/live/`. diff --git a/docs/lightning.md b/docs/lightning.md @@ -14,7 +14,7 @@ lnd_dir = "~/.lnd/" lnd_rpcport = "10009" ``` -Your lnd directory is used to find your `.tls` and `.macaroon` files that are required to talk to your lightning node. They are copied over SSH into your BTCPyment folder. If this copy fails, perhaps copy them manually and they will be identified on start up. +Your lnd directory is used to find your `.tls` and `.macaroon` files that are required to talk to your lightning node. They are copied over SSH into your SatSale folder. If this copy fails, perhaps copy them manually and they will be identified on start up. Your node will require sufficient liquidity and connection to receive payments. diff --git a/docs/woocommerce.md b/docs/woocommerce.md @@ -1,13 +1,13 @@ # Woocommerce Payment Gateway -To install the woocommerce payment gateway plugin, first copy [/gateways/woo_btcpyment.php](/gateways/woo_btcpyment.php) to your Wordpress site in `wp-content/plugins/`. +To install the woocommerce payment gateway plugin, first copy [/gateways/woo_satsale.php](/gateways/woo_satsale.php) to your Wordpress site in `wp-content/plugins/`. -Next, in your Wordpress admin area, go to the plugins section and activate BTCPyment. Then go to the Woocommerce settings and the "Payments" tab. Enable BTCPyment as a payment gateway. +Next, in your Wordpress admin area, go to the plugins section and activate SatSale. Then go to the Woocommerce settings and the "Payments" tab. Enable SatSale as a payment gateway. ![Woocommerce Settings](https://user-images.githubusercontent.com/24557779/104807944-c74b2100-5836-11eb-8dba-dfaf8b5f5e1f.png) -Click 'Set Up'/'Manage' and fill out the required fields and point towards your BTCPyment instance. You will need to copy the contents of `BTCPyment/BTCPyment_API_key` into your API key field. This is generated after running BTCPyment for the first time. -![BTCPyment Settings](https://user-images.githubusercontent.com/24557779/105259537-164ed880-5be0-11eb-9785-9b2208ad04cb.png) +Click 'Set Up'/'Manage' and fill out the required fields and point towards your SatSale instance. You will need to copy the contents of `SatSale/SatSale_API_key` into your API key field. This is generated after running SatSale for the first time. +![SatSale Settings](https://user-images.githubusercontent.com/24557779/105259537-164ed880-5be0-11eb-9785-9b2208ad04cb.png) -Now you should be able to view BTCPyment as an option in your checkout: -![BTCPyment in Checkout](https://user-images.githubusercontent.com/24557779/105259742-7776ac00-5be0-11eb-82fd-9d82a7f1316b.png) +Now you should be able to view SatSale as an option in your checkout: +![SatSale in Checkout](https://user-images.githubusercontent.com/24557779/105259742-7776ac00-5be0-11eb-82fd-9d82a7f1316b.png) That's it! Please reach out if there are some further features you desire in this plugin. diff --git a/gateways/woo_btcpyment.php b/gateways/woo_btcpyment.php @@ -1,206 +0,0 @@ -<?php -/* - * Plugin Name: BTCPyment - * Plugin URI: https://github.com/nickfarrow/BTCPyment - * Description: Take Bitcoin payments on your store. - * Author: Nick Farrow - * Author URI: https://nickfarrow.com - * Version: 1.0.1 - * -*/ - -/* Based. -* Based on https://rudrastyh.com/woocommerce/payment-gateway-plugin.html */ - -/* - * This action hook registers our PHP class as a WooCommerce payment gateway - */ - -// Debugging helper -// Writes to wp-content/debug.log - if (!function_exists('write_log')) { - function write_log($log) { - if (true) { - if (is_array($log) || is_object($log)) { - error_log(print_r($log, true)); - } else { - error_log($log); - } - } - } - } - -// BTCPyment class -add_filter( 'woocommerce_payment_gateways', 'btcpyment_add_gateway_class' ); -function btcpyment_add_gateway_class( $gateways ) { - $gateways[] = 'WC_Btcpyment_Gateway'; - return $gateways; -} - -// Extend existing payment gateway -add_action( 'plugins_loaded', 'btcpyment_init_gateway_class' ); -function btcpyment_init_gateway_class() { - class WC_Btcpyment_Gateway extends WC_Payment_Gateway { - - public static $secret = 0; - /** - * Class constructor - */ - public function __construct() { - - $this->id = 'btcpyment'; // payment gateway plugin ID - $this->icon = ''; // URL of the icon that will be displayed on checkout page near your gateway name - $this->has_fields = true; // in case you need a custom credit card form - $this->method_title = 'BTCPyment Gateway'; - $this->method_description = 'Description of btcpyment payment gateway'; // will be displayed on the options page - - $this->supports = array( - 'products' - ); - - // Method with all the options fields - $this->init_form_fields(); - - // Load the settings. - $this->init_settings(); - $this->title = $this->get_option( 'title' ); - $this->description = $this->get_option( 'description' ); - $this->enabled = $this->get_option( 'enabled' ); - $this->btcpyment_server_url = $this->get_option( 'btcpyment_server_url' ); - // $this->redirect_url = $this->get_option( 'redirect_url' ); - // $this->testmode = 'yes' === $this->get_option( 'testmode' ); - $this->BTCPyment_API_Key = $this->get_option( 'BTCPyment_API_Key' ); - - $this->callback_URL = str_replace( 'https:', 'http:', add_query_arg( 'wc-api', 'wc_btcpyment_gateway', home_url( '/' ) ) ); - // $this->callback_URL = home_url( '/' ) . 'wc-api/' . 'WC_Btcpyment_Gateway/'; - - // This action hook saves the settings - add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); - - // You can also register a webhook here - add_action( 'woocommerce_api_wc_btcpyment_gateway', array( $this, 'webhook' ) ); - } - - /** - * Plugin options - */ - public function init_form_fields(){ - - $this->form_fields = array( - 'enabled' => array( - 'title' => 'Enable/Disable', - 'label' => 'Enable btcpyment Gateway', - 'type' => 'checkbox', - 'description' => '', - 'default' => 'no' - ), - 'title' => array( - 'title' => 'Title', - 'type' => 'text', - 'description' => 'This controls the title which the user sees during checkout.', - 'default' => 'Bitcoin', - 'desc_tip' => true, - ), - 'description' => array( - 'title' => 'Description', - 'type' => 'textarea', - 'description' => 'This controls the description which the user sees during checkout.', - 'default' => 'Pay with Bitcoin via BTCPyment', - ), - 'btcpyment_server_url' => array( - 'title' => 'BTCPyment URL', - 'type' => 'text', - 'description' => 'Points towards your instance of BTCPyment, should be IP or https://SERVER.com', - ), - 'BTCPyment_API_Key' => array( - 'title' => 'BTCPyment_API_Key', - 'type' => 'text' - ) - ); - } - - /* - * Processing the payments - */ - public function process_payment( $order_id ) { - - global $woocommerce; - - // we need it to get any order detailes - $order = wc_get_order( $order_id ); - - // We need to store a signature of the data, and check it later during the webhook to confirm it is the same! - /* - * Array with parameters for API interaction - */ - $args = array( - 'amount' => $order->get_total(), - 'id' => $order->get_id(), - 'w_url' => $this->callback_URL ); - - write_log($args); - - $key = hex2bin($this->BTCPyment_API_Key); - - $payment_url = add_query_arg( - $args, - $this->btcpyment_server_url . "/pay" - ); - - // Redirect to BTCPyment - return [ - 'result' => 'success', - 'redirect' => $payment_url - ]; - } - - /* - * Webhook to confirm payment - */ - public function webhook() { - $order = wc_get_order( $_GET['id'] ); - $headers = getallheaders(); - - $now = time(); // current unix timestamp - $json = json_encode($_GET, JSON_FORCE_OBJECT); - $key = hex2bin($this->BTCPyment_API_Key); - - // Order secret must match to ensure inital payment url - // had not been tampered when leaving the gateway. - // This secret is generated within the python backend (gateways/woo_webhook.py) - // For the payment to succeed, this will be provided in the success request header - // once the payment has been confirmed by the python backend. - // By confirming it matches the order details (amount * id) we know that - // the order has not been tampered with after leaving the php payment gateway. - $order_secret_seed = (int)($order->get_total() * 100.0 * $order->get_id()); - $order_secret_seed_str = (string)$order_secret_seed; - $secret = hash_hmac('sha256', $order_secret_seed, $key); - - if ($headers['X-Secret'] != $secret) { - header( 'HTTP/1.1 403 Forbidden' ); - return 1; - } - - // Main Signature. - // Get supplied signature - $signature = $headers['X-Signature']; - - // Calculate expected signature - $valid_signature = hash_hmac('sha256', $_GET['time'] .'.'.$json, $key); - - // Compare signature and timestamps - if (hash_equals($signature, $valid_signature) and (abs($now - $_GET['time']) < 5)) { - header( 'HTTP/1.1 200 OK' ); - // Complete order - $order->payment_complete(); - $order->reduce_order_stock(); - update_option('webhook_debug', $_GET); - - } else { - header( 'HTTP/1.1 403 Forbidden' ); - return 1; - } - - } - } -} diff --git a/gateways/woo_satsale.php b/gateways/woo_satsale.php @@ -0,0 +1,206 @@ +<?php +/* + * Plugin Name: SatSale + * Plugin URI: https://github.com/nickfarrow/SatSale + * Description: Take Bitcoin payments on your store. + * Author: Nick Farrow + * Author URI: https://nickfarrow.com + * Version: 1.0.1 + * +*/ + +/* Based. +* Based on https://rudrastyh.com/woocommerce/payment-gateway-plugin.html */ + +/* + * This action hook registers our PHP class as a WooCommerce payment gateway + */ + +// Debugging helper +// Writes to wp-content/debug.log + if (!function_exists('write_log')) { + function write_log($log) { + if (true) { + if (is_array($log) || is_object($log)) { + error_log(print_r($log, true)); + } else { + error_log($log); + } + } + } + } + +// SatSale class +add_filter( 'woocommerce_payment_gateways', 'satsale_add_gateway_class' ); +function satsale_add_gateway_class( $gateways ) { + $gateways[] = 'WC_Satsale_Gateway'; + return $gateways; +} + +// Extend existing payment gateway +add_action( 'plugins_loaded', 'satsale_init_gateway_class' ); +function satsale_init_gateway_class() { + class WC_Satsale_Gateway extends WC_Payment_Gateway { + + public static $secret = 0; + /** + * Class constructor + */ + public function __construct() { + + $this->id = 'satsale'; // payment gateway plugin ID + $this->icon = ''; // URL of the icon that will be displayed on checkout page near your gateway name + $this->has_fields = true; // in case you need a custom credit card form + $this->method_title = 'SatSale Gateway'; + $this->method_description = 'SatSale payment gateway'; // will be displayed on the options page + + $this->supports = array( + 'products' + ); + + // Method with all the options fields + $this->init_form_fields(); + + // Load the settings. + $this->init_settings(); + $this->title = $this->get_option( 'title' ); + $this->description = $this->get_option( 'description' ); + $this->enabled = $this->get_option( 'enabled' ); + $this->SatSale_server_url = $this->get_option( 'satsale_server_url' ); + // $this->redirect_url = $this->get_option( 'redirect_url' ); + // $this->testmode = 'yes' === $this->get_option( 'testmode' ); + $this->SatSale_API_Key = $this->get_option( 'SatSale_API_Key' ); + + $this->callback_URL = str_replace( 'https:', 'http:', add_query_arg( 'wc-api', 'wc_satsale_gateway', home_url( '/' ) ) ); + // $this->callback_URL = home_url( '/' ) . 'wc-api/' . 'WC_SatSale_Gateway/'; + + // This action hook saves the settings + add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); + + // You can also register a webhook here + add_action( 'woocommerce_api_wc_satsale_gateway', array( $this, 'webhook' ) ); + } + + /** + * Plugin options + */ + public function init_form_fields(){ + + $this->form_fields = array( + 'enabled' => array( + 'title' => 'Enable/Disable', + 'label' => 'Enable SatSale Gateway', + 'type' => 'checkbox', + 'description' => '', + 'default' => 'no' + ), + 'title' => array( + 'title' => 'Title', + 'type' => 'text', + 'description' => 'This controls the title which the user sees during checkout.', + 'default' => 'Bitcoin', + 'desc_tip' => true, + ), + 'description' => array( + 'title' => 'Description', + 'type' => 'textarea', + 'description' => 'This controls the description which the user sees during checkout.', + 'default' => 'Pay with Bitcoin via SatSale', + ), + 'satsale_server_url' => array( + 'title' => 'SatSale URL', + 'type' => 'text', + 'description' => 'Points towards your instance of SatSale, should be IP or https://SERVER.com', + ), + 'SatSale_API_Key' => array( + 'title' => 'SatSale_API_Key', + 'type' => 'text' + ) + ); + } + + /* + * Processing the payments + */ + public function process_payment( $order_id ) { + + global $woocommerce; + + // we need it to get any order detailes + $order = wc_get_order( $order_id ); + + // We need to store a signature of the data, and check it later during the webhook to confirm it is the same! + /* + * Array with parameters for API interaction + */ + $args = array( + 'amount' => $order->get_total(), + 'id' => $order->get_id(), + 'w_url' => $this->callback_URL ); + + write_log($args); + + $key = hex2bin($this->SatSale_API_Key); + + $payment_url = add_query_arg( + $args, + $this->satsale_server_url . "/pay" + ); + + // Redirect to SatSale + return [ + 'result' => 'success', + 'redirect' => $payment_url + ]; + } + + /* + * Webhook to confirm payment + */ + public function webhook() { + $order = wc_get_order( $_GET['id'] ); + $headers = getallheaders(); + + $now = time(); // current unix timestamp + $json = json_encode($_GET, JSON_FORCE_OBJECT); + $key = hex2bin($this->SatSale_API_Key); + + // Order secret must match to ensure inital payment url + // had not been tampered when leaving the gateway. + // This secret is generated within the python backend (gateways/woo_webhook.py) + // For the payment to succeed, this will be provided in the success request header + // once the payment has been confirmed by the python backend. + // By confirming it matches the order details (amount * id) we know that + // the order has not been tampered with after leaving the php payment gateway. + $order_secret_seed = (int)($order->get_total() * 100.0 * $order->get_id()); + $order_secret_seed_str = (string)$order_secret_seed; + $secret = hash_hmac('sha256', $order_secret_seed, $key); + + if ($headers['X-Secret'] != $secret) { + header( 'HTTP/1.1 403 Forbidden' ); + return 1; + } + + // Main Signature. + // Get supplied signature + $signature = $headers['X-Signature']; + + // Calculate expected signature + $valid_signature = hash_hmac('sha256', $_GET['time'] .'.'.$json, $key); + + // Compare signature and timestamps + if (hash_equals($signature, $valid_signature) and (abs($now - $_GET['time']) < 5)) { + header( 'HTTP/1.1 200 OK' ); + // Complete order + $order->payment_complete(); + $order->reduce_order_stock(); + update_option('webhook_debug', $_GET); + + } else { + header( 'HTTP/1.1 403 Forbidden' ); + return 1; + } + + } + } +} diff --git a/gateways/woo_webhook.py b/gateways/woo_webhook.py @@ -6,8 +6,8 @@ import time import requests -def hook(btcpyment_secret, payload, payment): - key = codecs.decode(btcpyment_secret, "hex") +def hook(satsale_secret, payload, payment): + key = codecs.decode(satsale_secret, "hex") # Calculate a secret that is required to send back to the # woocommerce gateway, proving we did not modify id nor amount. @@ -21,7 +21,7 @@ def hook(btcpyment_secret, payload, payment): # The main signature which proves we have paid, and very recently! paid_time = int(time.time()) params = { - "wc-api": "wc_btcpyment_gateway", + "wc-api": "wc_satsale_gateway", "id": payload["id"], "time": str(paid_time), } diff --git a/pay/lnd.py b/pay/lnd.py @@ -17,7 +17,7 @@ class lnd(invoice): from lndgrpc import LNDClient - # Copy invoice macaroon and tls cert to local machine + # Copy admin macaroon and tls cert to local machine self.copy_certs() # Conect to lightning node @@ -40,7 +40,8 @@ class lnd(invoice): if test: print("Getting lnd info...") - self.lnd.list_invoices() + info = self.lnd.get_info() + print(info) print("Successfully contacted lnd.") break @@ -63,22 +64,20 @@ class lnd(invoice): # Copy tls and macaroon certs from remote machine. def copy_certs(self): - self.certs = {'tls' : config.lnd_cert, 'macaroon' : config.lnd_macaroon} + self.certs = {'tls' : 'tls.cert', 'macaroon' : 'admin.macaroon'} - if (not os.path.isfile(config.lnd_cert)) or (not os.path.isfile(config.lnd_macaroon)): + if (not os.path.isfile("tls.cert")) or (not os.path.isfile("admin.macaroon")): try: tls_file = os.path.join(config.lnd_dir, "tls.cert") macaroon_file = os.path.join( - config.lnd_dir, "data/chain/bitcoin/mainnet/invoice.macaroon" + config.lnd_dir, "data/chain/bitcoin/mainnet/admin.macaroon" ) # SSH copy if config.tunnel_host is not None: print( - "Could not find {} or {} \ - Attempting to download from remote lnd directory.".format( - config.lnd_cert, config.lnd_macaroon - ) + "Could not find tls.cert or admin.macaroon in SatSale folder. \ + Attempting to download from remote lnd directory." ) subprocess.run( @@ -101,7 +100,7 @@ class lnd(invoice): print(e) print("Failed to copy tls and macaroon files to local machine.") else: - print("Found tls.cert and invoice.macaroon.") + print("Found tls.cert and admin.macaroon.") return # Create lightning invoice diff --git a/server.py b/server.py @@ -15,11 +15,11 @@ async_mode = None app = Flask(__name__) # Load an API key or create a new one -if os.path.exists("BTCPyment_API_key"): - with open(config.api_key_path, "r") as f: +if os.path.exists("SatSale_API_key"): + with open("SatSale_API_key", "r") as f: app.config["SECRET_KEY"] = f.read().strip() else: - with open(config.api_key_path, "w") as f: + with open("SatSale_API_key", "w") as f: app.config["SECRET_KEY"] = os.urandom(64).hex() f.write(app.config["SECRET_KEY"]) @@ -53,7 +53,6 @@ def index(): # /pay is the main payment method for initiating a payment websocket. @app.route("/pay") def payment_page(): - # Arguments passed to HTML and also server_connection.js params = dict(request.args) params['lnd_enabled'] = (config.pay_method == "lnd") # Render payment page with the request arguments (?amount= etc.) @@ -112,6 +111,14 @@ def make_payment(payload): print("Successfully confirmed payment via webhook.") update_status(payment, "Order confirmed.") + # Redirect after payment + # TODO: add a delay here. Test. + if config.redirect is not None: + print("Redirecting to {}".format(config.redirect)) + return redirect(config.redirect) + else: + print("No redirect, closing.") + return @@ -133,8 +140,6 @@ def update_status(payment, status, console_status=True): "time_left": payment.time_left, "uuid": payment.uuid, "response": payment.response, - "paid": payment.paid, - "redirect": config.redirect # Can later expand to invoice specific redirects. }, ) return diff --git a/templates/donate.html b/templates/donate.html @@ -1,7 +1,7 @@ <!DOCTYPE HTML> <html> <head> - <title>Donate Bitcoin - BTCPyment</title> + <title>Donate Bitcoin</title> <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}"> <script src="//code.jquery.com/jquery-1.12.4.min.js"></script> @@ -16,14 +16,14 @@ <!-- Open Graph / Facebook --> <meta property="og:type" content="website"> - <meta property="og:url" content="https://try.btcpyment.com/"> + <meta property="og:url" content="https://try.SatSale.com/"> <meta property="og:title" content="Donate Bitcoin"> <meta property="og:description" content="Lightweight Bitcoin payment processor written in easily deployable Python. "> <meta property="og:image" content="https://user-images.githubusercontent.com/24557779/109666538-60ee4800-7bc3-11eb-8615-2cb1b239cc11.png"> <!-- Twitter --> <meta property="twitter:card" content="summary_large_image"> - <meta property="twitter:url" content="https://try.btcpyment.com/"> + <meta property="twitter:url" content="https://try.SatSale.com/"> <meta property="twitter:title" content="Donate Bitcoin"> <meta property="twitter:description" content="Lightweight Bitcoin payment processor written in easily deployable Python. "> <meta property="twitter:image" content="https://user-images.githubusercontent.com/24557779/109666538-60ee4800-7bc3-11eb-8615-2cb1b239cc11.png"> diff --git a/templates/index.html b/templates/index.html @@ -1,7 +1,7 @@ <!DOCTYPE HTML> <html> <head> - <title>BTCPyment</title> + <title>SatSale</title> <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}"> <script src="//code.jquery.com/jquery-1.12.4.min.js"></script> @@ -56,7 +56,7 @@ </div> <div id="right" style="text-align: right; padding: 10px 10px;"> - <small style="vertical-align:middle"><a id="about" href="https://github.com/nickfarrow/BTCPyment" target="_blank">BTCPyment</a></small> + <small style="vertical-align:middle"><a id="about" href="https://github.com/nickfarrow/SatSale" target="_blank">SatSale</a></small> </div> </div> </div>