Разработка B2B SaaS CRM: кратко о главном
🎯 О чём этот конспект: Пошаговое руководство по созданию полноценного B2B SaaS-продукта (Garden CRM для команд от 1 до 50 человек) с нуля. Разбирается связка Claude Code для генерации full-stack логики, Supabase в качестве базы данных и аутентификации, а также платежной платформы Whop для обработки 7-дневных триалов, подписок ($49/мес и $249/мес), вебхуков и гейтинга платных функций.
👤 Кому будет полезно: Вайбкодерам, инди-хакерам и разработчикам, которые хотят быстро запустить продаваемый SaaS-продукт с готовой платежной инфраструктурой, разграничением доступа и защитой от абуза триалов.
✨ Что получите: Готовую архитектурную схему и пошаговый процесс развертывания B2B CRM с канбан-пайплайном, импортом CSV с дедупликацией, сквозным биллингом Whop и экранами восстановления отмененных подписок.
1. Архитектура B2B SaaS CRM: выбор ниши и продуктовые спецификации
Контекст: Создание узконишевой B2B CRM для малых команд (1–50 человек) решает главную проблему энтерпрайз-решений: перегруженность сотнями лишних настроек. Небольшому отделу продаж нужен понятный канбан-пайплайн сделок, список задач, база контактов и быстрый импорт лидов без сложного онбординга. CRM — идеальный тип SaaS для запуска: клиенты пользуются системой каждый рабочий день, что гарантирует высокое удержание (retention). Кроме того, на CRM легко отработать все граничные случаи биллинга: триалы, апгрейды, отказы карт, отмены и блокировку доступа.
Тайминг: , ,
Выгода: Фокус на четком B2B-сегменте позволяет запустить продукт с чеком $49–$249/мес за один вечер без необходимости вручную писать сложный биллинг с нуля.
Как применить:
- Шаг 1: Фиксация функциональных требований (PRD) — Определите ключевые модули: Kanban-доска сделок (этапы: New Lead → Contacted → Demo → Proposal → Won), управление компаниями и контактами, задачи (To-Do), дедупликация при импорте CSV и дашборд аналитики.
- Шаг 2: Разделение тарифных планов и лимитов — Сформируйте два четких тарифа:
- Garden Pro ($49/мес с 7-дневным триалом): 1 пользователь, 1 пайплайн, до 5 000 контактов, стандартный импорт/экспорт CSV, базовые отчеты.
- Garden Team ($249/мес без триала): Неограниченное число пользователей и пайплайнов, безлимитные контакты, полный экспорт, отчеты по Win Rate, Deal Velocity, лидерборды менеджеров и автозадачи при смене этапа сделки.
- Шаг 3: Проектирование матрицы доступа (Feature Gating) — Задайте правила: закрытые функции проверяют права через API биллинга перед рендером, блокируя доступ модальным окном апгрейда.
Результат: Готовая матрица фичей и тарифная сетка для передачи в AI-агент кодинга.
2. Настройка платежного провайдера Whop и генерация API-доступа
Контекст: Самостоятельное написание платежной системы требует создания таблиц подписок, фоновых задач обновления (cron jobs), логики обработки просроченных платежей и экранов ввода карт. Использование Whop перекладывает всю финансовую безопасность и обработку карт на внешний сервис. Для интеграции Whop с AI-агентами используется стандартный файл документации llms.txt, позволяющий Claude Code напрямую понимать спецификацию API и вебхуков сервиса.
Тайминг: , ,
Выгода: Экономия десятков часов на написании платежного шлюза, полное соответствие PCI-DSS (номера карт не проходят через ваш сервер) и автоматическая проверка валидности карт удержанием $0.01 при старте триала.
Как применить:
- Шаг 1: Регистрация бизнеса в Whop — Зайдите в Whop Dashboard, укажите тип бизнеса (Software), категорию выручки и создайте профиль компании.
- Шаг 2: Генерация API-ключа — Перейдите в настройки разработчика Whop, создайте ключ с правами владельца (Owner permissions) и скопируйте его для конфигурации окружения.
- Шаг 3: Скармливание документации агенту Claude Code — При запуске генерации укажите Claude Code ссылку на файл документации для LLM:
Read the documentation at https://docs.whop.com/llms.txt before writing the integration. Follow the SaaS guide for webhooks, memberships, checkout configurations, and access checks.- Шаг 4: Создание продуктов в Whop — Сгенерируйте в панели два продукта:
Garden Pro: $49/month, 7-day free trial.Garden Team: $249/month, immediate billing.
Результат: Настроен аккаунт Whop, получены ID продуктов (prod_...) и планов (plan_...), а Claude Code обучен работе со спецификацией Whop API.
3. Инициализация проекта через Claude Code и настройка Supabase
Контекст: Связка Supabase и Next.js под управлением Claude Code позволяет развернуть базу данных PostgreSQL, настроить изоляцию команд (Multi-tenancy) и политики Row Level Security (RLS) за один промпт. База данных хранит сущности сделок, компаний, контактов и связывает внешний user_id из Whop с локальным user_id в Supabase.
Тайминг: , ,
Выгода: Изоляция данных между командами на уровне базы (RLS) исключает утечку данных клиентов при масштабировании.
Как применить:
- Шаг 1: Инициализация Claude Code в рабочей директории — Откройте терминал, создайте папку проекта и запустите Claude Code в автономном режиме:
mkdir garden-crm && cd garden-crm
claude- Шаг 2: Создание проекта в Supabase — Создайте новый проект в Supabase Dashboard, перейдите в Project Settings → API и скопируйте
SUPABASE_URL,ANON_KEYиSERVICE_ROLE_KEY. - Шаг 3: Применение SQL-схемы базы данных — Вставьте в SQL Editor Supabase сгенерированную схему с таблицами
teams,memberships,pipelines,deals,contacts,companies,tasks. - Шаг 4: Настройка URL Configuration в Supabase Auth — В панели Supabase перейдите в Authentication → URL Configuration, добавьте wildcard для тестового домена Cloudflare Tunnel (например,
https://*.trycloudflare.com/**) и продакшн-домен. - Шаг 5: Отключение подтверждения почты для dev-тестов — В Authentication → Providers → Email временно отключите тумблер Confirm email для быстрого сквозного тестирования онбординга.
# .env.local
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOi...
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOi...
WHOP_API_KEY=whop_api_...
WHOP_WEBHOOK_SECRET=ws_...Результат: Рабочая база данных PostgreSQL с настроенными RLS-политиками и авторизацией, готовая к приему данных вебхуков.
4. Разработка ядра CRM: Канбан, дедупликация CSV и управление сделками
Контекст: Пользователи CRM ожидают моментального отклика UI: перетаскивание карточек с автоматическим пересчетом сумм на этапах (totals live update), просмотр истории заметок/звонков по компаниям и гибкий импорт лидов. Ошибки дублирования контактов при импорте больших CSV-файлов — частая проблема, требующая алгоритмической сверки перед вставкой в БД.
Тайминг: , ,
Выгода: Безошибочная загрузка до 20 000 строк CSV с сопоставлением колонок и отсевом дублей без падения браузера и базы данных.
Как применить:
- Шаг 1: Реализация интерактивного пайплайна — Сгенерируйте Drag-and-Drop канбан-доску, где перетаскивание сделки между колонками сразу обновляет ее статус в Supabase и пересчитывает сумму сделок в заголовке колонки.
- Шаг 2: Реализация модуля задач (To-Do List) — Добавьте контекстные задачи на день (отправить презентацию, созвониться, отправить запись) с чекбоксами выполнения.
- Шаг 3: Построение таймлайна компании — В карточке компании создайте вкладки заметок, звонков и связанных контактов.
- Шаг 4: Создание умного импорта CSV — Реализуйте интерфейс сопоставления колонок (Column Mapping) и алгоритм дедупликации (проверка совпадений по Email/Phone) перед финальной записью в базу:
// Пример логики дедупликации на клиенте/сервере
export function filterDuplicateContacts(importedRows: any[], existingContacts: any[]) {
const existingEmails = new Set(existingContacts.map(c => c.email?.toLowerCase().trim()));
const uniqueRows: any[] = [];
const duplicates: any[] = [];
importedRows.forEach(row => {
const email = row.email?.toLowerCase().trim();
if (email && existingEmails.has(email)) {
duplicates.push(row);
} else {
uniqueRows.push(row);
if (email) existingEmails.add(email);
}
});
return { uniqueRows, duplicatesCount: duplicates.length };
}Результат: Полнофункциональный интерфейс CRM с поддержкой загрузки листов лидов, поиском дубликатов и канбан-доской.
5. Обработка Webhook-событий Whop и синхронизация подписок
Контекст: Связь между фронтендом, бэкендом и Whop держится на системе вебхуков. Когда клиент оформляет триал, обновляет план или отменяет подписку, Whop отправляет подписанный запрос на бэкенд приложения. Приложение проверяет криптографическую подпись вебхука, сверяет идемпотентность (чтобы не обрабатывать повторные запросы) и меняет статус команды (active, trialing, past_due, canceled).
Тайминг: , ,
Выгода: Мгновенное переключение статусов доступа без необходимости регулярного ручного опроса (polling) сторонних API.
Как применить:
- Шаг 1: Регистрация эндпоинта вебхуков — В панели Whop настройте Webhook URL (например,
https://your-domain.com/api/webhooks/whop). - Шаг 2: Подписка на ключевые события — Активируйте 5 обязательных событий:
membership.activated— старт триала или первая оплата.membership.updated— апгрейд/даунгрейд тарифа.membership.trial_ending_soon— срабатывает за 72 часа до окончания триала (для отправки email и показа баннера).payment.failed— ошибка списания (перевод в льготный период grace period).membership.cancel/membership.deactivated— завершение подписки.
- Шаг 3: Сохранение секрета вебхука — Скопируйте секрет, начинающийся с
ws_..., и добавьте его в.env.localкакWHOP_WEBHOOK_SECRET. - Шаг 4: Реализация валидатора подписи — Убедитесь, что эндпоинт проверяет заголовок подписи Whop перед выполнением SQL-транзакций.
// Обработчик вебхуков Whop (app/api/webhooks/whop/route.ts)
import { NextResponse } from 'next/server';
import { createClient } from '@supabase/supabase-js';
const supabaseAdmin = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!
);
export async function POST(req: Request) {
const payload = await req.json();
const eventType = payload.action;
const teamId = payload.data?.metadata?.team_id || payload.data?.user?.id;
const planId = payload.data?.plan_id;
switch (eventType) {
case 'membership.activated':
case 'membership.updated':
await supabaseAdmin.from('teams').update({
subscription_status: payload.data.status, // 'active' | 'trialing'
plan_id: planId,
valid_until: payload.data.expires_at,
has_used_trial: true
}).eq('id', teamId);
break;
case 'membership.deactivated':
await supabaseAdmin.from('teams').update({
subscription_status: 'canceled'
}).eq('id', teamId);
break;
}
return NextResponse.json({ received: true });
}Результат: Отказоустойчивый серверный обработчик, поддерживающий актуальный статус подписки в базе данных Supabase.
6. Защита от абуза триалов, Grace Period и экран возврата (Win-Back)
Контекст: При отмене подписки пользователю необходимо оставить доступ до конца оплаченного периода (или конца 7 дней триала) — это так называемый grace period. Однако после истечения срока приложение должно полностью заблокировать доступ к интерфейсу. Если пользователь возвращается после отмененного триала, система не должна давать ему второй бесплатный период: кнопка «Restart Pro» обязана сразу вести на оплату без триала.
Тайминг: , , ,
Выгода: Исключение финансовых потерь от бесконечного пересоздания триалов и сохранение клиентских данных (детали, контакты и заметки не удаляются), что повышает конверсию в повторную активацию.
Как применить:
- Шаг 1: Проверка флага
has_used_trial— В таблицеteamsсохраняйте булево значение использования бесплатного периода. При попытке повторного чекаута генерируйте ссылку Whop безtrial_days. - Шаг 2: Реализация защитного экрана блокировки — Если статус подписки
canceledилиpast_due, перенаправляйте пользователя на экран блокировки:- Сообщение: «Your Garden plan has ended. The app is paused. Your deals, contacts, and notes are still here.»
- Кнопки: «Restart Pro ($49/mo)», «Upgrade to Team ($249/mo)», «Manage Billing».
- Шаг 3: Feature Gating для Team-тарифа — Оберните закрытые разделы (Leaderboard менеджеров, Win Rate, Deal Velocity, мультипайплайны) в компонент проверки тарифа. При попытке перехода на Team-фичи с Pro-тарифа показывайте страницу «Grow together on Team» со списком преимуществ и кнопкой апгрейда.
// Компонент проверки доступа к Team фичам
export function TeamGate({ currentPlan, children }: { currentPlan: string; children: React.ReactNode }) {
if (currentPlan !== 'team_plan_id') {
return (
<div className="p-8 text-center border rounded-xl bg-card">
<div className="w-12 h-12 mx-auto mb-4 bg-primary/10 rounded-full flex items-center justify-center">🔒</div>
<h3 className="text-xl font-bold">Unlocked with Garden Team</h3>
<p className="text-muted-foreground my-2">Win rate, Deal velocity, and Leaderboards are only available on Team plan.</p>
<button onClick={() => window.location.href = '/settings/billing'} className="btn-primary mt-4">
Upgrade to Team ($249/mo)
</button>
</div>
);
}
return <>{children}</>;
}Результат: Корректно функционирующий жизненный цикл аккаунта: от триала и апгрейда до мягкой блокировки с возможностью восстановления в один клик.
Разработка B2B SaaS CRM: ответы на частые вопросы
В: Зачем использовать Whop вместо стандартного Stripe для SaaS?
О: Whop берет на себя создание страниц чекаута, портал управления подписками, работу с отменами, обработку триалов и встроенную защиту от сбоев платежей. Это избавляет от необходимости писать сотни строк шаблонного кода интеграции Stripe Elements и биллинг-портала.
В: Списываются ли деньги с клиента при старте 7-дневного триала?
О: Whop валидирует карту с помощью микро-авторизации на сумму $0.01 (1 цент / 1 пенни), которая сразу возвращается. Полноценное списание $49 происходит строго по истечении 7 дней, если клиент не отменил подписку.
В: Как предотвратить абуз повторных триалов одним и тем же пользователем?
О: В базе данных Supabase в таблице команды фиксируется флаг has_used_trial = true при первой активации. Если пользователь отменил подписку и пытается войти снова, приложение направляет его на чекаут плана Pro без параметра триального периода.
В: Удаляются ли данные пользователя (сделки, контакты), если подписка аннулирована?
О: Нет. При отмене или истечении срока действия подписки доступ к приложению блокируется экраном-заглушкой («App Paused»), но все данные (пайплайны, контакты, заметки) сохраняются в Supabase, чтобы пользователь мог мгновенно продолжить работу после продления.
В: Как Claude Code узнает, как правильно интегрировать Whop API?
О: Перед началом кодинга агенту передается ссылка на системную документацию Whop для нейросетей: https://docs.whop.com/llms.txt. Это позволяет модели использовать актуальные эндпоинты, типы данных и названия вебхуков без галлюцинаций.
В: Как работает разграничение прав (Feature Gating) между планами Pro и Team?
О: Приложение сверяет текущий plan_id команды в базе данных. Если пользователь на плане Pro пытается создать второй пайплайн или открыть раздел отчетов/лидербордов, компонент TeamGate блокирует отображение контента и выводит окно апгрейда на план Team ($249/мес).
Разработка B2B SaaS CRM: инструменты и ссылки из видео
- Claude Code (Anthropic) — CLI-агент для автономного написания кода, миграций и построения архитектуры приложений —
https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview - Supabase — Open-source Firebase-альтернатива: база данных PostgreSQL, Auth и Row Level Security —
https://supabase.com - Whop — Платформа для монетизации цифровых продуктов, подписок и обработки платежей —
https://whop.com - Whop LLMs Documentation — Машиночитаемая документация API и вебхуков Whop для ИИ-агентов —
https://docs.whop.com/llms.txt - Cloudflare Tunnels (trycloudflare) — Инструмент для локального туннелирования портов при тестировании вебхуков и OAuth-редиректов —
https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/ - Build Software Solo — Проект и сообщество автора видео —
https://buildsoftwaresolo.com
Конспект создан на основе видео «Full Stack CRM SaaS Build» канала Oliver / buildsoftwaresolo.com. Все права на оригинальный материал принадлежат авторам. Источник: https://www.youtube.com/watch?v=uIXUGOPsHqU