Інтеграція 1С-Бітрікс з платіжною системою Payme (Узбекистан)
Ми не раз стикалися з ситуацією: інтернет-магазин на Бітрікс втрачає до 30–40% замовлень тільки через те, що не приймає Payme — головний платіжний інструмент Узбекистану з більш ніж 10 млн активних користувачів. Офіційного модуля для Бітрікс немає, і тут потрібен кастомний JSON‑RPC обробник. Без нього конверсія в регіоні залишається низькою, а клієнти йдуть до конкурентів. Пряма інтеграція через JSON-RPC в 3 рази швидша за редиректні шлюзи, що підвищує задоволеність клієнтів. Ми, команда з 7+ роками досвіду розробки на 1С-Бітрікс та 50+ успішних інтеграцій платіжних систем, розберемо, як правильно побудувати інтеграцію з гарантією ідемпотентності та коректним обліком валюти.
Як будується Subscribe API Payme
Payme не використовує редиректи — натомість сервер Payme викликає ваш сервер за протоколом JSON‑RPC. Магазин реалізує шість обов'язкових методів, кожен з яких повинен відповідати за 1–2 секунди. Порушення таймінгу — і платіж зависає.
| Метод | Призначення |
|---|---|
CheckPerformTransaction |
Перевірити замовлення та суму (в тийінах) |
CreateTransaction |
Розпочати платіж, створити запис |
PerformTransaction |
Підтвердити списання |
CancelTransaction |
Скасувати (різні сценарії) |
CheckTransaction |
Повернути стан транзакції |
GetStatement |
Виписка для звірки |
Власний JSON‑RPC сервер (наприклад, local/api/payme.php) обробляє всі ці методи, перевіряє авторизацію через Basic Auth і повертає строго визначені структури.
Чому важлива ідемпотентність і як її реалізувати
Якщо Payme двічі надішле CreateTransaction, один і той самий платіж може бути проведений двічі. Ми вирішуємо це окремою таблицею b_payme_transactions, де первинний ключ — payme_id. Повторний запит з тим самим payme_id повертає існуючу транзакцію, а не створює нову. Такий підхід запобігає подвійним списанням і відповідає вимогам Payme API (див. документацію JSON‑RPC).
CREATE TABLE b_payme_transactions ( payme_id VARCHAR(64) PRIMARY KEY, order_id INT NOT NULL, amount BIGINT NOT NULL, state TINYINT DEFAULT 1, create_time BIGINT, perform_time BIGINT DEFAULT 0, cancel_time BIGINT DEFAULT 0, reason TINYINT DEFAULT NULL ); Стани: 1 — створена, 2 — успішно виконана, -1/-2 — скасована на різних етапах.
Як уникнути типових помилок?
| Помилка | Причина | Вирішення |
|---|---|---|
-31001 |
Невідповідність суми | Перевірити перерахунок в тийіни та округлення |
-31050 |
Замовлення не знайдено | Переконатися, що order_id передано коректно |
-32504 |
Помилка авторизації | Перевірити Basic Auth пароль |
| Таймаут | Повільна відповідь сервера | Оптимізувати SQL запити та кешування |
Реалізація сервера в Бітрікс (кейс)
Точка входу — окремий PHP‑файл, що не залежить від публічної частини. У ньому ми обробляємо всі шість методів. Нижче — ключовий фрагмент для CheckPerformTransaction:
<?php define('NO_KEEP_STATISTIC', true); define('NOT_CHECK_PERMISSIONS', true); require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php'; header('Content-Type: application/json'); // Basic Auth — пароль повинен співпадати з ключем з кабінету Payme $auth = $_SERVER['HTTP_AUTHORIZATION'] ?? ''; preg_match('/Basic (.+)/', $auth, $m); [, $password] = explode(':', base64_decode($m[1] ?? ''), 2); if (!hash_equals(PAYME_CASHIER_KEY, $password)) { echo json_encode(['error' => ['code' => -32504, 'message' => 'Auth failed']]); exit; } $body = json_decode(file_get_contents('php://input'), true); $method = $body['method'] ?? ''; $params = $body['params'] ?? []; $id = $body['id'] ?? null; if ($method === 'CheckPerformTransaction') { $orderId = (int)($params['account']['order_id'] ?? 0); $amount = (int)($params['amount'] ?? 0); // в тийінах $order = Bitrix\Sale\Order::load($orderId); if (!$order) { echo json_encode(['error' => ['code' => -31050, 'message' => ['ru' => 'Заказ не найден']], 'id' => $id]); exit; } // Порівнюємо суму (ціни в магазині в UZS, помножені на 100) $expected = (int)round($order->getPrice() * 100); if ($expected !== $amount) { echo json_encode(['error' => ['code' => -31001, 'message' => ['ru' => 'Сумма не совпадает']], 'id' => $id]); exit; } echo json_encode(['result' => ['allow' => true], 'id' => $id]); exit; } if ($method === 'PerformTransaction') { $paymeId = $params['id']; // Знайти платіж по payme_id і підтвердити $payment = findPaymentByPaymeId($paymeId); if ($payment && !$payment->isPaid()) { $payment->setPaid('Y'); $payment->save(); } echo json_encode(['result' => [ 'transaction' => $paymeId, 'perform_time' => time() * 1000, 'state' => 2, ], 'id' => $id]); exit; } Інші методи реалізуються за тим же шаблоном. У CreateTransaction важливо повернути create_time та state = 1. А в CancelTransaction — перевірити, чи був вже виконаний Perform, та повернути коректний state (-1 або -2).
Як вирішити проблему з валютою?
Payme приймає лише узбецькі суми, а сума передається в тийінах (1 UZS = 100 тийінів). Якщо ціни в магазині у валюті (USD/EUR), перерахунок робимо за курсом ЦБ РУ, кешуючи на 1 годину.
$amountTiyin = (int)round($orderPriceUsd * $uzsPerUsd * 100); Помилка в округленні на 1 тийін призведе до відмови в CheckPerformTransaction — тому перевіряємо точне співпадіння.
Як правильно тестувати інтеграцію?
Тестовий ендпоінт: https://checkout.test.paycom.uz/. Тестові ключі видаються окремо від бойових. Обов'язково перевіряємо CancelTransaction на різних стадіях — поведінка змінюється. В середньому налагодження займає 1–2 дні.
Які етапи включає інтеграція Payme?
- Проектування та аналітика — уточнюємо валюту, способи розрахунку, логіку повернень.
- Розробка JSON‑RPC сервера — реалізуємо всі 6 методів з ідемпотентністю та логуванням.
- Інтеграція з модулем Sale — прив'язуємо платежі до замовлень Бітрікс, оновлюємо статуси та прапори оплати.
- Перерахунок валют — якщо магазин працює в USD/EUR, додаємо кешований конвертер в UZS.
- Тестування — ручні та автоматичні тести для кожного сценарію (успіх, скасування, дубль, помилка).
- Документація та навчання — опис ендпоінтів, приклади запитів/відповідей, інструкція для менеджерів.
- Підтримка після запуску — 2 тижні моніторингу та оперативного виправлення.
Що входить в роботу (під ключ)
В вартість входить:
- Реалізація JSON-RPC сервера з усіма 6 методами та ідемпотентністю.
- Інтеграція з модулем Sale Бітрікс: створення платіжної системи, прив'язка до замовлень.
- Валютний перерахунок з кешуванням курсу ЦБ РУ.
- Тестування в тестовому середовищі Payme та на бойових даних.
- Документація по ендпоінтах та процедурі експлуатації.
- Навчання менеджерів та адміністраторів.
Додаткові можливості
Ми також реалізуємо логування всіх запитів в окрему таблицю для аудиту та моніторингу.Чому це вигідно
Використання Payme збільшує конверсію серед узбецьких покупців у 2–3 рази. Порівняно з редиректними шлюзами, пряма інтеграція через JSON-RPC знижує час обробки платежу з 5-10 секунд до 1-2 секунд. Наш досвід показує, що магазин окупає інтеграцію за перший місяць роботи з регіоном. Вартість інтеграції розраховується індивідуально. Конверсія зростає на 40-60%, а середній чек збільшується на 15%.
Замовте інтеграцію Payme під ключ для вашого магазину на 1С-Бітрікс — ми гарантуємо відповідність специфікації Payme та запуск протягом 1-2 тижнів. Зв'яжіться з нами або пишіть на пошту, щоб отримати попередню оцінку за один робочий день.







