WooCommerce: как показывать в тикетах только заказы клиента и не раскрывать чужие данные

Типичная проблема в поддержке интернет-магазина выглядит так: клиент открывает тикет по заказу, а в карточке поддержки подтягиваются лишние данные — чужие заказы, внутренние заметки, иногда даже ссылки на админские страницы. Это уже не просто неудобно, а риск утечки персональных данных.

Ниже разберём рабочий сценарий для WordPress и WooCommerce: как связать тикет с заказом, ограничить выбор заказов только текущим пользователем и проверить, что в поддержку не попадают чужие записи.

Когда это реально нужно

Задача возникает не только в крупных магазинах. Достаточно одной формы поддержки, где клиент может выбрать номер заказа, чтобы начались проблемы:

  • пользователь видит заказы других аккаунтов после импорта или ошибки в логике выборки;
  • в тикет можно привязать любой заказ по ID, даже если он не принадлежит текущему email;
  • менеджер поддержки работает быстрее, но фронтенд показывает слишком много данных;
  • после обновления темы или плагина ломается фильтрация заказов в форме тикета.

Если у вас уже есть интеграция WPtickets с WooCommerce, сначала проверьте, где именно формируется список заказов: в шаблоне формы, в AJAX-обработчике или в фильтре запроса к shop_order.

Диагностика проблемы

Начинать лучше не с кода, а с проверки фактического поведения. Это экономит время: часто проблема не в WooCommerce, а в том, что список заказов строится без привязки к текущему пользователю.

Что проверить в админке и на фронтенде

  • Откройте форму создания тикета под обычным клиентским аккаунтом.
  • Посмотрите, какие заказы доступны в выпадающем списке или автодополнении.
  • Попробуйте войти под другим пользователем и сравнить результат.
  • Проверьте, не кэшируется ли страница формы плагином кэша или серверным кэшем.
  • Если используется AJAX, откройте DevTools и посмотрите ответ сервера: там не должно быть чужих заказов.

Для WooCommerce важно помнить: заказ принадлежит конкретному пользователю через customer_id. Если выборка строится только по статусу или дате, фильтрации по владельцу нет.

Быстрая проверка через SQL-логику

Если нужно понять, есть ли у пользователя вообще заказы, можно проверить это через стандартный запрос WordPress. В коде ниже используется WC_Order_Query, а не прямой SQL — так проще не сломать совместимость.

$orders = wc_get_orders(array(
    'customer_id' => get_current_user_id(),
    'limit'        => 10,
    'orderby'      => 'date',
    'order'        => 'DESC',
    'return'       => 'ids',
));

if (empty($orders)) {
    error_log('У пользователя нет заказов или он не авторизован');
}

Если этот запрос возвращает корректные ID, а в форме тикета всё равно видны чужие заказы, значит проблема в слое отображения или в AJAX-обработчике.

Пошаговое решение: ограничить список заказов текущим клиентом

Самый надёжный вариант — формировать список заказов только для авторизованного пользователя и не отдавать в интерфейс ничего лишнего. Логику можно повесить на свой обработчик или на фильтр плагина, если он предусмотрен в вашей сборке WPtickets.

1. Получаем только заказы текущего пользователя

Ниже пример функции, которая возвращает безопасный список заказов для формы тикета. Она не использует email как единственный критерий и опирается на customer_id.

function wptickets_get_customer_orders_for_ticket_form() {
    if ( ! is_user_logged_in() ) {
        return array();
    }

    $orders = wc_get_orders(array(
        'customer_id' => get_current_user_id(),
        'status'      => array('wc-processing', 'wc-completed', 'wc-on-hold'),
        'limit'       => 20,
        'orderby'     => 'date',
        'order'       => 'DESC',
        'return'      => 'objects',
    ));

    $result = array();

    foreach ( $orders as $order ) {
        $result[ $order->get_id() ] = sprintf(
            '#%1$s — %2$s',
            $order->get_order_number(),
            $order->get_formatted_order_total()
        );
    }

    return $result;
}

Такой список можно вывести в <select> или использовать для автодополнения. Главное — не передавать в шаблон весь объект заказа, если в нём есть лишние поля.

2. Проверяем принадлежность заказа перед сохранением тикета

Даже если фронтенд ограничен, серверная проверка обязательна. Пользователь может подменить значение формы вручную. Перед сохранением тикета нужно убедиться, что заказ действительно принадлежит текущему аккаунту.

function wptickets_validate_ticket_order_id( $order_id ) {
    $order = wc_get_order( absint( $order_id ) );

    if ( ! $order ) {
        return false;
    }

    if ( ! is_user_logged_in() ) {
        return false;
    }

    return (int) $order->get_customer_id() === get_current_user_id();
}

Если проверка не проходит, тикет лучше не сохранять, а показать понятную ошибку: «Выбранный заказ не принадлежит вашему аккаунту».

3. Подключаем это к форме тикета

В зависимости от того, как устроен WPtickets в вашей установке, список заказов можно подставить в поле формы через шаблон или через фильтр. Если у вас есть собственный шаблон формы, логика будет простой:

$orders = wptickets_get_customer_orders_for_ticket_form();

if ( ! empty( $orders ) ) {
    echo '<select name="ticket_order_id" required>';
    echo '<option value="">Выберите заказ</option>';

    foreach ( $orders as $order_id => $label ) {
        echo '<option value="' . esc_attr( $order_id ) . '">' . esc_html( $label ) . '</option>';
    }

    echo '</select>';
} else {
    echo '<p>У вас пока нет заказов, к которым можно привязать тикет.</p>';
}

Если форма отправляется через AJAX, ту же проверку нужно повторить в обработчике запроса. Фронтенд-ограничение само по себе не защищает данные.

Сравнение подходов

ПодходПлюсыМинусыКогда использовать
Только фронтенд-фильтрБыстро внедряетсяНе защищает от подмены запросаТолько как временная мера
Фронтенд + серверная проверкаБезопасно и предсказуемоНужно немного кодаДля рабочих магазинов
Плагин без кастомизацииМинимум разработкиНе всегда учитывает вашу логику заказовЕсли сценарий стандартный

Проверка результата после внедрения

После изменения логики не ограничивайтесь визуальной проверкой. Нужно убедиться, что данные не утекают ни в интерфейс, ни в запросы.

  • Откройте форму тикета под пользователем с 2–3 заказами.
  • Проверьте, что в списке есть только его заказы.
  • Выйдите из аккаунта и убедитесь, что список пуст или форма предлагает войти.
  • Попробуйте вручную подставить чужой order_id в запросе и отправить форму.
  • Проверьте, что тикет не создался или заказ не привязался.
  • Посмотрите логи PHP и логи плагина, если они есть.

Если у вас включён кэш страницы, проверьте отдельный сценарий: один и тот же URL формы под двумя разными аккаунтами. Кэш не должен отдавать одному пользователю список заказов другого.

Частые ошибки и как их исправить

Используют email вместо customer_id

Это частая причина ложных совпадений. Email может измениться, а у одного пользователя может быть несколько адресов доставки. Для проверки прав доступа к заказу лучше использовать customer_id.

Проверяют только на фронтенде

Если ограничение есть только в HTML, его легко обойти через DevTools или прямой POST-запрос. Серверная валидация обязательна.

Не учитывают гостей

Если магазин разрешает гостевые заказы, у такого клиента нет обычного customer_id. В этом случае нужна отдельная логика: например, привязка по email и номеру заказа, но только после дополнительной проверки.

Ломают кэширование

Страница с персонализированным списком заказов не должна кэшироваться как общая. Иначе один пользователь увидит данные другого. Для таких страниц стоит исключить кэш на уровне плагина или сервера.

Практические советы по безопасности и производительности

Если заказов много, не выводите весь список в форме тикета. Ограничьте выборку последними 10–20 заказами и добавьте поиск по AJAX только для авторизованных пользователей. Это снижает нагрузку и не перегружает интерфейс.

Для защиты данных полезно дополнительно:

  • проверять nonce в AJAX-запросах;
  • использовать absint() для ID заказа;
  • не отдавать в ответе лишние поля заказа;
  • не хранить в тикете персональные данные, которые не нужны для поддержки;
  • логировать только факт ошибки, без полного dump заказа.

Если вам нужно быстро убрать дублирующиеся элементы интерфейса или почистить лишние скрипты на страницах поддержки, иногда помогает Clearfy Pro. Но саму фильтрацию заказов он не заменяет — это уже задача кода или логики плагина.

В рабочем магазине лучше держать правило простым: клиент видит только свои заказы, сервер проверяет принадлежность заказа перед сохранением тикета, а кэш и AJAX не должны обходить эту проверку.

Как создать системный автоприкрепление файлов к тикетам в WordPress
12.01.2026
Как настроить отправку писем в WordPress без использования PHPMailer
09.12.2025
Как удалить спам из формы тикетов WPtickets
17.04.2026
Как создать автоматический отчет по тикетам в WordPress с WPtickets и WPRemark
04.04.2026
Как установить права доступа к тикетам WPtickets через capabilities в WordPress
31.05.2026