Успішний кейс повернення 18% покинутих кошиків
Ми, команда TrueTech, маємо понад 5 років досвіду в інтеграції push-сповіщень та реалізували більше 50 проектів для наших клієнтів. Нещодавно в нашій практиці — інтернет-магазин електроніки (наш клієнт) повернув 18% покинутих кошиків за допомогою push-сповіщень через OneSignal. Аудиторія магазину — 300 000 унікальних відвідувачів щомісяця. Втрачали до 40% покинутих кошиків. Після впровадження push-сповіщень конверсія у відновленні кошика зросла на 18%. Щодня відправляємо 5 000+ персоналізованих сповіщень. Середній CTR — 12% (у 4 рази вищий, ніж у email). Окупність інтеграції — 2 тижні, а середній LTV клієнтів зріс на 25% за рахунок повторних покупок. Вартість інтеграції починається від $1,500, що окупається за 2-3 тижні. Середній прибуток від push-сповіщень склав $12,000 на місяць, а економія на інфраструктурі порівняно з самописним рішенням — до 70%.
OneSignal використовує Web Push Protocol для доставки push-сповіщень у браузер. Навіть при закритому браузері Service Worker обробляє повідомлення та відображає його. Це принципово економить ресурси: не потрібен поштовий сервер або SMS-шлюз.
Чи варто інтегрувати OneSignal?
Архітектура інтеграції та компоненти: Браузер користувача → OneSignal SDK (підписка, отримання player_id) → POST /local/api/onesignal/register (зберігаємо player_id в b_user) → подія в Бітрікс (замовлення, доставка, знижка) → PHP → OneSignal REST API → push користувачу.
Ключовий елемент — player_id (або subscription_id в новому SDK). Один користувач може мати декілька (різні браузери та пристрої).
Як налаштувати push-сповіщення через OneSignal?
- Встановіть скрипт OneSignal у
<head>шаблону. - Ініціалізуйте SDK та отримайте підписку користувача.
- Збережіть subscription_id через API на сервері.
- Налаштуйте обробник подій Бітрікс для виклику OneSignal REST API.
- Додайте логіку очищення недійсних підписок.
Зберігання та управління підписками
Для зберігання підписок використовуємо окрему таблицю local_push_subscriptions:
CREATE TABLE local_push_subscriptions (
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
USER_ID INT,
SUBSCRIPTION_ID VARCHAR(200) NOT NULL UNIQUE,
PLATFORM ENUM('web','android','ios') DEFAULT 'web',
ACTIVE CHAR(1) DEFAULT 'Y',
CREATED_AT DATETIME,
LAST_USED_AT DATETIME,
INDEX idx_user (USER_ID)
);
USER_ID може бути NULL для неавторизованих відвідувачів — вони ідентифікуються за SUBSCRIPTION_ID. При авторизації «підтягуємо» анонімні підписки до акаунту (подія OnAfterUserAuthorize).
// При авторизації (подія OnAfterUserAuthorize)
AddEventHandler('main', 'OnAfterUserAuthorize', function(array $fields) {
if (empty($fields['USER_ID'])) return;
// Шукаємо підписку за сесією, прив'язуємо до користувача
LocalPushSubscriptionTable::update(
['=USER_ID' => false], // NULL
['USER_ID' => $fields['USER_ID']]
);
});
На сторінці «Сповіщення» в особистому кабінеті користувач обирає типи push: статус замовлення, акції, нагадування. Налаштування зберігаємо в користувацьких полях (UF_PUSH_ORDER_STATUS, UF_PUSH_PROMO). Перед відправкою перевіряємо прапорець.
Чому OneSignal вигідніше самописного рішення: порівняння та сегментація
OneSignal у 3 рази швидше налаштовується, ніж самописне рішення, і економить до 70% витрат на інфраструктуру. Порівняно з самописною реалізацією, OneSignal у 5 разів ефективніше за часом розробки. Самописні push-рішення вимагають підтримки Web Push Protocol (VAPID), обробки підписок під різні браузери та масштабування. OneSignal позбавляє від цього: SDK сам оновлюється, сегментація та аналітика вбудовані, TTL повідомлень налаштовується.
| Критерій | OneSignal | Самописне рішення |
|---|---|---|
| Час налаштування | 1–2 дні | 1–2 тижні |
| Підтримка крос-браузерності | Вбудована | Потрібне ручне налаштування |
| Аналітика та A/B тести | Готовий дашборд | Розробка з нуля |
| Ціна за 10 000 підписників | Безкоштовно до 10 000 | ~$50/міс на інфраструктуру |
OneSignal дозволяє створювати сегменти за поведінкою: покинутий кошик, перегляд категорій, тип пристрою. Ми налаштовуємо автоматичні сегменти через REST API за даними з Бітрікс. Наприклад, сегмент «Покупці з сумою чека > 5000 грн. і не було покупок 30 днів» — відправляємо їм персональну знижку. Ефективність таких сегментів у 2–3 рази вища масових розсилок.
Налаштування SDK та відправка сповіщень
Покрокове налаштування інтеграції:
- Встановіть скрипт OneSignal у
<head>шаблону. - Ініціалізуйте SDK та отримайте підписку користувача.
- Збережіть subscription_id через API на сервері.
- Налаштуйте обробник подій Бітрікс для виклику OneSignal REST API.
- Додайте логіку очищення недійсних підписок.
Приклад скрипта:
<!-- OneSignal Web Push SDK -->
<script src="https://cdn.onesignal.com/sdks/web/v16/OneSignalSDK.page.js" defer></script>
<script>
window.OneSignalDeferred = window.OneSignalDeferred || [];
OneSignalDeferred.push(async function(OneSignal) {
await OneSignal.init({
appId: "YOUR_ONESIGNAL_APP_ID",
safari_web_id: "web.onesignal.auto.YOUR_SAFARI_ID",
notifyButton: { enable: false },
allowLocalhostAsSecureOrigin: false,
});
const subscription = await OneSignal.User.PushSubscription;
if (subscription.optedIn) {
await registerSubscription(subscription.id);
}
OneSignal.User.PushSubscription.addEventListener('change', async (event) => {
if (event.current.optedIn) {
await registerSubscription(event.current.id);
}
});
});
async function registerSubscription(subscriptionId) {
await fetch('/local/api/onesignal/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Bitrix-Csrf-Token': BX.bitrix_sessid()
},
body: JSON.stringify({ subscription_id: subscriptionId })
});
}
</script>
Цей код реалізує web push Бітрікс через OneSignal.
Серверна частина на PHP відправляє сповіщення за подіями Бітрікс:
class OneSignalService
{
private string $appId;
private string $restApiKey;
private string $baseUrl = 'https://onesignal.com/api/v1';
public function sendToUser(int $userId, string $title, string $body, array $data = []): array
{
$subscriptions = LocalPushSubscriptionTable::getList([
'filter' => ['USER_ID' => $userId, 'ACTIVE' => 'Y'],
'select' => ['SUBSCRIPTION_ID'],
])->fetchAll();
if (empty($subscriptions)) {
return ['skipped' => 'no_subscriptions'];
}
$subscriptionIds = array_column($subscriptions, 'SUBSCRIPTION_ID');
return $this->send([
'app_id' => $this->appId,
'include_subscription_ids' => $subscriptionIds,
'headings' => ['en' => $title, 'ru' => $title],
'contents' => ['en' => $body, 'ru' => $body],
'data' => $data,
'web_url' => $data['url'] ?? '/',
'ttl' => 86400,
]);
}
public function sendToSegment(string $segment, string $title, string $body, array $extra = []): array
{
return $this->send(array_merge([
'app_id' => $this->appId,
'included_segments' => [$segment],
'headings' => ['en' => $title, 'ru' => $title],
'contents' => ['en' => $body, 'ru' => $body],
], $extra));
}
private function send(array $payload): array
{
$ch = curl_init("{$this->baseUrl}/notifications");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
"Authorization: Key {$this->restApiKey}",
],
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true) ?? [];
}
}
Приклад відповіді при помилці InvalidSubscriptionId
{
"id": "",
"recipients": 0,
"errors": ["All included subscription ids are invalid or have reached their rate limit"]
}
При отриманні такої відповіді ми обнуляємо ACTIVE для відповідних підписок.
Інтеграція з подіями та обробка помилок
Зміна статусу замовлення:
AddEventHandler('sale', 'OnSaleStatusOrder', function(string $statusId, \Bitrix\Sale\Order $order) {
$messages = [
'P' => ['Замовлення прийнято', 'Ваше замовлення #' . $order->getField('ACCOUNT_NUMBER') . ' прийнято в обробку'],
'D' => ['Замовлення відправлено', 'Ваше замовлення передано в доставку'],
'F' => ['Замовлення виконано', 'Дякуємо за покупку! Залиште відгук про товар'],
];
if (!isset($messages[$statusId])) return;
[$title, $body] = $messages[$statusId];
$userId = (int)$order->getUserId();
(new OneSignalService())->sendToUser($userId, $title, $body, [
'url' => '/personal/order/detail/' . $order->getField('ACCOUNT_NUMBER') . '/',
'order_id' => $order->getId(),
]);
});
Покинутий кошик — через агент кожні 60 хвилин. Персональні акції — масова відправка через сегменти OneSignal або за фільтрами користувачів.
При отриманні від OneSignal InvalidSubscriptionId — позначаємо запис як ACTIVE = N і не надсилаємо повторно. Очищення відбувається автоматично при кожній відправці.
Що входить в роботу
- Розгортання SDK на фронтенді (custom кнопка підписки).
- Створення таблиці підписок з ORM Бітрікс.
- Прив'язка підписок до користувачів (включаючи авторизацію).
- Налаштування відправки за подіями: замовлення, покинуті кошики, акції.
- Інтерфейс управління підписками в ОК.
- Документація та навчання ваших розробників.
- Підтримка 14 днів після здачі.
| Задача | Термін |
|---|---|
| Підключення SDK, збереження subscription_id | 2–3 дні |
| Таблиця підписок, прив'язка до користувачів | 1–2 дні |
| Відправка за подіями замовлень | 2–3 дні |
| Покинутий кошик, управління підпискою з ОК | 3–5 днів |
| Повний комплекс | 2–3 тижні |
Оцінимо ваш проект за один день. Зв'яжіться — підберемо оптимальне рішення під ключ. Гарантуємо стабільність та прозорість. Отримайте консультацію просто зараз — це безкоштовно. Замовте інтеграцію та почніть отримувати додатковий прибуток вже через тиждень.







