Назад к блогу

Изменения в Google Play и соглашение с Epic: Архитектура Third-Party Mobile Billing

Опубликовано 6 марта 2026 г.
Изменения в Google Play и соглашение с Epic: Архитектура Third-Party Mobile Billing

Каждый разработчик мобильных игр хоть раз смотрел на свой ежемесячный дашборд доходов и вздрагивал от 30-процентной комиссии платформы, мгновенно испаряющей маржу. Годами разработчики под Android были заперты в жесткой экосистеме: если вы хотели видеть свою игру в крупнейшем мобильном сторе мира, вы использовали их проприетарную систему биллинга, отдавали огромную долю микротранзакций и строили всю архитектуру прав доступа (entitlements) вокруг их специфических API.

Эта эра официально заканчивается. Чтобы в полной мере извлечь выгоду из условий, которые принесли google play changes epic settlement, разработчики должны фундаментально переосмыслить свою инфраструктуру бэкенда.

Недавнее завершение юридической саги Epic Games против Google привело к изменениям, предписанным судом, которые распахивают экосистему Android настежь. Теперь разработчики могут направлять игроков на внешние payment gateways, обходить обязательный 30-процентный налог и даже распространять игры через альтернативные магазины приложений, размещенные прямо внутри Google Play.

Но эта новообретенная финансовая свобода сопряжена с серьезными техническими издержками. Отказавшись от Google Play Billing, вы теряете автоматическую валидацию чеков (receipt validation), офлайн-кеширование и централизованное отслеживание прав доступа, которые она обеспечивала. Теперь вы несете полную ответственность за безопасное управление покупками ваших игроков через несколько платежных шлюзов.

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

Техническое влияние соглашения Epic против Google

Прежде чем погружаться в код, нам нужно понять, что именно судебный запрет (действующий с ноября 2024 года по ноябрь 2027 года) меняет в архитектуре вашей игры.

1. Внешняя маршрутизация платежей теперь законна

Google больше не может банить вашу игру за наличие ссылок, направляющих игроков в веб-браузер для завершения покупки. Это означает, что вы можете интегрировать таких платежных провайдеров, как Stripe, Xsolla или PayPal, которые обычно взимают от 2,9% до 5% плюс небольшую фиксированную комиссию за транзакцию. Для инди-игры среднего уровня, приносящей 50 000 долларов в месяц на микротранзакциях, уход от 30-процентной комиссии платформы экономит примерно 12 500 долларов каждый месяц.

2. Sideloading и сторонние магазины

Альтернативные магазины приложений теперь могут распространяться напрямую через Google Play Store, а Google запрещено платить производителям устройств за эксклюзивную предустановку Google Play. Ваши игроки могут скачать вашу игру из Epic Games Store, Amazon Appstore или через кастомный лаунчер издателя, играя при этом на одном и том же Android-устройстве.

3. Смерть единого источника прав доступа (Entitlements)

Исторически ваш игровой клиент мог просто запросить Google Play Billing Library: «Владеет ли этот пользователь премиальным боевым пропуском?». Если ответ был «да», вы разблокировали контент.

Теперь игрок может купить боевой пропуск через ссылку Stripe на своем ПК, войти в вашу игру, скачанную из альтернативного Android-стора, и ожидать, что его контент будет на месте. Валидация на стороне клиента (client-side validation) официально мертва. Вы должны перейти к архитектуре server-authoritative, где ваш бэкенд является единственным источником истины для всех инвентарей игроков.

Проектирование независимого от стора бэкенда прав доступа

Для поддержки нескольких платежных шлюзов вашему бэкенду требуется надежная схема базы данных, которая отделяет финансовую транзакцию от внутриигрового права доступа (entitlement).

Никогда не привязывайте инвентарь игрока напрямую к ID чека конкретного магазина. Вместо этого используйте промежуточную таблицу транзакций.

Рекомендуемая схема базы данных

Чтобы построить это вручную, вам понадобятся три основные таблицы в вашей реляционной базе данных (например, PostgreSQL):

  • Users: Основной профиль игрока.
  • Transactions: Логирует финансовое событие. Включает GatewayProvider (например, «Stripe», «Google», «Xsolla»), GatewayTransactionId, Amount, Currency и Status (Pending, Completed, Refunded).
  • Entitlements: Фактические внутриигровые предметы, которыми владеет пользователь. Включает UserId, ItemId, AcquiredViaTransactionId и RevokedAt.

Когда происходит покупка, платежный шлюз отправляет вебхук на ваш сервер. Ваш сервер проверяет вебхук, создает запись Completed в таблице Transactions, а затем вставляет соответствующие предметы в таблицу Entitlements.

Реализация безопасной валидации вебхуков на стороне сервера

Самая важная часть этой новой архитектуры — обработчик вебхуков. Если вы направляете игроков на стороннюю страницу оплаты, этот внешний провайдер отправит HTTP POST-запрос на ваш бэкенд при успешном платеже.

Мошенники активно ищут незащищенные эндпоинты вебхуков. Если ваш эндпоинт слепо принимает JSON-пейлоады без проверки криптографических подписей, злоумышленники подделают сообщения об «успешном платеже» и начислят себе бесконечную премиальную валюту.

Вот готовый к использованию пример на TypeScript с использованием Express.js. Этот фрагмент демонстрирует, как безопасно валидировать подпись вебхука Stripe, обеспечить идемпотентность (чтобы с игроков не списывали средства дважды, если вебхук сработает дважды) и обновить базу данных игрока.

import express from 'express';
import crypto from 'crypto';
import { PrismaClient } from '@prisma/client';

const app = express();
const prisma = new PrismaClient();
const WEBHOOK_SECRET = process.env.PAYMENT_WEBHOOK_SECRET || '';

// We need the raw body to verify the cryptographic signature
app.post('/api/webhooks/billing', express.raw({ type: 'application/json' }), async (req, res) => {
    const signature = req.headers['x-payment-signature'] as string;
    const rawBody = req.body;

    // 1. Cryptographic Signature Verification
    const expectedSignature = crypto
        .createHmac('sha256', WEBHOOK_SECRET)
        .update(rawBody)
        .digest('hex');

    if (signature !== expectedSignature) {
        console.error("Security Alert: Invalid webhook signature detected.");
        return res.status(401).send('Invalid signature');
    }

    const event = JSON.parse(rawBody.toString());

    // 2. Process only successful payments
    if (event.type === 'payment.success') {
        const { transactionId, playerId, itemId } = event.data;

        try {
            // 3. Database Transaction with Idempotency Check
            await prisma.$transaction(async (tx) => {
                // Check if we already processed this transaction (Idempotency)
                const existingTx = await tx.transaction.findUnique({
                    where: { gatewayTransactionId: transactionId }
                });

                if (existingTx) {
                    console.log(`Transaction ${transactionId} already processed. Skipping.`);
                    return;
                }

                // Log the financial transaction
                const newTx = await tx.transaction.create({
                    data: {
                        gatewayTransactionId: transactionId,
                        provider: 'CustomStripeGateway',
                        status: 'COMPLETED',
                        playerId: playerId
                    }
                });

                // Grant the in-game entitlement
                await tx.entitlement.create({
                    data: {
                        playerId: playerId,
                        itemId: itemId,
                        acquiredViaTransactionId: newTx.id
                    }
                });
                
                console.log(`Successfully granted item ${itemId} to player ${playerId}`);
            });

            return res.status(200).send('Webhook processed');

        } catch (error) {
            console.error("Database error during webhook processing:", error);
            return res.status(500).send('Internal Server Error');
        }
    }

    // Acknowledge other event types without crashing
    return res.status(200).send('Event ignored');
});

Важность Payload Hardening

Обратите внимание, как приведенный выше код использует express.raw() для захвата точного байтового потока запроса перед его парсингом в JSON. Даже один лишний пробел в JSON-пейлоаде приведет к несовпадению HMAC-хэша.

Защита этих эндпоинтов не является опциональной. Как мы видели в крупных отраслевых инцидентах, отсутствие защиты бэкенда от поддельных HTTP-запросов — гарантированный способ разрушить экономику вашей игры. Для более глубокого изучения того, как открытые API приводят к катастрофическим эксплойтам, прочитайте наш анализ The Star Citizen Data Breach Explained Architecting Game Backends To Survive Compromises.

Решение проблемы синхронизации в реальном времени

Мы решили логику прав доступа на бэкенде, но теперь перед нами стоит проблема UX.

Представьте путь игрока:

  1. Игрок нажимает «Купить 1000 монет» в вашей Android-игре.
  2. Игра открывает веб-браузер устройства с вашей кастомной страницей оплаты.
  3. Игрок завершает покупку с помощью кредитной карты.
  4. Платежный шлюз отправляет вебхук на ваш сервер.
  5. Игрок возвращается в игровое приложение.

Как игровой клиент узнает, что покупка прошла успешно? Если вы полагаетесь на HTTP polling (заставляя клиент спрашивать сервер «Я уже купил?» каждые 3 секунды), вы разрядите батарею устройства и завалите бэкенд бесполезными запросами.

Вместо этого ваш бэкенд должен отправить обновленное состояние инвентаря клиенту в ту же миллисекунду, когда фиксируется транзакция в базе данных. Для этого требуется постоянное двунаправленное соединение. Если вы строите эту инфраструктуру с нуля, вам нужно будет реализовать слой WebSocket, который прослушивает события вашей базы данных и транслирует их в активную сессию клиента.

Если вы испытываете трудности с архитектурой для этого, вы можете узнать, как реализовать такие push-уведомления в реальном времени, в нашем руководстве: Ditch Http Polling An Unreal Engine Websockets Tutorial For Real Time Backends.

5 лучших практик для стороннего мобильного биллинга

Если вы мигрируете свою игру со стандартной библиотеки Google Play Billing, чтобы воспользоваться преимуществами новых изменений в экосистеме, придерживайтесь этих пяти архитектурных правил:

  1. Соблюдайте строгую идемпотентность: Тайм-ауты сети постоянно случаются на мобильных устройствах. Платежный шлюз может отправить один и тот же вебхук об «успехе» трижды, если ваш сервер слишком долго отвечает. Всегда проверяйте базу данных на наличие TransactionId перед выдачей предметов, чтобы игроки случайно не получили несколько копий одного и того же предмета.
  2. Автоматизируйте отзыв прав при чарджбэках: Сторонний биллинг означает, что вы несете ответственность за обработку чарджбэков и возвратов. Ваш обработчик вебхуков должен прослушивать события payment.refunded и автоматически помечать соответствующую строку в таблице Entitlements как Revoked. Если вы пропустите это, игроки быстро поймут, что могут вернуть деньги через банк и оставить себе премиальную валюту.
  3. Отделите клиент от платежного шлюза: Ваш игровой клиент никогда не должен напрямую взаимодействовать с API платежного шлюза. Клиент должен запросить токен сессии оплаты у вашего бэкенда, открыть веб-вью с этим токеном, а бэкенд должен взять на себя фактическую валидацию транзакции.
  4. Реализуйте Graceful Degradation: Если ваша база данных упадет, игра все равно должна оставаться играбельной. Кешируйте права доступа локально на устройстве, используя зашифрованный файл сохранения, но всегда проводите валидацию по серверным данным, когда игрок пытается потратить премиальную валюту или присоединиться к мультиплеерному матчу.
  5. Унифицируйте пайплайн виртуальной валюты: Не создавайте отдельные «Google Coins» и «Stripe Coins» в вашей базе данных. Сопоставляйте все входящие фиатные транзакции с единым унифицированным ID виртуальной валюты на вашем бэкенде, чтобы избежать огромных проблем в логике UI вашей игры.

Реальность инфраструктуры: Build vs. Buy

Соглашение Epic против Google — это огромная победа для доходов разработчиков, но оно перекладывает бремя инфраструктуры прямо на ваши плечи.

Создание высокодоступного, независимого от стора биллинг-бэкенда требует настройки баз данных PostgreSQL, конфигурации Redis для кеширования идемпотентности, управления SSL-сертификатами для безопасных вебхуков и поддержки WebSocket-серверов для обновлений клиента в реальном времени. Для небольшой инди-команды это минимум 4–6 недель чистой разработки бэкенда — времени, которое должно быть потрачено на то, чтобы сделать вашу игру интересной.

Это именно те архитектурные сложности, которые мы устраняем. С horizOn эти сложные бэкенд-сервисы поставляются уже настроенными. Наша платформа предоставляет готовую независимую от стора систему прав доступа, которая безопасно обрабатывает валидацию вебхуков server-to-server, предотвращает дублирование транзакций и автоматически синхронизирует инвентари игроков в реальном времени. Вы получаете финансовые выгоды стороннего биллинга, не становясь DevOps-инженером.

Взгляд в будущее

Экосистема мобильных игр претерпевает самые значительные структурные изменения за последние десять лет. «Огороженные сады» наконец-то рушатся, и разработчики, которые адаптируют свои бэкенд-архитектуры к платформонезависимости, получат огромные финансовые выгоды, избегая традиционного 30-процентного налога платформы.

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

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


Источник: Major Google Play Changes as Epic v Google Ends