name = 'paybox'; $this->version = '3.3.8'; $this->author = 'PrestaShop'; if (version_compare(_PS_VERSION_, '1.4.0.0') >= 0) $this->tab = 'payments_gateways'; else $this->tab = 'Payment'; $this->module_key = '170f3891caee2f46fbbad73f0ce74276'; parent::__construct(); /** Backward compatibility */ require(_PS_MODULE_DIR_.'/paybox/backward_compatibility/backward.php'); $this->page = basename(__FILE__, '.php'); $this->displayName = $this->l('Paybox'); $this->description = $this->l('This payment module for banks using Paybox allows your customers to pay by Credit Card'); $this->bin_dir = dirname(__FILE__).'/cgi/'; } public function install() { return ( parent::install() && $this->registerHook('payment') && $this->registerHook('orderConfirmation') && $this->registerHook('cancelProduct') && $this->registerHook('cancelShipping') ); } public function hookOrderConfirmation($params) { global $smarty; if ($params['objOrder']->module != $this->name) return; if ($params['objOrder']->valid) $smarty->assign( array( 'mobile' => (_PS_MOBILE_) ? 1 : 0, 'status' => 'ok', 'id_order' => $params['objOrder']->id) ); else $smarty->assign('status', 'failed'); return $this->display(__FILE__, 'hookorderconfirmation.tpl'); } public function getProperBin() { $file_list = Tools::scandir($this->bin_dir, ''); $ignore_list = array('.', '..', 'index.php', 'modulev2.exe'); $handle = array_diff($file_list, $ignore_list); foreach ($handle as $file) { $is_response = stristr($file, 'module'); if($is_response !== false) { $result = $this->simpleExec($this->bin_dir.$file); if (!empty($result)) { if ($file == 'modulev2.cgi') break; $suffix = str_replace('modulev2', '', $file); $this->renameBin($suffix); break; } unset($result); } } unset($handle, $file, $ignore_list, $file_list); } public function renameBin($suffix) { if (file_exists($this->bin_dir.$suffix)) { rename($this->bin_dir.'modulev2.cgi', $this->bin_dir.'modulev2_old.cgi'); rename($this->bin_dir.$suffix, $this->bin_dir.'modulev2.cgi'); } } public function simpleExec($cmd) { exec($cmd, $output); return ($output); } public function getContent() { $exec = is_callable('exec'); $is_win = (Tools::strtoupper(Tools::substr(PHP_OS, 0, 3)) === 'WIN'); // Binary auto configuration if ($exec && (int)$is_win === 0) { $result = $this->simpleExec($this->bin_dir.'modulev2.cgi'); if (empty($result)) $this->getProperBin(); unset($result); } $html = ''; if (Tools::isSubmit('submitPaybox')) { Configuration::updateValue('PBX_SITE', trim(Tools::getValue('PBX_SITE'))); Configuration::updateValue('PBX_RANG', trim(Tools::getValue('PBX_RANG'))); Configuration::updateValue('PBX_ID', trim(Tools::getValue('PBX_ID'))); Configuration::updateValue('PBX_DEMO_MODE', (int)Tools::getValue('demo_mode')); $html .= $this->displayConfirmation($this->l(' Configuration updated')); } if (Tools::isSubmit('submitPaybox2')) { Configuration::updateValue('PBX_3X', Tools::getValue('PBX_3X')); Configuration::updateValue('PBX_DELAY', Tools::getValue('PBX_DELAY')); $html .= $this->displayConfirmation($this->l(' Options updated')); } $html .= '

'.$this->displayName.'

 
'.$this->l('Settings').'
 
 
 
'.$this->l('Test').'  '.$this->l('Production').'

'.$this->l('URL of the merchand test account backoffice : https://preprod-admin.paybox.com/').'
'.$this->l('The username and password are the same that for your production account.').'

'.$this->l('Here are the test informations you have to use on test mode :').'
'.$this->l('Site Number (TPE) 1999888').'
'.$this->l('Rang 99').'
'.$this->l('Paybox ID 2').'

'.$this->l('Before moving paybox into production mode, you must first set your Paybox account into production mode otherwise you will get a payment error.').'
 
PrestaShop Addons '.$this->l('Thank you for choosing a module developed by the Addons Team of PrestaShop.').'

'.$this->l('If you encounter a problem using the module, our team is at your service via the ').' '.$this->l('contact form').'.
'; return $html; } public function loadKey($keyfile, $pub=true, $pass='') { $keyfile = dirname(__FILE__).'/pubkey.pem'; $fpk = $filedata = $key = false; // initialisation variables $fsize = filesize( $keyfile ); // taille du fichier if( !$fsize ) return false; // si erreur on quitte de suite $fpk = fopen( $keyfile, 'r' ); // ouverture fichier if( !$fpk ) return false; // si erreur ouverture on quitte $filedata = fread( $fpk, $fsize ); // lecture contenu fichier fclose( $fpk ); // fermeture fichier if( !$filedata ) return false; // si erreur lecture, on quitte if( $pub ) $key = openssl_pkey_get_public( $filedata ); // recuperation de la cle publique else // ou recuperation de la cle privee $key = openssl_pkey_get_private( array( $filedata, $pass )); return $key; // renvoi cle ( ou erreur ) } // comme precise la documentation Paybox, la signature doit �tre // obligatoirement en derni�re position pour que cela fonctionne public function GetSignedData( $qrystr, &$data, &$sig, $url ) // renvoi les donnes signees et la signature { $pos = strrpos( $qrystr, '&' ); // cherche dernier separateur $data = substr( $qrystr, 0, $pos ); // et voila les donnees signees $pos= strpos( $qrystr, '=', $pos ) + 1; // cherche debut valeur signature $sig = substr( $qrystr, $pos ); // et voila la signature if( $url ) $sig = urldecode( $sig ); // decodage signature url $sig = base64_decode( $sig ); // decodage signature base 64 } // $querystring = chaine enti�re retourn�e par Paybox lors du retour au site (m�thode GET) // $keyfile = chemin d'acc�s complet au fichier de la cl� publique Paybox public function PbxVerSign( $qrystr, $keyfile, $url ) // verification signature Paybox { $key = self::loadKey($keyfile); // chargement de la cle if( !$key ) return -1; // si erreur chargement cle // penser � openssl_error_string() pour diagnostic openssl si erreur self::GetSignedData( $qrystr, $data, $sig, $url ); // separation et recuperation signature et donnees return openssl_verify( $data, $sig, $key ); // verification : 1 si valide, 0 si invalide, -1 si erreur } public function hookPayment($params) { global $cart, $smarty; $customer = new Customer((int)$cart->id_customer); if (!Validate::isLoadedObject($customer)) die(Tools::displayError()); // verif if there's at least one order with this delivery address $orders_with_delivery_address = Db::getInstance()->getValue(' SELECT COUNT(o.`id_order`) FROM `'._DB_PREFIX_.'orders` o WHERE o.`id_address_delivery` = '.(int)$cart->id_address_delivery.' AND o.`id_customer` = '.(int)$cart->id_customer.' AND ( o.valid = 1 OR ( o.valid = 0 AND (SELECT h.id_order_state FROM `'._DB_PREFIX_.'order_history` h WHERE h.id_order = o.id_order ORDER BY h.date_add DESC LIMIT 1) NOT IN (6,8,15,16,18) ) ) '); if ($orders_with_delivery_address == 0){ $paybox_cards = array(); } else { $paybox_cards = Db::getInstance()->executeS(' SELECT `id_paybox_card`, `value`, `date`, `payment_type` FROM `'._DB_PREFIX_.'paybox_customer_agreement` WHERE `id_customer` = '.(int)$cart->id_customer.' '); foreach ($paybox_cards as $key => $card) { $paybox_cards[$key]['date_validity'] = substr_replace($card['date'],'/',-2,0); } } // @Override Antadis HMAC $ps_url = ((Configuration::get('PS_SSL_ENABLED') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PORT'] == '443')) ? 'https://' : 'http://').$_SERVER['HTTP_HOST'].__PS_BASE_URI__; $pbx_link_plus = $ps_url.'modules/'.$this->name.'/direct_paiement.php'; $pbx_site = trim(Configuration::get('PBX_SITE')); $pbx_rang = trim(Configuration::get('PBX_RANG')); $pbx_id = trim(Configuration::get('PBX_ID')); $pbx_cmd = $cart->id; $pbx_total = (int)sprintf('%f', number_format(Tools::convertPrice($cart->getOrderTotal(), null, false), 2, '.', '') * 100); $pbx_devise = 978; // euro $pbx_ipn = $ps_url.'modules/'.$module->name.'/validation.php'; $pbx_porteur = $customer->email; $pbx_refabonne = $customer->email; $pbx_retour = 'm:M;r:R;t:T;a:A;b:B;p:P;c:C;s:S;y:Y;e:E;n:N;j:J;d:D;i:I;k:K'; $pbx_retour_save = 'm:M;r:R;t:T;a:A;b:B;p:P;c:C;s:S;y:Y;e:E;n:N;j:J;d:D;u:U;i:I;k:K'; $language = new Language((int)$cart->id_lang); switch ($language->iso_code) { case 'fr': $pbx_langue = 'FRA'; break; case 'es': $pbx_langue = 'ESP'; break; case 'de': $pbx_langue = 'DEU'; break; case 'it': $pbx_langue = 'ITA'; break; case 'nl': $pbx_langue = 'NLD'; break; case 'sv': $pbx_langue = 'SWE'; break; case 'en-us': default: $pbx_langue = 'GBR'; break; } unset($language); $count_cards = Db::getInstance()->getValue(' SELECT COUNT(`id_paybox_card`) FROM `'._DB_PREFIX_.'paybox_customer_agreement` WHERE `id_customer` = '.(int)$cart->id_customer.' '); if ($count_cards) { $pbx_refabonne_save = $customer->email.((int)$count_cards+1); } else { $pbx_refabonne_save = $customer->email; } if (version_compare(_PS_VERSION_, '1.5', '>')){ $pbx_confurl = $ps_url.'index.php?controller=order-confirmation&id_cart='.$cart->id.'&id_module='.$module->id.'&key='.$customer->secure_key; $pbx_cancelurl = $ps_url.'index.php?controller=order&step=3'; } else { $pbx_confurl = $ps_url.'order-confirmation.php?id_cart='.$cart->id.'&id_module='.$module->id.'&key='.$customer->secure_key; $pbx_cancelurl = $ps_url.'order.php?step=3'; } if(Configuration::get('PBX_DEMO_MODE') == 0){ if (_PS_MOBILE_) { $pbx_paybox = "https://preprod-tpeweb.paybox.com/cgi/ChoixPaiementMobile.cgi"; $pbx_backup1 = "https://preprod-tpeweb.paybox.com/cgi/ChoixPaiementMobile.cgi"; } else { $pbx_paybox = "https://preprod-tpeweb.paybox.com/cgi/MYchoix_pagepaiement.cgi"; $pbx_backup1 = "https://preprod-tpeweb.paybox.com/cgi/MYchoix_pagepaiement.cgi"; } } else { if (_PS_MOBILE_) { $pbx_paybox = "https://tpeweb.paybox.com/cgi/ChoixPaiementMobile.cgi"; $pbx_backup1 = "https://tpeweb.paybox.com/cgi/ChoixPaiementMobile.cgi"; } else { $pbx_paybox = "https://tpeweb.paybox.com/cgi/MYchoix_pagepaiement.cgi"; $pbx_backup1 = "https://tpeweb.paybox.com/cgi/MYchoix_pagepaiement.cgi"; } } // clef secrète du commerçant $secretKeyTest = Configuration::get('PBX_SECRETE_KEY'); $binKey = pack("H*", $secretKeyTest); $pbx_hash = "SHA512"; $pbx_time = date("c"); $pbx_3ds = 'N'; // On crée la chaîne à hacher sans URLencodage $msg ="PBX_SITE=$pbx_site". "&PBX_RANG=$pbx_rang". "&PBX_IDENTIFIANT=$pbx_id". "&PBX_LANGUE=$pbx_langue". "&PBX_TOTAL=$pbx_total". "&PBX_DEVISE=$pbx_devise". "&PBX_CMD=$pbx_cmd". "&PBX_PORTEUR=$pbx_porteur". "&PBX_REFABONNE=$pbx_refabonne". "&PBX_RETOUR=$pbx_retour". "&PBX_EFFECTUE=$pbx_confurl". "&PBX_ANNULE=$pbx_cancelurl". "&PBX_REFUSE=$pbx_confurl". "&PBX_REPONDRE_A=$pbx_ipn". "&PBX_3DS=$pbx_3ds". "&PBX_HASH=$pbx_hash". "&PBX_TIME=$pbx_time"; // Chaine pour save la ref abonne au retour $msg_save ="PBX_SITE=$pbx_site". "&PBX_RANG=$pbx_rang". "&PBX_IDENTIFIANT=$pbx_id". "&PBX_LANGUE=$pbx_langue". "&PBX_TOTAL=$pbx_total". "&PBX_DEVISE=$pbx_devise". "&PBX_CMD=$pbx_cmd". "&PBX_PORTEUR=$pbx_porteur". "&PBX_REFABONNE=$pbx_refabonne_save". "&PBX_RETOUR=$pbx_retour_save". "&PBX_EFFECTUE=$pbx_confurl". "&PBX_ANNULE=$pbx_cancelurl". "&PBX_REFUSE=$pbx_confurl". "&PBX_REPONDRE_A=$pbx_ipn". "&PBX_3DS=$pbx_3ds". "&PBX_HASH=$pbx_hash". "&PBX_TIME=$pbx_time"; $pbx_hmac = strtoupper(hash_hmac('sha512', $msg, $binKey)); $pbx_hmac_save = strtoupper(hash_hmac('sha512', $msg_save, $binKey)); // @End override $smarty->assign(array( 'PBX_MODE' => 1, 'pbx_paybox' => $pbx_paybox, 'pbx_total' => $pbx_total, 'pbx_site' => $pbx_site, 'pbx_rang' => $pbx_rang, 'pbx_id' => $pbx_id, 'pbx_cmd' => $pbx_cmd, 'pbx_total' => $pbx_total, 'pbx_devise' => $pbx_devise, 'pbx_ipn' => $pbx_ipn, 'pbx_porteur' => $pbx_porteur, 'pbx_refabonne' => $pbx_refabonne, 'pbx_refabonne_save' => $pbx_refabonne_save, 'pbx_retour' => $pbx_retour, 'pbx_retour_save' => $pbx_retour_save, 'pbx_confurl' => $pbx_confurl, 'pbx_cancelurl' => $pbx_cancelurl, 'pbx_3ds' => $pbx_3ds, 'pbx_langue' => $pbx_langue, 'pbx_hmac' => $pbx_hmac, 'pbx_hmac_save' => $pbx_hmac_save, 'pbx_picture' => 'paybox', 'pbx_text' => $this->l('Pay by credit card with Paybox'), 'paybox_cards' => $paybox_cards, 'pbx_link_plus' => $pbx_link_plus )); return ($this->display(__FILE__, 'hookpayment.tpl')); } public function validateOrder($id_cart, $id_order_state, $amount_paid, $payment_method = 'Unknown', $message = null, $transaction = array(), $currency_special = null, $dont_touch_amount = false, $secure_key = false, $values = array()) { if ($this->active) { parent::validateOrder((int)$id_cart, (int)$id_order_state, (float)$amount_paid, $payment_method, $message, $transaction, $currency_special, $dont_touch_amount, $secure_key); } if(!empty($values) && isset($values['i'])) { if (!class_exists('Fraud')) { include_once _MODULE_DIR_.'fraud/fraud.php'; } $fraud = new Fraud(); $fraud->testPaybox($this->currentOrder,$values['i']); } } /** * Save Information de Paiement Paybox (retour de la banque) * @param array $values Tableau de retour Paybox **/ public function saveInformationPaiement($values,$direct_plus=false) { if(isset($values['u']) || !empty($values['u']) && !$direct_plus ) { $cart = new Cart((int)$values["r"]); $this->saveInformationCB($values,$cart->id_customer); } $sql_cart = 'SELECT `num_transaction` FROM `ps_paybox_transaction` WHERE `id_cart` = ' .(int)$values["r"]; $exists = Db::getInstance()->getValue($sql_cart); if (empty($exists)) { $sql = 'INSERT INTO `ps_paybox_transaction` (`amount`, `id_cart`, `num_appel`, `num_autorisation`, `paiement`, `type`, `num_transaction`, `code_erreur`, `date_carte`, `date_add`, `is_saved_card`) VALUES ( '. (int)$values["m"] .', '. (int)$values["r"] .', '. (int)$values["t"] .', "'. pSQL($values["p"]) .'", "'. pSQL($values["c"]) .'", "'. pSQL($values["a"]) .'", '. (int)$values["s"] .', "'. pSQL($values["e"]) .'", "'. pSQL($values["d"]) .'", "'. date("Y-m-d H:i:s").'", '.(isset($values['saved'])?1:0).' )'; $save = Db::getInstance()->execute($sql); if(!$save) { mail('thibault@antadis.com', 'Erreur save commande', serialize($values)); mail('marion@antadis.com', '[BBB] Erreur save commande', serialize($values)); } } } /** * Save Information de carte Paiement Paybox (retour de la banque + handle de la cart) * @param array $values Tableau de retour Paybox **/ public function saveInformationCB($values,$id_customer) { $handle = explode(' ',$values['u']); $date = substr($values["d"], -2).substr($values["d"], 0, 2); $payment = str_replace("_", " ",$values["c"]); $customer = new Customer((int)$id_customer); $refabonne = $customer->email; $exists = Db::getInstance()->getValue(' SELECT `id_paybox_card` FROM `ps_paybox_customer_agreement` WHERE `handle` = "'.pSQL($handle[0]).'" AND `date`="'.pSQL($date).'" AND `payment_type`="'.pSQL($payment).'" AND `id_customer`='.(int)$id_customer.' '); if (empty($exists)) { $count_cards = Db::getInstance()->getValue(' SELECT COUNT(`id_paybox_card`) FROM `'._DB_PREFIX_.'paybox_customer_agreement` WHERE `id_customer` = '.(int)$id_customer.' '); if ($count_cards) { $refabonne = $customer->email.((int)$count_cards+1); } $num_value = $values["n"].'XXXXX'.$values["j"]; $save = Db::getInstance()->execute(' INSERT INTO `ps_paybox_customer_agreement` (`id_customer`,`refabonne`,`handle`,`value`,`date`,`payment_type`) VALUES ( '. (int)$id_customer .', "'. pSQL($refabonne) .'", "'. pSQL($handle[0]) .'", "'. pSQL($num_value) .'", "'.pSQL($date).'", "'. pSQL($payment) .'" )'); if(!$save) { mail('marion@antadis.com', 'Erreur save card', http_build_query($values,'',', ')); } } } public function hookcancelShipping($params) { global $cookie; if(Tools::getValue('noCancelHook')) { return; } // if(Tools::isSubmit('generateDiscount')) // return false; if($params['order']->module != $this->name) return false; if(!($order = $params['order']) OR !Validate::isLoadedObject($order)) return false; if($cookie->profile == 1 || $cookie->profile == 7 || $cookie->profile == 14 || $cookie->profile == 11) { if(!$order->hasBeenPaid()) { // mail('thibault@antadis.com', 'Erreur remboursement', 'Erreur de remboursement sur la commande ' . $order_detail->id_order . ' la commande n\'a pas été payée.'); mail('karen@bebeboutik.com', 'Erreur remboursement', 'Erreur de remboursement sur la commande ' . $order_detail->id_order . ' la commande n\'a pas été payée.'); mail('doreen@bebeboutik.com', 'Erreur remboursement', 'Erreur de remboursement sur la commande ' . $order_detail->id_order . ' la commande n\'a pas été payée.'); mail('contact@bebeboutik.com', 'Erreur remboursement', 'Erreur de remboursement sur la commande ' . $order_detail->id_order . ' la commande n\'a pas été payée.'); } else { if ($order->payment == "Paybox") { $this->refundShipping($order); } } } } public function hookcancelProduct($params) { global $cookie; // if(Tools::isSubmit('generateDiscount')) { // return FALSE; // } if($params['order']->module != $this->name) { return FALSE; } if(!($order_detail = new OrderDetail((int)($params['id_order_detail']))) || !Validate::isLoadedObject($order_detail)) { return FALSE; } $employee = new Employee((int) $cookie->id_employee); if(!Validate::isLoadedObject($employee)) { return FALSE; } if (Tools::isSubmit('generateCreditSlip')) { if($cookie->profile == 1 || $cookie->profile == 7 || $cookie->profile == 14 || $cookie->profile == 11) { $order = new Order($order_detail->id_order); if ($order->payment == "Paybox") { if(!$order->hasBeenPaid()) { // mail('thibault@antadis.com', 'Erreur remboursement la commande nest pas valide pour etre rembourse', 'Erreur de remboursement sur la commande ' . $order_detail->id_order . ' la commande n\'a pas été payée.'); mail('karen@bebeboutik.com', 'Erreur remboursement', 'Erreur de remboursement sur la commande ' . $order_detail->id_order . ' la commande n\'a pas été payée.'); mail('doreen@bebeboutik.com', 'Erreur remboursement', 'Erreur de remboursement sur la commande ' . $order_detail->id_order . ' la commande n\'a pas été payée.'); mail('contact@bebeboutik.com', 'Erreur remboursement', 'Erreur de remboursement sur la commande ' . $order_detail->id_order . ' la commande n\'a pas été payée.'); } else { $this->refundProduct($params['id_order_detail']); } } } } } /** * Rembourse un Order Detail * @param int $id_order_detail Numéro de ligne de commande à refund **/ public function refundProduct($id_order_detail) { global $cookie; $order_detail = new OrderDetail($id_order_detail); $order = new Order($order_detail->id_order); $transaction = $this->loadTransaction($order->id_cart); if(empty($transaction)) { return false; } else { $products = $order->getProducts(); // quantite deja envoye $send_quantity = (int) Db::getInstance()->getValue(' SELECT `quantity` FROM `'._DB_PREFIX_.'lapostews` WHERE `id_order_detail` = '. (int) $order_detail->id ); $quantity_available = $order_detail->product_quantity; // $quantity_available = $order_detail->product_quantity - (($send_quantity - $order_detail->product_quantity_return)); if ( $_POST['cancelQuantity'][(int) $order_detail->id] <= $quantity_available) { $total_shipping = (int) Db::getInstance()->getValue(' SELECT `shipping_cost` FROM `'._DB_PREFIX_.'order_slip` WHERE `id_order` = '.(int) $order->id.' AND `shipping_cost` = 1 '); $total_refunded = (float) Db::getInstance()->getValue(' SELECT SUM(ROUND((product_price * (1 - reduction_percent / 100) - reduction_amount) * (1 - group_reduction / 100) * (1 + tax_rate / 100), 2) * product_quantity_refunded) FROM `'._DB_PREFIX_.'order_detail` WHERE `id_order` = '.(int) $order->id.' AND `id_order_detail` != '.(int) $order_detail->id.' '); $amt = $products[(int) $order_detail->id]['product_price_wt'] * (int) ($_POST['cancelQuantity'][(int) $order_detail->id]); $montant = min($amt, $order->total_paid_real - ((int) $total_shipping * $order->total_shipping) - $total_refunded); $refund = $this->sendRefundPaybox($montant, 978, $transaction['num_transaction'], $order->id_cart, $transaction['num_appel']); if (!$refund) { // mail('thibault@antadis.com', 'Erreur dans le remboursement produit', 'Erreur remboursement échoué pour la commande ' . $order_detail->id_order); mail('karen@bebeboutik.com', 'Erreur dans le remboursement', 'Erreur remboursement échoué pour la commande ' . $order_detail->id_order); mail('doreen@bebeboutik.com', 'Erreur dans le remboursement', 'Erreur remboursement échoué pour la commande ' . $order_detail->id_order); mail('contact@bebeboutik.com', 'Erreur dans le remboursement', 'Erreur remboursement échoué pour la commande ' . $order_detail->id_order); } else { $this->refundSave($order_detail->id_order, $order_detail->id, $montant, $cookie->id_employee); } } else { // mail('thibault@antadis.com', 'Erreur dans la quantité du remboursement pas de num de transaction', 'Erreur remboursement pour la commande ' . $order_detail->id_order); mail('karen@bebeboutik.com', 'Erreur dans la quantité du remboursement', 'Erreur remboursement pour la commande ' . $order_detail->id_order); mail('doreen@bebeboutik.com', 'Erreur dans la quantité du remboursement', 'Erreur remboursement pour la commande ' . $order_detail->id_order); mail('contact@bebeboutik.com', 'Erreur dans la quantité du remboursement', 'Erreur remboursement pour la commande ' . $order_detail->id_order); } } } /** * Remboursement des frais de port d'une commande * @param Object $order **/ public function refundShipping($order) { global $cookie; $total_refunded = (float) Db::getInstance()->getValue(' SELECT SUM(ROUND((product_price * (1 - reduction_percent / 100) - reduction_amount) * (1 - group_reduction / 100) * (1 + tax_rate / 100), 2) * product_quantity_refunded) FROM `'._DB_PREFIX_.'order_detail` WHERE `id_order` = '.(int) $order->id.' '); $transaction = $this->loadTransaction($order->id_cart); if(empty($transaction)) { return false; } else { $montant = $order->total_shipping; $montant = Tools::ps_round(min($montant, $order->total_paid_real - $total_refunded), 2); if($montant > 0) { $refund = $this->sendRefundPaybox($montant, 978, $transaction['num_transaction'], $order->id_cart, $transaction['num_appel']); if (!$refund) { // mail('thibault@antadis.com', 'Erreur dans le remboursement des shippings', 'Erreur remboursement échoué pour la commande ' . $order->id); mail('karen@bebeboutik.com', 'Erreur dans le remboursement', 'Erreur remboursement échoué pour la commande ' . $order->id); mail('doreen@bebeboutik.com', 'Erreur dans le remboursement', 'Erreur remboursement échoué pour la commande ' . $order->id); mail('contact@bebeboutik.com', 'Erreur dans le remboursement', 'Erreur remboursement échoué pour la commande ' . $order->id); } else { $this->refundSave($order->id, 0, $montant, $cookie->id_employee); } } } } /** * Génére un remboursement PAYBOX * @param float $montant Montant à rembourser * @param int $devise Numéro de la devise * @param int $num_transaction Numéro unique de transaction retourné par Paybox au paiement initial * @param int $reference Numéro de référence de la commande (id_cart) * @param int $num_appel Numéro d'appel retourné par Paybox au paiement initial **/ public function sendRefundPaybox($montant, $devise, $num_transaction, $reference, $num_appel) { $curl = curl_init('https://ppps.paybox.com/PPPS.php'); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_COOKIESESSION, true); $pbx_site = trim(Configuration::get('PBX_SITE')); $pbx_rang = trim(Configuration::get('PBX_RANG')); $pbx_id = trim(Configuration::get('PBX_ID')); $num_question = Configuration::get('NUM_QUESTION_PAYBOX') + 1; Configuration::updateValue('NUM_QUESTION_PAYBOX', $num_question); $montant = $montant * 100; $montant = str_pad($montant, 10, 0, STR_PAD_LEFT); $postfields = array( 'VERSION' => '00104', 'TYPE' => '00014', 'SITE' => $pbx_site, 'RANG' => $pbx_rang, // 'IDENTIFIANT' => $pbx_id, 'CLE' => 'EFNLJKFB', 'NUMQUESTION' => $num_question, 'MONTANT' => $montant, 'DEVISE' => $devise, 'NUMTRANS' => $num_transaction, 'NUMAPPEL' => $num_appel, 'REFERENCE' => $reference, 'DATEQ' => date('dmYHis') ); $trame = http_build_query($postfields, '', '&'); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); curl_setopt($curl, CURLOPT_POSTFIELDS, $trame); $response = curl_exec($curl); curl_close($curl); $data = explode('&', $response); $code_reponse = explode('CODEREPONSE=', $data[6]); // refund success if ( $code_reponse[1] == "00000" || $code_reponse[0] == "00000") { return true; } else { // mail('thibault@antadis.com', 'Soucis remboursement reponse globale', json_encode($response)); // mail('thibault@antadis.com', 'Soucis remboursement envoi + code reponse', json_encode($postfields).' -- '.json_encode($code_reponse)); // mail('thibault@antadis.com', 'post remboursement', $num_transaction .' -- '. json_encode($code_reponse)); return false; } } /** * Save refund transaction in BDD when its OK * @param int $id_order * @param int $id_order_detail * @param int $montant * @param int $id_employee **/ protected function refundSave($id_order, $id_order_detail = 0, $montant, $id_employee) { Db::getInstance()->execute(' INSERT INTO `'._DB_PREFIX_.'refund_transaction` (`id_order`, `id_order_detail`, `amount`, `date`, `id_employee`) VALUES ( '. (int)$id_order .', '. (int)$id_order_detail .', '. $montant * 100 .', "'. date('Y-m-d H:i:s') .'", '. (int)$id_employee .' )' ); } /** * Load les informations d'une transaction paybox * @param int $id_cart Numéro du panier à charger * @return array Les informations de transaction **/ public function loadTransaction($id_cart) { return Db::getInstance()->getRow(' SELECT * FROM `'._DB_PREFIX_.'paybox_transaction` WHERE `id_cart` = '. (int)$id_cart ); } /** * Recupere la liste des remboursements effectués sur un id cmomande * @param int $order_id id de la commande * @return array **/ public static function getAllRefundbyOrder($order_id) { return Db::getInstance()->executeS(' SELECT e.`email`, r.`date`, r.`amount`, r.`id_order_detail`, d.`product_name` FROM `'._DB_PREFIX_.'refund_transaction` r LEFT JOIN `'._DB_PREFIX_.'employee` e ON r.`id_employee` = e.`id_employee` LEFT JOIN `'._DB_PREFIX_.'order_detail` d on d.`id_order_detail` = r.`id_order_detail` WHERE r.`id_order` = '. (int)$order_id ); } }