fixed cart clearance
This commit is contained in:
@@ -1,18 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Opencart\Catalog\Controller\Extension\Hutko\Payment;
|
||||
|
||||
class Hutko extends \Opencart\System\Engine\Controller {
|
||||
class Hutko extends \Opencart\System\Engine\Controller
|
||||
{
|
||||
private $checkout_url = 'https://pay.hutko.org/api/checkout/url/';
|
||||
|
||||
public function index(): string {
|
||||
public function index(): string
|
||||
{
|
||||
$this->load->language('extension/hutko/payment/hutko');
|
||||
return $this->load->view('extension/hutko/payment/hutko', ['language' => $this->config->get('config_language')]);
|
||||
}
|
||||
|
||||
public function confirm(): void {
|
||||
public function confirm(): void
|
||||
{
|
||||
$this->load->language('extension/hutko/payment/hutko');
|
||||
$this->load->model('checkout/order');
|
||||
|
||||
|
||||
$json = [];
|
||||
|
||||
if (!isset($this->session->data['order_id'])) {
|
||||
@@ -20,7 +24,7 @@ public function confirm(): void {
|
||||
$json['redirect'] = $this->url->link('checkout/failure', 'language=' . $this->config->get('config_language'), true);
|
||||
} else {
|
||||
$order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);
|
||||
|
||||
|
||||
if (!$order_info) {
|
||||
$json['error'] = 'Order missing';
|
||||
} else {
|
||||
@@ -28,7 +32,7 @@ public function confirm(): void {
|
||||
|
||||
// Call the shared logic method
|
||||
$request_data = $this->buildRequest($order_info, $hutko_ref);
|
||||
|
||||
|
||||
if (!$request_data) {
|
||||
$json['error'] = $this->language->get('error_payment_data_build');
|
||||
} else {
|
||||
@@ -58,14 +62,27 @@ public function confirm(): void {
|
||||
if ($new_status_id <= 0) {
|
||||
$new_status_id = 1; // Default to Pending
|
||||
}
|
||||
|
||||
|
||||
$this->model_checkout_order->addHistory($order_info['order_id'], $new_status_id, $this->language->get('text_initiated_payment'), false);
|
||||
}
|
||||
|
||||
// Clear Cart and Session Data BEFORE redirecting to Gateway
|
||||
// This ensures the cart is empty regardless of the return path/device.
|
||||
$this->cart->clear();
|
||||
unset($this->session->data['shipping_method']);
|
||||
unset($this->session->data['shipping_methods']);
|
||||
unset($this->session->data['payment_method']);
|
||||
unset($this->session->data['payment_methods']);
|
||||
unset($this->session->data['guest']);
|
||||
unset($this->session->data['comment']);
|
||||
unset($this->session->data['coupon']);
|
||||
unset($this->session->data['reward']);
|
||||
unset($this->session->data['voucher']);
|
||||
unset($this->session->data['vouchers']);
|
||||
unset($this->session->data['totals']);
|
||||
// NOTE: Do NOT unset 'order_id' here, as checkout/success needs it to show the "Order #123 placed" page.
|
||||
$json['redirect'] = $url;
|
||||
} else {
|
||||
// ... error handling (same as before) ...
|
||||
$err = $response['response']['error_message'] ?? $this->language->get('error_api_communication');
|
||||
$err = $response['response']['error_message'] ?? $this->language->get('error_api_communication');
|
||||
$json['error'] = $err;
|
||||
$this->model_extension_hutko_payment_hutko->logTransaction(
|
||||
$order_info['order_id'],
|
||||
@@ -84,9 +101,10 @@ public function confirm(): void {
|
||||
$this->response->addHeader('Content-Type: application/json');
|
||||
$this->response->setOutput(json_encode($json));
|
||||
}
|
||||
public function callback(): void {
|
||||
public function callback(): void
|
||||
{
|
||||
$this->load->language('extension/hutko/payment/hutko');
|
||||
|
||||
|
||||
$input = file_get_contents("php://input");
|
||||
$data = json_decode($input, true);
|
||||
|
||||
@@ -105,7 +123,7 @@ public function confirm(): void {
|
||||
$hutko_ref = $data['order_id']; // e.g., 55#17555555
|
||||
$parts = explode('#', $hutko_ref);
|
||||
$order_id = (int)$parts[0];
|
||||
|
||||
|
||||
$this->load->model('checkout/order');
|
||||
$order_info = $this->model_checkout_order->getOrder($order_id);
|
||||
|
||||
@@ -125,12 +143,12 @@ public function confirm(): void {
|
||||
);
|
||||
|
||||
$current_status_id = (int)$order_info['order_status_id'];
|
||||
|
||||
|
||||
// 2. Update OpenCart History (Clean Messages Only)
|
||||
if ($status === 'approved') {
|
||||
if (isset($data['response_status']) && $data['response_status'] == 'success') {
|
||||
$target_status_id = (int)$this->config->get('payment_hutko_success_status_id');
|
||||
|
||||
|
||||
// Avoid duplicates: Only update if status is different
|
||||
if ($current_status_id != $target_status_id) {
|
||||
$this->model_checkout_order->addHistory($order_id, $target_status_id, $this->language->get('text_payment_approved'), true);
|
||||
@@ -163,9 +181,10 @@ public function confirm(): void {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function validate($data) {
|
||||
|
||||
|
||||
private function validate($data)
|
||||
{
|
||||
$sig = $data['signature'] ?? '';
|
||||
unset($data['signature'], $data['response_signature_string']);
|
||||
return hash_equals($this->sign($data), $sig);
|
||||
@@ -177,9 +196,10 @@ public function confirm(): void {
|
||||
// MAINTENANCE WARNING: Keep synchronized with Admin Controller
|
||||
// =========================================================================
|
||||
|
||||
private function buildRequest($order, $hutko_ref) {
|
||||
private function buildRequest($order, $hutko_ref)
|
||||
{
|
||||
$products_data = $this->getProducts($order['order_id'], $order);
|
||||
|
||||
|
||||
$total_products_sum = 0;
|
||||
foreach ($products_data as $p) {
|
||||
$total_products_sum += $p['total_amount'];
|
||||
@@ -194,7 +214,7 @@ public function confirm(): void {
|
||||
}
|
||||
|
||||
$order_total_val = $this->currency->format($order['total'], $order['currency_code'], $order['currency_value'], false);
|
||||
|
||||
|
||||
if ($this->config->get('payment_hutko_include_discount_to_total')) {
|
||||
$amount_val = $order_total_val;
|
||||
if (!$this->config->get('payment_hutko_shipping_include')) {
|
||||
@@ -207,7 +227,8 @@ public function confirm(): void {
|
||||
if ($amount_val < 0.01) $amount_val = 0.01;
|
||||
$total_cents = (int)round($amount_val * 100);
|
||||
|
||||
// Catalog side URLs are simple
|
||||
|
||||
|
||||
$response_url = $this->url->link('checkout/success', 'language=' . $this->config->get('config_language'), true);
|
||||
$callback_url = $this->url->link('extension/hutko/payment/hutko.callback', '', true);
|
||||
|
||||
@@ -234,12 +255,25 @@ public function confirm(): void {
|
||||
'sender_email' => $order['email'],
|
||||
'reservation_data' => base64_encode(json_encode($reservation_data))
|
||||
];
|
||||
|
||||
|
||||
$data['signature'] = $this->sign($data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function getProducts(int $order_id, array $order_info): array {
|
||||
|
||||
public function response(): void
|
||||
{
|
||||
// Post-Redirect-Get pattern.
|
||||
// Accepts the POST from Gateway, then redirects user via GET to restore Session/Cookies.
|
||||
// This ensures the Cart is cleared and User is not logged out.
|
||||
|
||||
// If the gateway passes specific error flags in POST, you could check them here
|
||||
// and redirect to checkout/failure instead. For now, we assume success flow.
|
||||
$this->response->redirect($this->url->link('checkout/success', 'language=' . $this->config->get('config_language'), true));
|
||||
}
|
||||
|
||||
private function getProducts(int $order_id, array $order_info): array
|
||||
{
|
||||
$products_data = [];
|
||||
$query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "order_product` WHERE `order_id` = '" . (int)$order_id . "'");
|
||||
|
||||
@@ -274,16 +308,20 @@ public function confirm(): void {
|
||||
return $products_data;
|
||||
}
|
||||
|
||||
private function sign($data) {
|
||||
private function sign($data)
|
||||
{
|
||||
$key = $this->config->get('payment_hutko_secret_key');
|
||||
$arr = array_filter($data, function($v){ return $v !== '' && $v !== null; });
|
||||
$arr = array_filter($data, function ($v) {
|
||||
return $v !== '' && $v !== null;
|
||||
});
|
||||
ksort($arr);
|
||||
$str = $key;
|
||||
foreach($arr as $v) $str .= '|' . $v;
|
||||
foreach ($arr as $v) $str .= '|' . $v;
|
||||
return sha1($str);
|
||||
}
|
||||
|
||||
private function api($url, $data) {
|
||||
private function api($url, $data)
|
||||
{
|
||||
if ($this->config->get('payment_hutko_save_logs')) $this->logOC('Req: ' . json_encode($data));
|
||||
|
||||
$ch = curl_init($url);
|
||||
@@ -293,7 +331,7 @@ public function confirm(): void {
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||
|
||||
|
||||
$res = curl_exec($ch);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
@@ -302,14 +340,15 @@ public function confirm(): void {
|
||||
$this->logOC('Res: ' . $res);
|
||||
if ($error) $this->logOC('Curl Error: ' . $error);
|
||||
}
|
||||
|
||||
|
||||
return json_decode($res, true) ?: [];
|
||||
}
|
||||
|
||||
private function logOC($msg) {
|
||||
private function logOC($msg)
|
||||
{
|
||||
$this->log->write("Hutko Payment: " . $msg);
|
||||
}
|
||||
// =========================================================================
|
||||
// SHARED LOGIC END
|
||||
// =========================================================================
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user