Настройка оплаты по QR-коду в 1С-Битрикс
QR-код для оплаты в интернет-магазине — это не то же самое, что QR-код в офлайн-точке. В онлайне QR-код чаще всего является визуальным представлением платёжной ссылки СБП (Система быстрых платежей) или ссылки конкретного банка. Покупатель сканирует QR → приложение банка открывается с заполненными реквизитами → подтверждает оплату.
Типы QR-кодов для оплаты
QR СБП — через Систему быстрых платежей Банка России. Работает с любым банком-участником СБП. Генерируется через банк-эквайер, участвующий в СБП.
QR банка — proprietary-формат конкретного банка (SberPay QR, Тинькофф QR и др.). Работает только с приложением этого банка.
QR как картинка ссылки — обычная ссылка на страницу оплаты, закодированная в QR. Открывает мобильный браузер, покупатель выбирает способ оплаты на сайте.
QR СБП через Тинькофф
// Создаём платёж с типом QR
$params = [
'TerminalKey' => TINKOFF_TERMINAL,
'Amount' => (int)($order->getPrice() * 100),
'OrderId' => $order->getAccountNumber(),
'Description' => 'Заказ #' . $order->getAccountNumber(),
'NotificationURL' => 'https://shop.ru/bitrix/tools/sale_ps_result.php',
'PayType' => 'O',
];
$params['Token'] = tinkoffSign($params, TINKOFF_SECRET);
$initResult = tinkoffPost('/v2/Init', $params);
$paymentId = $initResult['PaymentId'];
// Запрашиваем QR для СБП
$qrParams = [
'TerminalKey' => TINKOFF_TERMINAL,
'PaymentId' => $paymentId,
'DataType' => 'IMAGE', // или 'PAYLOAD' для получения строки ссылки
];
$qrParams['Token'] = tinkoffSign($qrParams, TINKOFF_SECRET);
$qrResult = tinkoffPost('/v2/GetQr', $qrParams);
// $qrResult['Data'] — base64-encoded PNG с QR-кодом (при DataType=IMAGE)
// или строка-ссылка СБП (при DataType=PAYLOAD)
Отображение QR на странице
// Показываем QR и полим статус платежа
async function showQRPayment(orderId) {
const resp = await fetch('/api/get-payment-qr.php', {
method: 'POST',
body: JSON.stringify({ orderId }),
});
const data = await resp.json();
document.getElementById('qr-image').src = 'data:image/png;base64,' + data.qrBase64;
document.getElementById('qr-block').style.display = 'block';
// Polling: проверяем статус каждые 3 секунды
const pollInterval = setInterval(async () => {
const status = await checkPaymentStatus(orderId);
if (status === 'paid') {
clearInterval(pollInterval);
window.location.href = '/payment/success/';
}
if (status === 'expired') {
clearInterval(pollInterval);
showExpiredMessage();
}
}, 3000);
// Останавливаем polling через 15 минут
setTimeout(() => clearInterval(pollInterval), 15 * 60 * 1000);
}
Серверный polling статуса
// local/api/check-payment-status.php
$orderId = (int)($_POST['orderId'] ?? 0);
$paymentId = getExternalPaymentId($orderId); // сохранённый PaymentId Тинькофф
$params = [
'TerminalKey' => TINKOFF_TERMINAL,
'PaymentId' => $paymentId,
];
$params['Token'] = tinkoffSign($params, TINKOFF_SECRET);
$status = tinkoffPost('/v2/GetState', $params);
$map = [
'CONFIRMED' => 'paid',
'CANCELED' => 'cancelled',
'DEADLINE_EXPIRED' => 'expired',
];
echo json_encode([
'status' => $map[$status['Status']] ?? 'pending',
]);
QR через ЮКасса СБП
ЮКасса формирует QR СБП автоматически при создании платежа с методом sbp:
$payment = $client->createPayment([
'amount' => ['value' => '1500.00', 'currency' => 'RUB'],
'payment_method_data' => ['type' => 'sbp'],
'confirmation' => ['type' => 'qr'],
'description' => 'Заказ #' . $orderId,
], uniqid('', true));
$qrUrl = $payment->getConfirmation()->getConfirmationData();
// qrUrl — строка вида https://qr.nspk.ru/... — кодируем в QR на клиенте
Для отрисовки QR из URL на клиенте используем JS-библиотеку qrcodejs или qr-code-styling.
Сроки
| Задача | Срок |
|---|---|
| QR СБП через Тинькофф/ЮКасса | 1–2 дня |
| Polling статуса + UX обновления | 0.5–1 день |
| Интеграция в страницу оформления заказа | 0.5–1 день |







