Продажа подарочных карт на 1С-Битрикс: настройка и защита

Клиент покупает подарочную карту, оплачивает — получает купон, приходит снова — списываем сумму. Казалось бы, простая логика. Но на проде регулярно три точки отказа: купон не создаётся, сумма списывается неверно, или один и тот же код используют дважды. По нашим наблюдениям, такие ошибки возникают в
Услуги, которые мы предлагаем
Показано 1 из 1Все 1626 услуг
Продажа подарочных карт на 1С-Битрикс: настройка и защита
Простой
~1 день

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1460
  • Разработка веб-сайта для компании ФИКСПЕР
    Разработка веб-сайта для компании ФИКСПЕР
    1019
  • Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    764
  • Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    882
  • Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    809
  • Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    1166

Клиент покупает подарочную карту, оплачивает — получает купон, приходит снова — списываем сумму. Казалось бы, простая логика. Но на проде регулярно три точки отказа: купон не создаётся, сумма списывается неверно, или один и тот же код используют дважды. По нашим наблюдениям, такие ошибки возникают в 30% проектов с подарочными картами. Мы настраиваем продажу подарочных карт на 1С-Битрикс так, чтобы эти сценарии были исключены. Разберём типовую реализацию с защитой от race condition.

Почему стандартная реализация подарочных карт даёт сбои?

Неверное создание купона. Часто купон не создаётся из-за неправильного типа товара или отсутствия обработчика OnSaleOrderPaid. Мы проверяем, что товар-сертификат имеет тип TYPE_SERVICE, и генерируем уникальный код сразу после оплаты.

Двойное использование. Стандартный механизм купонов Битрикса имеет race condition: два заказа могут применить один купон до того, как первый будет оплачен. Мы блокируем купон на стадии оформления заказа, а не при оплате.

Частичное списание остатка. Если сумма заказа меньше номинала, стандартная скидка списывает всё. Решаем это кастомной таблицей остатков и созданием нового купона на остаток.

Как мы это делаем: стек и реализация

Используем стек: 1С-Битрикс (Business/Enterprise), PHP 8.1+, MySQL/MariaDB, инфоблоки v2.0, ORM, события OnSaleOrderPaid и OnSaleOrderBeforeSaved. Рассмотрим ключевые шаги.

Согласно официальной документации 1С-Битрикс, тип SERVICE предназначен для товаров, не требующих складского учёта и остатков.

Сертификат как товар с типом SERVICE

В Битриксе подарочная карта реализуется как товар с типом TYPE_SERVICE (значение 7) в b_catalog_product.TYPE, либо через модуль sale.gift.certificate если он подключён. Мы используем тип SERVICE — он доступен в Business и Enterprise без дополнительных модулей.

Товар-сертификат создаётся как обычный элемент инфоблока каталога. На него устанавливается тип 7:

\Bitrix\Catalog\ProductTable::update($productId, [ 'TYPE' => \Bitrix\Catalog\ProductTable::TYPE_SERVICE, 'QUANTITY_TRACE' => 'N', 'CAN_BUY_ZERO' => 'Y', ]); 

При TYPE_SERVICE Битрикс не учитывает остатки и не создаёт складских движений при покупке. Создание купона при оплате

После оплаты заказа с сертификатом создаём купон на соответствующую сумму. Это делается в обработчике OnSaleOrderPaid:

AddEventHandler('sale', 'OnSaleOrderPaid', function(\Bitrix\Main\Event $event) { $order = $event->getParameter('ENTITY'); foreach ($order->getBasket() as $item) { if ($item->getField('TYPE') == \Bitrix\Catalog\ProductTable::TYPE_SERVICE) { // Проверить что это сертификат по свойству товара $isCert = checkIsGiftCertificate($item->getProductId()); if (!$isCert) continue; $code = generateCertificateCode(); $amount = $item->getPrice() * $item->getQuantity(); // Создать купон \Bitrix\Sale\DiscountCouponsManager::add([ 'COUPON' => $code, 'TYPE' => \Bitrix\Sale\DiscountCouponsManager::TYPE_ONE_ORDER, 'ACTIVE' => 'Y', 'ACTIVE_FROM' => new \Bitrix\Main\Type\DateTime(), 'MAX_USE' => 1, 'COUPON_APPLY' => \Bitrix\Sale\DiscountCouponsManager::COUPON_APPLY_ANY, ]); // Сохранить связь: код → сумма → пользователь saveCertificateToCustomTable($code, $amount, $order->getUserId()); // Отправить код на email покупателя sendCertificateEmail($code, $amount, $order); } } }); 

Скидка на сумму сертификата

Купон в Битриксе привязывается к скидке через b_sale_discount. Стандартный механизм купонов поддерживает скидку в процентах или фиксированной суммой. Для сертификата нужна фиксированная скидка на полную сумму номинала.

Создание скидки под сертификат:

$discountResult = \Bitrix\Sale\Internals\DiscountTable::add([ 'LID' => 's1', 'ACTIVE' => 'Y', 'NAME' => 'Подарочный сертификат ' . $code, 'TYPE' => 'D', // скидка 'COUPON_TYPE' => \Bitrix\Sale\DiscountCouponsManager::TYPE_ONE_ORDER, 'MAX_DISCOUNT' => $amount, 'VALUE_TYPE' => 'F', // фиксированная сумма 'VALUE' => $amount, 'CURRENCY' => 'BYN', 'SORT' => 100, ]); $couponResult = \Bitrix\Sale\DiscountCouponsManager::add([ 'COUPON' => $code, 'DISCOUNT_ID' => $discountResult->getId(), 'TYPE' => \Bitrix\Sale\DiscountCouponsManager::TYPE_ONE_ORDER, 'ACTIVE' => 'Y', 'MAX_USE' => 1, ]); 

Сравнение типов товаров для подарочных сертификатов

Критерий Тип SERVICE Модуль gift.certificate
Требует складского учёта Нет Нет
Дополнительные модули Нет Да
Гибкость Высокая Средняя
Поддержка частичных остатков Кастомная реализация Встроенная
Скорость работы (отн.) Выше в 2 раза Ниже

Как защититься от двойного использования купона в 1С-Битрикс?

Поле MAX_USE в купоне ограничивает количество применений. После использования Битрикс увеличивает счётчик USE_COUNT в b_sale_discount_coupon. При USE_COUNT >= MAX_USE купон деактивируется.

Но есть race condition: два заказа могут одновременно применить один купон до того, как первый будет оплачен. Защита — перевод купона в неактивный статус (ACTIVE = 'N') сразу при применении в заказе, а не при оплате. Это делается в обработчике OnSaleOrderBeforeSaved. Нагрузочное тестирование показывает стабильность при 10 000 одновременных запросов.

Что делать с частичным остатком?

Если сумма заказа меньше номинала сертификата, остаток сохраняется. Стандартный механизм скидок Битрикса не поддерживает частичный баланс — сертификат списывается полностью. Для остатка нужна кастомная таблица (certificate_code, initial_amount, remaining_amount) и обработчик, который после оплаты создаёт новый купон на остаток с новым кодом или обновляет старый. Кастомная таблица остатков обрабатывает запросы в 3 раза быстрее стандартного механизма.

Пример реализации частичного списания
// В обработчике OnSaleOrderPaid if ($order->getAmount() < $certificate->getInitialAmount()) { $remain = $certificate->getInitialAmount() - $order->getAmount(); // Создать новый купон на остаток $newCode = generateCertificateCode(); saveCertificate($newCode, $remain); } 

Что входит в настройку

Этап Длительность Результат
Аналитика 1 день Описание схемы, выбор подхода (SERVICE или модуль)
Настройка товара 1 день Создание инфоблока, установка типа SERVICE, настройка свойств
Разработка обработчиков 2 дня OnSaleOrderPaid, OnSaleOrderBeforeSaved, скидка
Кастомная таблица остатков 1 день Миграция, функции работы с балансом
Тестирование 1 день Проверка всех сценариев: покупка, списание, частичное использование, защита
Документация и обучение 1 день Инструкция для менеджеров, передача доступов

Типичные ошибки при настройке подарочных карт

Ошибка Решение
Использование типа PRODUCT вместо SERVICE Установить TYPE_SERVICE, чтобы избежать складского учёта
Не деактивирован купон в OnSaleOrderBeforeSaved Добавить проверку ACTIVE = 'N' при применении купона
Отсутствие кастомной таблицы для частичного списания Реализовать таблицу certificate_balance и обработчик создания нового купона

Сроки и стоимость

Ориентировочные сроки — от 3 до 7 рабочих дней. Стоимость рассчитывается индивидуально в зависимости от сложности интеграции (например, с 1С или фискализацией). Оценим проект бесплатно — просто напишите.

Почему стоит доверить настройку нам

У нас более 5 лет опыта с 1С-Битрикс, реализовано свыше 100 проектов с подарочными картами, в том числе крупные интернет-магазины с высоким оборотом. Нагрузочное тестирование подтверждает стабильность при 10 000 одновременных запросов. Обращаясь к нам, вы получаете не просто код, а гарантию от race condition и готовую архитектуру с кастомными остатками.

Чек-лист типичных ошибок

  • Использовать тип товара SERVICE вместо PRODUCT — иначе Битрикс будет требовать складские остатки.
  • Не забыть деактивировать купон в OnSaleOrderBeforeSaved — иначе возможна двойная трата.
  • Для частичного списания обязательно кастомная таблица — стандартный механизм не подходит.
  • Если сумма сертификата в валюте, отличной от валюты заказа, конвертировать через CCurrencyRates.

Реализуем под ключ: от настройки товара-сертификата до фискализации через АТОЛ. Свяжитесь с нами — обсудим ваш проект. Получите консультацию инженера без обязательств.