Когда для акции нужны не один общий промокод, а тысячи уникальных купонов — по одному на подписчика — ручной ввод в админке отпадает. В 1С-Битрикс серию купонов генерируют программно через API модуля sale, привязывая каждый код к готовому правилу корзины и затем выгружая список в рассылку.
Когда нужна именно серия, а не один код
Общий промокод вроде SALE15 удобен для баннера, но плохо подходит для персональной рассылки: его мгновенно расшаривают в чатах и на форумах кэшбэк-сервисов, и скидку получают все подряд, а не ваши подписчики. Серия уникальных одноразовых промокодов решает эту проблему — каждому получателю письма достаётся свой код, который сгорает после первого применения.
Типовые сценарии, где нужна массовая генерация:
- приветственная скидка за подписку — по коду на каждый новый email;
- реактивация «спящих» клиентов из CRM-сегмента;
- распространение купонов через партнёров и офлайн-точки с контролем по каждому коду;
- розыгрыши и промо в соцсетях, где нужно отследить, кто и какой код погасил.
Ключевое требование — уникальность и возможность связать факт использования кода с конкретным адресатом. Именно это даёт программная генерация через API, а не ручное заведение купонов.
Готовим правило корзины-основу
В 1С-Битрикс купон сам по себе скидку не задаёт — он лишь активирует правило корзины (Discount). Поэтому перед генерацией серии в разделе Магазин → Маркетинг → Правила работы с корзиной создаётся одно правило: условие (например, сумма заказа от 3000 ₽), действие (скидка 15% или фикс на доставку) и, главное, тип применения — «По купону».
У этого правила есть числовой идентификатор DISCOUNT_ID — его видно в адресной строке при редактировании (discount_edit.php?ID=...). Именно к нему мы привяжем все коды серии. Один купон в Битрикс всегда относится ровно к одному правилу.
Типы купонов и таблица хранения
Купоны хранятся в таблице b_sale_discount_coupon, за которую отвечает ORM-класс \Bitrix\Sale\Internals\DiscountCouponTable. Тип поведения кода задаёт поле TYPE — от него зависит, сколько раз код сработает.
| Тип (константа) | Значение | Поведение |
|---|---|---|
TYPE_ONE_TIME | Одноразовый | Гасится после первого успешного заказа |
TYPE_MULTI_ONCE | Один раз на пользователя | Один клиент — одно применение, но код общий |
TYPE_BASKET | Неограниченный | Работает до истечения срока / лимита |
Для персональной рассылки практически всегда нужен DiscountCouponTable::TYPE_ONE_TIME: каждый сгенерированный код одноразовый и после покупки автоматически переходит в статус применённого. Дополнительно можно ограничить период действия полями ACTIVE_FROM и ACTIVE_TO.
Скрипт генерации серии через API
Массовую вставку удобно выполнить php-скриптом из-под bitrix (агент, консольный скрипт или разовый файл в защищённой папке). Логика проста: генерируем читаемый уникальный код, проверяем, что его ещё нет, и добавляем строку через DiscountCouponTable::add() с привязкой к DISCOUNT_ID.
use Bitrix\Main\Loader;
use Bitrix\Sale\Internals\DiscountCouponTable;
Loader::includeModule('sale');
$discountId = 42; // ID правила корзины "По купону"
$count = 5000; // сколько кодов нужно
$prefix = 'MAIL-';
$codes = [];
while (count($codes) < $count) {
$code = $prefix . mb_strtoupper(
\Bitrix\Main\Security\Random::getString(8, true)
);
// защита от дубля
$exists = DiscountCouponTable::getList([
'filter' => ['=COUPON' => $code],
'select' => ['ID'],
'limit' => 1,
])->fetch();
if ($exists) {
continue;
}
$res = DiscountCouponTable::add([
'DISCOUNT_ID' => $discountId,
'COUPON' => $code,
'TYPE' => DiscountCouponTable::TYPE_ONE_TIME,
'ACTIVE' => 'Y',
'MAX_USE' => 1,
'ACTIVE_FROM' => new \Bitrix\Main\Type\DateTime(),
'DESCRIPTION' => 'Рассылка "Июльская акция"',
]);
if ($res->isSuccess()) {
$codes[] = $code;
}
}
Класс \Bitrix\Main\Security\Random даёт криптостойкую случайность — коды не угадать перебором, в отличие от rand(). Поле MAX_USE дублирует ограничение по числу применений, а DESCRIPTION помогает потом отфильтровать серию в списке купонов.
Экспорт списка и передача в рассылку
После генерации массив $codes нужно связать с адресами получателей. Порядок работы обычно такой:
- выгружаем коды в CSV (
email;coupon) — по коду на подписчика из сегмента; - загружаем файл в сервис рассылок или в штатный модуль;
- в шаблоне письма подставляем персональный код через merge-переменную.
Если рассылка идёт через внешний сервис (Unisender, Sendsay, Mindbox), проще всего сформировать CSV скриптом сразу после генерации и передать по API сервиса. Если используется штатный модуль subscribe 1С-Битрикс, персонализация делается на этапе сборки письма — например, скрипт достаёт очередной свободный код из серии и записывает его в свойство подписчика.
Достать всю серию для выгрузки можно тем же ORM-запросом:
$rows = DiscountCouponTable::getList([
'filter' => [
'=DISCOUNT_ID' => $discountId,
'=ACTIVE' => 'Y',
],
'select' => ['ID', 'COUPON', 'USE_COUNT'],
]);
while ($row = $rows->fetch()) {
// пишем в CSV: $row['COUPON']
}
Контроль использования и чистка
Факт применения купона Битрикс фиксирует в полях USE_COUNT (сколько раз сработал) и DATE_APPLY (когда). Одноразовые коды после успешного заказа сами переходят в неактивное состояние, поэтому повторно их не применят.
Что полезно отслеживать по серии:
- конверсию — доля кодов с
USE_COUNT > 0от всей выгрузки; - привязку к заказам — через таблицу
b_sale_order_couponsвидно, в каком заказе погашен конкретный код; - остаток — неиспользованные коды можно деактивировать по истечении срока акции.
Свернуть акцию просто: выключите активность правила корзины — и вся серия перестанет давать скидку, даже если коды где-то ещё «гуляют». Массово удалить отработавшие купоны можно тем же DiscountCouponTable::delete() по фильтру DISCOUNT_ID, но чаще их оставляют для истории и аналитики.
Итог
Серия промокодов для рассылки в 1С-Битрикс — это одно правило корзины типа «По купону» плюс массовая программная генерация уникальных одноразовых кодов через \Bitrix\Sale\Internals\DiscountCouponTable. Криптостойкий генератор, проверка на дубли, привязка к DISCOUNT_ID, экспорт в CSV и персонализация письма — вот весь цикл. Контроль ведётся по USE_COUNT и таблице заказов, а свернуть акцию можно одним переключателем активности правила.
Если нужно связать генерацию с сегментами CRM, внешним сервисом рассылок и отчётностью — мы в B2Bsite настраиваем такие механики под ключ: от правил корзины до API-интеграции с рассыльщиком и выгрузки статистики. Поможем спроектировать серию, которая не «утечёт» и даст измеримую конверсию.
Частые вопросы
Чем серия уникальных купонов лучше одного общего промокода?
Общий код быстро расходится по кэшбэк-сервисам и чатам, и скидку получают все. Уникальные одноразовые коды достаются только вашим подписчикам и сгорают после первого применения, что защищает маржу и позволяет считать конверсию по рассылке.
Какой класс отвечает за купоны в API Битрикс?
За таблицу b_sale_discount_coupon отвечает ORM-класс \Bitrix\Sale\Internals\DiscountCouponTable из модуля sale. Через его методы add(), getList() и delete() выполняются генерация, выборка и очистка серии.
Как сделать код одноразовым?
При добавлении укажите TYPE равным DiscountCouponTable::TYPE_ONE_TIME и MAX_USE = 1. После первого успешного заказа такой купон автоматически перейдёт в применённое состояние и повторно не сработает.
Обязательно ли создавать правило корзины перед генерацией?
Да. Купон в Битрикс сам скидку не задаёт — он активирует правило работы с корзиной типа «По купону». Все коды серии привязываются к идентификатору этого правила через поле DISCOUNT_ID.
Как гарантировать уникальность и стойкость кодов?
Генерируйте код через \Bitrix\Main\Security\Random::getString() — это криптостойкий источник случайности. Перед вставкой проверяйте наличие такого COUPON запросом getList(), чтобы исключить дубли.
Как отследить, что код погашен и в каком заказе?
Смотрите поля USE_COUNT и DATE_APPLY в самой таблице купонов, а привязку к конкретному заказу — в таблице b_sale_order_coupons. По ним считается конверсия серии и связь код-получатель.
Как передать коды во внешний сервис рассылок?
Выгрузите серию запросом getList() в CSV формата email;coupon и загрузите файл или отправьте по API сервиса (Unisender, Sendsay, Mindbox). В шаблоне письма персональный код подставляется merge-переменной.
Как быстро отключить всю акцию, если что-то пошло не так?
Выключите активность правила корзины, к которому привязана серия. Все коды сразу перестанут давать скидку, даже если они уже разошлись, — удалять сами купоны при этом не обязательно.
Поможем с настройкой и поддержкой 1С-Битрикс: Управление сайтом
Поможем с настройкой, доработкой и поддержкой 1С-Битрикс: Управление сайтом.