Площадка для краудфандинга: MVP, AON, награды и выплаты создателям

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

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Площадка для краудфандинга: MVP, AON, награды и выплаты создателям
Сложный
от 2 недель до 3 месяцев
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1358
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    956
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    947

При разработке краудфандинговой платформы инженер сталкивается с двумя классами проблем: гарантия корректного списания средств по модели All-or-Nothing и обеспечение real-time обновления прогресс-бара при пиковых нагрузках. Мы разберем, как решаем эти задачи с помощью Stripe Payment Intents, фоновых задач Celery и правильно спроектированной схемы данных PostgreSQL. Также рассмотрим типичные ошибки: потеря авторизации при длинных кампаниях, N+1 запросы при подсчете собранной суммы и race conditions при одновременном завершении кампании и поступлении платежей. Пишите — оценим ваш проект за 2 рабочих дня.

За 5+ лет мы реализовали более 30 платформ разных моделей. Один из проектов — платформа для независимых художников с гибридной моделью и автоматическими выплатами через Stripe Connect. Это позволило клиенту сократить время на выплаты на 80%.

Какие модели финансирования выбрать?

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

Модель Описание Техническая сложность
All-or-Nothing (AON) Средства списываются только при достижении цели. Требует pre-authorization или отложенный capture. Высокая
Keep-it-All (KIA) Средства списываются сразу, создатель получает всё. Проще юридически и технически. Средняя
Гибридная Цель фиксирована, при превышении открываются stretch goals. Сложная логика состояний. Очень высокая

Для стартапов чаще выбирают KIA из-за простоты реализации, но AON даёт больше доверия у бекеров. Необходимо учитывать требования платёжных систем к срокам холдирования. Например, Stripe держит авторизацию максимум 7 дней для карт — для более длинных кампаний нужен другой подход.

Схема данных: от кампаний до наград

CREATE TABLE campaigns (
    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    creator_id  UUID NOT NULL REFERENCES users(id),
    title       VARCHAR(200) NOT NULL,
    slug        VARCHAR(200) UNIQUE NOT NULL,
    description TEXT,
    goal_amount NUMERIC(15,2) NOT NULL,
    currency    CHAR(3) NOT NULL DEFAULT 'RUB',
    model       VARCHAR(20) NOT NULL CHECK (model IN ('aon','kia','hybrid')),
    status      VARCHAR(20) NOT NULL DEFAULT 'draft'
                CHECK (status IN ('draft','active','funded','failed','cancelled')),
    starts_at   TIMESTAMPTZ NOT NULL,
    ends_at     TIMESTAMPTZ NOT NULL,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE pledges (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    campaign_id     UUID NOT NULL REFERENCES campaigns(id),
    backer_id       UUID NOT NULL REFERENCES users(id),
    amount          NUMERIC(15,2) NOT NULL,
    reward_id       UUID REFERENCES rewards(id),
    status          VARCHAR(20) NOT NULL DEFAULT 'pending'
                    CHECK (status IN ('pending','authorized','captured','refunded','failed')),
    payment_intent  VARCHAR(200),
    captured_at     TIMESTAMPTZ,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE rewards (
    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    campaign_id UUID NOT NULL REFERENCES campaigns(id),
    title       VARCHAR(200) NOT NULL,
    description TEXT,
    min_pledge  NUMERIC(15,2) NOT NULL,
    limit_qty   INTEGER,
    claimed_qty INTEGER NOT NULL DEFAULT 0,
    ships_at    DATE,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_pledges_campaign_status
    ON pledges(campaign_id, status)
    WHERE status IN ('authorized','captured');

Индекс idx_pledges_campaign_status критичен для быстрого подсчёта собранной суммы в real-time. Без него каждый рендер прогресс-бара вызывает полный seq scan. Подробнее: Stripe Payment Intents.

Как реализовать платёжный флоу для AON?

AON требует двухэтапной оплаты: авторизация (холдирование) и capture при успехе кампании. Stripe предоставляет capture_method='manual' для этого.

import stripe

stripe.api_key = settings.STRIPE_SECRET_KEY

def authorize_pledge(pledge, card_token):
    intent = stripe.PaymentIntent.create(
        amount=int(pledge.amount * 100),
        currency=pledge.campaign.currency.lower(),
        payment_method=card_token,
        capture_method='manual',
        confirm=True,
        metadata={
            'pledge_id': str(pledge.id),
            'campaign_id': str(pledge.campaign_id),
        }
    )
    pledge.payment_intent = intent.id
    pledge.status = 'authorized'
    pledge.save()
    return intent

def capture_pledges_for_campaign(campaign_id):
    pledges = Pledge.objects.filter(
        campaign_id=campaign_id,
        status='authorized'
    )
    for pledge in pledges:
        try:
            stripe.PaymentIntent.capture(pledge.payment_intent)
            pledge.status = 'captured'
            pledge.captured_at = timezone.now()
            pledge.save()
        except stripe.error.InvalidRequestError as e:
            pledge.status = 'failed'
            pledge.save()
            logger.error(f'Capture failed for pledge {pledge.id}: {e}')

def cancel_pledges_for_campaign(campaign_id):
    pledges = Pledge.objects.filter(
        campaign_id=campaign_id,
        status='authorized'
    )
    for pledge in pledges:
        stripe.PaymentIntent.cancel(pledge.payment_intent)
        pledge.status = 'refunded'
        pledge.save()

Важно: Stripe держит authorization максимум 7 дней для карт. Для кампаний длиннее 7 дней нужна стратегия с сохранением платёжного метода и capture в последний день. Иначе pledge переходит в статус requires_payment_method, и бэкеру приходится повторно вводить карту.

Сохранение платёжных методов для длинных кампаний

Если кампания длится более недели, лучше сохранить карту через SetupIntent и выполнить capture в конце. Это снижает риск истечения авторизации. Мы используем off_session платежи для списания без участия бэкера.

Автоматизация завершения кампаний с Celery

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

Типичные ошибки и как их избежать

  1. N+1 запросы: При выводе списка кампаний с суммой собранных средств каждый запрос к pledges вызывает отдельный SQL. Решение — агрегация через SUM с индексом idx_pledges_campaign_status или кэширование суммы в Redis.
  2. Race condition при завершении кампании: Если платёж поступает в момент перехода кампании в статус 'funded', возможен конфликт. Используйте блокировки на уровне базы данных или Redis-замки.

Выплаты создателям через Stripe Connect

Stripe Connect — стандарт для маркетплейсов. Создатели проходят KYC-онбординг, после чего платформа может переводить средства напрямую на их счёт.

def create_connect_account(creator):
    account = stripe.Account.create(
        type='express',
        country='RU',
        email=creator.email,
        capabilities={
            'card_payments': {'requested': True},
            'transfers': {'requested': True},
        },
    )
    creator.stripe_account_id = account.id
    creator.save()
    link = stripe.AccountLink.create(
        account=account.id,
        refresh_url='https://site.com/dashboard/connect/refresh',
        return_url='https://site.com/dashboard/connect/complete',
        type='account_onboarding',
    )
    return link.url

def transfer_to_creator(campaign, net_amount):
    transfer = stripe.Transfer.create(
        amount=int(net_amount * 100),
        currency=campaign.currency.lower(),
        destination=campaign.creator.stripe_account_id,
        metadata={'campaign_id': str(campaign.id)},
    )
    return transfer

Комиссионная модель платформы

Стандартная комиссия платформы составляет 5–8% от собранной суммы плюс транзакционные издержки. Stripe позволяет удержать комиссию автоматически через application_fee_amount. Мы помогаем клиентам оптимизировать комиссии: например, для проектов с оборотом свыше 5 млн рублей удаётся договориться о снижении ставки.

Что входит в работу

  • Документация: техническое задание, описание API, инструкция по администрированию.
  • Исходный код: полный код платформы с комментариями, CI/CD пайплайны.
  • Доступы: права администратора, доступ к хостингу, Stripe Dashboard, репозиторию.
  • Обучение: два сеанса для команды по администрированию и добавлению кампаний.
  • Поддержка: 1 месяц гарантийной поддержки после деплоя, исправление багов.

Процесс работы

  1. Аналитика: изучаем бизнес-модель, целевую аудиторию, юридические ограничения.
  2. Проектирование: схема данных, выбор стека (React/Next.js, Laravel, PostgreSQL, Redis).
  3. Разработка: реализация MVP (авторизация, кампании, платежи).
  4. Тестирование: нагрузочное тестирование, проверка крайних случаев (AON, race conditions).
  5. Деплой: настройка CI/CD, мониторинг, обучение команды.

Сроки разработки

Этап Срок
MVP (KIA, базовые кампании, награды, Stripe) 6–8 недель
Полная AON-платформа + Connect + stretch goals + email-уведомления + аналитика 3–4 месяца
Интеграция дополнительных платёжных шлюзов (ЮKassa, PayPal) +2–4 недели

Сроки варьируются в зависимости от сложности требований и необходимости кастомизации. Стоимость рассчитывается индивидуально и зависит от объёма работ.

Свяжитесь с нами для оценки вашего проекта — мы подготовим детальное коммерческое предложение за 2 рабочих дня.

Интеграция платёжных систем: ЮKassa, Stripe, PayPal, Apple Pay, Google Pay

Конверсия упала на 12% сразу после редизайна. Команда запулила новый SPA-чекаут на Vue 3, забыв про обработку fallback-сценариев. Sentry зафиксировал шквал ошибок: Payment method not available, 3DS2 challenge flow failed, webhook signature verification failed. Пользователи бросали корзину на этапе выбора способа оплаты. Проверка показала, что Stripe Elements не получал корректный clientSecret после редиректа, а webhook-эндпоинт отвечал 500 из-за отсутствия идемпотентности. После замены checkout-формы на кастомную интеграцию с раздельным хранением event ID в Redis ошибки ушли, конверсия восстановилась за двое суток. Задача не в том, чтобы «подключить SDK» — платёжка требует синхронизации с требованиями банков, SCA в Европе и 54-ФЗ в России. Наш опыт — 7 лет интеграций для 50+ проектов, от интернет-магазинов до SaaS-платформ с миллионными оборотами.

Что входит в работу под ключ

  • Аудит текущего payment flow и требований (валюты, фискализация, подписки).
  • Выбор провайдера с учётом географии и бизнес-модели.
  • Backend-интеграция (Laravel/Node.js/Go) с обработкой webhook'ов, идемпотентностью и ретраями.
  • Frontend-виджет (Stripe Elements / ЮKassa SDK) с поддержкой Apple Pay и Google Pay.
  • Тестирование всех сценариев: успех, отказ, 3DS, возвраты, чек коррекции.
  • Мониторинг первых транзакций и документация.

Оценим проект за 1 день — для получения консультации напишите в чат.

Сравнение провайдеров: что выбрать

Критерий ЮKassa Stripe PayPal
Валюты RUB только 135+ 25+
Фискализация 54-ФЗ Встроена Нет (нужен ОФД) Нет
Поддержка Apple/Google Pay Через SDK Через PaymentElement Через Braintree
Комиссия за транзакцию 2.5–4% 2.9% + $0.30 2.99% + $0.49
Рекуррентные платежи Через автоплатежи Stripe Billing Reference Transactions
PCI DSS SAQ A (токены) SAQ A (Elements) SAQ A (токены)

Stripe выигрывает по гибкости: 135+ валют против одной у ЮKassa. Но для РФ с 54-ФЗ и СБП ЮKassa в 3 раза быстрее в интеграции — не нужен внешний ОФД. Для подписок Stripe Billing — готовый engine с trial'ами и email-уведомлениями в 2 клика.

Как выбрать подходящего провайдера?

Ключевых точек три. Где живут ваши клиенты? Только РФ — ЮKassa, глобально — Stripe. Нужна ли фискализация по 54-ФЗ? Да — ЮKassa, иначе Stripe + облачный ОФД. Планируете ли подписки? Да — Stripe Billing как эталон, ЮKassa требует собственной логики с автоплатежами. Экономия на комиссиях при выборе правильного провайдера — до 1.5% с оборота. Для проекта с 2 млн ₽ в месяц это 360 000 ₽ в год.

Где прячутся реальные сложности

Подключить тестовый режим — час. Правильно обработать все сценарии — несколько недель.

Webhook надёжность. Webhook может не дойти — сервер недоступен, таймаут, сеть. Провайдер повторяет с экспоненциальным backoff (Stripe — до 3 дней). Обработчик обязан быть идемпотентным: если payment.succeeded придёт дважды с одним payment_id, заказ обновится только раз. Реализуется через хранение event ID в Redis с TTL.

3DS2 и redirect flow. При оплате картой с 3DS2 пользователь уходит на страницу банка, затем возвращается по return_url. За это время сессия могла истечь, корзина очиститься. Статус проверяем не по query-параметрам, а прямым запросом к API провайдера при возврате.

Частичные возвраты и чеки. Клиент вернул часть товаров — нужен чек коррекции (ФНС) и частичный refund в ЮKassa. Stripe делает partial_refund нативно. В обоих случаях синхронизация статусов между платёжкой, БД и складом — отдельная задача.

Валютные ограничения. ЮKassa — только рубли. Если клиент из РФ платит в евро через Stripe, конвертация идёт через его банк, и вы не управляете курсом.

Почему webhook'и требуют идемпотентности?

Webhook может быть доставлен дважды из-за сетевых таймаутов или повторных попыток провайдера. Без идемпотентности второй вызов вызовет дублирование заказа или ошибочное начисление. Решение — сохранять уникальный ID события (например, Stripe event id + timestamp) в Redis с TTL 24 часа и проверять перед обработкой. Если ID уже существует — возвращаем 200, не выполняя бизнес-логику. Типичные ошибки при интеграции webhook'ов: не проверять подпись HMAC (любой может отправить фальшивый payment.succeeded), не использовать очередь (обработчик блокирует ответ — провайдер считает фейлом и шлёт повторно), не сохранять event ID (дубликаты рассинхронизируют статусы).

Как строим интеграцию

Архитектура. Никогда не храним данные карт — только токены провайдера. Flow: Order в БД → Payment Intent → редирект/виджет → webhook подтверждает → обновляем статус. База истины — статус в платёжной системе.

Для Laravel используем stripe/stripe-php или yookassa-sdk. Webhook — отдельный контроллер с VerifyCsrfToken исключением, проверка подписи в первой строке, Queue job для бизнес-логики.

Для Next.js/React — @stripe/stripe-js + @stripe/react-stripe-js. PaymentElement включает Apple/Google Pay автоматически. Пример:

const stripe = await stripePromise;
const { error } = await stripe.confirmPayment({
  elements,
  confirmParams: { return_url: 'https://example.com/order/thank-you' },
});

Тестирование. Stripe CLI: stripe listen --forward-to localhost:8000/webhook. Тест-карты для всех сценариев (3DS, decline, insufficient funds). Cypress-тест checkout flow в CI — обязательная гарантия стабильности.

Мы отлаживали интеграцию Stripe Billing для SaaS с 50 000 подписчиков. Проблема возникла с обработкой invoice.payment_succeeded: фронтенд обновлял подписку сразу после редиректа, но webhook мог задержаться на 10 секунд, и статус перезаписывался на incomplete. Решение — добавить polling API с проверкой статуса инвойса до показа успешной страницы. Это снизило количество ошибочных отписок на 18%.

Процесс и сроки

Аудит → выбор провайдера → backend → frontend → тесты → деплой → мониторинг.

Сценарий Срок
Один провайдер (ЮKassa или Stripe), базовый flow 1–2 недели
Несколько методов оплаты + Apple/Google Pay 2–4 недели
Мультивалютность + частичные возвраты + фискализация 4–8 недель
SaaS подписки через Stripe Billing 3–6 недель

Стоимость рассчитывается индивидуально. Закажите интеграцию, и ваш checkout не упадёт при следующем обновлении.

Ссылки:

Гарантируем: 7 лет опыта, 50+ успешных интеграций. Свяжитесь с нами для аудита вашего checkout'а — мы оценим проект и подберём оптимального провайдера.