Compare commits

...

24 Commits

Author SHA1 Message Date
Nicolas Dorier
2e4673c832
Update README.md 2021-01-11 11:34:33 +09:00
Nicolas Dorier
7ba9816e25
Update README.md 2021-01-11 11:31:45 +09:00
Adrien Bensaïbi
8e088c737a
Merge pull request #11 from btcpayserver/improvments
Improvments
2019-02-04 16:48:16 +01:00
Adrien Bensaïbi
257724c584 fix: rm old logs 2019-02-04 16:47:21 +01:00
Adrien Bensaïbi
4a5ce954dc fix: respect class convention 2019-02-03 02:07:25 +01:00
Adrien Bensaïbi
04658e4e92 fix: add some sleep to let order_bitcoin update 2019-02-02 22:45:29 +01:00
Adrien Bensaïbi
c6bb530fa2 chore: dump version 2019-02-02 19:18:31 +01:00
Adrien Bensaïbi
87092e062f feat: cleaning and links 2019-02-02 19:16:50 +01:00
Adrien Bensaïbi
96601c9222 doc: resolve #8 small notice about servers access 2019-02-02 18:34:09 +01:00
Adrien Bensaïbi
67dba23743
Merge pull request #10 from btcpayserver/fix-currency
fix: multi currency instead of euro only
2019-02-02 18:17:40 +01:00
Adrien Bensaïbi
04ec130145 fix: multi currency instead of euro only 2019-02-02 18:03:12 +01:00
Adrien Bensaïbi
e523d46703
Merge pull request #9 from btcpayserver/fix-syntax-associative-array
Fix syntax associative array
2019-02-02 17:17:57 +01:00
Adrien B
dcccf8903c doc: add bcmath deps to GUIDE.md 2019-02-02 17:09:43 +01:00
Adrien Bensaïbi
cf09154f25 fix #7: string instead of constante in ipn 2019-01-11 23:48:41 +01:00
Adrien Bensaïbi
85ea627829
doc(README): update TODOs 2018-09-18 09:54:41 +02:00
Adrien Bensaïbi
a6ff243b9c
Merge pull request #4 from btcpayserver/feat-txspeed-and-ordermode
Feat txspeed and ordermode
2018-09-17 10:55:09 +02:00
Adrien Bensaïbi
8222972a0b fix: version in xmls 2018-09-17 10:51:05 +02:00
Adrien Bensaïbi
fa499693cf fix: order mode info
fix: update order state history
2018-09-17 10:50:07 +02:00
Adrien Bensaïbi
3b6b3b56d5 fix: update payment status in case ordermode is 'beforepayment' 2018-08-06 10:29:07 +02:00
Adrien Bensaïbi
0fb32d6407 feat: order mode selection 2018-08-06 01:10:41 +02:00
Adrien Bensaïbi
1444b8479a feat: re-add txspeed 2018-08-05 23:44:46 +02:00
Adrien Bensaïbi
2d8c604ad0
Merge pull request #3 from btcpayserver/fix-ipn
fix: typo on check invoice
2018-07-20 11:41:32 +02:00
Adrien Bensaïbi
4035e47757 fix: typo on check invoice
Authored-by: star0422<anonymous@random.guy>
2018-07-20 11:32:10 +02:00
Adrien Bensaïbi
9f5f3676ec fix: order state initialization for ps
fix: unused vars

Signed-off-by: Adrien Bensaïbi <adrien@adapp.tech>
2018-05-12 22:43:58 +02:00
13 changed files with 577 additions and 182 deletions

View File

@ -5,8 +5,8 @@
1.7.0 (19 June 2017)
* Now compatible with PrestaShop 1.6 and 1.7
1.5.0 (11 March 2015)
1.5.0 (11 March 2015)
* Now compatible with PrestaShop 1.5+
Version 0.5
* Tested against PrestaShop v1.5.4.1 and 1.6.0.5
* Tested against PrestaShop v1.5.4.1 and 1.6.0.5

View File

@ -16,11 +16,14 @@ If you want to test in test mode, just paste an other btcpayserver url with test
+ PHP 5+
+ Curl PHP Extension
+ JSON PHP Extension
+ Install PHP bcmath module
+ be sure your BTCPay server is whitelisted by Prestashop server
+ be sure your Prestashop server is whitelisted by BTCPay server
## Plugin Configuration
### For Prestashop versions 1.7:
1. Download the latest release from https://github.com/adapp-tech/prestashop-plugin/releases
1. Download the latest release from https://github.com/btcpayserver/prestashop-plugin/releases
2. Go to your PrestaShop administration. Under "Modules and services" select "Upload a module" (v1.7)
3. Go to your "installed modules" -> "BTCPay" and click [Configure]<br />
4. Go on your BTCPay server, in your store and display access tokens.

View File

@ -1,3 +1,5 @@
> :warning: THIS PLUGIN IS FUNCTIONING BUT DEPRECATED, USE https://github.com/btcpayserver/prestashop-plugin INSTEAD
# Prestashop Plugin for BTCPay server, an opensource Payment processor
Warning this is an Beta version
@ -14,7 +16,7 @@ and if you want, some companies provide hosting services.
## Quick Start Guide
To get up and running with our plugin quickly, see the GUIDE here: https://github.com/adapp-tech/prestashop-plugin/blob/master/GUIDE.md
To get up and running with our plugin quickly, see the GUIDE here: https://github.com/btcpayserver/prestashop-plugin/blob/master/GUIDE.md
# Internals
@ -25,13 +27,19 @@ Prestashop design ensure customer is ready to pay, with a checkbox, when he is f
# TODO
Their is still a lot's of place for improvement.
* ~~on/off postponed order~~
* ~~direct configuration for block confirmations~~
* composer with php-bitpay-client
* on/off postponed order
* direct configuration for block confirmations
* docker for testing
* travis integration
* check 1.6.X compatibility
* ensure stats are correctly displayed in prestashop
* share the same order number BTCPay server and prestashop, or give insight in order details
* give bitcoin rate in local currency in order details
* still in order details, give exact time of payment and bitcoin transaction
* find a way to not override order state numbers currently used in case another plugin use it.
e.g: plugin use order state id: 39,40,41,42. Should use 49,50,51,52 if other plugins use the first one.
* refactoring in ipn.php
# Support
@ -42,7 +50,7 @@ Their is still a lot's of place for improvement.
## Contribute
To contribute to this project, please fork and submit a pull request.
* [GitHub Issues](https://github.com/adapptech/prestashop-plugin/issues)
* [GitHub Issues](https://github.com/btcpayserver/prestashop-plugin/issues)
## PrestaShop Support

View File

@ -37,7 +37,7 @@ if (!defined('_PS_VERSION_')) {
exit;
}
class btcpay extends PaymentModule {
class BTCpay extends PaymentModule {
private $_html = '';
private $key;
protected $_postErrors = array();
@ -70,25 +70,16 @@ class btcpay extends PaymentModule {
$this->name = 'btcpay';
$this->tab = 'payments_gateways';
$this->version = '0.1.0';
$this->version = '0.3.2';
$this->author = 'ADAPP';
$this->className = 'btcpay';
$this->className = 'BTCpay';
$this->currencies = true;
$this->currencies_mode = 'checkbox';
$this->display = 'view';
$this->btcpayurl = '';
$this->is_eu_compatible = 1;
$this->ps_versions_compliancy = array('min' => '1.7', 'max' => '1.7');
if (Configuration::get('btcpay_TESTMODE') == "1") {
$this->btcpayurl = $testurl;
$this->apiurl = $testurl;
} else {
$this->btcpayurl = $btcpayurl;
$this->apiurl = $btcpayurl;
}
$this->sslport = $sslport;
$this->verifypeer = $verifypeer;
$this->verifyhost = $verifyhost;
$this->controllers = array('payment', 'validation');
$this->bootstrap = true;
@ -99,13 +90,6 @@ class btcpay extends PaymentModule {
$this->description = $this->l('Accepts Bitcoin payments via BTCPay.');
$this->confirmUninstall = $this->l('Are you sure you want to delete your details?');
// Define BitPay settings
$this->api_key = null;
$this->api_pub = null;
$this->api_sin = null;
$this->api_token = null;
$this->api_token_label = null;
$this->api_url = null;
}
public function install() {
@ -150,29 +134,31 @@ class btcpay extends PaymentModule {
// to be sure not other plugin do that.
// TODO maybe take the last number available
$query = "INSERT INTO `"._DB_PREFIX_."order_state_lang` (`id_order_state`,`id_lang`,`name`,`template`) VALUES ('39','1','En attente de la transaction Bitcoin','emitbtcpayment');";
$query = "INSERT INTO `"._DB_PREFIX_."order_state_lang` (`id_order_state`,`id_lang`,`name`,`template`) VALUES ('39','1','Want to pay in Bitcoin','bitcoin_want');";
$db->Execute($query);
$query = "INSERT INTO `"._DB_PREFIX_."order_state` (`id_order_state`, `invoice`, `send_email`, `module_name`, `color`, `unremovable`, `hidden`, `logable`, `delivery`, `shipped`, `paid`, `pdf_invoice`, `pdf_delivery`, `deleted`) VALUES ('39', '0', '0', 'btcpay', '#FFFF00', '1', '0', '0', '0', '0', '0', '0', '0', '0');";
$db->Execute($query);
$query = "INSERT INTO `"._DB_PREFIX_."order_state_lang` (`id_order_state`,`id_lang`,`name`,`template`) VALUES ('40','1','En attente de la transaction Bitcoin','waitingbtcconfirmation');";
$query = "INSERT INTO `"._DB_PREFIX_."order_state_lang` (`id_order_state`,`id_lang`,`name`,`template`) VALUES ('40','1','Waiting Bitcoin confirmations','bitcoin_waiting');";
$db->Execute($query);
$query = "INSERT INTO `"._DB_PREFIX_."order_state` (`id_order_state`, `invoice`, `send_email`, `module_name`, `color`, `unremovable`, `hidden`, `logable`, `delivery`, `shipped`, `paid`, `pdf_invoice`, `pdf_delivery`, `deleted`) VALUES ('40', '0', '0', 'btcpay', '#FFFF00', '1', '0', '0', '0', '0', '0', '0', '0', '0');";
$db->Execute($query);
$query2 = "INSERT INTO `"._DB_PREFIX_."order_state_lang` (`id_order_state`,`id_lang`,`name`,`template`) VALUES ('42','1','Paiement Bitcoin confirmé','paidbtcconfirmation');";
$db->Execute($query2);
$query = "INSERT INTO `"._DB_PREFIX_."order_state_lang` (`id_order_state`,`id_lang`,`name`,`template`) VALUES ('41','1','Bitcoin transaction invalid','bitcoin_invalid');";
$db->Execute($query);
$query = "INSERT INTO `"._DB_PREFIX_."order_state` (`id_order_state`, `invoice`, `send_email`, `module_name`, `color`, `unremovable`, `hidden`, `logable`, `delivery`, `shipped`, `paid`, `pdf_invoice`, `pdf_delivery`, `deleted`) VALUES ('41', '0', '0', 'btcpay', '#565656', '1', '0', '1', '0', '0', '1', '0', '0', '0');";
$db->Execute($query);
$query2 = "INSERT INTO `"._DB_PREFIX_."order_state` (`id_order_state`, `invoice`, `send_email`, `module_name`, `color`, `unremovable`, `hidden`, `logable`, `delivery`, `shipped`, `paid`, `pdf_invoice`, `pdf_delivery`, `deleted`) VALUES ('42', '0', '0', 'btcpay', '#FFCE00', '1', '0', '1', '0', '0', '1', '1', '0', '0');";
$db->Execute($query2);
$query3 = "INSERT INTO `"._DB_PREFIX_."order_state_lang` (`id_order_state`,`id_lang`,`name`,`template`) VALUES ('41','1','Transaction Bitcoin invalide','invalidbtcconfirmation');";
$db->Execute($query3);
$query = "INSERT INTO `"._DB_PREFIX_."order_state_lang` (`id_order_state`,`id_lang`,`name`,`template`) VALUES ('42','1','Bitcoin payment confirm','bitcoin_confirm');";
$db->Execute($query);
$query = "INSERT INTO `"._DB_PREFIX_."order_state` (`id_order_state`, `invoice`, `send_email`, `module_name`, `color`, `unremovable`, `hidden`, `logable`, `delivery`, `shipped`, `paid`, `pdf_invoice`, `pdf_delivery`, `deleted`) VALUES ('42', '0', '0', 'btcpay', '#FFCE00', '1', '0', '1', '0', '0', '1', '1', '0', '0');";
$db->Execute($query);
// insert module install timestamp
$query = "INSERT IGNORE INTO `ps_configuration` (`name`, `value`, `date_add`, `date_upd`) VALUES ('PS_OS_BTCPAY', '13', NOW(), NOW());";
$db->Execute($query);
//init configurations
//init clear configurations
Configuration::updateValue('btcpay_URL', "");
Configuration::updateValue('btcpay_LABEL', "");
Configuration::updateValue('btcpay_PAIRINGCODE', "");
@ -180,11 +166,15 @@ class btcpay extends PaymentModule {
Configuration::updateValue('btcpay_PUB', "");
Configuration::updateValue('btcpay_SIN', "");
Configuration::updateValue('btcpay_TOKEN', "");
Configuration::updateValue('btcpay_TXSPEED', "");
Configuration::updateValue('btcpay_ORDERMODE', "");
return true;
}
public function uninstall() {
Configuration::deleteByName('btcpay_ORDERMODE');
Configuration::deleteByName('btcpay_TXSPEED');
Configuration::deleteByName('btcpay_TOKEN');
Configuration::deleteByName('btcpay_SIN');
Configuration::deleteByName('btcpay_PUB');
@ -288,11 +278,46 @@ class btcpay extends PaymentModule {
private function _getSettingsTabHtml() {
global $cookie;
// default set a test btcpayserver
$btcpayserver_url = Configuration::get('btcpay_URL');
if (true === empty($btcpayserver_url)) {
$btcpayserver_url = "https://btcpay-server-testnet.azurewebsites.net";
}
// select list for bitcoin confirmation
// 'default' => 'Keep store level configuration',
// 'high' => '0 confirmation on-chain',
// 'medium' => '1 confirmation on-chain',
// 'low-medium' => '2 confirmations on-chain',
// 'low' => '6 confirmations on-chain',
$lowSelected = '';
$mediumSelected = '';
$highSelected = '';
// Remember which speed has been selected and display that upon reaching the settings page; default to low
if (Configuration::get('btcpay_TXSPEED') == "high") {
$highSelected = "selected=\"selected\"";
} elseif (Configuration::get('btcpay_TXSPEED') == "medium") {
$mediumSelected = "selected=\"selected\"";
} else {
$lowSelected = "selected=\"selected\"";
}
// delayed order mecanism
// create a 'prestashop order' when you create btcpay invoice
// or
// create a 'prestashop order' when you receive bitcoin payment
// or
// create a 'prestashop order' when you receive bitcoin payment and confirmation
$orderBeforePaymentSelected = '';
$orderAfterPaymentSelected = '';
if (Configuration::get('btcpay_ORDERMODE') == "afterpayment") {
$orderAfterPaymentSelected = "selected=\"selected\"";
} else {
$orderBeforePaymentSelected = "selected=\"selected\"";
}
$html = '<h2>'.$this->l('Settings').'</h2>
<style type="text/css" src="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css"></style>
<style type="text/css" src="../modules/btcpay/assets/css/style.css"></style>
@ -303,6 +328,23 @@ class btcpay extends PaymentModule {
<input name="form_btcpay_url" type="text" value="'.htmlentities(Tools::getValue('serverurl', Configuration::get('btcpay_URL')),ENT_COMPAT, 'UTF-8').'" placeholder="BTCPay Url (eg. '.$btcpayserver_url.')" class="bitpay-url"> <br />
</div>
<div style="clear:both;margin-bottom:30px;">
<h3 style="clear:both;">'.$this->l('Transaction Speed').'</h3>
<select name="form_btcpay_txspeed">
<option value="low" '.$lowSelected.'>Low</option>
<option value="medium" '.$mediumSelected.'>Medium</option>
<option value="high" '.$highSelected.'>High</option>
</select>
</div>
<div style="clear:both;margin-bottom:30px;">
<h3 style="clear:both;">'.$this->l('Order Mode').'</h3>
<select name="form_btcpay_ordermode">
<option value="beforepayment" '.$orderBeforePaymentSelected.'>Order before payment</option>
<option value="afterpayment" '.$orderAfterPaymentSelected.'>Order after payment</option>
</select>
</div>
<div style="clear:both;margin-bottom:30px;">
<h3 style="clear:both;">'.$this->l('Pairing Code').'</h3>
<input type="text" style="width:400px;" name="form_btcpay_pairingcode" value="'.htmlentities(Tools::getValue('pairingcode', Configuration::get('btcpay_PAIRINGCODE')),ENT_COMPAT, 'UTF-8').'" />
@ -365,8 +407,6 @@ class btcpay extends PaymentModule {
$sin->setPublicKey($pub);
$sin->generate();
$order_status = (int)$status_btcpay;
// Create an API Client
$client = new \Bitpay\Client\Client();
if (true === empty($client)) {
@ -407,6 +447,10 @@ class btcpay extends PaymentModule {
return;
} else {
if ( false === isset($token)) {
$this->_errors[] = $this->l("Failed to create token, you are maybe using an already activated pairing code.");
return;
}
Configuration::updateValue('btcpay_URL', $_btcpay_url);
Configuration::updateValue('btcpay_LABEL', $label);
Configuration::updateValue('btcpay_PUB', (string)$this->bitpay_encrypt($pub));
@ -430,6 +474,11 @@ class btcpay extends PaymentModule {
$this->_errors[] = $this->l('Missing BTCPay server url');
}
$this->_ajax_bitpay_pair_code(
Tools::getValue('form_btcpay_pairingcode'),
Tools::getValue('form_btcpay_url')
);
if (count($this->_errors) > 0) {
$error_msg = '';
@ -440,14 +489,11 @@ class btcpay extends PaymentModule {
return;
} else {
$this->_ajax_bitpay_pair_code(
Tools::getValue('form_btcpay_pairingcode'),
Tools::getValue('form_btcpay_url')
);
Configuration::updateValue('btcpay_ORDERMODE', trim(Tools::getValue('form_btcpay_ordermode')));
Configuration::updateValue('btcpay_TXSPEED', trim(Tools::getValue('form_btcpay_txspeed')));
Configuration::updateValue('btcpay_PAIRINGCODE', trim(Tools::getValue('form_btcpay_pairingcode')));
Configuration::updateValue('btcpay_URL', trim(Tools::getValue('form_btcpay_url')));
$this->_html = $this->displayConfirmation($this->l('Pairing created'));
$this->_html = $this->displayConfirmation($this->l('Pairing done'));
}
}
}
@ -457,6 +503,15 @@ class btcpay extends PaymentModule {
// Get shopping currency, currently tested with be EUR
$currency = Currency::getCurrencyInstance((int)$cart->id_currency);
if (true === empty($currency)) {
$currency = Currency::getDefaultCurrency();
return;
}
$transaction_speed = Configuration::get('btcpay_TXSPEED');
if (true === empty($transaction_speed)) {
$transaction_speed = 'default';
}
// get the cart id to fetch cart information
$cart_id = $cart->id;
@ -469,7 +524,7 @@ class btcpay extends PaymentModule {
$cart_total = $cart->getOrderTotal(true);
// This is the callback url for invoice paid
$notification_url = 'https://'.htmlspecialchars($_SERVER['HTTP_HOST'], ENT_COMPAT, 'UTF-8').__PS_BASE_URI__.'modules/'.$this->name.'/ipn.php';
$notification_url = Tools::getShopDomainSsl(true, true).__PS_BASE_URI__.'modules/'.$this->name.'/ipn.php';
// Get a BitPay Client to prepare for invoice creation
$client = new \Bitpay\Client\Client();
@ -520,19 +575,17 @@ class btcpay extends PaymentModule {
PrestaShopLogger::addLog('[Error] The BTCPay payment plugin was called to process a payment but could not instantiate an Invoice object.', 3);
}
$btcpay_currency = new \Bitpay\Currency('EUR');
$btcpay_currency = new \Bitpay\Currency($currency->iso_code);
$invoice->setOrderId((string)$cart_id);
$invoice->setCurrency($btcpay_currency);
$invoice->setFullNotifications(true);
$invoice->setExtendedNotifications(true);
// Add a priced item to the invoice
$item = new \Bitpay\Item();
if (false === isset($item) || true === empty($item)) {
$this->_errors[] = $this->l('[Error] The BTCPay payment plugin was called to process a payment but could not instantiate an item object.');
}
$customer = new Customer((int)$cart->id_customer);
$email = $customer->email;
@ -567,7 +620,7 @@ class btcpay extends PaymentModule {
// Add the Redirect and Notification URLs
$invoice->setRedirectUrl($redirect_url);
$invoice->setNotificationUrl($notification_url);
$this->transaction_speed = 'default';
$invoice->setTransactionSpeed($transaction_speed);
// If another BTCPay invoice was created before, returns the original one
$redirect = $this->get_btcpay_redirect($cart_id, $client);
@ -598,7 +651,6 @@ class btcpay extends PaymentModule {
$responseData = json_decode($client->getResponse()->getBody());
// register invoice url and rate into order_bitcoin table
$this->update_order_field($cart_id, 'amount', $cart_total);
$this->update_order_field($cart_id, 'rate', $invoice->getRate());
@ -656,7 +708,7 @@ class btcpay extends PaymentModule {
if(isset($redirect) && !empty($redirect))
{
$result_invoice_id = $this->get_order_field($cart_id, 'invoice_id');
$invoice = $client->getInvoice($result_invoice_id['invoice_id']);
$invoice = $client->getInvoice($result_invoice_id);
$status = $invoice->getStatus();
if($status === 'invalid' || $status === 'expired')
{
@ -740,6 +792,7 @@ class btcpay extends PaymentModule {
{
if (false === isset($data) || true === empty($data)) {
$this->_errors[] = $this->l('The BTCPay payment plugin was called to encrypt data but no data was passed!');
return;
}
$openssl_ext = new \Bitpay\Crypto\OpenSSLExtension();
@ -771,6 +824,7 @@ class btcpay extends PaymentModule {
{
if (false === isset($encrypted) || true === empty($encrypted)) {
$this->_errors[] = $this->l('The BTCPay payment plugin was called to decrypt data but no data was passed!');
return;
}
$openssl_ext = new \Bitpay\Crypto\OpenSSLExtension();
$fingerprint = sha1(sha1(__DIR__));

View File

@ -2,7 +2,7 @@
<module>
<name>btcpay</name>
<displayName><![CDATA[BTCPay]]></displayName>
<version><![CDATA[0.1.0]]></version>
<version><![CDATA[0.3.2]]></version>
<description><![CDATA[Accepts Bitcoin payments via BTCPay.]]></description>
<author><![CDATA[ADAPP]]></author>
<tab><![CDATA[payments_gateways]]></tab>

View File

@ -2,7 +2,7 @@
<module>
<name>btcpay</name>
<displayName><![CDATA[btcpay]]></displayName>
<version><![CDATA[0.1.0]]></version>
<version><![CDATA[0.3.2]]></version>
<description><![CDATA[Acceptez les paiements en bitcoin via BTCPay.]]></description>
<author><![CDATA[ADAPP]]></author>
<tab><![CDATA[payments_gateways]]></tab>

View File

@ -1,7 +1,7 @@
<?php
class btcpayPaymentModuleFrontController extends ModuleFrontController
class BTCpayPaymentModuleFrontController extends ModuleFrontController
{
public $ssl = true;
public $display_column_left = false;
@ -11,11 +11,9 @@ class btcpayPaymentModuleFrontController extends ModuleFrontController
*/
public function initContent()
{
parent::initContent();
$cart = $this->context->cart;
echo $this->module->execPayment($cart);
parent::initContent();
$cart = $this->context->cart;
echo $this->module->execPayment($cart);
}
}

View File

@ -1,42 +1,43 @@
<?php
class btcpayValidationModuleFrontController extends ModuleFrontController
class BTCpayValidationModuleFrontController extends ModuleFrontController
{
/**
* @see FrontController::postProcess()
*/
public function postProcess()
{
$cart = $this->context->cart;
if ($cart->id_customer == 0
|| $cart->id_address_delivery == 0
|| $cart->id_address_invoice == 0
|| !$this->module->active)
Tools::redirect('index.php?controller=order&step=1');
public function postProcess() {
$cart = $this->context->cart;
if ($cart->id_customer == 0
|| $cart->id_address_delivery == 0
|| $cart->id_address_invoice == 0
|| !$this->module->active)
Tools::redirect('index.php?controller=order&step=1');
// Check that this payment option is still available in case the customer changed his address just before the end of the checkout process
$authorized = false;
foreach (Module::getPaymentModules() as $module)
if ($module['name'] == 'btcpay')
{
$authorized = true;
break;
}
if (!$authorized)
die($this->module->l('This payment method is not available.', 'validation'));
$customer = new Customer($cart->id_customer);
if (!Validate::isLoadedObject($customer))
Tools::redirect('index.php?controller=order&step=1');
$currency = $this->context->currency;
$total = (float)$cart->getOrderTotal(true, Cart::BOTH);
$mailVars = array(
);
Tools::redirect('index.php?controller=order-confirmation&id_cart='.(int)$cart->id.'&id_module='.(int)$this->module->id.'&id_order='.$this->module->currentOrder.'&key='.$customer->secure_key);
// Check that this payment option is still available in case the customer changed his address just before the end of the checkout process
$authorized = false;
foreach (Module::getPaymentModules() as $module) {
if ($module['name'] == 'btcpay')
{
$authorized = true;
break;
}
}
if (!$authorized) {
die($this->module->l('This payment method is not available.', 'validation'));
}
$customer = new Customer($cart->id_customer);
if (!Validate::isLoadedObject($customer)) {
Tools::redirect('index.php?controller=order&step=1');
}
$currency = $this->context->currency;
$total = (float)$cart->getOrderTotal(true, Cart::BOTH);
$mailVars = array();
Tools::redirect('index.php?controller=order-confirmation&id_cart='.(int)$cart->id.'&id_module='.(int)$this->module->id.'&id_order='.$this->module->currentOrder.'&key='.$customer->secure_key);
}
}

View File

@ -14,7 +14,7 @@
</tr>
<tr>
<td align="left" valign="top">{l s='Status:' mod='btcpay'}</td>
<td>{$status}</td>
<td>-----{$status}</td>
</tr>
</table>
</div>

View File

@ -29,9 +29,13 @@
include(dirname(__FILE__).'/../../config/config.inc.php');
include(dirname(__FILE__).'/btcpay.php');
$btcpay = new btcpay();
$btcpay = new BTCpay();
$post = file_get_contents("php://input");
$post = file_get_contents('php://input');
if (!$post) {
PrestaShopLogger::addLog('[Error] bad input', 3);
die;
}
function get_order_field($invoice_id, $order_field) {
$db = Db::getInstance();
@ -61,55 +65,65 @@ function update_order_field($invoice_id, $order_field, $order_value) {
}
if (true === empty($post)) {
PrestaShopLogger::addLog('[Error] Empty post',3);
exit;
PrestaShopLogger::addLog('[Error] Empty post', 3);
die;
}
$json = json_decode($post, true);
$event = "";
$event= array();
if(true === array_key_exists('event', $json) ) // extended notification type
{
// extended notification type
if(true === array_key_exists('event', $json) ) {
$event = $json['event'];
} else {
//nothing to do
exit;
exit(1);
}
if(true === array_key_exists('data', $json))
{
$data = array();
if(true === array_key_exists('data', $json)) {
$data = $json['data'];
} else {
//nothing to do
exit;
}
if (empty($json->event->code)) {
PrestaShopLogger::addLog('[Error] Event code missing from callback.', 1);
}
$btcpay_ordermode = '';
$btcpay_ordermode = Configuration::get('btcpay_ORDERMODE');
# refactoring needed, next version
### ----------------
# Payment Received
if (true == array_key_exists('name', $event) && strcmp($event[name],"invoice_receivedPayment") == 0) {
# Invoice created
if (true == array_key_exists('name', $event)
&& $event['name'] === "invoice_created"
&& $btcpay_ordermode === "beforepayment" ) {
// sleep to not receive ipn notification
// before the update of bitcoin order table
sleep(15);
// check if we have needed data
if (true === empty($data)) {
PrestaShopLogger::addLog('[Error] No data',3);
exit;
exit(1);
}
if (false === array_key_exists('id', $data)) {
PrestaShopLogger::addLog('[Error] No data id',3);
exit;
exit(1);
}
if (false === array_key_exists('url', $data)) {
PrestaShopLogger::addLog('[Error] No data url',3);
exit;
exit(1);
}
// get invoice id, to go back on cart and check the amount
$invoice_id = (string)$data[id];
if ( false === isset($rate)) {
$invoice_id = (string)$data['id'];
if ( false === isset($invoice_id)) {
PrestaShopLogger::addLog('[Error] No invoice id',3);
exit;
exit(1);
}
$cart_id = get_order_field($invoice_id, 'cart_id');
@ -117,84 +131,390 @@ if (true == array_key_exists('name', $event) && strcmp($event[name],"invoice_rec
// search the invoice to get amount
$cart_total = get_order_field($invoice_id, 'amount');
// waiting confirmation
$status_btcpay = 40;
// waiting payment
$status_btcpay = 39;
// on Order, just say payment processor is BTCPay
$display_name = $btcpay->displayName;
// fetch secure key, used to check cart comes from your prestashop
$secure_key = $data[posData];
$secure_key = $data['posData'];
if ( false === isset($secure_key)) {
PrestaShopLogger::addLog('[Error] No securekey',3);
exit;
exit(1);
}
// rate in fiat currency
$rate = $data[rate];
$rate = $data['rate'];
if ( false === isset($rate)) {
PrestaShopLogger::addLog('[Error] No rate',3);
exit;
exit(1);
}
$order_status = (int) $status_btcpay;
// generate an order only if their is not another one with this cart
$order_id = (int)Order::getIdByCartId($cart_id);
if ( $order_id == null
|| $order_id == 0) {
$btcpay->validateOrder(
$cart_id,
$status_btcpay,
$cart_total,
$display_name,
$rate, array(), null, false,
$secure_key
);
$btcpay->validateOrder(
$cart_id,
$status_btcpay,
$cart_total,
$display_name, //bitcoin btcpay
null, //message should be new Message
array(), //extravars for mail
null, //currency special
false, // don't touch amount
$secure_key
);
$order_id = (int)Order::getIdByCartId($cart_id);
$order_id = (int)Order::getIdByCartId($cart_id);
// register order id for payment in BTC
$db = Db::getInstance();
$query = 'UPDATE `' . _DB_PREFIX_ . "order_bitcoin` SET `id_order`='". $order_id ."' WHERE `invoice_id`='" . $invoice_id . "';";
// register order id for payment in BTC
$db = Db::getInstance();
$query = 'UPDATE `' . _DB_PREFIX_ . "order_bitcoin` SET `id_order`='". $order_id ."' WHERE `invoice_id`='" . $invoice_id . "';";
$result = array();
$result = $db->Execute($query);
$result = array();
$result = $db->Execute($query);
$order_status = (int)$status_btcpay;
// update order_bitcoin paid amount
$db = Db::getInstance();
$query = 'UPDATE `' . _DB_PREFIX_ . "order_bitcoin` SET `btc_paid`='0.0' WHERE `id_order`=" . intval($order_id) . ';';
$result = array();
$result = $db->Execute($query);
// update order_bitcoin paid amount
$db = Db::getInstance();
$query = 'UPDATE `' . _DB_PREFIX_ . "order_bitcoin` SET `btc_paid`='".$data[btcPaid]."' WHERE `id_order`=" . intval($order_id) . ';';
$result = array();
$result = $db->Execute($query);
// update payment status
$db = Db::getInstance();
$query = 'UPDATE `' . _DB_PREFIX_ . "order_bitcoin` SET `status`='" . $order_status . "' WHERE `id_order`=" . intval($order_id) . ';';
$result = array();
$result = $db->Execute($query);
// update payment status
$db = Db::getInstance();
$query = 'UPDATE `' . _DB_PREFIX_ . "order_bitcoin` SET `status`='" . $order_status . "' WHERE `id_order`=" . intval($order_id) . ';';
$result = array();
$result = $db->Execute($query);
// add Order status change to Order history table
$new_history = new OrderHistory();
$new_history->id_order = (int)$order_id;
// bitcoin confirmation ok
$new_history->changeIdOrderState((int)$order_status, (int)$order_id, true);
//add with email is mandatory to add new order state in order_history
$new_history->add(true);
exit(0);
} else {
// Order already paid
PrestaShopLogger::addLog('[Error] already paid order',1);
exit(0);
} else {
// Order already paid
PrestaShopLogger::addLog('[Error] already created order',1);
exit(1);
}
}
# ----------------
# Payment Received
if (true == array_key_exists('name', $event)
&& $event['name'] === 'invoice_receivedPayment'
&& $btcpay_ordermode === 'afterpayment' ) {
// sleep to not receive ipn notification
// before the update of bitcoin order table
sleep(15);
// check if we have needed data
if (true === empty($data)) {
PrestaShopLogger::addLog('[Error] No data',3);
exit;
}
if (false === array_key_exists('id', $data)) {
PrestaShopLogger::addLog('[Error] No data id',3);
exit;
}
if (false === array_key_exists('url', $data)) {
PrestaShopLogger::addLog('[Error] No data url',3);
exit;
}
// get invoice id, to go back on cart and check the amount
$invoice_id = (string)$data['id'];
if ( false === isset($invoice_id)) {
PrestaShopLogger::addLog('[Error] No invoice id',3);
exit;
}
$cart_id = get_order_field($invoice_id, 'cart_id');
// search the invoice to get amount
$cart_total = get_order_field($invoice_id, 'amount');
// waiting confirmation
$status_btcpay = 40;
// on Order, just say payment processor is BTCPay
$display_name = $btcpay->displayName;
// fetch secure key, used to check cart comes from your prestashop
$secure_key = $data['posData'];
if ( false === isset($secure_key)) {
PrestaShopLogger::addLog('[Error] No securekey',3);
exit;
}
// rate in fiat currency
$rate = $data['rate'];
if ( false === isset($rate)) {
PrestaShopLogger::addLog('[Error] No rate',3);
exit;
}
// generate an order only if their is not another one with this cart
$order_id = (int)Order::getIdByCartId($cart_id);
if ( $order_id == null
|| $order_id == 0) {
$btcpay->validateOrder(
$cart_id,
$status_btcpay,
$cart_total,
$display_name, //bitcoin btcpay
$rate, //message
array(), //extravars
null, //currency special
false, // don't touch amount
$secure_key
);
$order_id = (int)Order::getIdByCartId($cart_id);
// register order id for payment in BTC
$db = Db::getInstance();
$query = 'UPDATE `' . _DB_PREFIX_ . "order_bitcoin` SET `id_order`='". $order_id ."' WHERE `invoice_id`='" . $invoice_id . "';";
$result = array();
$result = $db->Execute($query);
$order_status = (int)$status_btcpay;
// update order_bitcoin paid amount
$db = Db::getInstance();
$query = 'UPDATE `' . _DB_PREFIX_ . "order_bitcoin` SET `btc_paid`='".$data['btcPaid']."' WHERE `id_order`=" . intval($order_id) . ';';
$result = array();
$result = $db->Execute($query);
// update payment status
$db = Db::getInstance();
$query = 'UPDATE `' . _DB_PREFIX_ . "order_bitcoin` SET `status`='" . $order_status . "' WHERE `id_order`=" . intval($order_id) . ';';
$result = array();
$result = $db->Execute($query);
// add Order status change to Order history table
$new_history = new OrderHistory();
$new_history->id_order = (int)$order_id;
// bitcoin confirmation ok
$new_history->changeIdOrderState((int)$order_status, (int)$order_id, true);
$new_history->add(true);
exit(0);
} else {
// Order already paid
PrestaShopLogger::addLog('[Error] already paid order',1);
exit(1);
}
}
if (true == array_key_exists('name', $event)
&& $event['name'] === 'invoice_receivedPayment'
&& $btcpay_ordermode === 'beforepayment' ) {
PrestaShopLogger::addLog('[Info] payment received', 1);
if (true === empty($data)) {
PrestaShopLogger::addLog('[Error] invalide json', 3);
exit(1);
}
if (false === array_key_exists('id', $data)) {
PrestaShopLogger::addLog('[Error] No id in data', 3);
exit(1);
}
// get invoice id, to go back on cart and check the amount
$invoice_id = (string)$data['id'];
if ( false === isset($invoice_id)) {
PrestaShopLogger::addLog('[Error] No invoice id',3);
exit(1);
}
// fetch order id
$db = Db::getInstance();
$result = array();
$order_id = null;
$result = $db->ExecuteS("SELECT `id_order` FROM `" . _DB_PREFIX_ . "order_bitcoin` WHERE `invoice_id`='" . $invoice_id . "';");
if (count($result) > 0 && $result[0] !== null && $result[0]['id_order'] !== null) {
$order_id = $result[0]['id_order'];
} else {
PrestaShopLogger::addLog('[Error] IPN order id not found', 3);
exit(1);
}
$order = new Order($order_id);
// waiting confirmation
$order_status = (int)40;
// update order_bitcoin paid amount
$db = Db::getInstance();
$query = 'UPDATE `' . _DB_PREFIX_ . "order_bitcoin` SET `btc_paid`='".$data['btcPaid']."' WHERE `id_order`=" . intval($order_id) . ';';
$result = array();
$result = $db->Execute($query);
// update payment status
$db = Db::getInstance();
$query = 'UPDATE `' . _DB_PREFIX_ . "order_bitcoin` SET `status`='" . $order_status . "' WHERE `id_order`=" . intval($order_id) . ';';
$result = array();
$result = $db->Execute($query);
// add Order status change to Order history table
$new_history = new OrderHistory();
$new_history->id_order = (int)$order_id;
// bitcoin confirmation ok
$new_history->changeIdOrderState((int)$order_status, (int)$order_id, true);
//add with email is mandatory to add new order state in order_history
$new_history->add(true);
exit(0);
}
###
# Payment Confirmed
# 1 to 6 confirmation depending on your network
if (true === array_key_exists('name', $event) && strcmp($event[name],"invoice_paidInFull") == 0) {
//nothing to do
# pending full payment Confirmed
# 1 to 6 confirmation depending on your setup
# see TX speed
if (true === array_key_exists('name', $event)
&& $event['name'] === 'invoice_paidInFull' ) {
PrestaShopLogger::addLog('[Error] Paid in FULL',3);
exit;
}
if (true === array_key_exists('name', $event)
&& $event['name'] === 'invoice_failedToConfirm'
or $event['name'] === 'invoice_markedInvalid' ) {
if (true === empty($data)) {
PrestaShopLogger::addLog('[Error] invalide json', 3);
exit;
}
if (false === array_key_exists('id', $data)) {
PrestaShopLogger::addLog("[Error] No id in data", 3);
exit;
}
if (false === array_key_exists('url', $data)) {
PrestaShopLogger::addLog("[Error] No url in data", 3);
exit;
}
// Get a BitPay Client to prepare for invoice fetching
$client = new \Bitpay\Client\Client();
if (false === isset($client) && true === empty($client)) {
PrestaShopLogger::addLog('[Error] Failed to instanciate Client', 3);
exit;
}
$serverurl_btcpay = Configuration::get('btcpay_URL');
$client->setUri($serverurl_btcpay);
$curlAdapter = new \Bitpay\Client\Adapter\CurlAdapter();
if (false === isset($curlAdapter) || true === empty($curlAdapter)) {
PrestaShopLogger::addLog('[Error] Failed to instanciate curlAdapter', 3);
exit;
}
// Setting the Adapter param to a new BitPay CurlAdapter object
$client->setAdapter($curlAdapter);
$encrypted_key_btcpay = Configuration::get('btcpay_KEY');
$key_btcpay = (string) $btcpay->bitpay_decrypt($encrypted_key_btcpay);
if (true === empty($key_btcpay)) {
PrestaShopLogger::addLog('[Error] Failed to decrypt key', 3);
exit;
}
$key = new \Bitpay\PrivateKey();
$key->setHex($key_btcpay);
$client->setPrivateKey($key);
$pub_btcpay = Configuration::get('btcpay_PUB');
if (false === empty($pub_btcpay)) {
$pubk = $key->getPublicKey();
$client->setPublicKey($pubk);
} else {
PrestaShopLogger::addLog('[Error] Failed to get pubkey', 3);
exit;
}
$token_btcpay = (string) $btcpay->bitpay_decrypt(Configuration::get('btcpay_TOKEN'));
if (false === empty($token_btcpay)) {
$_token = new \Bitpay\Token();
$_token->setToken($token_btcpay);
$client->setToken($_token);
} else {
PrestaShopLogger::addLog('[Error] Failed to decrypt token', 3);
exit;
}
// handle case order id already exist
// Setup the Invoice
$invoice = new \Bitpay\Invoice();
if (false === isset($invoice) || true === empty($invoice)) {
PrestaShopLogger::addLog('[Error] Failed to instanciate Invoice', 3);
exit;
}
$db = Db::getInstance();
$result = array();
$order_id = "";
$result = $db->ExecuteS("SELECT `id_order` FROM `" . _DB_PREFIX_ . "order_bitcoin` WHERE `invoice_id`='" . (string)$data['id'] . "';");
if (count($result)>0 && $result[0] !== null && $result[0]['id_order'] !== null) {
$order_id = $result[0]['id_order'];
} else {
PrestaShopLogger::addLog('[Error] IPN order id not found', 3);
exit;
}
$order = new Order($order_id);
// wait for confirm
$status_btcpay = 41;
if($data['status'] === 'invalid' || $data['status'] === 'expired')
{
// time setup on invoice is expired
$status_btcpay = 41;
}
$order_status = (int)$status_btcpay;
// update amount paid
$db = Db::getInstance();
$query = 'UPDATE `' . _DB_PREFIX_ . "order_bitcoin` SET `status`='".$order_status."' WHERE `id_order`=" . intval($order_id) . ';';
$result = array();
$result = $db->Execute($query);
// add Order status change to Order history table
$new_history = new OrderHistory();
$new_history->id_order = intval($order_id);
// bitcoin confirmation ok
$new_history->changeIdOrderState((int)$order_status, (int)$order_id, true);
$new_history->add(true);
}
###
# Payment Confirmed
# 1 to 6 confirmation depending on your network
# 1 to 6 confirmation depending on your setup
# confirmed then completed
if (true === array_key_exists('name', $event) && strcmp($event[name],"invoice_confirmed") == 0) {
# see TX speed
if (true === array_key_exists('name', $event)
&& $event['name'] === 'invoice_confirmed' ) {
if (true === empty($data)) {
PrestaShopLogger::addLog('[Error] invalide json', 3);
@ -278,9 +598,9 @@ if (true === array_key_exists('name', $event) && strcmp($event[name],"invoice_co
$db = Db::getInstance();
$result = array();
$order_id = "";
$result = $db->ExecuteS('SELECT `id_order` FROM `' . _DB_PREFIX_ . "order_bitcoin` WHERE `invoice_id`='" . (string)$data[id] . "';");
if (count($result)>0 && $result[0] !== null && $result[0][id_order] !== null) {
$order_id = $result[0][id_order];
$result = $db->ExecuteS("SELECT `id_order` FROM `" . _DB_PREFIX_ . "order_bitcoin` WHERE `invoice_id`='" . (string)$data['id'] . "';");
if (count($result)>0 && $result[0] !== null && $result[0]['id_order'] !== null) {
$order_id = $result[0]['id_order'];
} else {
PrestaShopLogger::addLog('[Error] IPN order id not found', 3);
exit;
@ -291,21 +611,21 @@ if (true === array_key_exists('name', $event) && strcmp($event[name],"invoice_co
// wait for confirm
$status_btcpay = 40;
if($data[status] === 'invalid' || $data[status] === 'expired')
if($data['status'] === 'invalid' || $data['status'] === 'expired')
{
// time setup on invoice is expired
$status_btcpay = 41;
}
if($data[status] === 'paid')
if($data['status'] === 'paid')
{
// TX received but we have to wait some confirmation
$status_btcpay = 40;
}
if($data[status] === 'confirmed' || $data[status] == 'complete')
if($data['status'] === 'confirmed' || $data['status'] === 'complete')
{
//Transaction confirmée
//Transaction confirmed
$status_btcpay = 42;
}
@ -317,11 +637,14 @@ if (true === array_key_exists('name', $event) && strcmp($event[name],"invoice_co
$result = array();
$result = $db->Execute($query);
// add Order status change to Order history table
$new_history = new OrderHistory();
$new_history->id_order = (int)$order_id;
// bitcoin confirmation ok
$new_history->changeIdOrderState((int)$order_status, $order, true);
$new_history->addWithemail(true);
if ( $order->current_state != $order_status) {
$new_history = new OrderHistory();
$new_history->id_order = (int)$order_id;
// bitcoin confirmation ok
$new_history->changeIdOrderState((int)$order_status, (int)$order_id, true);
$new_history->add(true);
} else {
PrestaShopLogger::addLog('[Error] current state is not different than new order status in invoice confirmed', 3);
}
}

View File

@ -2,19 +2,19 @@
/**
* The MIT License (MIT)
*
*
* Copyright (c) 2011-2014 BitPay
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

View File

@ -14,21 +14,23 @@ $cart = $context->cart;
$btcpay = new btcpay();
if ($cart->id_customer == 0 OR $cart->id_address_delivery == 0 OR $cart->id_address_invoice == 0 OR !$btcpay->active)
Tools::redirect('index.php?controller=order&step=1');
if ($cart->id_customer == 0 OR $cart->id_address_delivery == 0 OR $cart->id_address_invoice == 0 OR !$btcpay->active) {
Tools::redirect('index.php?controller=order&step=1');
}
// Check that this payment option is still available in case the customer
// changed his address just before the end of the checkout process
$authorized = false;
foreach (Module::getPaymentModules() as $module)
if ($module['name'] == 'btcpay') {
$authorized = true;
break;
}
foreach (Module::getPaymentModules() as $module) {
if ($module['name'] == 'btcpay') {
$authorized = true;
break;
}
}
if (!$authorized) {
die($btcpay->l('This payment method is not available.', 'validation'));
die($btcpay->l('This payment method is not available.', 'validation'));
}
echo $btcpay->execPayment($cart);

View File

@ -1,10 +1,16 @@
{if $state == '42'}
<p>{l s='Your order on %s is complete.' sprintf=$shop_name mod='btcpay'}
<br /><br /> <strong>{l s='Your order will be sent as soon as your payment is confirmed by the Bitcoin network.' mod='btcpay'}</strong>
<br /><br />{l s='If you have questions, comments or concerns, please contact our' mod='btcpay'} <a href="{$link->getPageLink('contact', true)|escape:'html'}">{l s='expert customer support team. ' mod='btcpay'}</a>
</p>
{/if}
{if $state == '2'}
<p>{l s='Your order on %s is complete.' sprintf=$shop_name mod='btcpay'}
<br /><br /> <strong>{l s='Your order will be sent as soon as your payment is confirmed by the Bitcoin network.' mod='btcpay'}</strong>
<br /><br />{l s='If you have questions, comments or concerns, please contact our' mod='btcpay'} <a href="{$link->getPageLink('contact', true)|escape:'html'}">{l s='expert customer support team. ' mod='btcpay'}</a>
</p>
{else}
<p class="warning">
<p class="warning">
{l s="We noticed a problem with your order. If you think this is an error, feel free to contact our" mod='btcpay'}
<a href="{$link->getPageLink('contact', true)|escape:'html'}">{l s='expert customer support team. ' mod='btcpay'}</a>.
</p>