Skip to content

Commit d244d6b

Browse files
committed
First commit
1 parent e29cf6e commit d244d6b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+4615
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
# php-plugin-woocommerce
1+
# php-plugin-woocommerce wordpress
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
h2, #woocommerce_wc_payneteasy_section_separator {
2+
font-size: 1.5em;
3+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
document.addEventListener('DOMContentLoaded', function() {
2+
// Проверяем, находимся ли мы на странице редактирования заказа
3+
if (document.querySelector('body.post-type-shop_order')) {
4+
5+
/*
6+
* *** Добавление функционала актуализации статуса оплаты
7+
*/
8+
// Находим блоки с классом order_data_column
9+
const orderDataColumns = document.querySelectorAll('.order_data_column');
10+
11+
/*
12+
Выбираем второй блок с классом order_data_column, если он существует.
13+
Если второго блока нет, используем первый блок.
14+
*/
15+
let targetColumn = orderDataColumns[1]; // Индекс 1 соответствует второму блоку
16+
if (!targetColumn) {
17+
targetColumn = orderDataColumns[0]; // Индекс 0 соответствует первому блоку
18+
}
19+
20+
// Создаем HTML-код для кнопки
21+
const buttonHtml = `
22+
<p class="form-field form-field-wide">
23+
<label for="payneteasy-button-check-status">Для проверки состояния заказа в платежной системе PAYNET, пожалуйста, нажмите кнопку:</label>
24+
<button class="button custom-action" id="payneteasy-button-check-status">Проверить статус</button>
25+
</p>
26+
`;
27+
28+
// Проверяем условие добавления кнопки
29+
if (targetColumn) {
30+
// Добавляем кнопку в выбранный блок
31+
targetColumn.insertAdjacentHTML('beforeend', buttonHtml);
32+
33+
const button = document.getElementById('payneteasy-button-check-status');
34+
35+
if (button) {
36+
button.addEventListener('click', function(event) {
37+
event.preventDefault();
38+
39+
const orderID = window.location.href.match(/post=([0-9]+)/)[1];
40+
41+
// Создаем объект FormData для сбора данных формы
42+
const formData = new FormData();
43+
formData.append('action', 'check_status');
44+
formData.append('nonce', payneteasy_ajax_var.nonce);
45+
formData.append('order_id', orderID);
46+
47+
// Выполняем AJAX-запрос к веб-хуку плагина wc-payneteasy
48+
fetch(payneteasy_ajax_var.api_url, {
49+
method: 'POST',
50+
body: formData
51+
})
52+
.then(response => response.json())
53+
.then(data => {
54+
if (data.success && confirm(data.message)) {
55+
location.reload();
56+
} else {
57+
alert(data.message);
58+
}
59+
})
60+
.catch(error => {
61+
console.error('Ошибка запроса:', error);
62+
alert('Произошла ошибка при выполнении запроса.');
63+
});
64+
});
65+
}
66+
}
67+
68+
69+
/**
70+
* *** Добавление функционала возрата
71+
*/
72+
const originalButton = document.querySelector('.refund-actions button.do-manual-refund'); // Находим оригинальную кнопку
73+
74+
if (originalButton) {
75+
// Создаем копию кнопки
76+
const copyButton = originalButton.cloneNode(true);
77+
copyButton.id = 'do-manual-refund-copy';
78+
copyButton.classList.remove('do-manual-refund'); // Удаляем класс do-manual-refund у копии
79+
80+
// Скрываем оригинальную кнопку
81+
originalButton.style.display = 'none';
82+
83+
// Вставляем копию кнопки после оригинальной кнопки
84+
originalButton.parentNode.insertBefore(copyButton, originalButton.nextSibling);
85+
86+
// Функция для синхронизации атрибутов и текста копии с оригиналом
87+
function synchronizeButtons() {
88+
copyButton.innerHTML = originalButton.innerHTML;
89+
copyButton.disabled = originalButton.disabled;
90+
// При необходимости синхронизировать другие атрибуты
91+
}
92+
93+
// Синхронизация при изменении атрибутов и текста оригинала
94+
const observer = new MutationObserver(synchronizeButtons);
95+
observer.observe(originalButton, { childList: true, attributes: true, subtree: true });
96+
97+
// Добавление функционала возврата на копию кнопки
98+
copyButton.addEventListener('click', function(event) {
99+
event.preventDefault(); // Предотвращаем выполнение остальных действий
100+
101+
// Получаем таблицу с классом woocommerce_order_items
102+
const table = document.querySelector('#woocommerce-order-items');
103+
104+
if (table) {
105+
// Идентификатор текущего заказа
106+
const orderID = window.location.href.match(/post=([0-9]+)/)[1];
107+
108+
// Создаем объект FormData для сбора данных формы
109+
const formData = new FormData();
110+
formData.append('action', 'refund');
111+
formData.append('nonce', payneteasy_ajax_var.nonce);
112+
formData.append('order_id', orderID);
113+
114+
// Получаем все инпуты с именами, начинающимися с "refund_"
115+
const refundInputs = table.querySelectorAll('input[name^="refund_"]');
116+
117+
// Добавляем данные в FormData
118+
refundInputs.forEach(input => {
119+
formData.append(input.name, input.value);
120+
});
121+
122+
// Запрос подтверждения у пользователя
123+
if (confirm('Выполнить возврат в платёжной системе PAYNET?')) {
124+
// Отправляем AJAX-запрос с помощью fetch
125+
fetch(payneteasy_ajax_var.api_url, {
126+
method: 'POST',
127+
body: formData
128+
})
129+
.then(response => response.json())
130+
.then(data => {
131+
if (data.success) {
132+
alert(`Платёжная система PAYNET: ${data.message}`);
133+
originalButton.click();
134+
} else {
135+
if (confirm(`Платёжная система PAYNET: ${data.message}. Продолжит возврат в WordPress?`)) {
136+
originalButton.click();
137+
}
138+
}
139+
})
140+
.catch(error => {
141+
console.error('Ошибка запроса:', error);
142+
if (confirm('Произошла ошибка при возврате в платёжной системе PAYNET. Продолжит возврат в WordPress?')) {
143+
originalButton.click();
144+
}
145+
});
146+
} else {
147+
originalButton.click();
148+
}
149+
150+
} else {
151+
console.error('Таблица с классом woocommerce_order_items не найдена.');
152+
}
153+
});
154+
}
155+
}
156+
});

form_fields.php

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
return [
3+
'enabled' => [
4+
'title' => __('Enable/Disable', 'woocommerce'),
5+
'type' => 'checkbox',
6+
'label' => __('Enable Payment system PAYNET', 'wc-payneteasy'),
7+
'default' => 'yes'
8+
],
9+
'title' => [
10+
'title' => __('Title', 'woocommerce'),
11+
'type' => 'text',
12+
'description' => __('This controls the title which the user sees during checkout.', 'woocommerce'),
13+
'default' => __('Payment system PAYNET', 'wc-payneteasy'),
14+
'desc_tip' => true,
15+
],
16+
'description' => [
17+
'title' => __('Customer Message', 'wc-payneteasy'),
18+
'type' => 'textarea',
19+
'css' => 'width:500px;',
20+
'default' => __('Pay with PaynetEasy payment', 'wc-payneteasy'),
21+
'description' => __('The message which you want it to appear to the customer in the checkout page.', 'wc-payneteasy'),
22+
],
23+
'endpoint_id' => [
24+
'title' => __('Endpoint id', 'wc-payneteasy') . ' <span style="color:red;">*<span/>',
25+
'type' => 'text',
26+
'description' => __('Merchant\'s Endpoint id is required to call the API.', 'wc-payneteasy'),
27+
'placeholder' => __('Enter Endpoint id', 'wc-payneteasy'),
28+
'custom_attributes' => ['required' => 'required'],
29+
],
30+
'login' => [
31+
'title' => __('Login', 'wc-payneteasy') . ' <span style="color:red;">*<span/>',
32+
'type' => 'text',
33+
'description' => __('Merchant\'s Login is required to call the API.', 'wc-payneteasy'),
34+
'placeholder' => __('Enter Login', 'wc-payneteasy'),
35+
'custom_attributes' => ['required' => 'required'],
36+
],
37+
'control_key' => [
38+
'title' => __('Control key', 'wc-payneteasy') . ' <span style="color:red;">*<span/>',
39+
'type' => 'text',
40+
'description' => __('Merchant\'s Control key is required to call the API.', 'wc-payneteasy'),
41+
'placeholder' => __('Enter Control key', 'wc-payneteasy'),
42+
'custom_attributes' => ['required' => 'required'],
43+
],
44+
'payment_method' => [
45+
'title' => __('Payment method', 'wc-payneteasy'),
46+
'type' => 'select',
47+
'description' => __('', 'wc-payneteasy'),
48+
'placeholder' => __('Enter Payment method', 'wc-payneteasy'),
49+
'options' => [
50+
'form' => __('Form', 'wc-payneteasy'),
51+
'direct' => __('Direct', 'wc-payneteasy')
52+
],
53+
'desc_tip' => true,
54+
'default' => 'form'
55+
],
56+
'sandbox' => [
57+
'title' => __('Sandbox mode', 'wc-payneteasy'),
58+
'type' => 'checkbox',
59+
'label' => __('Enable sandbox mode', 'wc-payneteasy'),
60+
'description' => __('In this mode, the payment for the goods is not charged.', 'wc-payneteasy'),
61+
'default' => 'no'
62+
],
63+
'logging' => [
64+
'title' => __('Logging', 'wc-payneteasy'),
65+
'type' => 'checkbox',
66+
'label' => __('Enable logging', 'wc-payneteasy'),
67+
'description' => __('Logging is used to debug plugin performance by storing API request data.', 'wc-payneteasy'),
68+
'default' => 'no'
69+
],
70+
'three_d_secure' => [
71+
'title' => __('3D Secure', 'wc-payneteasy'),
72+
'type' => 'checkbox',
73+
'label' => __('Enable 3D Secure', 'wc-payneteasy'),
74+
'description' => __('3D Secure or Non 3D Secure (WORK ONLY WITH DIRECT INTEGRATION METHOD)', 'wc-payneteasy'),
75+
'default' => 'no'
76+
],
77+
'live_url' => [
78+
'title' => __('Gateway url (LIVE)', 'wc-payneteasy'),
79+
'type' => 'text',
80+
'description' => __("https://gate.payneteasy.com/ etc.", 'wc-payneteasy'),
81+
'placeholder' => __('Enter live url.', 'wc-payneteasy'),
82+
],
83+
'sandbox_url' => [
84+
'title' => __('Gateway url (SANDBOX)', 'wc-payneteasy'),
85+
'type' => 'text',
86+
'description' => __("https://sandbox.payneteasy.com/ etc.", 'wc-payneteasy'),
87+
'placeholder' => __('Enter sandbox url.', 'wc-payneteasy'),
88+
],
89+
'transaction_end' => [
90+
'title' => __('Successful transaction order status', 'wc-payneteasy'),
91+
'type' => 'select',
92+
'options' => wc_get_order_statuses(),
93+
'description' => __('Select the order status to be displayed after successful payment.', 'wc-payneteasy'),
94+
'default' => 'wc-processing'
95+
]
96+
];

hooks.php

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
/**
3+
* Функция add_payneteasy_gateway
4+
*
5+
* Добавляет платёжный метод "WC_Payneteasy" в список доступных платёжных методов WooCommerce.
6+
*
7+
* @param array $methods - Список доступных платёжных методов
8+
* @return array - Модифицированный список платёжных методов с добавлением WC_Payneteasy
9+
*/
10+
function add_payneteasy_gateway(array $methods): array
11+
{
12+
$methods[] = 'WC_Payneteasy';
13+
global $wpdb;
14+
15+
$charset_collate = $wpdb->get_charset_collate();
16+
17+
$sql = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}payneteasy_payments (
18+
`id` int(11) NOT NULL AUTO_INCREMENT,
19+
`paynet_order_id` int(11) NOT NULL,
20+
`merchant_order_id` int(11) NOT NULL,
21+
PRIMARY KEY (id)
22+
) $charset_collate;";
23+
24+
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
25+
dbDelta( $sql );
26+
27+
return $methods;
28+
}
29+
add_filter('woocommerce_payment_gateways', 'add_payneteasy_gateway');
30+
31+
32+
/**
33+
* Функция load_payneteasy_textdomain
34+
*
35+
* Загружает локализацию (текстовый перевод) для плагина WC_Payneteasy.
36+
*/
37+
function load_payneteasy_textdomain(): void
38+
{
39+
load_plugin_textdomain('wc-payneteasy', false, dirname(plugin_basename(__FILE__)) . '/languages');
40+
}
41+
add_action('plugins_loaded', 'load_payneteasy_textdomain');
42+
43+
/**
44+
* Функция get_payneteasy_field_options
45+
*
46+
* Возвращает список доступных опций для полей настроек WC_Payneteasy на основе идентификатора поля.
47+
*
48+
* @param string $field_id - Идентификатор поля настроек
49+
* @return array - Список опций для поля
50+
*/
51+
function get_payneteasy_field_options($field_id): array
52+
{
53+
$options = [
54+
'-' => __('Select an option', 'wc-payneteasy')
55+
];
56+
// Определяет опции для конкретного поля
57+
switch ($field_id) {
58+
case 'payneteasy_payment_method':
59+
$options = array_merge($options, [
60+
'form' => __('Form', 'wc-payneteasy'),
61+
'direct' => __('Direct', 'wc-payneteasy')
62+
]);
63+
break;
64+
}
65+
66+
return $options;
67+
}
68+
69+
/**
70+
* Функция adding_payneteasy_button_to_orders_page
71+
*
72+
* Добавляет скрипты и стили к странице заказов и настройкам WC_Payneteasy в административной части.
73+
*
74+
* @param string $hook - Идентификатор страницы в административной части WordPress
75+
*/
76+
function adding_payneteasy_button_to_orders_page($hook): void
77+
{
78+
// Проверяет наличие настроек WC_Payneteasy и условия для добавления скриптов и стилей
79+
$payneteasy_settings = get_option('woocommerce_wc_payneteasy_settings');
80+
global $post;
81+
82+
if (
83+
($hook == 'post-new.php' || $hook == 'post.php') &&
84+
!empty($post) && $post->post_type === 'shop_order'
85+
) {
86+
$order_id = $post->ID;
87+
$order = wc_get_order($order_id);
88+
$order_status = $order->get_status();
89+
$payment_method = $order->get_payment_method();
90+
91+
if (
92+
$order_status !== 'failed' &&
93+
$order_status !== 'refunded' &&
94+
$order_status !== 'cancelled' &&
95+
$payment_method === 'wc_payneteasy'
96+
) {
97+
// Подключает скрипт для работы с заказами WC_Payneteasy
98+
wp_enqueue_script('payneteasy-order-page-script', plugins_url('/assets/js/payneteasy-order-page-script.js', __FILE__), ['jquery'], '1.0', true);
99+
wp_localize_script(
100+
'payneteasy-order-page-script',
101+
'payneteasy_ajax_var', [
102+
'nonce' => wp_create_nonce('payneteasy-ajax-nonce'),
103+
'api_url' => home_url('/wc-api/wc_payneteasy_ajax')
104+
]);
105+
}
106+
}
107+
}
108+
add_action('admin_enqueue_scripts', 'adding_payneteasy_button_to_orders_page');

index.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?php
2+
// Silence is golden

0 commit comments

Comments
 (0)