Dilshat Rakhimov
Май 2026 · 14 мин чтения

В банковском маркетинге есть классическая слепая зона: рекламная система видит клик, лендинг, форму или звонок, а деньги появляются позже и в другом месте - в отделении, call center, CRM, АБС или DWH. Для ecommerce это выглядело бы абсурдно: покупать трафик по AddToCart, но никогда не отправлять обратно Purchase. В банках это часто считается нормой.

Особенно заметно это в кредитах, картах, депозитах и региональных продуктах. Пользователь может увидеть рекламу в Google, Meta или TikTok, открыть лендинг, изучить условия, получить SMS, закрыть сайт и через два дня прийти в отделение. Менеджер оформит заявку, банк выдаст кредит или откроет депозит, finance увидит маржу, но рекламная платформа увидит только слабый lead или вообще bounce.

Проблема не в том, что offline нельзя измерить. Проблема в том, что банк часто не строит нормальный O2O-контракт между digital intent и branch outcome. Нужны не "загрузки продаж раз в месяц", а операционная система: click capture, lead bridge, branch handoff, offline event ledger, value model, postback service и QA.

O2O Banking Cover

Главная мысль

Это не reach campaign и не Brand Lift exercise. Если задача звучит "привести людей в отделение и довести до покупки", кампания должна работать как O2O demand capture: реклама создает продуктовый intent, digital-flow выдает человеку понятный reason-to-visit, отделение подтверждает визит, а DWH возвращает платформам validated outcome.

Визит в отделение сам по себе не является хорошей финальной optimization goal. Это контролируемый mid-funnel signal. Для банковского O2O важны подтвержденные бизнес-события:

  1. Клиент пришел в отделение после digital touch.
  2. Менеджер начал консультацию по нужному продукту.
  3. Заявка была создана и прошла проверку.
  4. Продукт был выдан, активирован или профинансирован.
  5. Банк посчитал ожидаемую ценность этого события.
  6. Рекламная система получила consent-safe offline conversion с value.

Если остановиться на шаге "пользователь оставил телефон", алгоритм будет искать дешевые телефоны. Если остановиться на шаге "посетил отделение", алгоритм будет искать людей, которые ходят в отделения. Если отправлять только факт выдачи без корректной связки с кликом, большая часть офлайн-ценности останется unattributed. Поэтому визит нужен как управляемый bridge metric, но покупки и маржинальная ценность должны стать тем сигналом, по которому система учится распределять бюджет.

Почему старая логика ломается

Обычная digital-воронка банка выглядит так:

ad click -> landing page -> lead form -> CRM -> manager call -> branch visit -> product issue

Но аналитика часто видит только первую половину:

ad click -> landing page -> lead form

Дальше начинается организационный разрыв. CRM живет отдельно, branch managers работают в своей системе, кредитный конвейер живет в АБС, DWH обновляется батчами, а рекламный кабинет получает максимум Lead. В результате маркетинг оптимизируется на CPL, хотя бизнесу нужен issued loan, funded deposit или activated card.

В банковском O2O нужно принять жесткое правило:

Digital lead - это не доход. CRM status - это не доход. Визит в отделение - это не доход. Доход начинается там, где банк может подтвердить финансовое событие и его ожидаемую contribution value.

Архитектура: от клика до offline value

Хорошая O2O-система строится не вокруг одного пикселя, а вокруг event ledger. Пиксель фиксирует online intent. Ledger связывает intent, branch activity и финансовый outcome.

Офлайн Архитектура

Минимальный стек:

СлойЧто делаетКлючевой риск
Click captureСохраняет gclid, gbraid, wbraid, fbclid, _fbc, _fbp, UTM, offer id, landing URLПараметры теряются до формы или appointment
Lead bridgeСоздает lead_id, получает phone/email с consent, связывает с click contextНельзя потом сматчить CRM outcome
Branch handoffПередает lead_id в SMS, QR, appointment, queue token или manager workspaceМенеджер создает новую заявку без исходного lead id
Branch CRM / OCRMФиксирует визит, консультацию, заявку, approval, отказ, выдачуСтатусы не нормализованы и не имеют event time
DWH value modelСчитает expected value по продуктуВ value попадает principal вместо маржи
Postback serviceОтправляет validated offline events в Google Ads, Meta CAPI и BIДубли, неверное время события, утечка PII

Click capture: что нужно сохранить в первый момент

Когда пользователь приходит с рекламы, банк должен создать click_context до того, как человек ушел в форму, приложение, звонок или отделение.

{
"click_context_id": "clk_01HX...",
"created_at": "2026-05-04T10:32:00Z",
"landing_url": "https://bank.kz/loans/cash",
"utm_source": "google",
"utm_medium": "cpc",
"utm_campaign": "cash_loan_shymkent",
"utm_content": "rate_hero",
"gclid": "EAIaIQob...",
"gbraid": null,
"fbclid": null,
"fbc": null,
"fbp": null,
"product_type": "loan",
"offer_id": "cash_loan_2026_q2",
"region": "shymkent",
"consent_state": "marketing_analytics_allowed"
}

Этот объект не обязан сразу содержать телефон или ИИН. Он должен зафиксировать рекламный контекст и destination. Потом, когда пользователь оставит телефон, оформит appointment или покажет SMS в отделении, этот click context будет связан с lead_id.

Для Google Ads есть два основных пути. Старый надежный путь - сохранять GCLID и потом импортировать offline conversion с этим GCLID. Более современный путь - Enhanced Conversions for Leads, где first-party user-provided data, например email или phone, нормализуется, хешируется и помогает улучшить match и bidding. Google прямо описывает offline conversion imports как способ измерить действия, которые происходят после рекламного клика уже в offline world.

Для Meta старый подход с отдельной "offline conversions" логикой постепенно ушел в сторону Conversions API и datasets. Практический подход сейчас: отправлять server/offline события в Meta CAPI с корректным source/action context, event time, event id, match parameters и value. Не нужно пытаться сделать branch sale "web purchase"; источник должен честно описывать, где произошло событие.

Lead bridge: как склеить digital и отделение

Пользователь не должен вводить чувствительные данные "просто для аналитики". Ему нужен полезный повод:

  1. Получить предварительный расчет кредита.
  2. Забронировать время в отделении.
  3. Получить QR или SMS-код для менеджера.
  4. Проверить eligibility для продукта.
  5. Получить персональное предложение в приложении.
  6. Сохранить условия депозита или ставки.

В этот момент создается lead_id:

{
"lead_id": "lead_01HX...",
"click_context_id": "clk_01HX...",
"product_type": "loan",
"phone_sha256": "f2a4...",
"email_sha256": null,
"iin_internal_hash": "vault_only_9b1...",
"branch_id": "shymkent_abay_12",
"handoff_method": "sms_code",
"created_at": "2026-05-04T10:35:00Z"
}

Important: ИИН может быть сильным внутренним ключом для банковского matching, но это не значит, что его нужно отправлять в рекламные платформы. Даже хешированный национальный идентификатор остается чувствительным с точки зрения комплаенса, банковской тайны, платформенных правил и локального законодательства. В рекламные системы лучше отправлять только те user identifiers, которые разрешены договором, consent flow и политиками платформы: обычно phone/email в normalized hashed form, плюс click ids там, где они были сохранены.

Branch handoff: как не потерять lead_id в отделении

Самая частая поломка O2O происходит не в API, а в отделении. Пользователь пришел, менеджер создал заявку вручную, но не подтянул original lead. Все: рекламная связка потеряна.

Нужен branch handoff, который менеджер реально использует:

Handoff methodКак работаетПлюсыРиск
SMS promo codeПользователь показывает код менеджеруПросто объяснить клиентуМенеджер может забыть ввести код
QR appointmentВ SMS или приложении есть QR для стойки/менеджераБыстро связывает визит с lead_idНужна инфраструктура в отделении
Queue tokenПользователь берет очередь по продукту из digital flowХорошо для branch opsТребует интеграции с queue system
Manager workspaceCRM показывает online intent при поиске телефонаЛучший вариант для продажНужна доработка CRM/OCRM
Call center pre-qualificationОператор создает appointment и lead_idКонтроль качества вышеДороже и медленнее

Минимальный рабочий вариант: когда менеджер ищет клиента по телефону, CRM должна показывать active digital leads за последние N дней:

Client found by phone:
active online intent:
lead_id: lead_01HX...
product: cash loan
campaign: cash_loan_shymkent
offer: rate_hero
expires: 2026-05-11
Manager action:
attach lead to branch application

Если менеджер не видит digital intent в привычном рабочем месте, O2O-атрибуция будет зависеть от дисциплины людей. Это не система.

Offline event ledger: CRM status недостаточно

CRM status часто создан для менеджеров, а не для bidding. Там могут быть статусы вроде "в работе", "перезвонить", "пакет документов", "отправлено", "ожидание". Для рекламной оптимизации нужен отдельный event ledger с нормализованными событиями.

Offline Event Ledger

Пример event taxonomy:

EventКогда отправлять в ledgerИспользование
branch_visit_matchedКлиент пришел, lead_id найден или сматчен по разрешенному ключуДиагностика O2O, не финальная цель
branch_consultation_startedМенеджер начал консультацию по продуктуQuality signal
offline_application_submittedВ АБС создана заявкаMid-funnel conversion
offline_application_approvedЗаявка одобренаStrong quality signal
offline_loan_issuedДеньги выданы / договор активенPrimary value event
offline_deposit_fundedДепозит открыт и пополненPrimary value event
offline_card_activatedКарта выпущена и активированаPrimary или secondary — зависит от экономики продукта
offline_reversalОтмена, refund, fraud, раннее закрытиеQA и корректировка value

Финальное событие должно выглядеть как продуктовый факт, а не как CRM строка:

{
"event_id": "evt_loan_issued_01HX...",
"event_name": "offline_loan_issued",
"event_time": "2026-05-07T14:18:00+05:00",
"lead_id": "lead_01HX...",
"click_context_id": "clk_01HX...",
"product_type": "loan",
"product_id": "cash_loan",
"branch_id": "shymkent_abay_12",
"value": 18500,
"currency": "KZT",
"value_model": "risk_adjusted_expected_margin_90d",
"dedupe_key": "loan_contract_hash_01HX",
"source_system": "abs",
"status": "validated"
}

Обратите внимание на event_time. В offline import нужно передавать время, когда бизнес-событие произошло, а не время, когда ночной batch job отправил файл в рекламный кабинет. Иначе lag analysis и attribution будут ломаться.

Value model: что отправлять как conversion value

Ошибка банковского O2O - отправлять в value сумму кредита или депозитный баланс. Это красиво выглядит в ROAS, но технически и экономически неверно.

ПродуктНельзя отправлять как valueПравильнее отправлять
КредитPrincipal / сумма кредитаExpected net margin - expected loss - subsidy cost
ДепозитПолный баланс депозитаNet interest margin over window × retention probability - bonus
КартаЛимит картыExpected interchange + fee income - cashback/acquisition cost
СтраховкаPremium целиком, если банк агентCommission / gross margin
Перевод / платеж в отделенииTransaction amountFee, commission, activation value

Формула для кредита:

offline_loan_value =
disbursed_amount
* expected_net_margin_rate
* repayment_quality_probability
- expected_credit_loss
- promo_cost
- servicing_cost

Формула для депозита:

offline_deposit_value =
funded_balance
* net_interest_margin_90d
* retention_probability_90d
- acquisition_bonus

На первом этапе value model может быть приближенной. Например, по продукту и risk band. Но она должна быть сравнимой между кампаниями и не должна превращать principal в fake revenue.

Отправка offline-событий обратно в рекламу

Когда финансовое событие подтверждено, postback service решает, куда и как отправить событие.

Offline Postback Loop

Для Google Ads:

  1. Если есть gclid, используйте offline conversion import by click id.
  2. Если настроен Enhanced Conversions for Leads, отправляйте normalized hashed first-party identifiers, которые были собраны на lead form с нужным consent.
  3. Не отправляйте только "выдачи из Google". Google рекомендует импортировать все доступные offline events, даже если часть не пришла из Google Ads: это помогает диагностике и корректной отчетности.
  4. Используйте order_id или dedupe key, чтобы не загрузить одну выдачу дважды.
  5. Смотрите diagnostics и partial failures. Успешный API response не всегда значит, что conversion атрибутировалась к клику.

Для Meta:

  1. Отправляйте события через Conversions API в нужный dataset/pixel setup.
  2. Используйте event_id для дедупликации и traceability.
  3. Передавайте hashed user data только в разрешенном формате и только с допустимым consent.
  4. Для branch outcomes не притворяйтесь, что это website event. Указывайте source/action context, соответствующий offline/physical/CRM происхождению.
  5. Следите за Event Match Quality, deduplication и временем события.

Для TikTok, Snap и других платформ логика похожа: не выгружать банковскую запись, а отправлять нормализованный conversion event с event time, value, currency, hashed match keys и dedupe id.

Не reach, а O2O demand capture

Если бизнес говорит "нам нужны визиты в отделение и покупки", не надо переводить это в медийную логику "давайте купим охват рядом с филиалами". Охват может быть верхним слоем, но операционная цель другая: привести человека с понятным продуктовым намерением в конкретный канал обслуживания и вернуть в рекламную систему outcome.

Практический campaign contract выглядит так:

УровеньЧто оптимизируемЧто не считаем успехом
Product intentКлик на продукт, расчет, eligibility, appointment, callbackПросто reach или video views
Visit bridgeSMS/QR/appointment/route click, который несет lead_idАнонимный footfall без product context
Branch outcomebranch_visit_matched, consultation, application submittedЛюбой визит в отделение
Purchase/valueoffline_loan_issued, offline_deposit_funded, offline_card_activated с valueCRM status без финансового факта

На Google Ads стороне можно использовать store visits и store sales там, где аккаунт и география проходят eligibility, но это не заменяет собственный event ledger банка. Store visit помогает понять footfall после ad interactions, а store sales/offline imports помогают вернуть платформе продажи. Для кредитов и депозитов лучше строить собственную связку lead_id -> branch application -> validated product event, потому что платформенная store visit модель не знает, был ли человек в отделении из-за кредита, депозита, кассовой операции или сервисного вопроса.

На Meta и других paid social платформах логика такая же: reach campaign может создать знание о продукте, но чтобы довести человека до отделения и продажи, нужен lead/message/conversion flow, server/offline events, dedupe, value и match keys. Иначе алгоритм будет оптимизировать дешевое внимание, а не людей, которые дошли до отделения и купили продукт.

Что делать с визитами в отделения

Визиты полезны, но их нельзя путать с продажами.

branch_visit_matched хорошо использовать для:

  1. Оценки качества креативов и офферов.
  2. Географической оптимизации по регионам и филиалам.
  3. Диагностики branch handoff.
  4. Создания аудиторий re-engagement.
  5. Понимания lag между click и visit.

Но если вы сделаете visit primary conversion слишком рано, алгоритм начнет искать foot traffic, а не прибыль. Для кредитов, депозитов и карт финальная цель должна быть ближе к validated product outcome.

Исключение: если у банка пока нет надежной покупки в feedback loop, визит можно временно сделать primary или account-default goal для кампаний, которые действительно продают через отделения. Но тогда должны быть guardrails: продуктовый creative, branch capacity, региональная eligibility, исключение сервисных визитов и регулярная сверка с downstream approvals/issuance. Как только появляется достаточный объем validated purchases, visit возвращается в secondary/diagnostic layer.

Правильный maturity path:

Phase 1: optimize to qualified online lead
Phase 2: import branch_visit_matched as secondary or temporary primary bridge
Phase 3: import offline_application_approved
Phase 4: make offline_loan_issued / deposit_funded primary value event
Phase 5: move bidding toward value once volume and match quality are stable

Кампании и география

O2O-кампании нельзя управлять как обычным nationwide leadgen, если продукт закрывается в отделениях. Важны пропускная способность отделений, экономика региона и eligibility продукта.

Рекомендованная структура:

CampaignЦельBidding
Regional demand captureДешевый qualified intent по регионамtCPA / Max conversions
Branch appointment / callbackДовести до визита или консультацииtCPA на qualified appointment
Branch visit bridgeДоказать, что digital intent доходит до отделенияStore visits / imported branch_visit_matched, обычно secondary
Offline loan valueВыданные кредиты с risk-adjusted valueMax conversion value / tROAS после объема
Deposit funded valueFunded deposits по категорииtROAS только при достаточном volume
Re-engagementВернуть matched leads без финального outcomeAudiences + product-specific creative

Охватные кампании здесь не являются основным механизмом. Их можно держать отдельно для product education, new branch opening или regional launch, но не смешивать с O2O acquisition reporting. Если в одной кампании одновременно стоят reach KPI, branch visit KPI и offline purchase KPI, команда быстро потеряет причинность: медиа будет защищать CPM, продажи - выдачи, а алгоритм будет получать противоречивые goals.

Не делите кампании по каждому отделению, если у вас нет объема. Лучше передавать branch_id, region, city, product_type в BI и offline ledger, а campaign split делать только там, где отличается экономика, пропускная способность или юридические требования к сообщению. Для отделений с ограниченной пропускной способностью используйте budget caps, location targeting, расписания показов и appointment availability, иначе кампания приведет людей туда, где их не смогут обработать.

QA: без этого O2O развалится

Технический QA должен быть жестким.

  1. Click IDs сохраняются до lead creation.
  2. lead_id не меняется между лендингом, SMS, CRM и branch application.
  3. Manager workflow реально подтягивает online intent.
  4. Все offline events имеют event_time, event_id, dedupe_key, source_system.
  5. Одна выдача не отправляется дважды в Google/Meta.
  6. Refund, reversal и досрочное расторжение отражаются в BI и в корректировке value.
  7. value не равен телу кредита, остатку на депозите или сумме договора — если только это действительно выручка.
  8. Телефон и email нормализованы до хеширования: trim, нижний регистр где применимо, E.164 для телефона.
  9. ИИН, номер счета, номер договора, заметки менеджера и любые сырые PII не покидают системы под контролем банка.
  10. Диагностика импорта в Google Ads проверяется еженедельно.
  11. Meta Event Match Quality и дедупликация проверяются еженедельно.
  12. Лаг конверсии виден в разрезе продукта и региона.
  13. Объем offline-конверсий достаточен, прежде чем переводить основную стратегию на tROAS.

SQL-проверки, которые нужны в DWH

Матчинг online lead to offline sale:

select
l.lead_id,
l.click_context_id,
l.product_type,
l.created_at as lead_created_at,
b.branch_id,
b.application_id,
b.status,
b.status_time,
v.expected_value_kzt
from marketing.leads l
join branch.applications b
on b.lead_id = l.lead_id
join finance.product_value_model v
on v.application_id = b.application_id
where b.status in ('issued', 'funded', 'activated')
and b.status_time >= l.created_at
and b.status_time < l.created_at + interval '30 days';

Поиск дублей:

select
dedupe_key,
count(*) as events
from marketing.offline_conversion_events
where event_name in ('offline_loan_issued', 'offline_deposit_funded')
group by 1
having count(*) > 1;

Отчет по лагу:

select
product_type,
region,
percentile_cont(0.5) within group (
order by extract(epoch from (event_time - lead_created_at)) / 86400
) as median_days_to_outcome
from marketing.offline_conversion_events
group by 1, 2;

Антипаттерны

  1. "Давайте просто выгрузим все кредиты в Meta". Без click context, consent, dedupe и value model это не attribution, а data dump.
  2. "ИИН захеширован, значит можно отправлять куда угодно". Нет. Хеширование не отменяет чувствительность данных и ограничения политик платформ.
  3. "Визит в отделение равен продаже". Нет. Для части продуктов это может быть просто интерес или сервисный визит.
  4. "Менеджер сам введет промокод". Если это не встроено в workflow, не введет.
  5. "Один импорт раз в месяц достаточно". Для bidding это слишком медленно. Нужен стабильный cadence: daily или near-real-time там, где возможно.
  6. "Все offline events делаем primary". Primary goals должны быть только те события, по которым вы хотите оптимизацию.
  7. "Value = сумма кредита". Это сломает tROAS.

Что делать за 30 дней

Неделя 1: аудит маршрутов.

Соберите все lead sources, landing pages, app forms, call center flows, SMS-шаблоны и процессы в отделениях. Найдите, где теряется gclid, fbclid, UTM, телефон и lead_id.

Неделя 2: event contract.

Определите canonical events: online_intent_captured, lead_created, branch_visit_matched, offline_application_submitted, offline_application_approved, offline_loan_issued, offline_deposit_funded, offline_reversal.

Неделя 3: branch handoff.

Встройте lead_id в SMS, QR, запись на прием или рабочее место менеджера. Менеджер не должен вручную угадывать источник клиента.

Неделя 4: postback service.

Начните с daily batch в Google Ads и Meta CAPI. Смотрите diagnostics, match rate, duplicate rate, lag и распределение conversion value. Только после этого переводите финальные offline value events в primary optimization.

Итог

O2O banking attribution - это не отчет "сколько людей пришли в отделение". Это система, которая связывает paid intent с банковским outcome. В ней есть click context, lead bridge, branch handoff, offline event ledger, value model и постбэки в платформы. Когда эта система работает, маркетинг перестает спорить с продажами о CPL и начинает оптимизировать бюджет по тому, что банк реально зарабатывает: выданные кредиты, пополненные депозиты, активированные карты и подтвержденная маржа.

Источники

Частые вопросы

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

Потому что алгоритм учится находить людей, которые заполняют формы, а не людей, которые берут кредиты. Финальное событие происходит офлайн, платформа его не видит и продолжает покупать самый дешевый лид. Пока исход из отделения не вернется как конверсия, биддинг не улучшится.

Достаточно ли статуса в CRM, чтобы отправить его как offline-конверсию?

Нет. У статуса в CRM нет ни `event_time`, ни `event_id`, ни dedupe-ключа, ни source system — его нельзя дедуплицировать и нельзя привязать к клику. Нужен отдельный offline event ledger, где каждый подтвержденный финансовый исход — это строка с этими полями.

Что банку отправлять как conversion value по кредиту?

Не тело кредита. Отправляйте ожидаемую маржу за выбранное окно с поправкой на risk band и вероятность удержания, минус бонусы за привлечение. Модель может быть приближенной, но она должна быть сравнимой между кампаниями, а refund, reversal и досрочное закрытие должны возвращаться как корректировки.