# Плагин WooCommerce

> Как установить плагин Qut Pay в магазин на WordPress, настроить API-ключ и вебхук, как меняются статусы заказа, как делать возвраты, где чек и что делать при типовых сбоях.

## Коротко

Плагин добавляет в кассу WooCommerce способ «Оплата через Kaspi»: покупатель выбирает Kaspi → попадает на страницу оплаты Qut Pay (QR или ссылка Kaspi) → после оплаты заказ автоматически становится «Обработка» или «Выполнен». Деньги приходят напрямую на ваш счёт Kaspi Pay.

Загрузка: **https://api.qut.kz/downloads/qutpay-for-woocommerce.zip**
Полная инструкция: **https://api.qut.kz/docs/guide/wordpress**

Всё вместе занимает 10–15 минут.

## Требования

| Что | Значение |
|---|---|
| WordPress | 6.0 и новее |
| WooCommerce | 7.0 и новее. Поддерживаются классическая касса, Checkout Blocks и HPOS |
| PHP | 7.4 и новее |
| Сайт | должен открываться по **https** |
| Валюта магазина | **KZT (₸)**. При другой валюте способ в кассе вообще не появится |
| Qut Pay | организация с подключённым кассиром Kaspi. Для проверки в песочнице кассир не нужен |

## Шаг 1. Установка плагина

1. Скачайте архив.
2. WordPress → **Плагины → Добавить новый → Загрузить плагин** → выберите zip → **Установить** → **Активировать**.
3. Если в списке висит старая или битая запись «qutpay-for-woocommerce», сначала удалите её, при необходимости сотрите на хостинге папку `wp-content/plugins/qutpay-for-woocommerce`, и только потом загружайте новый архив.

## Шаг 2. Ключ и вебхук

Кабинет: https://qut.kz/app

1. **Интеграции → API-ключи** → назовите ключ именем сайта → **Создать**. Ключ показывается один раз — скопируйте сразу. Чтобы работали возвраты, отметьте право `refunds:write`.
2. **Интеграции → Вебхуки** → адрес:

   ```
   https://ВАШ-САЙТ/wp-json/qutpay/v1/webhook
   ```

   В списке «Ключ» выберите только что созданный ключ — тогда на этот адрес будут приходить события только этого сайта. **Создать** → скопируйте показанный секрет (`whsec_…`), он тоже показывается один раз.

Если на сайте отключены «Постоянные ссылки», адрес будет другим: `https://ВАШ-САЙТ/?rest_route=/qutpay/v1/webhook`.

## Шаг 3. Настройка

**WooCommerce → Настройки → Платежи → «Qut Pay (Kaspi QR)» → Управление**:

| Поле | Что указать |
|---|---|
| Включить | ✔ |
| Название на кассе | То, что видит покупатель. Можно оставить по умолчанию |
| Описание | Короткое пояснение в кассе |
| API-ключ | Ключ из шага 2 |
| Секрет webhook | `whsec_…` из шага 2 |
| Адрес API | `https://api.qut.kz` — не менять |
| Статус после оплаты | Физический товар — **Обработка (processing)**, цифровая услуга или курс — **Выполнен (completed)** |
| Лог | На время настройки поставьте ✔ |

Нажмите **Сохранить изменения**. Затем проверьте **WooCommerce → Настройки → Общие → Валюта** — там должен стоять **Казахстанский тенге (KZT)**.

## Как меняются статусы заказа

1. Когда покупатель подтверждает заказ, плагин вызывает `POST /api/v1/invoices`: `externalOrderId` — номер заказа, `Idempotency-Key` — `wc-{id}-…`. Поэтому даже при двойном нажатии кнопки второй счёт не создаётся. Покупателя перебрасывает на `payUrl`.
2. Счёт живёт в статусе `pending` около 3 минут — это окно сканирования QR у Kaspi.
3. Оплата прошла — приходит вебхук `invoice.paid`, заказ переходит в выбранный вами статус, в примечаниях появляется «Qut Pay: оплачен, счёт inv_…».
4. Не оплатили — счёт становится `expired`, заказ переходит в «Отменён».
5. **Поздняя оплата.** Если деньги пришли уже после закрытия счёта, `invoice.paid` придёт позже и снова отметит заказ оплаченным. Это нормальная ситуация: либо выдайте товар, либо сделайте возврат.

На странице «Спасибо» плагин ещё раз запрашивает статус через API — покупатель увидит корректное состояние, даже если вебхук задержался. Повторная доставка одного события не меняет заказ дважды.

## Возвраты

Возврат делается прямо из карточки заказа WooCommerce: откройте заказ и нажмите **«Возврат»**. Плагин вызовет `POST /invoices/{id}/refund`. Частичный возврат тоже работает.

Условие одно: **у ключа должно быть право `refunds:write`.** Если при создании ключа его не отметили, возврат упрётся в 403 — создайте новый ключ и замените значение в настройках плагина.

Возврат можно сделать и из кабинета — тогда заказ обновится по вебхуку.

## Чек

После оплаты ссылка на чек появляется на странице «Спасибо» и записывается в примечания к заказу. Если при создании счёта передан e-mail покупателя, чек уходит письмом (когда в кабинете настроен SMTP). Подробнее: [Чеки](/kb/ru/receipts).

## Проверка

**Песочница.** Пока организация в кабинете в режиме sandbox, счета не уходят в Kaspi. Сделайте заказ, выберите Kaspi → на странице оплаты нажмите **«[Sandbox] имитировать оплату»** → вернётесь на сайт, заказ станет оплаченным. Вебхуки при этом отправляются по-настоящему.

**Боевой режим.** Подключите кассира, переключите режим на live, создайте ключ `qp_live_…` и вставьте его в плагин. Сделайте тестовый товар за 10 ₸ и оплатите со своего телефона. Потом верните этот заказ и убедитесь, что в WooCommerce он стал «Возвращён».

## Частые проблемы

| Симптом | Причина и решение |
|---|---|
| Kaspi не появляется в кассе | Валюта не KZT; плагин не включён; поле API-ключа пустое |
| «Файл плагина не найден» | Старый или битый архив. Удалите папку плагина и загрузите новый zip |
| Заказ зависает в «Ожидает оплаты» | Вебхук не зарегистрирован или не совпадает секрет. Кабинет → Интеграции → Вебхуки → **Журнал доставок**: 401 — неверный секрет, 404 — неверный адрес, 5xx — ошибка сайта |
| В журнале «timeout» | Сайт отвечает дольше 8 секунд. Проверьте плагины кеша и защиты; при Cloudflare поставьте путь `/wp-json/qutpay/` в «Bypass» |
| `kaspi_session_expired` | Оборвалась привязка кассира: кабинет → Kaspi → переподключить по SMS |
| `tariff_limit_reached` | Исчерпан лимит: кабинет → Тариф |
| В live счета не создаются, а в песочнице создаются | В плагине стоит ключ `qp_test_…`. Вставьте боевой |
| Возврат не проходит | У ключа нет права `refunds:write`. Создайте новый ключ |

Если проверки из таблицы не помогли: [Плагин не работает](/kb/ru/plugin-not-working).

## Вопросы и ответы

**Работает ли с Checkout Blocks?** Да. Поддерживаются и классическая касса, и Blocks, и HPOS.

**Мой сайт открывается по http.** В боевом режиме адрес вебхука обязан быть https. Поставьте сертификат — сейчас это бесплатно.

**У меня несколько магазинов, хватит ли одного ключа?** Лучше сделать по ключу на сайт и привязать адрес вебхука к своему ключу: тогда каждый магазин получает только свои события.

**Что будет, если покупатель ушёл со страницы оплаты?** Заказ останется в «Ожидает оплаты», счёт в свой срок станет `expired`. Покупатель может вернуться к заказу и оплатить снова.

**Если я вручную поменяю статус заказа, плагин его перепишет?** Нет. Если менеджер перевёл заказ в processing или complete, запоздавшее событие `expired`/`cancelled` статус не изменит.

**А что делать магазину на OpenCart?** Для него есть отдельное расширение: [Расширение OpenCart 4](/kb/ru/opencart).
