public function confirm() { // Global vars $kccPath = Configuration::get(KCC_PATH); $kccLogPath = Configuration::get(KCC_LOG); // Order States $order_state_completed = (int) Configuration::get('PS_OS_PAYMENT'); $order_state_failed = (int) Configuration::get('PS_OS_ERROR'); $order_state_waiting_payment = (int) Configuration::get(KCC_WAITING_PAYMENT_STATE); // TBK Vars $tbk_session_id = isset($_POST['TBK_ID_SESION']) ? trim($_POST['TBK_ID_SESION']) : null; $tbk_order_id = isset($_POST['TBK_ORDEN_COMPRA']) ? trim($_POST['TBK_ORDEN_COMPRA']) : null; $tbk_response = isset($_POST['TBK_RESPUESTA']) ? trim($_POST['TBK_RESPUESTA']) : null; $tbk_total_amount = isset($_POST['TBK_MONTO']) ? trim($_POST['TBK_MONTO']) : null; // Log helper closure $logger = function ($message) { $today = date('Y-m-d'); $now = date('Y-m-d H:i:s'); $name = "validation.{$today}.log"; $path = _PS_MODULE_DIR_ . 'webpaykcc/logs/'; $logPath = Configuration::get(KCC_LOG); if ($logPath) { $path = $logPath; } $logFile = $path . $name; $log = fopen($logFile, 'a'); $text = "{$now} : {$message}\n"; fwrite($log, $text); fclose($log); }; // Helper closure // for the total amount $getOrderTotalAmount = function ($cart) { $order_total = 0; if ($cart) { $order_total = Tools::ps_round(floatval($cart->getOrderTotal(true, Cart::BOTH)), 0); } return $order_total; }; // Default Values $result = KCC_REJECTED_RESULT; $order = null; $cart = null; $isDone = false; // Start Validation Process $logger("Start Validation"); $logger("#################"); // Log Params Received if (count($_POST) > 0) { $logger("Params Received"); foreach ($_POST as $key => $value) { $logger("{$key} => {$value}"); } } else { $logger("Params Not Found"); } // Get cart data if (isset($tbk_order_id)) { try { $order = new Order(Order::getOrderByCartId($tbk_order_id)); $cart = Cart::getCartByOrderId($order->id); } catch (Exception $e) { $logger($e->getMessage()); } } else { $logger("TBK_ORDEN_COMPRA Not Set"); } // First we must check the tbk_response. if (isset($tbk_response)) { if ($tbk_response == KCC_OK_RESPONSE) { $logger("Response is OK"); // Both order and cart must exist if (isset($order->id) && isset($cart->id)) { $logger("Order Exists"); // Now we check the current state of the order and cart if ($order->current_state == $order_state_waiting_payment) { $logger("Order is Waiting Payment"); // The amounts must be equal $total_order_amount = $getOrderTotalAmount($cart); // Needed 00 at the end $total_order_amount_formatted = $total_order_amount . '00'; if ($total_order_amount_formatted == $tbk_total_amount) { $logger("Amounts are Equal"); // Now check the session log file if (isset($tbk_session_id)) { // The log file was generated in front controller $tbk_log_path = getKccLog($kccLogPath, $tbk_session_id); if (file_exists($tbk_log_path)) { // Open the log file $tbk_log = fopen($tbk_log_path, 'r'); // Put everything inside in a string $tbk_log_string = fgets($tbk_log); fclose($tbk_log); // $tbk_details is an array // separated by semicolon $tbk_details = explode(';', $tbk_log_string); // Details should exist if (isset($tbk_details) && isset($tbk_details[0]) && isset($tbk_details[1])) { $logger("Session File Exists"); $tbk_session_total_amount = $tbk_details[0]; $tbk_session_order_id = $tbk_details[1]; // Session values and POST values must be equal if ($tbk_session_total_amount == $tbk_total_amount && $tbk_session_order_id == $tbk_order_id) { $logger("Session Values are Correct"); // Check KCC Path if (!(is_null($kccPath) || $kccPath == '')) { // The cache file is needed for validation $tbk_cache_path = $tbk_log_path . '.cache'; $tbk_cache = fopen($tbk_cache_path, 'w+'); // Write all the vars to cache foreach ($_POST as $tbk_key => $tbk_value) { fwrite($tbk_cache, "{$tbk_key}={$tbk_value}&"); } fclose($tbk_cache); $logger("Cache file created"); // Execute the CGI Check Script $logger("Start CGI Verification Process"); if (KCC_USE_EXEC) { $logger("Verify Using Exec"); // Store the result in $tbk_result // executing the script with the log cache file // as param $command = $kccPath . KCC_CGI_CHECK . ' ' . $tbk_cache_path; exec($command, $tbk_result); } else { // Use perl // TODO: Implement Perl Someday $logger("Verify Using Perl"); } // Check the result $logger("Checking the CGI Result"); if (isset($tbk_result[0]) && $tbk_result[0] == KCC_VERIFICATION_OK) { // Verification OK // Change the order status $logger("Transbank Verification Complete"); $current_state = $order->current_state; try { $order->setCurrentState($order_state_completed); $logger("Order State Was Changed From ({$current_state}) to ({$order->current_state})"); } catch (Exception $e) { $logger($e->getMessage()); } // Last Check if ($order->current_state == $order_state_completed) { $result = KCC_ACCEPTED_RESULT; $logger("Order state is Completed"); $isDone = true; } else { $result = KCC_REJECTED_RESULT; $logger("Order State is not Completed."); } } else { $logger("Failed CGI Verification " . json_encode($tbk_result)); } } else { $logger("KCC Path not Found"); } } else { $logger("Session and Post Vars are different"); $logger("Session Total : {$tbk_session_total_amount}"); $logger("TBK Total: {$tbk_total_amount}"); $logger("Session Order: {$tbk_session_order_id}"); $logger("TBK Order Id: {$tbk_order_id}"); } } else { $logger("{$tbk_log_path} does not contains valid data"); } } else { $logger("{$tbk_log_path} does not exist"); } } else { $logger("TBK_ID_SESION not set"); } } else { $logger("Amounts are different " . "{$total_order_amount_formatted} != {$tbk_total_amount}"); } } else { $logger("Order State is not Waiting Payment ({$order_state_waiting_payment})"); $logger("Current Order State is ({$order->current_state})"); } } else { $logger("Order not found in DB"); } } else { if ($tbk_response >= -8 && $tbk_response <= -1) { $result = KCC_ACCEPTED_RESULT; $logger("Accepted Result, but TBK_RESPUESTA != OK (0)"); } else { $logger("TBK_RESPUESTA has invalid value"); } } } else { $logger("TBK_RESPUESTA not set"); } // Set state to failed if not done if (!$isDone && isset($order->current_state)) { if ($order->current_state != $order_state_completed) { try { $order->setCurrentState($order_state_failed); $logger("Order State was set to Failed ({$order_state_failed})"); } catch (Exception $e) { $logger($e->getMessage()); } } } // End Validation Process $logger("Final Result: {$result}"); $logger("End Validation"); $logger("#################"); echo $result; }
private function handleOK() { // Get Webpay Post Data // Check if the Post Data exists $session_id = isset($_POST['TBK_ID_SESION']) ? $_POST['TBK_ID_SESION'] : null; $cart_id = isset($_POST['TBK_ORDEN_COMPRA']) ? $_POST['TBK_ORDEN_COMPRA'] : null; $response = isset($_POST['TBK_RESPUESTA']) ? $_POST['TBK_RESPUESTA'] : null; $tbk_total_amount = isset($_POST['TBK_MONTO']) ? $_POST['TBK_MONTO'] : null; // log files $tbk_log_path = null; $tbk_cache_path = null; // Paths from Configuration $kccPath = Configuration::get(KCC_PATH); $kccLogPath = Configuration::get(KCC_LOG); $kccTocPage = Configuration::get(KCC_TOC_PAGE_URL); $cart = null; $order = null; $customer = null; $webpaykcc = new WebpayKcc(); // Error vars $error = false; $error_message = null; // Set the log paths // and cart and order vars if (!is_null($cart_id) && !is_null($session_id)) { // The log file was generated in front controller $tbk_log_path = getKccLog($kccLogPath, $session_id); // The cache file is needed for validation // was generated in validate.php $tbk_cache_path = $tbk_log_path . '.cache'; // Get cart data // $cart_id is set in /controllers/front/payment.php // as the current cart id // this is called by transbank with those vars try { $order = new Order(Order::getOrderByCartId($cart_id)); $cart = Cart::getCartByOrderId($order->id); } catch (Exception $e) { $error = true; $error_message = $e->getMessage(); } } else { $error = true; $error_message = 'Session and Cart params not found'; } // Start Checks for Success if (!$error) { // Check if log files are present if (file_exists($tbk_log_path) && file_exists($tbk_cache_path)) { // Check if order and cart exists if (isset($order->id) && isset($cart->id)) { // Check for customer $customer = $order->getCustomer(); if (isset($customer->id)) { // Check Log Data $tbk_cache = fopen($tbk_cache_path, 'r'); $tbk_cache_string = fgets($tbk_cache); fclose($tbk_cache); $tbk_data = explode('&', $tbk_cache_string); // there must be at least 12 params // response is the 2nd param if (is_array($tbk_data) && isset($tbk_data[2]) && count($tbk_data) >= 12) { // Check Response to be OK $tbk_response = explode('=', $tbk_data[2]); if (isset($tbk_response[1]) && $tbk_response[1] == KCC_OK_RESPONSE) { // Check current order state // must be completed $order_state_completed = (int) Configuration::get('PS_OS_PAYMENT'); if ($order->current_state == $order_state_completed) { // Everything seems OK // should render the Success Page $error = false; $error_message = null; } else { $error = true; $error_message = "Order state is not completed, current state {$order->current_state}"; } } else { $error = true; $error_message = 'Response is not OK'; } } else { $error = true; $error_message = 'Cache data is invalid'; } } else { $error = true; $error_message = 'Customer not found'; } } else { $error = true; $error_message = 'Order or Cart Objects not Found'; } } else { $error = true; $error_message = 'Log files not found'; } } // Render the template if (!$error && is_null($error_message)) { // Init params var $params = array(); // Get the active shop id if in multistore shop $activeShopID = (int) Context::getContext()->shop->id; // Parse Cache // $tbk_data and tbk_response are set in checks above $tbk_cart_id = explode('=', $tbk_data[0]); $tbk_transaction_type = explode('=', $tbk_data[1]); $tbk_amount = explode('=', $tbk_data[3]); $tbk_auth_code = explode('=', $tbk_data[4]); $tbk_card_last_digit = explode('=', $tbk_data[5]); $tbk_accounting_date = explode('=', $tbk_data[6]); $tbk_transaction_date = explode('=', $tbk_data[7]); $tbk_transaction_time = explode('=', $tbk_data[8]); $tbk_transaction_id = explode('=', $tbk_data[10]); $tbk_payment_type = explode('=', $tbk_data[11]); $tbk_installment_quantity = explode('=', $tbk_data[12]); $tbk_mac = explode('=', $tbk_data[13]); // Do some formatting for the Accounting Year $tbk_accounting_year = date('Y'); if (substr($tbk_accounting_date[1], 0, 2) == '12' && date('d') == '01') { $tbk_accounting_year = date('Y') - 1; } else { if (substr($tbk_accounting_date[1], 0, 2) == '01' && date('d') == '12') { $tbk_accounting_year = date('Y') + 1; } } // Do some formatting for the Transaction Year $tbk_transaction_year = date('Y'); if (substr($tbk_transaction_date[1], 0, 2) == '12' && date('d') == '01') { $tbk_transaction_year = date('Y') - 1; } else { if (substr($tbk_transaction_date[1], 0, 2) == '01' && date('d') == '12') { $tbk_transaction_year = date('Y') + 1; } } // Start Adding info to Params // Format transaction date $params['tbk_transaction_date'] = substr($tbk_transaction_date[1], 2, 2) . '-' . substr($tbk_transaction_date[1], 0, 2) . '-' . $tbk_transaction_year; // Format transaction time $params['tbk_transaction_time'] = substr($tbk_transaction_time[1], 0, 2) . ':' . substr($tbk_transaction_time[1], 2, 2) . ':' . substr($tbk_transaction_time[1], 4, 2); // Do some formatting for the payment type if ($tbk_payment_type[1] == 'VD') { $params['tbk_payment_type'] = $this->module->l('Redcompra'); } else { $params['tbk_payment_type'] = $this->module->l("Crédito"); } // Do some formatting for the Installment Type if ($tbk_payment_type[1] == 'VN') { $params['tbk_installment_type'] = $this->module->l('Sin cuotas'); } else { if ($tbk_payment_type[1] == 'VC') { $params['tbk_installment_type'] = $this->module->l('Cuotas normales'); } else { if ($tbk_payment_type[1] == 'SI') { $params['tbk_installment_type'] = $this->module->l('Sin interés'); } else { if ($tbk_payment_type[1] == 'S2') { $params['tbk_installment_type'] = $this->module->l('Dos cuotas sin interés'); } else { if ($tbk_payment_type[1] == 'CI') { $params['tbk_installment_type'] = $this->module->l('Cuotas comercio'); } else { if ($tbk_payment_type[1] == 'VD') { $params['tbk_installment_type'] = $this->module->l('Débito'); } } } } } } // Check for Quantity of Installments if ($tbk_installment_quantity[1] == 0) { $params['tbk_installment_quantity'] = '00'; } else { $params['tbk_installment_quantity'] = $tbk_installment_quantity[1]; } // Add more info to params // General Info $base_url = Tools::getShopDomainSsl(true, true); $order_history_url = $base_url . __PS_BASE_URI__ . 'index.php?controller=order-detail&id_cart=' . $cart_id . '&id_module=' . (int) $webpaykcc->id . '&id_order=' . $order->id . '&key=' . $customer->secure_key . '&status=OPEN'; $params['toc_page'] = $kccTocPage; $params['order_history'] = $order_history_url; $params['shop_name'] = Context::getContext()->shop->name; $params['shop_url'] = $base_url; $params['customer_name'] = $customer->firstname . ' ' . $customer->lastname; // Transbank Info $params['tbk_accounting_year'] = $tbk_accounting_year; $params['tbk_transaction_year'] = $tbk_transaction_year; $params['tbk_mac'] = $tbk_mac[1]; $params['tbk_cart_id'] = $tbk_cart_id[1]; // TODO: Should check tbk_transaction_type value // For now this will work $params['tbk_transaction_type'] = $this->module->l('Venta'); $params['tbk_amount'] = $tbk_amount[1] / 100; $params['tbk_auth_code'] = $tbk_auth_code[1]; $params['tbk_card_last_digit'] = '************' . $tbk_card_last_digit[1]; $params['tbk_transaction_id'] = $tbk_transaction_id[1]; $params['string'] = print_r($params, true); $params['logo'] = $this->logo; // Now we pass the data // to smarty and render // the template $this->context->smarty->assign($params); $this->setTemplate('success.tpl'); } else { // for generating pages $base_url = Tools::getShopDomainSsl(true, true) . __PS_BASE_URI__; // Base URL for success // or failure pages $module_url = "index.php?fc=module&module=" . "{$webpaykcc->name}&controller=" . "validate" . "&cartId=" . $cart_id; $failure_page = $base_url . $module_url . "&return=error"; // set the error message $this->error_message = $error_message; // Redirect to failure // $this->handleError(); Tools::redirect($failure_page); } }