first commit

This commit is contained in:
O K
2025-12-12 09:28:40 +02:00
commit b1b2ef5949
15 changed files with 1303 additions and 0 deletions

View File

@@ -0,0 +1,302 @@
<?php
namespace Opencart\Admin\Controller\Extension\Hutko\Payment;
class Hutko extends \Opencart\System\Engine\Controller {
private $refund_url = 'https://pay.hutko.org/api/reverse/order_id';
private $status_url = 'https://pay.hutko.org/api/status/order_id';
public function index(): void {
$this->load->language('extension/hutko/payment/hutko');
$this->document->setTitle($this->language->get('heading_title'));
$data['breadcrumbs'] = [];
$data['breadcrumbs'][] = [
'text' => $this->language->get('text_home'),
'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'])
];
$data['breadcrumbs'][] = [
'text' => $this->language->get('text_extension'),
'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment')
];
$data['breadcrumbs'][] = [
'text' => $this->language->get('heading_title'),
'href' => $this->url->link('extension/hutko/payment/hutko', 'user_token=' . $this->session->data['user_token'])
];
// Save action
$data['save'] = $this->url->link('extension/hutko/payment/hutko.save', 'user_token=' . $this->session->data['user_token']);
$data['back'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=payment');
// Configuration Fields
$fields = [
'payment_hutko_merchant_id',
'payment_hutko_secret_key',
'payment_hutko_shipping_include',
'payment_hutko_shipping_product_name',
'payment_hutko_shipping_product_code',
'payment_hutko_new_order_status_id',
'payment_hutko_success_status_id',
'payment_hutko_declined_status_id',
'payment_hutko_expired_status_id',
'payment_hutko_refunded_status_id',
'payment_hutko_include_discount_to_total',
'payment_hutko_status',
'payment_hutko_sort_order',
'payment_hutko_geo_zone_id',
'payment_hutko_total',
'payment_hutko_save_logs'
];
foreach ($fields as $field) {
$data[$field] = $this->config->get($field);
}
// Defaults
if (is_null($data['payment_hutko_shipping_product_name'])) $data['payment_hutko_shipping_product_name'] = 'Package material';
if (is_null($data['payment_hutko_shipping_product_code'])) $data['payment_hutko_shipping_product_code'] = '0_0_1';
if (is_null($data['payment_hutko_total'])) $data['payment_hutko_total'] = '0.01';
$this->load->model('localisation/order_status');
$data['order_statuses'] = $this->model_localisation_order_status->getOrderStatuses();
$this->load->model('localisation/geo_zone');
$data['geo_zones'] = $this->model_localisation_geo_zone->getGeoZones();
$data['log_content'] = $this->displayLastDayLog();
$data['header'] = $this->load->controller('common/header');
$data['column_left'] = $this->load->controller('common/column_left');
$data['footer'] = $this->load->controller('common/footer');
$this->response->setOutput($this->load->view('extension/hutko/payment/hutko', $data));
}
public function save(): void {
$this->load->language('extension/hutko/payment/hutko');
$json = [];
if (!$this->user->hasPermission('modify', 'extension/hutko/payment/hutko')) {
$json['error']['warning'] = $this->language->get('error_permission');
}
// Validation
if (empty($this->request->post['payment_hutko_merchant_id']) || !is_numeric($this->request->post['payment_hutko_merchant_id'])) {
$json['error']['payment_hutko_merchant_id'] = $this->language->get('error_merchant_id_numeric');
}
$key = $this->request->post['payment_hutko_secret_key'] ?? '';
if (empty($key) || ($key != 'test' && (strlen($key) < 10 || is_numeric($key)))) {
$json['error']['payment_hutko_secret_key'] = $this->language->get('error_secret_key_invalid');
}
if (!$json) {
$this->load->model('setting/setting');
$this->model_setting_setting->editSetting('payment_hutko', $this->request->post);
$json['success'] = $this->language->get('text_success');
}
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}
public function install(): void {
$this->load->model('extension/hutko/payment/hutko');
$this->model_extension_hutko_payment_hutko->install();
// OC4 Event Registration
$this->load->model('setting/event');
$event_code = 'hutko_order_info';
$event_trigger = 'admin/view/sale/order_info/after';
$event_action = 'extension/hutko/payment/hutko.order_info';
// OC 4.0.2.0 introduced the array signature for addEvent
if (version_compare(VERSION, '4.0.2.0', '>=')) {
$this->model_setting_event->addEvent([
'code' => $event_code,
'description' => 'Hutko Payment Info Panel',
'trigger' => $event_trigger,
'action' => $event_action,
'status' => 1,
'sort_order' => 0
]);
} else {
// Legacy argument style for 4.0.0.0 - 4.0.1.x
$this->model_setting_event->addEvent($event_code, $event_trigger, $event_action, 1, 0);
}
}
public function uninstall(): void {
$this->load->model('extension/hutko/payment/hutko');
$this->model_extension_hutko_payment_hutko->uninstall();
$this->load->model('setting/event');
$this->model_setting_event->deleteEventByCode('hutko_order_info');
}
// Event Handler for Admin Order View
public function order_info(string &$route, array &$args, string &$output): void {
if (!isset($args['order_id'])) return;
$this->load->model('sale/order');
$order_info = $this->model_sale_order->getOrder((int)$args['order_id']);
// FIX: Check if payment_code exists and matches either 'hutko' or 'hutko.hutko'
if ($order_info && isset($order_info['payment_code']) && ($order_info['payment_code'] == 'hutko' || $order_info['payment_code'] == 'hutko.hutko')) {
$this->load->language('extension/hutko/payment/hutko');
$this->load->model('extension/hutko/payment/hutko');
$hutko_order = $this->model_extension_hutko_payment_hutko->getHutkoOrder((int)$args['order_id']);
$data['hutko_transaction_ref'] = $hutko_order['hutko_transaction_ref'] ?? '';
$data['order_id'] = (int)$args['order_id'];
$data['user_token'] = $this->session->data['user_token'];
// URLs for AJAX actions
$data['refund_url'] = $this->url->link('extension/hutko/payment/hutko.refund', 'user_token=' . $this->session->data['user_token']);
$data['status_url'] = $this->url->link('extension/hutko/payment/hutko.status', 'user_token=' . $this->session->data['user_token']);
// Language Data
$data['text_payment_information'] = $this->language->get('text_payment_information');
$data['text_hutko_transaction_ref_label'] = $this->language->get('text_hutko_transaction_ref_label');
$data['hutko_transaction_ref_display'] = $data['hutko_transaction_ref'] ?: $this->language->get('text_not_available');
$data['text_not_available'] = $this->language->get('text_not_available');
$data['text_hutko_refund_title'] = $this->language->get('text_hutko_refund_title');
$data['entry_refund_amount'] = $this->language->get('entry_refund_amount');
$data['entry_refund_comment'] = $this->language->get('entry_refund_comment');
$data['button_hutko_refund'] = $this->language->get('button_hutko_refund');
$data['text_confirm_refund'] = $this->language->get('text_confirm_refund');
$data['text_hutko_status_title'] = $this->language->get('text_hutko_status_title');
$data['button_hutko_status_check'] = $this->language->get('button_hutko_status_check');
$content = $this->load->view('extension/hutko/payment/hutko_order', $data);
// Inject content before the History tab/card
$pos = strpos($output, '<div id="history"');
if ($pos !== false) {
$output = substr_replace($output, $content, $pos, 0);
} else {
$output .= $content;
}
}
}
public function refund(): void {
$this->load->language('extension/hutko/payment/hutko');
$this->load->model('extension/hutko/payment/hutko');
$this->load->model('sale/order');
$json = [];
$order_id = (int)($this->request->post['order_id'] ?? 0);
$amount = (float)($this->request->post['refund_amount'] ?? 0);
$comment = (string)($this->request->post['refund_comment'] ?? '');
$hutko_order = $this->model_extension_hutko_payment_hutko->getHutkoOrder($order_id);
$order_info = $this->model_sale_order->getOrder($order_id);
if ($hutko_order && $order_info && $amount > 0) {
$data = [
'order_id' => $hutko_order['hutko_transaction_ref'],
'merchant_id' => $this->config->get('payment_hutko_merchant_id'),
'version' => '1.0',
'amount' => round($amount * 100),
'currency' => $order_info['currency_code'],
'comment' => $comment
];
$data['signature'] = $this->sign($data);
$response = $this->api($this->refund_url, $data);
if (($response['response']['reverse_status'] ?? '') === 'approved') {
$json['success'] = $this->language->get('text_refund_success');
$msg = sprintf($this->language->get('text_refund_success_comment'), $hutko_order['hutko_transaction_ref'], $amount, $comment);
$this->model_sale_order->addHistory($order_id, $this->config->get('payment_hutko_refunded_status_id'), $msg, true);
} else {
$json['error'] = $response['response']['error_message'] ?? 'Unknown API Error';
$this->logOC("Refund Failed: " . json_encode($response));
}
} else {
$json['error'] = $this->language->get('error_invalid_request');
}
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}
public function status(): void {
$this->load->language('extension/hutko/payment/hutko');
$json = [];
$ref = $this->request->post['hutko_transaction_ref'] ?? '';
if ($ref) {
$data = [
'order_id' => $ref,
'merchant_id' => $this->config->get('payment_hutko_merchant_id'),
'version' => '1.0',
];
$data['signature'] = $this->sign($data);
$response = $this->api($this->status_url, $data);
if (($response['response']['response_status'] ?? '') === 'success') {
$json['success'] = $this->language->get('text_status_success');
unset($response['response']['response_signature_string'], $response['response']['signature']);
$json['data'] = $response['response'];
} else {
$json['error'] = $response['response']['error_message'] ?? 'API Error';
}
} else {
$json['error'] = $this->language->get('error_missing_params');
}
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}
// Helpers
private function sign(array $data): string {
$key = $this->config->get('payment_hutko_secret_key');
$filtered = array_filter($data, function ($v) { return $v !== '' && $v !== null; });
ksort($filtered);
$str = $key;
foreach ($filtered as $v) $str .= '|' . $v;
return sha1($str);
}
private function api(string $url, array $data): array {
if ($this->config->get('payment_hutko_save_logs')) $this->logOC('Req: ' . json_encode($data));
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['request' => $data]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$res = curl_exec($ch);
// curl_close($ch);
if ($this->config->get('payment_hutko_save_logs')) $this->logOC('Res: ' . $res);
return json_decode($res, true) ?: [];
}
private function displayLastDayLog() {
if (!$this->config->get('payment_hutko_save_logs')) return 'Logging Disabled';
$file = DIR_LOGS . 'error.log';
if (!file_exists($file)) return 'Log empty';
$lines = file($file);
$output = [];
// Get last 50 lines that match "Hutko"
for ($i = count($lines) - 1; $i >= 0 && count($output) < 50; $i--) {
if (strpos($lines[$i], 'Hutko') !== false) $output[] = htmlspecialchars($lines[$i], ENT_QUOTES, 'UTF-8');
}
return implode('<br>', $output);
}
private function logOC($message) {
$this->log->write('Hutko Payment: ' . $message);
}
}

View File

@@ -0,0 +1,114 @@
<?php
// Hutko translation file
// Heading
$_['heading_title'] = 'Hutko Payments';
// Text
$_['text_extension'] = 'Extensions';
$_['text_success'] = 'Success: You have modified Hutko payment module settings!';
$_['text_edit'] = 'Edit Hutko Payments';
$_['text_hutko'] = '<a href="https://hutko.org/" target="_blank"><img src="view/image/payment/hutko.png" alt="Hutko" title="Hutko" style="border: 1px solid #EEEEEE; max-height:25px;" /></a>'; // You'll need a hutko.png in admin/view/image/payment/
$_['text_enabled'] = 'Enabled';
$_['text_disabled'] = 'Disabled';
$_['text_yes'] = 'Yes';
$_['text_no'] = 'No';
$_['text_info_merchant'] = 'Use "1700243" for test setup.';
$_['text_info_secret'] = 'Use "test" for test setup.';
$_['text_logs_disabled'] = 'Logging is currently disabled. Enable "Save Logs" to see logs.';
$_['text_no_logs_found'] = 'No Hutko specific log entries found in the main log file for today, or logging is disabled.';
$_['text_log_file_not_found'] = 'Log file (%s) not found.';
$_['text_refund_success_comment'] = 'Refund Successful for ID: %s. Amount: %s. Comment: %s';
$_['text_refund_failed_comment'] = 'Refund Attempt Failed for ID: %s. Reason: %s';
$_['text_refund_success'] = 'Refund processed successfully via Hutko.';
$_['text_refund_api_error'] = 'Hutko API Error: %s';
$_['text_status_success'] = 'Status retrieved successfully from Hutko.';
$_['text_status_api_error'] = 'Hutko API Error fetching status: %s';
$_['text_unknown_error'] = 'An unknown error occurred.';
// Entry
$_['entry_merchant_id'] = 'Merchant ID';
$_['entry_secret_key'] = 'Secret Key';
$_['entry_new_order_status'] = 'New Order Status';
$_['entry_success_status'] = 'Successful Payment Status';
$_['entry_declined_status'] = 'Declined Payment Status';
$_['entry_expired_status'] = 'Expired Payment Status';
$_['entry_refunded_status'] = 'Refunded Payment Status';
$_['entry_shipping_include'] = 'Include Shipping Cost';
$_['entry_shipping_product_name'] = 'Shipping Fiscal Name';
$_['entry_shipping_product_code'] = 'Shipping Fiscal Code';
$_['entry_show_cards_logo'] = 'Show Visa/MasterCard Logo';
$_['entry_save_logs'] = 'Save Logs';
$_['entry_include_discount_to_total'] = 'Include Discounts in Total (for API)';
$_['entry_total'] = 'Minimum Order Total';
$_['entry_geo_zone'] = 'Geo Zone';
$_['entry_status'] = 'Status';
$_['entry_sort_order'] = 'Sort Order';
// Help
$_['help_total'] = 'The checkout total the order must reach before this payment method becomes active.';
$_['help_new_order_status'] = 'Status for new orders before payment redirection.';
$_['help_success_status'] = 'Status for successfully paid orders.';
$_['help_shipping_include'] = 'Include shipping cost as a separate item in the payment request details.';
$_['help_shipping_product_name'] = 'Name of product/service to use in fiscalization for shipping amount.';
$_['help_shipping_product_code'] = 'Code of product/service to use in fiscalization for shipping amount.';
$_['help_show_cards_logo'] = 'Display Visa/MasterCard logos next to the payment method name on checkout.';
$_['help_save_logs'] = 'Log API communication and callbacks to the system log file.';
$_['help_include_discount_to_total'] = 'If Yes, order discounts will be subtracted from the payment total, this may prevent fiscalization.';
// Error
$_['error_permission'] = 'Warning: You do not have permission to modify Hutko payment module!';
$_['error_merchant_id_required'] = 'Merchant ID is required!';
$_['error_merchant_id_numeric'] = 'Merchant ID must be numeric!';
$_['error_secret_key_required'] = 'Secret Key is required!';
$_['error_secret_key_invalid'] = 'Secret key must be "test" or at least 10 characters long and not entirely numeric.';
$_['error_invalid_request'] = 'Invalid request data for refund/status.';
$_['error_missing_params'] = 'Missing required parameters for refund/status.';
// Tab
$_['tab_general'] = 'General';
$_['tab_order_statuses'] = 'Order Statuses';
$_['tab_fiscalization'] = 'Fiscalization';
$_['tab_advanced'] = 'Advanced';
$_['tab_logs'] = 'Logs';
$_['text_payment_information'] = 'Payments History';
$_['text_not_available'] = 'N/A';
$_['text_hutko_transaction_ref_label'] = 'Hutko Transaction ID';
$_['text_hutko_refund_title'] = 'Hutko Refund';
$_['text_hutko_status_title'] = 'Hutko Status Check';
$_['button_hutko_refund'] = 'Process Hutko Refund';
$_['button_hutko_status_check'] = 'Check Hutko Payment Status';
$_['entry_refund_amount'] = 'Refund Amount';
$_['entry_refund_comment'] = 'Refund Comment (optional)';
$_['text_refund_success_comment'] = 'Refund for Hutko ID %s successful. Amount: %s. Comment: %s';
$_['text_refund_failed_comment'] = 'Refund attempt for Hutko ID %s failed. Gateway error: %s';
$_['text_refund_api_error'] = 'Hutko Refund API Error: %s';
$_['text_status_api_error'] = 'Hutko Status API Error: %s';
$_['text_unknown_error'] = 'An unknown error occurred with the API.';
$_['error_missing_order_id'] = 'Error: Order ID is missing from the request.';
$_['error_hutko_transaction_ref_not_found_db'] = 'Error: Hutko Transaction ID not found in database for this order.';
$_['error_hutko_transaction_ref_missing'] = 'Error: Hutko Transaction ID is required for this operation.';
$_['error_invalid_refund_amount'] = 'Error: Invalid refund amount. Must be greater than 0.';
$_['error_missing_refund_amount'] = 'Error: Refund amount is required.';
// For catalog side (checkout process)
$_['error_payment_data_build'] = 'Error: Could not prepare payment data. Please try again or contact support.';
$_['error_api_communication'] = 'Error: Could not communicate with the payment gateway. Please try again.';
$_['text_redirecting_comment'] = 'Redirecting to Hutko. Hutko Order ID: %s. URL: %s';
// For callback
$_['text_payment_approved'] = 'Payment Approved by Hutko.';
$_['text_payment_declined'] = 'Payment Declined by Hutko.';
$_['text_payment_expired'] = 'Payment Expired at Hutko.';
$_['text_payment_processing'] = 'Payment is Processing at Hutko.';
$_['text_confirm_refund'] = 'Are you sure you want to refund this transaction via Hutko? This action cannot be undone.';
$_['text_loading'] = 'Loading...';
$_['error_order_not_found'] = 'Error: Order not found.';

View File

@@ -0,0 +1,104 @@
<?php
// Hutko translation file
// Heading
$_['heading_title'] = 'Платежи Hutko';
$_['text_extension'] = 'Расширения';
$_['text_success'] = 'Успех: Вы изменили настройки модуля оплаты Hutko!';
$_['text_edit'] = 'Изменить настройки Hutko';
$_['text_hutko'] = '<a href="https://hutko.org/" target="_blank"><img src="view/image/payment/hutko.png" alt="Hutko" title="Hutko" style="border: 1px solid #EEEEEE; max-height:25px;" /></a>'; // Вам понадобится hutko.png в admin/view/image/payment/
$_['text_enabled'] = 'Включено';
$_['text_disabled'] = 'Отключено';
$_['text_yes'] = 'Да';
$_['text_no'] = 'Нет';
$_['text_info_merchant'] = 'Используйте "1700243" для теста.';
$_['text_info_secret'] = 'Используйте "test" для теста.';
$_['text_logs_disabled'] = 'Ведение журнала в настоящее время отключено. Включите "Сохранить журналы", чтобы увидеть журналы.';
$_['text_no_logs_found'] = 'В главном файле журнала на сегодня не найдено никаких записей журнала Hutko, или ведение журнала отключено.';
$_['text_log_file_not_found'] = 'Файл журнала (%s) не найден.';
$_['text_refund_success_comment'] = 'Возмещение выполнен успешно для ID: %s. Сумма: %s. Комментарий: %s';
$_['text_refund_failed_comment'] = 'Попытка возмещения не удалась для ID: %s. Причина: %s';
$_['text_refund_success'] = 'Возмещение успешно обработано через Hutko.';
$_['text_refund_api_error'] = 'Ошибка API Hutko: %s';
$_['text_status_success'] = 'Статус успешно получен от Hutko.';
$_['text_status_api_error'] = 'Ошибка API Hutko при получении статуса: %s';
$_['text_unknown_error'] = 'Произошла неизвестная ошибка.';
$_['entry_merchant_id'] = 'ID продавца';
$_['entry_secret_key'] = 'Секретный ключ';
$_['entry_new_order_status'] = 'Статус нового заказа';
$_['entry_success_status'] = 'Статус при успешном платеже';
$_['entry_declined_status'] = 'Статус при отклоненном платеже';
$_['entry_expired_status'] = 'Статус при просроченном платеже';
$_['entry_refunded_status'] = 'Статус при возмещении платеже';
$_['entry_shipping_include'] = 'Включить стоимость доставки';
$_['entry_shipping_product_name'] = 'Наименование доставки в фискальном чеке';
$_['entry_shipping_product_code'] = 'Код доставки в фискальном чеке';
$_['entry_show_cards_logo'] = 'Показать логотип Visa/MasterCard';
$_['entry_save_logs'] = 'Сохранять журналы';
$_['entry_include_discount_to_total'] = 'Включить скидки в общую сумму (для API)';
$_['entry_total'] = 'Минимальная сумма заказа';
$_['entry_geo_zone'] = 'Геозона';
$_['entry_status'] = 'Статус';
$_['entry_sort_order'] = 'Порядок сортировки';
$_['help_total'] = 'Сумма, которую должен достичь заказ, прежде чем этот способ оплаты станет активным.';
$_['help_new_order_status'] = 'Статус для новых заказов до получения платежа.';
$_['help_success_status'] = 'Статус для успешно оплаченных заказов.';
$_['help_shipping_include'] = 'Включить стоимость доставки в суму платежа.';
$_['help_shipping_product_name'] = 'Название продукта/услуги для использования при фискализации для суммы доставки.';
$_['help_shipping_product_code'] = 'Код продукта/услуги для использования при фискализации для суммы доставки.';
$_['help_show_cards_logo'] = 'Отображать логотипы Visa/MasterCard рядом с названием способа оплаты при оформлении заказа.';
$_['help_save_logs'] = 'Записывать коммуникацию API и обратные вызовы в системный файл журнала.';
$_['help_include_discount_to_total'] = 'Если да, скидки по заказу будут вычтены из общей суммы платежа, это может помешать фискализации.';
$_['error_permission'] = 'Внимание: у вас нет разрешения на изменение платежного модуля Hutko!';
$_['error_merchant_id_required'] = 'Требуется идентификатор продавца!';
$_['error_merchant_id_numeric'] = 'Идентификатор продавца должен быть числовым!';
$_['error_secret_key_required'] = 'Требуется секретный ключ!';
$_['error_secret_key_invalid'] = 'Секретный ключ должен быть "test" или содержать не менее 10 символов и не состоять полностью из цифр.';
$_['error_invalid_request'] = 'Недопустимые данные запроса на возмещения/статус.';
$_['error_missing_params'] = 'Отсутствуют обязательные параметры для возмещения/статуса.';
$_['tab_general'] = 'Общие';
$_['tab_order_statuses'] = 'Статусы заказов';
$_['tab_fiscalization'] = 'Фискализация';
$_['tab_advanced'] = 'Дополнительно';
$_['tab_logs'] = 'Журналы';
$_['text_payment_information'] = 'История платежей';
$_['text_not_available'] = 'Н/Д';
$_['text_hutko_transaction_ref_label'] = 'Идентификатор заказа в Hutko';
$_['text_hutko_refund_title'] = 'Возмещение Hutko';
$_['text_hutko_status_title'] = 'Проверка статуса Hutko';
$_['button_hutko_refund'] = 'Обработать возмещение через Hutko';
$_['button_hutko_status_check'] = 'Проверить статус платежа Hutko';
$_['entry_refund_amount'] = 'Сумма возмещения';
$_['entry_refund_comment'] = 'Комментарий к возмещению (необязательно)';
$_['text_refund_success_comment'] = 'Возмещение средств по ID %s успешно. Сумма: %s. Комментарий: %s';
$_['text_refund_failed_comment'] = 'Попытка возмещения средств по ID %s не удалась. Ошибка шлюза: %s';
$_['text_refund_api_error'] = 'Ошибка API возмещения Hutko: %s';
$_['text_status_api_error'] = 'Ошибка API статуса Hutko: %s';
$_['text_unknown_error'] = 'Произошла неизвестная ошибка API.';
$_['error_missing_order_id'] = 'Ошибка: в запросе отсутствует идентификатор заказа.';
$_['error_hutko_transaction_ref_not_found_db'] = 'Ошибка: идентификатор заказа Hutko не найден в базе данных для этого заказа.';
$_['error_hutko_transaction_ref_missing'] = 'Ошибка: идентификатор заказа Hutko требуется для этой операции.';
$_['error_invalid_refund_amount'] = 'Ошибка: недопустимая сумма возврата. Должна быть больше 0.';
$_['error_missing_refund_amount'] = 'Ошибка: требуется сумма возврата.';
$_['error_payment_data_build'] = 'Ошибка: не удалось подготовить данные платежа. Повторите попытку или обратитесь в службу поддержки.';
$_['error_api_communication'] = 'Ошибка: не удалось связаться с платежным шлюзом. Повторите попытку.';
$_['text_redirecting_comment'] = 'Перенаправление на Hutko. Идентификатор заказа Hutko: %s. URL: %s';
// Для обратного вызова
$_['text_payment_approved'] = 'Платеж одобрен Hutko.';
$_['text_payment_declined'] = 'Платеж отклонен Hutko.';
$_['text_payment_expired'] = 'Срок платежа истек в Hutko.';
$_['text_payment_processing'] = 'Платеж обрабатывается в Hutko.';
$_['text_confirm_refund'] = 'Вы уверены, что хотите возместить оплату через Hutko? Это действие нельзя отменить.';
$_['text_loading'] = 'Загрузка...';
$_['error_order_not_found'] = 'Ошибка: заказ не найден.';

View File

@@ -0,0 +1,217 @@
<?php
// Hutko translation file
// Heading
$_['heading_title'] = 'Платежи Hutko';
$_['text_extension'] = 'Расширения';
$_['text_success'] = 'Успех: Вы изменили настройки модуля оплаты Hutko!';
$_['text_edit'] = 'Изменить настройки Hutko';
$_['text_hutko'] = '<a href="https://hutko.org/" target="_blank"><img src="view/image/payment/hutko.png" alt="Hutko" title="Hutko" style="border: 1px solid #EEEEEE; max-height:25px;" /></a>'; // Вам понадобится hutko.png в admin/view/image/payment/
$_['text_enabled'] = 'Включено';
$_['text_disabled'] = 'Отключено';
$_['text_yes'] = 'Да';
$_['text_no'] = 'Нет';
$_['text_info_merchant'] = 'Используйте "1700243" для теста.';
$_['text_info_secret'] = 'Используйте "test" для теста.';
$_['text_logs_disabled'] = 'Ведение журнала в настоящее время отключено. Включите "Сохранить журналы", чтобы увидеть журналы.';
$_['text_no_logs_found'] = 'В главном файле журнала на сегодня не найдено никаких записей журнала Hutko, или ведение журнала отключено.';
$_['text_log_file_not_found'] = 'Файл журнала (%s) не найден.';
$_['text_refund_success_comment'] = 'Возмещение выполнен успешно для ID: %s. Сумма: %s. Комментарий: %s';
$_['text_refund_failed_comment'] = 'Попытка возмещения не удалась для ID: %s. Причина: %s';
$_['text_refund_success'] = 'Возмещение успешно обработано через Hutko.';
$_['text_refund_api_error'] = 'Ошибка API Hutko: %s';
$_['text_status_success'] = 'Статус успешно получен от Hutko.';
$_['text_status_api_error'] = 'Ошибка API Hutko при получении статуса: %s';
$_['text_unknown_error'] = 'Произошла неизвестная ошибка.';
$_['entry_merchant_id'] = 'ID продавца';
$_['entry_secret_key'] = 'Секретный ключ';
$_['entry_new_order_status'] = 'Статус нового заказа';
$_['entry_success_status'] = 'Статус при успешном платеже';
$_['entry_declined_status'] = 'Статус при отклоненном платеже';
$_['entry_expired_status'] = 'Статус при просроченном платеже';
$_['entry_refunded_status'] = 'Статус при возмещении платеже';
$_['entry_shipping_include'] = 'Включить стоимость доставки';
$_['entry_shipping_product_name'] = 'Наименование доставки в фискальном чеке';
$_['entry_shipping_product_code'] = 'Код доставки в фискальном чеке';
$_['entry_show_cards_logo'] = 'Показать логотип Visa/MasterCard';
$_['entry_save_logs'] = 'Сохранять журналы';
$_['entry_include_discount_to_total'] = 'Включить скидки в общую сумму (для API)';
$_['entry_total'] = 'Минимальная сумма заказа';
$_['entry_geo_zone'] = 'Геозона';
$_['entry_status'] = 'Статус';
$_['entry_sort_order'] = 'Порядок сортировки';
$_['help_total'] = 'Сумма, которую должен достичь заказ, прежде чем этот способ оплаты станет активным.';
$_['help_new_order_status'] = 'Статус для новых заказов до получения платежа.';
$_['help_success_status'] = 'Статус для успешно оплаченных заказов.';
$_['help_shipping_include'] = 'Включить стоимость доставки в суму платежа.';
$_['help_shipping_product_name'] = 'Название продукта/услуги для использования при фискализации для суммы доставки.';
$_['help_shipping_product_code'] = 'Код продукта/услуги для использования при фискализации для суммы доставки.';
$_['help_show_cards_logo'] = 'Отображать логотипы Visa/MasterCard рядом с названием способа оплаты при оформлении заказа.';
$_['help_save_logs'] = 'Записывать коммуникацию API и обратные вызовы в системный файл журнала.';
$_['help_include_discount_to_total'] = 'Если да, скидки по заказу будут вычтены из общей суммы платежа, это может помешать фискализации.';
$_['error_permission'] = 'Внимание: у вас нет разрешения на изменение платежного модуля Hutko!';
$_['error_merchant_id_required'] = 'Требуется идентификатор продавца!';
$_['error_merchant_id_numeric'] = 'Идентификатор продавца должен быть числовым!';
$_['error_secret_key_required'] = 'Требуется секретный ключ!';
$_['error_secret_key_invalid'] = 'Секретный ключ должен быть "test" или содержать не менее 10 символов и не состоять полностью из цифр.';
$_['error_invalid_request'] = 'Недопустимые данные запроса на возмещения/статус.';
$_['error_missing_params'] = 'Отсутствуют обязательные параметры для возмещения/статуса.';
$_['tab_general'] = 'Общие';
$_['tab_order_statuses'] = 'Статусы заказов';
$_['tab_fiscalization'] = 'Фискализация';
$_['tab_advanced'] = 'Дополнительно';
$_['tab_logs'] = 'Журналы';
$_['text_payment_information'] = 'История платежей';
$_['text_not_available'] = 'Н/Д';
$_['text_hutko_transaction_ref_label'] = 'Идентификатор заказа в Hutko';
$_['text_hutko_refund_title'] = 'Возмещение Hutko';
$_['text_hutko_status_title'] = 'Проверка статуса Hutko';
$_['button_hutko_refund'] = 'Обработать возмещение через Hutko';
$_['button_hutko_status_check'] = 'Проверить статус платежа Hutko';
$_['entry_refund_amount'] = 'Сумма возмещения';
$_['entry_refund_comment'] = 'Комментарий к возмещению (необязательно)';
$_['text_refund_success_comment'] = 'Возмещение средств по ID %s успешно. Сумма: %s. Комментарий: %s';
$_['text_refund_failed_comment'] = 'Попытка возмещения средств по ID %s не удалась. Ошибка шлюза: %s';
$_['text_refund_api_error'] = 'Ошибка API возмещения Hutko: %s';
$_['text_status_api_error'] = 'Ошибка API статуса Hutko: %s';
$_['text_unknown_error'] = 'Произошла неизвестная ошибка API.';
$_['error_missing_order_id'] = 'Ошибка: в запросе отсутствует идентификатор заказа.';
$_['error_hutko_transaction_ref_not_found_db'] = 'Ошибка: идентификатор заказа Hutko не найден в базе данных для этого заказа.';
$_['error_hutko_transaction_ref_missing'] = 'Ошибка: идентификатор заказа Hutko требуется для этой операции.';
$_['error_invalid_refund_amount'] = 'Ошибка: недопустимая сумма возврата. Должна быть больше 0.';
$_['error_missing_refund_amount'] = 'Ошибка: требуется сумма возврата.';
$_['error_payment_data_build'] = 'Ошибка: не удалось подготовить данные платежа. Повторите попытку или обратитесь в службу поддержки.';
$_['error_api_communication'] = 'Ошибка: не удалось связаться с платежным шлюзом. Повторите попытку.';
$_['text_redirecting_comment'] = 'Перенаправление на Hutko. Идентификатор заказа Hutko: %s. URL: %s';
// Для обратного вызова
$_['text_payment_approved'] = 'Платеж одобрен Hutko.';
$_['text_payment_declined'] = 'Платеж отклонен Hutko.';
$_['text_payment_expired'] = 'Срок платежа истек в Hutko.';
$_['text_payment_processing'] = 'Платеж обрабатывается в Hutko.';
$_['text_confirm_refund'] = 'Вы уверены, что хотите возместить оплату через Hutko? Это действие нельзя отменить.';
$_['text_loading'] = 'Загрузка...';
$_['error_order_not_found'] = 'Ошибка: заказ не найден.';
$_['heading_title'] = 'Платежі Hutko';
$_['text_extension'] = 'Розширення';
$_['text_success'] = 'Успішно: Ви змінили налаштування модуля оплати Hutko!';
$_['text_edit'] = 'Змінити налаштуваннь Hutko';
$_['text_hutko'] = '<a href="https://hutko.org/" target="_blank"><img src="view/image/payment/hutko.png" alt="Hutko" title="Hutko" style="border: 1px solid #EEEEEE; max-he; /></a>';
$_['text_enabled'] = 'Увімкнено';
$_['text_disabled'] = 'Вимкнено';
$_['text_yes'] = 'Так';
$_['text_no'] = 'Ні';
$_['text_info_merchant'] = 'Використовуйте "1700243" для тестування.';
$_['text_info_secret'] = 'Використовуйте "test" для тестування.';
$_['text_logs_disabled'] = 'Ведення журналу в даний час вимкнено. Увімкніть "Зберегти журнали", щоб побачити журнали.';
$_['text_no_logs_found'] = 'У головному файлі журналу на сьогодні не знайдено жодних записів журналу Hutko, або ведення журналу вимкнено.';
$_['text_log_file_not_found'] = 'Файл журналу (%s) не знайдено.';
$_['text_refund_success_comment'] = 'Відшкодування успішно виконано для ID: %s. Сума: %s. Коментар: %s';
$_['text_refund_failed_comment'] = 'Спроба відшкодування не вдалася для ID: %s. Причина: %s';
$_['text_refund_success'] = 'Відшкодування успішно оброблено через Hutko.';
$_['text_refund_api_error'] = 'Помилка API Hutko: %s';
$_['text_status_success'] = 'Статус успішно отримано від Hutko.';
$_['text_status_api_error'] = 'Помилка API Hutko при отриманні статусу: %s';
$_['text_unknown_error'] = 'Відбулася невідома помилка.';
$_['entry_merchant_id'] = 'ID продавця';
$_['entry_secret_key'] = 'Секретний ключ';
$_['entry_new_order_status'] = 'Статус нового замовлення';
$_['entry_success_status'] = 'Статус за успішного платежу';
$_['entry_declined_status'] = 'Статус при відхиленому платежі';
$_['entry_expired_status'] = 'Статус при простроченому платежі';
$_['entry_refunded_status'] = 'Статус при відшкодуванні платежу';
$_['entry_shipping_include'] = 'Включати вартість доставки';
$_['entry_shipping_product_name'] = 'Найменування доставки у фіскальному чеку';
$_['entry_shipping_product_code'] = 'Код доставки у фіскальному чеку';
$_['entry_show_cards_logo'] = 'Показати логотип Visa/MasterCard';
$_['entry_save_logs'] = 'Зберігати журнали';
$_['entry_include_discount_to_total'] = 'Включити фіксовані знижки в загальну суму оплати';
$_['entry_total'] = 'Мінімальна сума замовлення';
$_['entry_geo_zone'] = 'Геозона';
$_['entry_status'] = 'Статус';
$_['entry_sort_order'] = 'Порядок сортування';
$_['help_total'] = 'Сума, яку має досягти замовлення, перш ніж цей спосіб оплати стане активним.';
$_['help_new_order_status'] = 'Статус для нових замовлень до отримання платежу.';
$_['help_success_status'] = 'Статус для успішно оплачених замовлень.';
$_['help_shipping_include'] = 'Включити вартість доставки до суми платежу.';
$_['help_shipping_product_name'] = 'Назва продукту/послуги для використання при фіскалізації для суми доставки.';
$_['help_shipping_product_code'] = 'Код продукту/послуги для використання при фіскалізації для суми доставки.';
$_['help_show_cards_logo'] = 'Відображати логотипи Visa/MasterCard поруч із назвою способу оплати при оформленні замовлення.';
$_['help_save_logs'] = 'Записувати комунікацію API та зворотні виклики до системного файлу журналу.';
$_['help_include_discount_to_total'] = 'Якщо так, знижки на замовлення будуть вираховані із загальної суми платежу, це може перешкодити фіскалізації.';
$_['error_permission'] = 'Увага: у вас немає дозволу на зміну платіжного модуля Hutko!';
$_['error_merchant_id_required'] = 'Потрібен ідентифікатор продавця!';
$_['error_merchant_id_numeric'] = 'Ідентифікатор продавця має бути числовим!';
$_['error_secret_key_required'] = 'Потрібен секретний ключ!';
$_['error_secret_key_invalid'] = 'Секретний ключ повинен бути "test" або містити не менше 10 символів і не складатися повністю із цифр.';
$_['error_invalid_request'] = 'Неприпустимі дані запиту на відшкодування/статус.';
$_['error_missing_params'] = 'Відсутні обов\'язкові параметри для відшкодування/статусу.';
$_['tab_general'] = 'Загальні';
$_['tab_order_statuses'] = 'Статуси замовлень';
$_['tab_fiscalization'] = 'Фіскалізація';
$_['tab_advanced'] = 'Додатково';
$_['tab_logs'] = 'Журнали';
$_['text_payment_information'] = 'Історія платежів';
$_['text_not_available'] = 'Н/Д';
$_['text_hutko_transaction_ref_label'] = 'Ідентифікатор замовлення в Hutko';
$_['text_hutko_refund_title'] = 'Відшкодування Hutko';
$_['text_hutko_status_title'] = 'Перевірка статусу Hutko';
$_['button_hutko_refund'] = 'Обробити відшкодування через Hutko';
$_['button_hutko_status_check'] = 'Перевірити статус платежу Hutko';
$_['entry_refund_amount'] = 'Сума відшкодування';
$_['entry_refund_comment'] = 'Коментар до відшкодування (необов\'язково)';
$_['text_refund_success_comment'] = 'Відшкодування коштів за ID %s успішно. Сума: %s. Коментар: %s';
$_['text_refund_failed_comment'] = 'Спроба відшкодування коштів за ID %s не вдалася. Помилка шлюзу: %s';
$_['text_refund_api_error'] = 'Помилка API відшкодування Hutko: %s';
$_['text_status_api_error'] = 'Помилка API статусу Hutko: %s';
$_['text_unknown_error'] = 'Відбулася невідома помилка API.';
$_['error_missing_order_id'] = 'Помилка: у запиті відсутній ідентифікатор замовлення.';
$_['error_hutko_transaction_ref_not_found_db'] = 'Помилка: ідентифікатор замовлення Hutko не знайдений у базі даних для цього замовлення.';
$_['error_hutko_transaction_ref_missing'] = 'Помилка: ідентифікатор замовлення Hutko потрібний для цієї операції.';
$_['error_invalid_refund_amount'] = 'Помилка: неприпустима сума повернення. Має бути більше 0.';
$_['error_missing_refund_amount'] = 'Помилка: потрібна сума повернення.';
$_['error_payment_data_build'] = 'Помилка: не вдалося підготувати дані платежу. Повторіть спробу або зверніться до служби підтримки.';
$_['error_api_communication'] = 'Помилка: не вдалося зв\'язатися з платіжним шлюзом. Повторіть спробу.';
$_['text_redirecting_comment'] = 'Перенаправлення на Hutko. Ідентифікатор замовлення Hutko: %s. URL: %s';
// Для зворотного виклику
$_['text_payment_approved'] = 'Платіж схвалений Hutko.';
$_['text_payment_declined'] = 'Платіж відхилений Hutko.';
$_['text_payment_expired'] = 'Термін платежу минув у Hutko.';
$_['text_payment_processing'] = 'Платіж обробляється в Hutko.';
$_['text_confirm_refund'] = 'Ви впевнені, що хочете відшкодувати оплату через Hutko? Цю дію не можна скасувати.';
$_['text_loading'] = 'Завантаження...';
$_['error_order_not_found'] = 'Помилка: замовлення не знайдено.';

View File

@@ -0,0 +1,26 @@
<?php
namespace Opencart\Admin\Model\Extension\Hutko\Payment;
class Hutko extends \Opencart\System\Engine\Model {
public function install(): void {
$this->db->query("
CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "hutko_order` (
`hutko_order_pk_id` INT(11) NOT NULL AUTO_INCREMENT,
`order_id` INT(11) NOT NULL,
`hutko_transaction_ref` VARCHAR(255) NOT NULL,
`date_added` DATETIME NOT NULL,
PRIMARY KEY (`hutko_order_pk_id`),
UNIQUE KEY `idx_order_id` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
");
}
public function uninstall(): void {
// table drop optional
}
public function getHutkoOrder(int $order_id): array {
$query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "hutko_order` WHERE `order_id` = '" . (int)$order_id . "'");
return $query->row;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,151 @@
{{ header }}{{ column_left }}
<div id="content">
<div class="page-header">
<div class="container-fluid">
<div class="float-end">
<button type="submit" form="form-payment" data-bs-toggle="tooltip" title="{{ button_save }}" class="btn btn-primary">
<i class="fa-solid fa-save"></i>
</button>
<a href="{{ back }}" data-bs-toggle="tooltip" title="{{ button_back }}" class="btn btn-light">
<i class="fa-solid fa-reply"></i>
</a>
</div>
<h1>{{ heading_title }}</h1>
<ol class="breadcrumb">
{% for breadcrumb in breadcrumbs %}
<li class="breadcrumb-item">
<a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a>
</li>
{% endfor %}
</ol>
</div>
</div>
<div class="container-fluid">
<div class="card">
<div class="card-header">
<i class="fa-solid fa-pencil"></i>
{{ text_edit }}</div>
<div class="card-body">
<form id="form-payment" action="{{ save }}" method="post" data-oc-toggle="ajax">
<ul class="nav nav-tabs">
<li class="nav-item">
<a href="#tab-general" data-bs-toggle="tab" class="nav-link active">{{ tab_general }}</a>
</li>
<li class="nav-item">
<a href="#tab-status" data-bs-toggle="tab" class="nav-link">{{ tab_order_statuses }}</a>
</li>
<li class="nav-item">
<a href="#tab-advanced" data-bs-toggle="tab" class="nav-link">{{ tab_advanced }}</a>
</li>
<li class="nav-item">
<a href="#tab-logs" data-bs-toggle="tab" class="nav-link">{{ tab_logs }}</a>
</li>
</ul>
<div class="tab-content">
<div id="tab-general" class="tab-pane active">
<div class="row mb-3 required">
<label for="input-merchant-id" class="col-sm-2 col-form-label">{{ entry_merchant_id }}</label>
<div class="col-sm-10">
<input type="text" name="payment_hutko_merchant_id" value="{{ payment_hutko_merchant_id }}" placeholder="{{ entry_merchant_id }}" id="input-payment-hutko-merchant-id" class="form-control"/>
<div id="error-payment-hutko-merchant-id" class="invalid-feedback"></div>
</div>
</div>
<div class="row mb-3 required">
<label for="input-secret-key" class="col-sm-2 col-form-label">{{ entry_secret_key }}</label>
<div class="col-sm-10">
<input type="text" name="payment_hutko_secret_key" value="{{ payment_hutko_secret_key }}" placeholder="{{ entry_secret_key }}" id="input-payment-hutko-secret-key" class="form-control"/>
<div id="error-payment-hutko-secret-key" class="invalid-feedback"></div>
</div>
</div>
<div class="row mb-3">
<label for="input-status" class="col-sm-2 col-form-label">{{ entry_status }}</label>
<div class="col-sm-10">
<div class="form-check form-switch form-switch-lg">
<input type="hidden" name="payment_hutko_status" value="0"/>
<input type="checkbox" name="payment_hutko_status" value="1" id="input-status" class="form-check-input" {% if payment_hutko_status %} checked {% endif %}/>
</div>
</div>
</div>
<div class="row mb-3">
<label for="input-sort-order" class="col-sm-2 col-form-label">{{ entry_sort_order }}</label>
<div class="col-sm-10">
<input type="text" name="payment_hutko_sort_order" value="{{ payment_hutko_sort_order }}" id="input-sort-order" class="form-control"/>
</div>
</div>
<div class="row mb-3">
<label class="col-sm-2 col-form-label">{{ entry_geo_zone }}</label>
<div class="col-sm-10">
<select name="payment_hutko_geo_zone_id" id="input-geo-zone" class="form-select">
<option value="0">{{ text_all_zones }}</option>
{% for geo_zone in geo_zones %}
<option value="{{ geo_zone.geo_zone_id }}" {% if geo_zone.geo_zone_id == payment_hutko_geo_zone_id %} selected {% endif %}>{{ geo_zone.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="row mb-3">
<label class="col-sm-2 col-form-label">{{ entry_total }}</label>
<div class="col-sm-10">
<input type="text" name="payment_hutko_total" value="{{ payment_hutko_total }}" placeholder="{{ entry_total }}" id="input-total" class="form-control"/>
<div class="form-text">{{ help_total }}</div>
</div>
</div>
</div>
<div id="tab-status" class="tab-pane">
<div class="row mb-3">
<label class="col-sm-2 col-form-label">{{ entry_new_order_status }}</label>
<div class="col-sm-10">
<select name="payment_hutko_new_order_status_id" class="form-select">
{% for status in order_statuses %}
<option value="{{ status.order_status_id }}" {% if status.order_status_id == payment_hutko_new_order_status_id %} selected {% endif %}>{{ status.name }}</option>
{% endfor %}
</select>
</div>
</div>
<!-- Repeat logic for other statuses -->
<div class="row mb-3">
<label class="col-sm-2 col-form-label">{{ entry_success_status }}</label>
<div class="col-sm-10">
<select name="payment_hutko_success_status_id" class="form-select">
{% for status in order_statuses %}
<option value="{{ status.order_status_id }}" {% if status.order_status_id == payment_hutko_success_status_id %} selected {% endif %}>{{ status.name }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
<div id="tab-advanced" class="tab-pane">
<div class="row mb-3">
<label class="col-sm-2 col-form-label">{{ entry_shipping_include }}</label>
<div class="col-sm-10">
<div class="form-check form-switch">
<input type="hidden" name="payment_hutko_shipping_include" value="0"/>
<input type="checkbox" name="payment_hutko_shipping_include" value="1" class="form-check-input" {% if payment_hutko_shipping_include %} checked {% endif %}/>
</div>
</div>
</div>
<div class="row mb-3">
<label class="col-sm-2 col-form-label">{{ entry_save_logs }}</label>
<div class="col-sm-10">
<div class="form-check form-switch">
<input type="hidden" name="payment_hutko_save_logs" value="0"/>
<input type="checkbox" name="payment_hutko_save_logs" value="1" class="form-check-input" {% if payment_hutko_save_logs %} checked {% endif %}/>
</div>
</div>
</div>
</div>
<div id="tab-logs" class="tab-pane">
<pre class="bg-light p-3 border">{{ log_content }}</pre>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{{ footer }}

View File

@@ -0,0 +1,101 @@
<div class="card mb-3">
<div class="card-header">
<i class="fa-solid fa-credit-card"></i> {{ text_payment_information }} (Hutko)
</div>
<div class="card-body">
<table class="table table-bordered">
<tr>
<td>{{ text_hutko_transaction_ref_label }}</td>
<td>{{ hutko_transaction_ref_display }}</td>
</tr>
</table>
{% if hutko_transaction_ref_display != text_not_available %}
<hr>
<h5>{{ text_hutko_refund_title }}</h5>
<div class="row g-3 align-items-center mb-3">
<div class="col-auto">
<input type="text" id="input-refund-amount" class="form-control" placeholder="{{ entry_refund_amount }}">
</div>
<div class="col-auto">
<input type="text" id="input-refund-comment" class="form-control" placeholder="{{ entry_refund_comment }}">
</div>
<div class="col-auto">
<button type="button" id="button-hutko-refund" class="btn btn-warning">{{ button_hutko_refund }}</button>
</div>
</div>
<div id="hutko-refund-response"></div>
<hr>
<h5>{{ text_hutko_status_title }}</h5>
<button type="button" id="button-hutko-status" class="btn btn-info text-white">{{ button_hutko_status_check }}</button>
<div id="hutko-status-response" class="mt-2"></div>
{% endif %}
</div>
</div>
<script type="text/javascript">
$('#button-hutko-refund').on('click', function () {
if (!confirm('{{ text_confirm_refund }}')) return;
var btn = $(this);
$.ajax({
url: '{{ hutko_refund_action_url|raw }}',
type: 'post',
dataType: 'json',
data: {
'refund_amount': $('#input-refund-amount').val(),
'refund_comment': $('#input-refund-comment').val(),
'order_id': {{ order_id }}
},
beforeSend: function () {
btn.prop('disabled', true);
$('#hutko-refund-response').html('');
},
complete: function () {
btn.prop('disabled', false);
},
success: function (json) {
if (json['error']) {
$('#hutko-refund-response').html('<div class="alert alert-danger">' + json['error'] + '</div>');
}
if (json['success']) {
$('#hutko-refund-response').html('<div class="alert alert-success">' + json['success'] + '</div>');
setTimeout(function(){ location.reload(); }, 2000);
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
}
});
});
$('#button-hutko-status').on('click', function () {
var btn = $(this);
$.ajax({
url: '{{ hutko_status_action_url|raw }}',
type: 'post',
dataType: 'json',
data: {'hutko_transaction_ref': '{{ hutko_transaction_ref_display }}'},
beforeSend: function () {
btn.prop('disabled', true);
$('#hutko-status-response').html('');
},
complete: function () {
btn.prop('disabled', false);
},
success: function (json) {
if (json['error']) {
$('#hutko-status-response').html('<div class="alert alert-danger">' + json['error'] + '</div>');
}
if (json['success']) {
let data = json['data'] ? JSON.stringify(json['data'], null, 2) : '';
$('#hutko-status-response').html('<div class="alert alert-success">' + json['success'] + '<pre class="mt-2 bg-light p-2">' + data + '</pre></div>');
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
}
});
});
</script>