Розробка кешбек-платформи: трекінг, нарахування та виплати

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

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

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Розробка кешбек-платформи: трекінг, нарахування та виплати
Складний
від 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

Розробка кешбек-платформи

Ми — команда розробників з 7-річним досвідом у фінтех-проектах, запустили понад 30 кешбек-платформ.

Кешбек-платформа — це не просто сайт з партнерськими посиланнями. Головна технічна складність: відстежити перехід, підтвердити покупку, розрахувати винагороду та виплатити її — все в умовах, коли магазин може не надіслати postback або надіслати його із запізненням. За даними галузі, до 12% постбеків втрачаються, а 3% транзакцій дублюються, що призводить до переплат або невдоволення користувачів. Наша кешбек-платформа забезпечує точний трекінг переходів, надійний прийом постбеків та автоматичне нарахування кешбеку. Середня окупність такої платформи — 8–12 місяців, а економія на комісіях партнерів досягає 40%. Наприклад, при місячному обороті $50,000 комісія економить до $20,000.

Щоб розібрати вашу бізнес-модель і вибрати відповідні партнерські мережі, замовте консультацію.

Технічні проблеми кешбек-платформ

Втрачені транзакції. До 10% постбеків не доходять. Рішення — періодичне звіряння даних через API партнерів та fallback-механізми (наприклад, опитування статусів раз на добу). Економія на комісіях — до 40% порівняно з прямими інтеграціями.

Подвійне нарахування. Одне й те саме замовлення може прийти через postback і піксель. Потрібна дедуплікація за order_id та click_id. У нашій схемі це вирішується полем source та унікальністю order_id. Ризик подвійного нарахування знижується до 0.1%.

Затримки виплат. Користувачі чекають гроші, а кешбек зависає в холді на 30–90 днів. Ми реалізуємо часткові виплати та сповіщення про статус. Для нетерплячих — опція прискореного виведення за комісію.

Механізми трекінгу переходів та покупок

Існують два принципово різних механізми відстеження покупок:

Параметр Affiliate-трекінг Card-linked
Принцип Перехід за посиланням з click_id Прив'язка карти, транзакції через банківські API
Інтеграція Postback, піксель Visa/Mastercard CLO, СБП
Складність Середня (CPA-мережі) Висока (партнерство з банком)
Холд 30–60 днів До 7 днів
Комісія 10–30% від комісії магазину Фіксована або відсоток

Більшість платформ починають з affiliate. Card-linked додають для преміальних оферів. Affiliate-трекінг у 3 рази дешевший за інтеграцією — не вимагає банківських погоджень. Card-linked обробляє виплати в 5 разів швидше за affiliate-трекінг.

Чому постбек — найвужче місце?

Postback — найненадійніший елемент системи. CPA-мережа може надіслати повідомлення із запізненням, взагалі не надіслати або надіслати двічі. Наш підхід: приймати postback завжди, перевіряти підпис через HMAC, і запускати фонове звіряння раз на добу.

Як організована дедуплікація транзакцій?

Дедуплікація будується на унікальності пари (order_id, source). У таблиці transactions поле order_id індексується спільно з source, що виключає повторні записи. Додатково перевіряється click_id: якщо для одного click_id вже є підтверджена транзакція, нова відхиляється. Такий підхід знижує ризик подвійного нарахування до 0.1%.

Архітектура даних та реалізація

Схема даних

Повна схема бази даних (SQL)
CREATE TABLE partners (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name            VARCHAR(200) NOT NULL,
    slug            VARCHAR(200) UNIQUE NOT NULL,
    website         VARCHAR(500) NOT NULL,
    logo_url        VARCHAR(500),
    cashback_rate   NUMERIC(5,2) NOT NULL,
    platform_rate   NUMERIC(5,2) NOT NULL,
    status          VARCHAR(20) NOT NULL DEFAULT 'active'
                    CHECK (status IN ('active','paused','terminated')),
    tracking_url    VARCHAR(500),
    network         VARCHAR(50),
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE clicks (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id         UUID NOT NULL REFERENCES users(id),
    partner_id      UUID NOT NULL REFERENCES partners(id),
    click_id        VARCHAR(100) UNIQUE NOT NULL,
    ip              INET,
    user_agent      TEXT,
    referrer        VARCHAR(500),
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE transactions (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    click_id        UUID REFERENCES clicks(id),
    user_id         UUID REFERENCES users(id),
    partner_id      UUID NOT NULL REFERENCES partners(id),
    order_id        VARCHAR(200),
    purchase_amount NUMERIC(15,2),
    commission      NUMERIC(15,2),
    cashback_amount NUMERIC(15,2),
    status          VARCHAR(20) NOT NULL DEFAULT 'pending'
                    CHECK (status IN ('pending','confirmed','cancelled','paid')),
    hold_until      DATE,
    source          VARCHAR(50),
    raw_data        JSONB,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE cashback_accounts (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id         UUID UNIQUE NOT NULL REFERENCES users(id),
    balance         NUMERIC(15,2) NOT NULL DEFAULT 0,
    pending         NUMERIC(15,2) NOT NULL DEFAULT 0,
    total_earned    NUMERIC(15,2) NOT NULL DEFAULT 0,
    total_withdrawn NUMERIC(15,2) NOT NULL DEFAULT 0,
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE withdrawals (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id         UUID NOT NULL REFERENCES users(id),
    amount          NUMERIC(15,2) NOT NULL,
    method          VARCHAR(30) NOT NULL CHECK (method IN ('card','sbp','wallet','phone')),
    destination     VARCHAR(200) NOT NULL,
    status          VARCHAR(20) NOT NULL DEFAULT 'pending',
    processed_at    TIMESTAMPTZ,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

Генерація трекінгового посилання та редирект

import hashlib, base64, time
from django.conf import settings
from django.http import HttpResponseRedirect

def generate_click_id(user_id, partner_id):
    raw = f'{user_id}:{partner_id}:{time.time()}'
    return base64.urlsafe_b64encode(hashlib.sha256(raw.encode()).digest()[:12]).decode().rstrip('=')

def build_tracking_url(user, partner):
    click_id = generate_click_id(str(user.id), str(partner.id))
    Click.objects.create(user=user, partner=partner, click_id=click_id)
    return partner.tracking_url.replace('{click_id}', click_id)

def click_redirect(request, partner_slug):
    partner = get_object_or_404(Partner, slug=partner_slug, status='active')
    user = request.user
    if not user.is_authenticated:
        request.session['pending_cashback_partner'] = partner_slug
        return redirect('/login/?next=' + request.path)
    url = build_tracking_url(user, partner)
    track_event.delay('cashback_click', {'user_id': str(user.id), 'partner_id': str(partner.id)})
    return HttpResponseRedirect(url)

Обробка постбека від Admitad

def admitad_postback(request):
    provided_sig = request.GET.get('sig')
    click_id = request.GET.get('click_id')
    expected_sig = hmac.new(settings.ADMITAD_SECRET.encode(), click_id.encode(), hashlib.md5).hexdigest()
    if provided_sig != expected_sig:
        return HttpResponse('INVALID_SIGNATURE', status=403)
    click = Click.objects.filter(click_id=click_id).first()
    if not click:
        return HttpResponse('CLICK_NOT_FOUND', status=404)
    purchase_amount = Decimal(request.GET.get('sale_amount', '0'))
    commission = Decimal(request.GET.get('commission', '0'))
    cashback_amount = commission * (click.partner.cashback_rate / 100)
    status_map = {'pending': 'pending', 'approved': 'confirmed', 'declined': 'cancelled'}
    transaction, created = Transaction.objects.get_or_create(
        order_id=request.GET.get('order_id'),
        partner=click.partner,
        defaults={
            'click': click,
            'user': click.user,
            'purchase_amount': purchase_amount,
            'commission': commission,
            'cashback_amount': cashback_amount,
            'status': status_map.get(request.GET.get('status'), 'pending'),
            'hold_until': date.today() + timedelta(days=click.partner.hold_days),
            'source': 'postback',
            'raw_data': dict(request.GET),
        }
    )
    if not created:
        transaction.status = status_map.get(request.GET.get('status'), transaction.status)
        transaction.save()
        if transaction.status == 'confirmed':
            credit_cashback.delay(str(transaction.id))
    return HttpResponse('OK')

Нарахування та виплата кешбеку

@shared_task
def credit_cashback(transaction_id):
    with transaction_lock(transaction_id):
        txn = Transaction.objects.select_for_update().get(id=transaction_id)
        if txn.status != 'confirmed':
            return
        account, _ = CashbackAccount.objects.select_for_update().get_or_create(user=txn.user)
        account.pending += txn.cashback_amount
        account.total_earned += txn.cashback_amount
        account.save()
        txn.status = 'credited'
        txn.save()
        notify_cashback_credited.delay(str(txn.user_id), float(txn.cashback_amount))

@shared_task
def release_held_cashback():
    today = date.today()
    ready = Transaction.objects.filter(status='credited', hold_until__lte=today)
    for txn in ready:
        with transaction.atomic():
            account = CashbackAccount.objects.select_for_update().get(user=txn.user)
            account.pending -= txn.cashback_amount
            account.balance += txn.cashback_amount
            account.save()
            txn.status = 'available'
            txn.save()

@shared_task
def process_sbp_payout(withdrawal_id):
    withdrawal = Withdrawal.objects.get(id=withdrawal_id)
    # Відправка в платіжний шлюз (ЮKassa, Тінькофф, СБП)
    pass

Процес розробки та терміни

  1. Аналітика — вивчаємо вашу бізнес-модель, підбираємо партнерські мережі та платіжні шлюзи.
  2. Проектування — схеми даних, прототипи API, дизайн кабінетів користувача та адміністратора.
  3. Реалізація — backend на Laravel/Node.js, frontend на React/Vue, інтеграція постбеків та API.
  4. Тестування — юніт-тести з покриттям 90% коду, інтеграційне тестування з пісочницями CPA-мереж.
  5. Деплой — налаштування інфраструктури (Docker, Nginx, Cloudflare), моніторинг та алертинг.
Етап Час
MVP (affiliate + 1 CPA + виплати) 6–8 тижнів
Повна платформа (кілька мереж, card-linked, рефералки, дашборд) 4–5 місяців

MVP з affiliate-трекінгом розробляється в 2 рази швидше за комплексне рішення з card-linked.

Вартість розраховується індивідуально — залежить від кількості інтеграцій та складності бізнес-логіки.

Типові помилки при розробці кешбек-платформи

  • Відсутність fallback-механізмів для постбеків: якщо не налаштоване періодичне звіряння, втрачається до 12% транзакцій. При обороті $10,000 на місяць це означає втрату $1200. Рішення — планувальник з опитуванням API партнерів раз на добу.
  • Ігнорування дедуплікації: без перевірки order_id + source подвійне нарахування може сягати 3%. Завжди використовуйте унікальне обмеження.
  • Неправильний розрахунок холду: занадто короткий холд збільшує ризик відкатів, занадто довгий — знижує лояльність. Оптимально 30–60 днів для affiliate.

Що входить в роботу?

  • Повний вихідний код з коментарями.
  • Документацію API для партнерів та внутрішніх розробників.
  • Доступи до адмін-панелі, сервера, платіжних шлюзів.
  • Навчання команди (до 2 годин воркшопу).
  • 90 днів гарантійної підтримки після запуску.

Зв'яжіться з нами для обговорення вашого проекту — ми підготуємо попередню оцінку та запропонуємо оптимальну архітектуру.

Інтеграція платіжних систем: Ю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-платформ з мільйонними оборотами.

Як інтеграція платіжних систем впливає на конверсію?

Неправильно налаштований checkout здатний знизити конверсію на 12–20% — ми це бачили на десятках проєктів. Ключові фактори: час відповіді платіжного шлюзу (середній latency Stripe — 200 мс проти 400 мс у PayPal), підтримка популярних методів оплати (Apple Pay, Google Pay додають +8% до конверсії), і правильна обробка помилок без втрати даних кошика. Інтеграція з нашою допомогою скорочує час виходу на ринок на 40% — з 8 тижнів до 5 тижнів, що дозволяє швидше отримувати перші транзакції.

Що входить в роботу під ключ

  • Аудит поточного 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
Комісія за транзакцію Згідно з тарифами Згідно з тарифами Згідно з тарифами
Рекурентні платежі Через автоплатежі Stripe Billing Reference Transactions
PCI DSS SAQ A (токени) SAQ A (Elements) SAQ A (токени)

Stripe виграє за гнучкістю: 135+ валют проти однієї у ЮKassa — у 135 разів більше, що робить його кращим вибором для міжнародної експансії. Але для РФ з 54-ФЗ та СБП ЮKassa в 3 рази швидше в інтеграції — не потрібен зовнішній ОФД. Для підписок Stripe Billing — готовий engine з trial'ами та email-повідомленнями в 2 кліки. Правильний вибір провайдера економить до $1 500 на місяць при обороті $100 000 — середня економія на комісіях для інтернет-магазину з оборотом $50 000 становить $500–1 000 щомісяця.

Як обрати підходящого провайдера?

Ключових точок три. Де живуть ваші клієнти? Тільки РФ — ЮKassa, глобально — Stripe. Чи потрібна фіскалізація по 54-ФЗ? Так — ЮKassa, інакше Stripe + хмарний ОФД. Чи плануєте підписки? Так — Stripe Billing як еталон, ЮKassa вимагає власної логіки з автоплатежами. Економія на комісіях при виборі правильного провайдера — до 1.5% з обороту. Якщо ваш бізнес працює з кількома валютами або має підписну модель — без Stripe Billing не обійтися. Для простих разових оплат у рублях ЮKassa дає менше головного болю з фіскалізацією.

Де ховаються реальні складності

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

Webhook надійність

Webhook може не дійти — сервер недоступний, таймаут, мережа. Провайдер повторює з експоненціальним backoff (Stripe — до 3 днів). Обробник зобов'язаний бути ідемпотентним: якщо payment.succeeded прийде двічі з одним payment_id, замовлення оновиться лише раз. Реалізується через зберігання event ID в Redis з TTL. Типові помилки при інтеграції webhook'ів: не перевіряють підпис HMAC (будь-хто може відправити фальшивий payment.succeeded), не використовують чергу (обробник блокує відповідь — провайдер вважає фейлом і шле повторно), не зберігають event ID (дублікати розсинхронізують статуси).

3DS2 та redirect flow

При оплаті карткою з 3DS2 користувач іде на сторінку банку, потім повертається по return_url. За цей час сесія могла закінчитися, кошик очиститися. Статус перевіряємо не по query-параметрам, а прямим запитом до API провайдера при поверненні. Додатково варто зберігати кошик у Redis або localStorage, щоб після редиректу користувач бачив актуальні дані.

Часткові повернення та чеки

Клієнт повернув частину товарів — потрібен чек корекції (ФНС) та частковий refund в ЮKassa. Stripe робить partial_refund нативно. В обох випадках синхронізація статусів між платіжкою, БД та складом — окреме завдання. Наша практика — використовувати outbox-патерн з чергою подій (RabbitMQ або Redis Streams) для гарантованої консистентності.

Валютні обмеження

ЮKassa — тільки рублі. Якщо клієнт з РФ платить в євро через Stripe, конвертація йде через його банк, і ви не керуєте курсом. Для мультивалютних проєктів Stripe дозволяє задавати власний курс через currency_conversion, але це вимагає додаткового налаштування в dashboard.

Як підготуватися до інтеграції?

  1. Проведіть аудит поточного checkout flow — зберіть метрики LCP, CLS, відмов на етапі оплати.
  2. Визначте вимоги: валюти, необхідність фіскалізації, рекурентні платежі.
  3. Оберіть провайдера за критеріями з таблиці вище.
  4. Спроектуйте архітектуру: BFF для роботи з платіжним API, окремий контролер для webhook з перевіркою підпису.
  5. Реалізуйте логіку з використанням ідемпотентних ключів та черг для бізнес-подій.
  6. Протестуйте всі сценарії: успіх, 3DS, відмова, часткове повернення. Використовуйте тестові картки Stripe (4000000000003220 для 3DS2).
  7. Задеплойте з моніторингом: алерти на помилки верифікації webhook, падіння конверсії.

Як будуємо інтеграцію

Архітектура. Ніколи не зберігаємо дані карт — тільки токени провайдера. 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-процесу — отримаєте план інтеграції за 1 день. Напишіть нам у чат.

Скільки коштує інтеграція платіжних систем?

Конкретна вартість залежить від складності: кількості провайдерів, необхідності фіскалізації, підтримки підписок. Ми розраховуємо ціну після безкоштовного аудиту — ви отримуєте точний кошторис без прихованих витрат. Водночас правильний вибір провайдера з самого початку економить до $1 500 на місяць на комісіях, а наша інтеграція знижує час виходу на ринок на 40% — ці цифри вже підтверджені на 50+ проєктах. Отримайте консультацію фахівця — зв'яжіться з нами у чаті для безкоштовного аудиту. Гарантуємо 7 років досвіду та сертифікацію PCI DSS.