Files
portal/app/config/services.php
T

389 lines
28 KiB
PHP
Raw Normal View History

<?php
return [
/*
|--------------------------------------------------------------------------
| Third Party Services
|--------------------------------------------------------------------------
|
| This file is for storing the credentials for third party services such
| as Mailgun, Postmark, AWS and more. This file provides the de facto
| location for this type of information, allowing packages to have
| a conventional file to locate the various service credentials.
|
*/
// Канал робота-грузчика креативов в веб-кабинет Яндекса. Свой токен, отдельный
// от клиентских и от токена «Поиск → Портал». Пусто → канал закрыт.
'creative_robot' => [
'token' => env('CREATIVE_ROBOT_TOKEN', ''),
],
// Рекламная аудитория кандидатов (Яндекс.Аудитории). Токен — OAuth Яндекс ID,
// выдаётся разово на аккаунт, где живёт сегмент. Пусто → синхронизация не идёт,
// джоб пишет причину в last_error и молчит.
'yandex_audience' => [
'token' => env('YANDEX_AUDIENCE_TOKEN'),
'segment_name' => env('YANDEX_AUDIENCE_SEGMENT_NAME', 'Лидерра — кандидаты'),
],
// Яндекс.Директ (B1) — рекламный кошелёк. ПЕСОЧНИЦА по умолчанию (В8): боевой —
// сменой env на api.direct.yandex.com после одобрения заявки. Денежный рубильник
// enabled: пока выкл — реальные вызовы Директа не идут (как enabled у прогрева).
'yandex_direct' => [
'base_url' => env('YANDEX_DIRECT_BASE_URL', 'https://api-sandbox.direct.yandex.com'),
'token' => env('YANDEX_DIRECT_TOKEN'),
'enabled' => env('YANDEX_DIRECT_ENABLED', false),
// Регионы показа по умолчанию (вся Россия = 225).
'region_ids' => [225],
// Предохранитель: SpendLimit в Яндексе = яндекс-бюджет × множитель (бэкстоп
// от перерасхода, НЕ клиентская цена).
'spend_limit_guard_multiplier' => (float) env('YANDEX_DIRECT_SPEND_GUARD', 1.2),
],
// Рекламная аудитория кандидатов в ВК (Task 8, 21.07.2026). Программный доступ
// запрошен 19.07, ждём проверки реквизитов — до получения токена джоб пишет
// vk_status=no_access и не делает ни одного обращения к ВК.
'vk_ads' => [
'token' => env('VK_ADS_TOKEN', ''),
],
'postmark' => [
'key' => env('POSTMARK_API_KEY'),
],
'resend' => [
'key' => env('RESEND_API_KEY'),
],
'ses' => [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
'slack' => [
'notifications' => [
'bot_user_oauth_token' => env('SLACK_BOT_USER_OAUTH_TOKEN'),
'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'),
],
],
// Капча самозаписи (G1/SP1). driver=null → NullCaptchaVerifier (dev/test).
// Реальный Yandex SmartCaptcha подключается позже (SP3/ops).
'captcha' => [
'driver' => env('CAPTCHA_DRIVER', 'null'),
'fake_passes' => filter_var(env('CAPTCHA_FAKE_PASSES', true), FILTER_VALIDATE_BOOL),
'yandex_server_key' => env('YANDEX_SMARTCAPTCHA_SERVER_KEY'),
'yandex_validate_url' => env('YANDEX_SMARTCAPTCHA_VALIDATE_URL', 'https://smartcaptcha.cloud.yandex.ru/validate'),
],
'supplier' => [
'login' => env('SUPPLIER_LOGIN'),
'password' => env('SUPPLIER_PASSWORD'),
'portal_url' => env('SUPPLIER_PORTAL_URL', 'https://crm.bp-gr.ru'),
'alert_email' => env('SUPPLIER_ALERT_EMAIL', 'ops@liderra.ru'),
// Плитка балансов (28.06): у кабинета поставщика НЕ денежный баланс, а остаток
// НОМЕРОВ («Баланс ГЦК» в выпадашке). Деньги = номера × number_price_rub (20 ₽/шт,
// подтверждено владельцем 28.06). avg_lead_price_rub=0 → расход/день неизвестен.
'number_price_rub' => (float) env('SUPPLIER_NUMBER_PRICE_RUB', 20),
'avg_lead_price_rub' => (float) env('SUPPLIER_AVG_LEAD_PRICE_RUB', 0),
'red_floor_rub' => (int) env('SUPPLIER_RED_FLOOR_RUB', 5000),
'amber_floor_rub' => (int) env('SUPPLIER_AMBER_FLOOR_RUB', 15000),
'topup_url' => env('SUPPLIER_TOPUP_URL', env('SUPPLIER_PORTAL_URL', 'https://crm.bp-gr.ru')),
// Рубильник ежедневной чистки доп-каналов (B6/B8/…). По умолчанию ВКЛ.
// Аварийное отключение: SUPPLIER_PRUNE_EXTRA_CHANNELS_ENABLED=false + рестарт воркеров.
'prune_extra_channels' => filter_var(env('SUPPLIER_PRUNE_EXTRA_CHANNELS_ENABLED', true), FILTER_VALIDATE_BOOL),
],
// DaData phone cleaner — резолв региона лида по телефону (lead region resolution).
// Ключи → YC Lockbox на проде; на dev/staging — .env. enabled=false до раскатки.
'dadata' => [
'api_key' => env('DADATA_API_KEY'),
'secret' => env('DADATA_SECRET'),
'timeout_ms' => (int) env('DADATA_TIMEOUT_MS', 2000),
'retries' => (int) env('DADATA_RETRIES', 1),
'daily_cap_rub' => (int) env('DADATA_DAILY_CAP_RUB', 10000),
'call_cost_kopecks' => (int) env('DADATA_CALL_COST_KOPECKS', 60), // ≈0.60 ₽/вызов, откалибровать по тарифу
'enabled' => filter_var(env('LEAD_REGION_RESOLVER_ENABLED', false), FILTER_VALIDATE_BOOL),
'cache_ttl_days' => (int) env('PHONE_REGION_CACHE_TTL_DAYS', 30),
// G1/SP2: подтяжка организации по ИНН (suggestions findById/party). Тот же api_key
// (Token), secret не нужен. Default false → NullPartyLookup (dev/тесты не ходят в сеть).
'party_enabled' => filter_var(env('DADATA_PARTY_ENABLED', false), FILTER_VALIDATE_BOOL),
// Плитка балансов (28.06): чтение баланса профиля + пороги светофора + ссылка пополнения.
'balance_url' => env('DADATA_BALANCE_URL', 'https://dadata.ru/api/v2/profile/balance'),
'red_floor_rub' => (int) env('DADATA_RED_FLOOR_RUB', 500),
'amber_floor_rub' => (int) env('DADATA_AMBER_FLOOR_RUB', 2000),
'topup_url' => env('DADATA_TOPUP_URL', 'https://dadata.ru/profile/#billing'),
],
// СМС-центр (smsc.ru) — HLR-проверка номеров в Поиске клиентов (жив/несуществует).
// Баланс на плитке присмотра. Логин/пароль — те же, что у службы поиска.
'smsc' => [
'login' => env('SMSC_LOGIN'),
'password' => env('SMSC_PASSWORD'),
'balance_url' => env('SMSC_BALANCE_URL', 'https://smsc.ru/sys/balance.php'),
'red_floor_rub' => (int) env('SMSC_RED_FLOOR_RUB', 300),
'amber_floor_rub' => (int) env('SMSC_AMBER_FLOOR_RUB', 1000),
'topup_url' => env('SMSC_TOPUP_URL', 'https://smsc.ru/oplata/'),
],
// AITUNNEL (OpenAI-совместимый) для автоподбора: эмбеддинги (похожесть конкурента на
// профиль клиента) + LLM-классификатор «поставщик услуги или площадка-агрегатор?».
// Ключ — только в .env/окружении, НИКОГДА в гит. Пусто → движок отдаёт сырой список
// (без % и без авто-отсева площадок).
'aitunnel' => [
'key' => env('AITUNNEL_API_KEY'),
'base_url' => env('AITUNNEL_BASE_URL', 'https://api.aitunnel.ru/v1'),
'embed_model' => env('AITUNNEL_EMBED_MODEL', 'text-embedding-3-small'),
'chat_model' => env('AITUNNEL_CHAT_MODEL', 'gpt-4o-mini'),
// Модель отсева агрегаторов (вариант А — точнее, чтобы не терять живых конкурентов вроде
// «ГорЗайм»). Пусто → фолбэк на chat_model. Пример: AITUNNEL_AGGREGATOR_MODEL=gpt-4o.
'aggregator_model' => env('AITUNNEL_AGGREGATOR_MODEL'),
// ИИ-вызовы (анализ рубрик, эмбеддинги) — с ЗАПАСОМ: латентность модели плавает
// (один и тот же запрос то 8с, то 30-40с), а сбор асинхронный и клиент ждёт — режем
// медленный-но-настоящий ответ таймаутом ХУЖЕ, чем ждём. Потому большие таймауты.
'timeout_sec' => (int) env('AITUNNEL_TIMEOUT_SEC', 120),
// Батч отсева агрегаторов: список фирм режем на порции по aggregator_batch_size (иначе
// один запрос на ~100 фирм долгий и рискует не успеть) + отдельный долгий таймаут на порцию.
'aggregator_batch_size' => (int) env('AITUNNEL_AGGREGATOR_BATCH_SIZE', 40),
'aggregator_timeout_sec' => (int) env('AITUNNEL_AGGREGATOR_TIMEOUT_SEC', 240),
// Канал В — генератор имён (ZAFIKSIROVANO §0-БИС): одна рассуждающая модель sonar-reasoning-pro,
// в реальном прогоне ~30-70 с/вызов и плавает вверх; 2 прохода. Большой таймаут с запасом —
// лучше дождаться, чем прислать пусто (сбор асинхронный, клиент всё равно ждёт результат).
'research_model' => env('AITUNNEL_RESEARCH_MODEL', 'sonar-reasoning-pro'),
'research_timeout_sec' => (int) env('AITUNNEL_RESEARCH_TIMEOUT_SEC', 300),
// Плитка балансов (16.07): ручка баланса `/v1/aitunnel/balance` (найдена в доках
// aitunnel, отдаёт {"balance":N} в рублях) + пороги светофора + ссылка пополнения.
'balance_url' => env('AITUNNEL_BALANCE_URL', 'https://api.aitunnel.ru/v1/aitunnel/balance'),
'red_floor_rub' => (int) env('AITUNNEL_RED_FLOOR_RUB', 500),
'amber_floor_rub' => (int) env('AITUNNEL_AMBER_FLOOR_RUB', 2000),
'topup_url' => env('AITUNNEL_TOPUP_URL', 'https://aitunnel.ru/'),
],
// EXA — поиск САЙТА по имени для канала В (федералы): у федерала нет карточки в 2ГИС/Яндексе
// на регион, а нам нужен сайт (ZAFIKSIROVANO / §11.5). Ключ только в .env. Пусто → канал В без сайтов.
'exa' => [
'key' => env('EXA_API_KEY'),
'base_url' => env('EXA_BASE_URL', 'https://api.exa.ai'),
'timeout_sec' => (int) env('EXA_TIMEOUT_SEC', 90),
// Сколько запросов сайта-федерала слать ОДНОВРЕМЕННО (пул EXA). Лимит EXA — на КЛЮЧ,
// общий на всех клиентов, поэтому бережно; глобальный потолок между клиентами — очередь.
'concurrency' => (int) env('EXA_CONCURRENCY', 5),
// Прокси для EXA (Guzzle proxy option). EXA за Cloudflare режет российские IP, поэтому
// федеральный канал ходит наружу через зарубежный выход. Формат socks5h://host:port или
// http://host:port. Пусто → напрямую.
'proxy' => env('EXA_PROXY'),
// У EXA нет программной ручки баланса (биллинг только в кабинете) → плитка «жив/нет».
'balance_url' => env('EXA_BALANCE_URL'),
'red_floor_rub' => (int) env('EXA_RED_FLOOR_RUB', 500),
'amber_floor_rub' => (int) env('EXA_AMBER_FLOOR_RUB', 2000),
'topup_url' => env('EXA_TOPUP_URL', 'https://dashboard.exa.ai/'),
// Плитка балансов (16.07): нейтральный адрес для проверки живости SSH-тоннеля
// (запрос через exa.proxy на него). Не EXA — чтобы отделить «тоннель жив» от «EXA жив».
'tunnel_check_url' => env('EXA_TUNNEL_CHECK_URL', 'https://api.ipify.org'),
// «Пополнить» для EXA-тоннеля: за ним платный зарубежный VPN (клиент Happ). Провайдер
// подписки задаётся владельцем — если платишь не через Happ, переопредели EXA_TUNNEL_TOPUP_URL.
'tunnel_topup_url' => env('EXA_TUNNEL_TOPUP_URL', 'https://happ-proxy.com/'),
],
// Плитка балансов (28.06): Yandex Cloud биллинг (серверы + Managed PG ~18к/мес).
// OAuth владельца (interim) → IAM-токен → billing API. SA billing-reader создан,
// миграция на него — follow-up (только источник токена сменится). console_billing_url
// + billing_account_id строят прямую ссылку «Пополнить» в дашборде.
'yandex_cloud' => [
'oauth_token' => env('YC_OAUTH_TOKEN'),
'billing_account_id' => env('YC_BILLING_ACCOUNT_ID'),
'iam_url' => env('YC_IAM_URL', 'https://iam.api.cloud.yandex.net/iam/v1/tokens'),
'billing_url' => env('YC_BILLING_URL', 'https://billing.api.cloud.yandex.net/billing/v1/billingAccounts'),
'console_billing_url' => env('YC_CONSOLE_BILLING_URL', 'https://console.yandex.cloud/billing/accounts'),
'daily_spend_rub' => (int) env('YC_DAILY_SPEND_RUB', 600), // оценка ~18к/мес; откалибровать
'red_floor_rub' => (int) env('YC_RED_FLOOR_RUB', 1000),
'amber_floor_rub' => (int) env('YC_AMBER_FLOOR_RUB', 5000),
],
// G7-A: клиентская «Помощь».
'support' => [
'email' => env('SUPPORT_EMAIL', 'support@liderra.ru'),
],
// Яндекс.Метрика. Два счётчика:
// counter_id — кабинет (110494416), историческая аналитика кабинета.
// path_counter_id — «полный путь» (110476275), тот же счётчик, что на лендинге
// liderra.ru. Грузится на входе/регистрации/публичных страницах
// и в кабинете, чтобы Вебвизор видел цепочку от клика по рекламе
// до действий в кабинете одним человеком, а не двумя.
// Пусто = соответствующий счётчик не грузится.
// Админка и портал продаж Метрику не грузят вообще — см. router/index.ts.
'metrika' => [
'counter_id' => env('METRIKA_COUNTER_ID'),
'path_counter_id' => env('METRIKA_PATH_COUNTER_ID'),
],
// ИИ-бот техподдержки в СВОЁМ окошке чата на сайте (спека 2026-07-13-own-chat-widget-design;
// до 07.07.2026 жил внутри чата Jivo — эта интеграция закрыта, см. docs/CHANGELOG).
// tours_enabled — «экскурсии»: ссылка «Показать на портале» в ответе бота. Раньше вели
// не по теме (совпало одно случайное слово) и были выключены. 13.07.2026 правило
// переписано: экскурсия только на ВОПРОС, слово которого попало в заголовок статьи
// или её синонимы, и только клиенту ИЗ КАБИНЕТА — гостю с лендинга там нечего смотреть.
'bot' => [
'tours_enabled' => env('BOT_TOURS_ENABLED', true),
// Показ примера на ЛЕНДИНГЕ для гостя (не вошедшего клиента): раздел «Как это
// работает» с якорями по темам (задача 2026-07-13). Гость не может открыть
// экскурсию внутри кабинета — ему нечего там показывать, но разбор на лендинге
// доступен без входа. Какие статьи имеют разбор — config/guides.php (связь по слагу).
'landing_url' => env('LANDING_URL', 'https://liderra.ru'),
// Мозг бота: yandex (данные не покидают РФ) | aitunnel (зарубежные модели через
// российский шлюз; ПДн вырезаются PersonalDataMask до отправки).
'llm' => env('BOT_LLM', 'yandex'),
'aitunnel_model' => env('BOT_AITUNNEL_MODEL', 'gpt-4o-mini'),
'timeout_seconds' => env('BOT_LLM_TIMEOUT', 10),
// Счётчики чата должны считать АТОМАРНО: файловый кэш под параллельной нагрузкой
// теряет до 74% прибавок (проверено), и защита от накрутки счёта становится дырявой.
// Redis (INCR) атомарен. В тестах — 'array' (один процесс, гонки не бывает).
'limiter_store' => env('BOT_LIMITER_STORE', 'redis'),
],
// YandexGPT Lite (Yandex Cloud Foundation Models) — мозг бота (решение 8 протокола).
'yandexgpt' => [
'api_key' => env('YANDEX_GPT_API_KEY', ''),
'folder_id' => env('YANDEX_GPT_FOLDER_ID', ''),
'model' => env('YANDEX_GPT_MODEL', 'yandexgpt-lite/latest'),
'endpoint' => env('YANDEX_GPT_ENDPOINT', 'https://llm.api.cloud.yandex.net/foundationModels/v1/completion'),
'timeout_seconds' => 8,
],
// Учёт посетителей: офлайн-базы гео (DB-IP Lite). Файлов нет → город не определяется,
// учёт продолжает работать. Обновление баз — раз в месяц, вручную.
'geoip' => [
'city_db' => env('GEOIP_CITY_DB', storage_path('geoip/dbip-city-lite.mmdb')),
'asn_db' => env('GEOIP_ASN_DB', storage_path('geoip/dbip-asn-lite.mmdb')),
],
// Платёжный шлюз ЮKassa. webhook_ip_allowlist — CSV IP/CIDR из env (defense-in-depth
// на /api/webhook/payment). Пусто → fail-open (поток не ломается). На проде заполнить
// опубликованными ЮKassa подсетями: 185.71.76.0/27,185.71.77.0/27,77.75.153.0/25,
// 77.75.154.128/25,77.75.156.11,77.75.156.35,2a02:5180::/32.
'yookassa' => [
'shop_id' => env('YOOKASSA_SHOP_ID'),
'secret_key' => env('YOOKASSA_SECRET_KEY'),
'api_url' => env('YOOKASSA_API_URL', 'https://api.yookassa.ru/v3'),
'webhook_ip_allowlist' => array_values(array_filter(array_map(
'trim',
explode(',', (string) env('YOOKASSA_WEBHOOK_IPS', '')),
))),
],
// Автоподбор шаг 2: сервис обхода антибота справочников (2ГИС/Яндекс) — xfetch.ru.
// Ключ — ТОЛЬКО в .env (gitignored), в код/гит не попадает. Без ключа загрузчик
// молча возвращает пусто (поток не падает).
'xfetch' => [
'key' => env('XFETCH_API_KEY'),
// Несколько ключей через запятую (round-robin) — суммарная параллельность = ключи × concurrency.
// Пусто → берётся одиночный XFETCH_API_KEY. Ключи — ТОЛЬКО в .env, в код/гит не попадают.
'keys' => array_values(array_filter(
array_map('trim', explode(',', (string) env('XFETCH_API_KEYS', ''))),
static fn (string $v): bool => $v !== '',
)),
'endpoint' => env('XFETCH_ENDPOINT', 'https://xf4.ru/fetch'),
// Параллельность НА КЛЮЧ. Эмпирический предел xf4.ru — ~3 одновременных на ключ
// (выше идут 429 Too Many Requests; замер 01.07.2026). Меняется без деплоя через .env.
'concurrency' => (int) env('XFETCH_CONCURRENCY', 3),
'balance_url' => env('XFETCH_BALANCE_URL'),
'red_floor_rub' => (int) env('XFETCH_RED_FLOOR_RUB', 300),
'amber_floor_rub' => (int) env('XFETCH_AMBER_FLOOR_RUB', 1000),
'topup_url' => env('XFETCH_TOPUP_URL', 'https://xf4.ru/'),
],
// Автоподбор self-render: свой рендер-сервис на виртуалке (замена xf4, за флагом autopodbor.self_render).
// Секрет портал↔виртуалка и адрес — ТОЛЬКО в .env. Без них SelfRenderClient молча пусто (деградация).
'self_render' => [
'endpoint' => env('SELF_RENDER_ENDPOINT', ''),
'key' => env('SELF_RENDER_KEY', ''),
// Параллельность запросов к виртуалке (браузерная параллельность — внутри виртуалки, §12).
'concurrency' => (int) env('SELF_RENDER_CONCURRENCY', 8),
// Плитка балансов (16.07): URL health-check виртуалки. Пусто → пингуем endpoint.
'health_url' => env('SELF_RENDER_HEALTH_URL'),
],
// Плитка балансов (17.07): прокси автоподбора (Proxy.Market, мобильный Tele2). «Баланс» = срок
// действия. Живость проверяет виртуалка-рендер (у неё логин/пароль прокси) через /proxy-check.
// Ключ виртуалки берём из services.self_render.key. Срок — руками в .env при продлении.
'proxy_market' => [
'check_url' => env('PROXY_MARKET_CHECK_URL'), // https://51-250-1-97.sslip.io/proxy-check
'expires_at' => env('PROXY_MARKET_EXPIRES_AT'), // 2026-08-04
'amber_days' => (int) env('PROXY_MARKET_AMBER_DAYS', 7),
'topup_url' => env('PROXY_MARKET_TOPUP_URL', 'https://proxy.market/'),
],
// Куда слать алерты о недоступности/исходе денег внешних сервисов.
'monitoring' => [
'alert_email' => env('MONITORING_ALERT_EMAIL', env('SUPPLIER_ALERT_EMAIL', 'ops@liderra.ru')),
],
// Баланс Яндекс 360 (почта) — РУЧНОЙ ввод (см. Yandex360BalanceProvider). Пороги
// светофора — как у dadata; topup_url — страница «Оплата и тариф» в кабинете Яндекс 360.
'yandex360' => [
'red_floor_rub' => (int) env('YANDEX360_RED_FLOOR_RUB', 500),
'amber_floor_rub' => (int) env('YANDEX360_AMBER_FLOOR_RUB', 2000),
'topup_url' => env('YANDEX360_TOPUP_URL', 'https://admin.yandex.ru/products'),
],
// Плитка балансов (16.07): служба поиска клиентов отдела продаж (/opt/sales-finder, :8200
// за nginx /finder/). Только живость (2ГИС-пробив; денежного баланса нет). Пусто → не проверяем.
// Дефолт ПУСТОЙ намеренно: реальный URL задаётся только в прод-.env (SALES_FINDER_BASE_URL),
// иначе dev/тесты стучались бы в боевой /finder/. Прод-адрес — https://lk.liderra.ru/finder/.
'sales_finder' => [
'base_url' => env('SALES_FINDER_BASE_URL', ''),
'health_path' => env('SALES_FINDER_HEALTH_PATH', ''),
],
// Плитка балансов (16.07): Keyso (keys.so) — разведка рекламы, зависимость службы
// «Поиск клиентов» (/opt/sales-finder держит токен). Портал только проверяет живость
// хоста (пинг api.keys.so, <500 = жив), денег/токена не нужно.
'keyso' => [
'base_url' => env('KEYSO_BASE_URL', 'https://api.keys.so'),
'topup_url' => env('KEYSO_TOPUP_URL', 'https://www.keys.so/ru/tarif'),
],
'sms' => [
// Песочница: провайдеры не вызываются, отправка только помечается в журнале.
'sandbox' => (bool) env('SMS_SANDBOX', true),
// Резерв канала: точный оператор отказал → попробовать универсала.
// По умолчанию ВЫКЛ (решение владельца 23.07.2026) — включить одной строкой.
'failover_to_universal' => filter_var(env('SMS_FAILOVER_TO_UNIVERSAL', false), FILTER_VALIDATE_BOOL),
// Канал МТС = «МТС Маркетолог, Рассылки по своей базе PRO» (омни-адаптер
// api.mts.ru). naming — согласованное имя отправителя (MTSM_Test/liderra.ru);
// connect_to — мост (host:port SSH-туннеля, напр. 127.0.0.1:18443), пусто → напрямую.
'mts' => [
'token' => env('SMS_MTS_TOKEN'),
'enabled' => (bool) env('SMS_MTS_ENABLED', false),
'base_url' => env('SMS_MTS_BASE_URL', 'https://api.mts.ru/client-omni-adapter_production/1.0.2'),
'naming' => env('SMS_MTS_NAMING', ''),
'connect_to' => env('SMS_MTS_CONNECT_TO', ''),
],
'beeline' => [
'token' => env('SMS_BEELINE_TOKEN'),
'enabled' => (bool) env('SMS_BEELINE_ENABLED', false),
],
// Декларативный реестр живых каналов. Новый оператор = запись здесь
// + ключ в .env + (если API другой) файл-провайдер + арм в makeSmsProvider().
// Цены — в копейках за сегмент, ключ '*' = единая цена канала; меняются
// через .env без выката.
'providers' => [
'smsc' => [
'enabled' => (bool) env('SMS_SMSC_ENABLED', false),
'serves' => ['*'],
'price_kopecks' => ['*' => (int) env('SMS_SMSC_PRICE_KOP', 0)],
],
'mts' => [
'enabled' => (bool) env('SMS_MTS_ENABLED', false),
'serves' => ['mts'],
'price_kopecks' => ['*' => (int) env('SMS_MTS_PRICE_KOP', 0)],
],
],
],
];