Update catalog/controller/payment/hutko.php
This commit is contained in:
@@ -10,7 +10,6 @@ class Hutko extends \Opencart\System\Engine\Controller {
|
||||
}
|
||||
|
||||
public function confirm(): void {
|
||||
// Load language here so 'text_redirecting_comment' is available
|
||||
$this->load->language('extension/hutko/payment/hutko');
|
||||
$this->load->model('checkout/order');
|
||||
|
||||
@@ -25,26 +24,59 @@ class Hutko extends \Opencart\System\Engine\Controller {
|
||||
if (!$order_info) {
|
||||
$json['error'] = 'Order missing';
|
||||
} else {
|
||||
$request_data = $this->buildRequest($order_info);
|
||||
// 1. Generate unique Ref for THIS attempt
|
||||
$timestamp = time();
|
||||
$hutko_ref = $order_info['order_id'] . '#' . $timestamp;
|
||||
|
||||
$request_data = $this->buildRequest($order_info, $hutko_ref);
|
||||
|
||||
if (!$request_data) {
|
||||
$json['error'] = $this->language->get('error_payment_data_build');
|
||||
} else {
|
||||
$this->load->model('extension/hutko/payment/hutko');
|
||||
$this->model_extension_hutko_payment_hutko->addHutkoOrder($order_info['order_id'], $request_data['order_id']);
|
||||
|
||||
// 2. Call API
|
||||
$response = $this->api($this->checkout_url, $request_data);
|
||||
|
||||
if (($response['response']['response_status'] ?? '') === 'success' && !empty($response['response']['checkout_url'])) {
|
||||
// Language keys are loaded now, so this will contain actual text
|
||||
$comment = sprintf($this->language->get('text_redirecting_comment'), $request_data['order_id'], $response['response']['checkout_url']);
|
||||
$this->model_checkout_order->addHistory($order_info['order_id'], $this->config->get('payment_hutko_new_order_status_id'), $comment, false);
|
||||
$url = $response['response']['checkout_url'];
|
||||
|
||||
$json['redirect'] = $response['response']['checkout_url'];
|
||||
// 3. Log to INTERNAL DB (Not Customer History)
|
||||
$this->model_extension_hutko_payment_hutko->logTransaction(
|
||||
$order_info['order_id'],
|
||||
$hutko_ref,
|
||||
'payment_request',
|
||||
'created',
|
||||
$request_data['amount'] / 100,
|
||||
$request_data['currency'],
|
||||
[
|
||||
'request_data' => $request_data, // Store sent data (except signature if needed)
|
||||
'checkout_url' => $url,
|
||||
'user_agent' => $this->request->server['HTTP_USER_AGENT'] ?? ''
|
||||
]
|
||||
);
|
||||
|
||||
// 4. Update Order Status to "Pending" (or configured status) if not already
|
||||
// Only add history if it's a fresh order, don't spam.
|
||||
if ($order_info['order_status_id'] == 0) {
|
||||
$this->model_checkout_order->addHistory($order_info['order_id'], $this->config->get('payment_hutko_new_order_status_id'), $this->language->get('text_initiated_payment'), false);
|
||||
}
|
||||
|
||||
$json['redirect'] = $url;
|
||||
} else {
|
||||
$err = $response['response']['error_message'] ?? $this->language->get('error_api_communication');
|
||||
$json['error'] = $err;
|
||||
$this->logOC('Checkout Error: ' . $err);
|
||||
|
||||
// Log Failure
|
||||
$this->model_extension_hutko_payment_hutko->logTransaction(
|
||||
$order_info['order_id'],
|
||||
$hutko_ref,
|
||||
'payment_request',
|
||||
'failed',
|
||||
$request_data['amount'] / 100,
|
||||
$request_data['currency'],
|
||||
['error' => $err, 'api_response' => $response]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,56 +87,73 @@ class Hutko extends \Opencart\System\Engine\Controller {
|
||||
}
|
||||
|
||||
public function callback(): void {
|
||||
// IMPORTANT: Load language for status translations (e.g. text_payment_approved)
|
||||
$this->load->language('extension/hutko/payment/hutko');
|
||||
|
||||
$input = file_get_contents("php://input");
|
||||
$data = json_decode($input, true);
|
||||
|
||||
if ($this->config->get('payment_hutko_save_logs')) {
|
||||
$this->logOC('Callback: ' . $input);
|
||||
}
|
||||
|
||||
if (!$data || !$this->validate($data)) {
|
||||
// Basic Validation
|
||||
if (!$data || !isset($data['order_id'])) {
|
||||
http_response_code(400);
|
||||
exit('Invalid Request');
|
||||
}
|
||||
|
||||
$parts = explode('#', $data['order_id']);
|
||||
// Verify Signature first
|
||||
if (!$this->validate($data)) {
|
||||
http_response_code(400);
|
||||
exit('Invalid Signature');
|
||||
}
|
||||
|
||||
$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);
|
||||
|
||||
if ($order_info) {
|
||||
$this->load->model('extension/hutko/payment/hutko');
|
||||
$status = $data['order_status'] ?? '';
|
||||
$comment_details = "Hutko Order ID: " . $data['order_id'] . ". Status: " . $status . ". ";
|
||||
|
||||
$current_status_id = $order_info['order_status_id'];
|
||||
// 1. Log the RAW callback to our internal table
|
||||
$this->model_extension_hutko_payment_hutko->logTransaction(
|
||||
$order_id,
|
||||
$hutko_ref,
|
||||
'callback',
|
||||
($status === 'approved') ? 'success' : 'failed',
|
||||
isset($data['amount']) ? $data['amount'] / 100 : 0,
|
||||
$data['currency'] ?? '',
|
||||
$data // Save full payload
|
||||
);
|
||||
|
||||
$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' && (!isset($data['reversal_amount']) || (int)$data['reversal_amount'] === 0)) {
|
||||
$target = (int)$this->config->get('payment_hutko_success_status_id');
|
||||
if ($current_status_id != $target) {
|
||||
$msg = $this->language->get('text_payment_approved') . ' ' . $comment_details;
|
||||
$this->model_checkout_order->addHistory($order_id, $target, $msg, true);
|
||||
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);
|
||||
}
|
||||
echo "OK";
|
||||
} else {
|
||||
echo "Approved but invalid details";
|
||||
}
|
||||
} elseif ($status === 'declined') {
|
||||
$target = (int)$this->config->get('payment_hutko_declined_status_id');
|
||||
if ($current_status_id != $target) {
|
||||
$msg = $this->language->get('text_payment_declined') . ' ' . $comment_details;
|
||||
$this->model_checkout_order->addHistory($order_id, $target, $msg, true);
|
||||
$target_status_id = (int)$this->config->get('payment_hutko_declined_status_id');
|
||||
if ($current_status_id != $target_status_id) {
|
||||
// Don't notify customer on decline to avoid spam if they retry
|
||||
$this->model_checkout_order->addHistory($order_id, $target_status_id, $this->language->get('text_payment_declined'), false);
|
||||
}
|
||||
echo "Order declined";
|
||||
} elseif ($status === 'expired') {
|
||||
$target = (int)$this->config->get('payment_hutko_expired_status_id');
|
||||
if ($current_status_id != $target) {
|
||||
$msg = $this->language->get('text_payment_expired') . ' ' . $comment_details;
|
||||
$this->model_checkout_order->addHistory($order_id, $target, $msg, true);
|
||||
// Often better not to change order status to "Expired" if you want to allow retries,
|
||||
// but if you do, don't notify customer.
|
||||
$target_status_id = (int)$this->config->get('payment_hutko_expired_status_id');
|
||||
if ($current_status_id != $target_status_id) {
|
||||
$this->model_checkout_order->addHistory($order_id, $target_status_id, $this->language->get('text_payment_expired'), false);
|
||||
}
|
||||
echo "Order expired";
|
||||
} else {
|
||||
@@ -116,9 +165,8 @@ class Hutko extends \Opencart\System\Engine\Controller {
|
||||
}
|
||||
}
|
||||
|
||||
private function buildRequest($order) {
|
||||
$ref = $order['order_id'] . '#' . time();
|
||||
|
||||
private function buildRequest($order, $hutko_ref) {
|
||||
// Logic same as before, but using passed $hutko_ref
|
||||
$products_data = $this->getProducts($order['order_id'], $order);
|
||||
|
||||
$total_products_sum = 0;
|
||||
@@ -161,7 +209,7 @@ class Hutko extends \Opencart\System\Engine\Controller {
|
||||
];
|
||||
|
||||
$data = [
|
||||
'order_id' => $ref,
|
||||
'order_id' => $hutko_ref,
|
||||
'merchant_id' => $this->config->get('payment_hutko_merchant_id'),
|
||||
'amount' => $total_cents,
|
||||
'currency' => $order['currency_code'],
|
||||
@@ -176,6 +224,8 @@ class Hutko extends \Opencart\System\Engine\Controller {
|
||||
return $data;
|
||||
}
|
||||
|
||||
// Helper functions (getProducts, sign, validate, api, logOC) remain the same...
|
||||
// Just ensure logOC uses file log for debug, not DB log.
|
||||
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 . "'");
|
||||
|
||||
Reference in New Issue
Block a user