Інтеграція 1С-Бітрікс з платіжною системою ЮKassa
ЮKassa (колишній ЯндексКаса) — один із найпоширеніших платіжних агрегаторів у російському e-commerce. За зовнішньою простотою «підключіть модуль з маркетплейсу» ховається кілька технічних нюансів: робота з повідомленнями, фіскалізація за 54-ФЗ, обробка повернень і вибір правильного режиму підтвердження платежу. Розберемо все по порядку.
Як працює ЮKassa технічно
ЮKassa надає REST API (api.yookassa.ru/v3/). Схема класичного платежу:
- Магазин надсилає
POST /paymentsіз сумою, валютою таconfirmation.type=redirect— ЮKassa повертаєpayment.idіconfirmation.confirmation_url - Покупець перенаправляється на сторінку оплати ЮKassa
- Після оплати ЮKassa надсилає webhook-повідомлення на
return_urlмагазину таPOSTна налаштований URL повідомлень - Магазин викликає
GET /payments/{id}для фінальної перевірки статусу
Аутентифікація — HTTP Basic: shopId:secretKey або OAuth-токен.
Підтримувані методи оплати: банківські картки, SBP, ЮМані, SberPay, Tinkoff, QIWI (з обмеженнями), готівка через термінали. Метод передається у payment_method_type або обирається покупцем на формі ЮKassa.
Варіанти інтеграції у 1С-Бітрікс
Офіційний модуль. ЮKassa надає офіційний модуль для Бітрікс, доступний безкоштовно через Маркетплейс (yoomoney.cms.bitrix) та на GitHub. Встановлюється через /bitrix/admin/update_system.php, налаштування — у Магазин → Налаштування → Платіжні системи. Модуль використовує офіційну PHP-бібліотеку yoomoney/yookassa-sdk-php.
Кастомний обробник потрібен, коли: потрібна нестандартна логіка статусів замовлень, проект не використовує стандартний модуль sale, або потрібна кастомна фіскалізація. Розміщується у /local/php_interface/include/sale_payment/yookassa_custom/.
Ключові параметри запиту
// Мінімальний запит на створення платежу через SDK
use YooKassa\Client;
$client = new Client();
$client->setAuth($shopId, $secretKey);
$payment = $client->createPayment([
'amount' => [
'value' => number_format($order->getPrice(), 2, '.', ''),
'currency' => 'RUB',
],
'confirmation' => [
'type' => 'redirect',
'return_url' => 'https://shop.ru/personal/order/detail/' . $order->getId() . '/',
],
'capture' => true, // false для двостадійних платежів
'description' => 'Замовлення №' . $order->getAccountNumber(),
'metadata' => ['bitrix_order_id' => $order->getId()],
'receipt' => $receiptData, // обов'язково при підключеній касі
], uniqid('', true)); // idempotency key
capture: true — одностадійний платіж, кошти списуються одразу. capture: false — двостадійний: ЮKassa холдує суму, магазин викликає POST /payments/{id}/capture при відвантаженні.
Ключ ідемпотентності (третій параметр) — обов'язковий. Без нього повторний запит при мережевій помилці створить дублюючий платіж.
Фіскалізація (54-ФЗ)
Якщо у договорі з ЮKassa підключено передачу чеків, об'єкт receipt у запиті стає обов'язковим. Без нього транзакція буде відхилена. Структура:
$receiptData = [
'customer' => [
'email' => $buyer->getEmail(),
'phone' => $buyer->getPersonalPhone(), // хоча б одне з двох
],
'items' => [],
];
foreach ($basket->getOrderableItems() as $item) {
$receiptData['items'][] = [
'description' => $item->getField('NAME'),
'quantity' => $item->getQuantity(),
'amount' => [
'value' => number_format($item->getPrice(), 2, '.', ''),
'currency' => 'RUB',
],
'vat_code' => 1, // 1=без ПДВ, 2=0%, 3=10%, 4=20%
'payment_subject' => 'commodity', // ознака предмета розрахунку
'payment_mode' => 'full_payment', // ознака способу розрахунку
];
}
// Не забути доставку як окрему позицію
if ($delivery->getPrice() > 0) {
$receiptData['items'][] = [
'description' => 'Доставка',
'quantity' => 1,
'amount' => ['value' => number_format($delivery->getPrice(), 2, '.', ''), 'currency' => 'RUB'],
'vat_code' => 1,
'payment_subject' => 'service',
'payment_mode' => 'full_payment',
];
}
Сума всіх позицій у чеку має точно збігатися з сумою платежу — ЮKassa перевіряє це та відхиляє невідповідності.
Обробка webhook-повідомлень
ЮKassa надсилає POST на налаштований URL при кожній зміні статусу платежу. У Бітрікс стандартний URL обробника: /bitrix/tools/sale_ps_result.php.
Критично важливі речі при обробці:
// 1. Перевіряємо IP-адресу джерела (ЮKassa публікує список своїх IP)
$allowedIPs = ['185.71.76.0/27', '185.71.77.0/27', '77.75.153.0/25', '77.75.156.11', '77.75.156.35'];
// 2. Читаємо тіло запиту
$body = file_get_contents('php://input');
$notification = json_decode($body, true);
// 3. Верифікуємо через API (не довіряємо даним із webhook напряму)
$payment = $client->getPaymentInfo($notification['object']['id']);
// 4. Обробляємо лише термінальні статуси
switch ($payment->getStatus()) {
case 'succeeded':
$bitrixPayment->setPaid('Y');
$bitrixPayment->save();
break;
case 'canceled':
// Записуємо причину скасування з $payment->getCancellationDetails()
break;
}
Таблиця статусів платежу ЮKassa:
| Статус | Значення | Дія |
|---|---|---|
pending |
Очікує дій покупця | Нічого |
waiting_for_capture |
Очікує підтвердження магазину | Викликати capture або скасувати |
succeeded |
Оплачено | Підтвердити у Бітрікс |
canceled |
Скасовано | Проаналізувати cancellation_details |
Повернення
ЮKassa підтримує частковий та повний повернення через POST /refunds:
$refund = $client->createRefund([
'payment_id' => $externalPaymentId,
'amount' => ['value' => $refundAmount, 'currency' => 'RUB'],
'description' => 'Повернення за замовленням №' . $orderNumber,
'receipt' => $refundReceiptData, // обов'язковий при касі
], uniqid('', true));
При підключеній касі повернення без чека відхиляється. Чек повернення дзеркально дублює позиції оригінального чека з типом refund.
Тестування
ЮKassa надає тестове середовище з тими самими endpoints. У тестовому режимі (shopId=test_...) платежі проходять із тестовими картками:
-
5555555555554477— успішна оплата -
5555555555554444— відмова
Обов'язково протестуйте: успішний платіж, скасування, webhook із затримкою (покупець закрив браузер до редиректу), частковий повернення.
Терміни
| Конфігурація | Термін |
|---|---|
| Готовий модуль, без каси | 1–2 дні |
| Готовий модуль + 54-ФЗ | 2–4 дні |
| Кастомний обробник + каса + двостадійні платежі | 5–8 днів |







