العودة إلى المدونة

تغييرات Google Play وتسوية Epic: هندسة نظام Third-Party Mobile Billing

نُشر في 6 مارس 2026
تغييرات Google Play وتسوية Epic: هندسة نظام Third-Party Mobile Billing

لقد نظر كل مطور ألعاب موبايل إلى لوحة بيانات الإيرادات الشهرية الخاصة به وتألم من رسوم المنصة البالغة 30% التي تتبخر معها هوامش أرباحه على الفور. لسنوات، كان مطورو Android محاصرين في نظام بيئي صارم: إذا كنت تريد لعبتك في أكبر متجر تطبيقات في العالم، فعليك استخدام نظام Billing الخاص بهم، والتنازل عن حصة ضخمة من الـ microtransactions، وبناء بنية الـ entitlement بالكامل حول الـ APIs الخاصة بهم.

هذا العصر ينتهي رسمياً. للاستفادة الكاملة من الشروط التي قدمتها google play changes epic settlement، يجب على المطورين إعادة التفكير بشكل جذري في بنية الـ backend التحتية الخاصة بهم.

أدى الختام الأخير للملحمة القانونية بين Epic Games و Google إلى تغييرات مفروضة من المحكمة تفتح نظام Android البيئي على مصراعيه. يمكن للمطورين الآن توجيه اللاعبين إلى payment gateways خارجية، وتجاوز ضريبة الـ 30% الإلزامية، وحتى التوزيع عبر متاجر تطبيقات بديلة مستضافة مباشرة داخل Google Play.

لكن هذه الحرية المالية المكتشفة حديثاً تأتي بتكلفة تقنية باهظة. إذا تخلصت من Google Play Billing، فستفقد الـ receipt validation التلقائي، والـ offline caching، وتتبع الـ entitlement المركزي الذي كان يوفره. أنت الآن مسؤول بالكامل عن إدارة مشتريات لاعبيك بشكل آمن عبر عدة payment gateways.

إليك تعمق في التأثير التقني لهذه التغييرات، وكيفية هندسة backend لنظام billing آمن ومستقل عن المتجر يمنع الاحتيال ويحافظ على مزامنة حالات العالم (world states).

التأثير التقني لتسوية Epic ضد Google

قبل الغوص في الكود، نحتاج إلى فهم ما يغيره الأمر القضائي (الفعال من نوفمبر 2024 إلى نوفمبر 2027) بالضبط في بنية لعبتك.

1. توجيه المدفوعات الخارجية أصبح قانونياً الآن

لم يعد بإمكان Google حظر لعبتك لتضمينها روابط توجه اللاعبين إلى متصفح ويب لإكمال عملية الشراء. هذا يعني أنه يمكنك دمج مزودي دفع مثل Stripe أو Xsolla أو PayPal، والذين يتقاضون عادةً حوالي 2.9% إلى 5% بالإضافة إلى رسوم ثابتة صغيرة لكل معاملة. بالنسبة للعبة indie متوسطة تحقق 50,000 دولار شهرياً من الـ microtransactions، فإن الابتعاد عن رسوم المنصة البالغة 30% يوفر حوالي 12,500 دولار كل شهر.

2. الـ Sideloading ومتاجر الطرف الثالث

يمكن الآن توزيع متاجر التطبيقات البديلة مباشرة من خلال Google Play Store، ويُحظر على Google الدفع لمصنعي الأجهزة لتثبيت Google Play مسبقاً بشكل حصري. قد يقوم لاعبوك بتنزيل لعبتك من Epic Games Store أو Amazon Appstore أو مشغل خاص بالناشر، كل ذلك أثناء اللعب على نفس جهاز Android.

3. نهاية الـ Entitlements من مصدر واحد

تاريخياً، كان بإمكان game client ببساطة الاستعلام من Google Play Billing Library للسؤال: "هل يمتلك هذا المستخدم الـ battle pass المميز؟". إذا كانت الإجابة نعم، تقوم بفتح المحتوى.

الآن، قد يشتري اللاعب الـ battle pass عبر رابط Stripe على جهاز الكمبيوتر الخاص به، ثم يسجل الدخول إلى لعبتك التي تم تنزيلها من متجر Android بديل، ويتوقع أن يجد محتواه هناك. الـ validation من جانب العميل (client-side validation) مات رسمياً. يجب عليك الانتقال إلى بنية server-authoritative حيث يكون الـ backend الخاص بك هو المصدر الوحيد للحقيقة (single source of truth) لجميع مخازن اللاعبين.

هندسة Backend لنظام Entitlement مستقل عن المتجر

لدعم عدة payment gateways، يحتاج الـ backend الخاص بك إلى database schema قوية تفصل المعاملة المالية عن الـ entitlement داخل اللعبة.

لا تربط أبداً مخزون اللاعب مباشرة بـ receipt ID الخاص بمتجر معين. بدلاً من ذلك، استخدم جدول معاملات وسيط.

الـ Database Schema الموصى بها

لبناء هذا يدوياً، ستحتاج إلى ثلاثة جداول أساسية في قاعدة بياناتك (مثل PostgreSQL):

  • Users: ملف تعريف اللاعب الأساسي.
  • Transactions: يسجل الحدث المالي. يتضمن GatewayProvider (مثل "Stripe"، "Google"، "Xsolla")، و GatewayTransactionId، و Amount، و Currency، و Status (Pending، Completed، Refunded).
  • Entitlements: العناصر الفعلية داخل اللعبة التي يمتلكها المستخدم. يتضمن UserId، و ItemId، و AcquiredViaTransactionId، و RevokedAt.

عند حدوث عملية شراء، يقوم الـ payment gateway بضرب خادمك عبر webhook. يتحقق خادمك من الـ webhook، وينشئ سجل Completed في جدول Transactions، ثم يدرج العناصر المقابلة في جدول Entitlements.

تنفيذ عملية Webhook Validation آمنة من جانب الخادم

الجزء الأكثر أهمية في هذه البنية الجديدة هو الـ webhook handler. إذا كنت توجه اللاعبين إلى صفحة دفع تابعة لجهة خارجية، فسيقوم هذا المزود الخارجي بإرسال طلب HTTP POST إلى الـ backend الخاص بك عند نجاح الدفع.

يقوم المحتالون بمسح نقاط نهاية الـ webhook غير المحمية بنشاط. إذا كانت نقطة النهاية الخاصة بك تقبل payloads JSON بشكل أعمى دون التحقق من التوقيعات التشفيرية، فسيقوم المهاجمون بتزوير رسائل "نجاح الدفع" ومنح أنفسهم عملة مميزة لا نهائية.

إليك مثال TypeScript جاهز للإنتاج باستخدام Express.js. يوضح هذا المقطع كيفية التحقق من توقيع Stripe webhook بشكل آمن، وضمان الـ idempotency (حتى لا يتم تحصيل الرسوم من اللاعبين مرتين إذا تم إطلاق الـ webhook مرتين)، وتحديث قاعدة بيانات اللاعب.

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 payload ستؤدي إلى عدم تطابق في HMAC hash.

تأمين نقاط النهاية هذه ليس اختيارياً. كما رأينا في حوادث الصناعة الكبرى، فإن الفشل في تقوية الـ backend ضد طلبات HTTP المزيفة هو وسيلة مضمونة لتدمير اقتصاد لعبتك. لإلقاء نظرة أعمق على كيفية أداء الـ APIs المكشوفة إلى ثغرات كارثية، اقرأ تحليلنا حول The Star Citizen Data Breach Explained Architecting Game Backends To Survive Compromises.

حل مشكلة المزامنة في الوقت الفعلي (Real-Time Synchronization)

لقد حللنا منطق الـ entitlement في الـ backend، لكننا نواجه الآن مشكلة في تجربة المستخدم (UX).

تخيل مسار اللاعب:

  1. يضغط اللاعب على "شراء 1000 عملة" في لعبتك على Android.
  2. تفتح اللعبة متصفح الويب الخاص بالجهاز للذهاب إلى صفحة الدفع المخصصة لك.
  3. يكمل اللاعب عملية الشراء عبر بطاقة الائتمان.
  4. يقوم الـ payment gateway بإرسال webhook إلى خادمك.
  5. يعود اللاعب إلى تطبيق لعبتك.

كيف يعرف game client أن عملية الشراء نجحت؟ إذا كنت تعتمد على HTTP polling (جعل العميل يسأل الخادم "هل اشتريت بالفعل؟" كل 3 ثوانٍ)، فستستنزف بطارية الجهاز وتنهك الـ backend بطلبات عديمة الفائدة.

بدلاً من ذلك، يحتاج الـ backend الخاص بك إلى دفع (push) حالة المخزون المحدثة إلى العميل في نفس الملي ثانية التي يتم فيها تنفيذ معاملة قاعدة البيانات. يتطلب هذا اتصالاً ثنائي الاتجاه مستمراً. إذا كنت تبني هذه البنية التحتية من الصفر، فستحتاج إلى تنفيذ طبقة WebSocket تستمع إلى أحداث قاعدة بياناتك وتبثها إلى جلسة العميل النشطة.

إذا كنت تواجه صعوبة في هندسة ذلك، يمكنك تعلم كيفية تنفيذ إشعارات الدفع في الوقت الفعلي في دليلنا: Ditch Http Polling An Unreal Engine Websockets Tutorial For Real Time Backends.

5 ممارسات فضلى لنظام Third-Party Mobile Billing

إذا كنت تقوم بنقل لعبتك بعيداً عن مكتبة Google Play Billing القياسية للاستفادة من هذه التغييرات الجديدة، فالتزم بهذه الممارسات الهندسية الخمس:

  1. فرض Idempotency صارم: تحدث مهلات الشبكة (network timeouts) باستمرار على الأجهزة المحمولة. قد يرسل الـ payment gateway نفس webhook الـ "success" ثلاث مرات إذا استغرق خادمك وقتاً طويلاً للرد. تحقق دائماً من قاعدة بياناتك بحثاً عن TransactionId قبل منح العناصر لضمان عدم منح اللاعبين نسخاً متعددة من العنصر بالخطأ.
  2. أتمتة عمليات إلغاء الـ Chargeback: نظام Billing الطرف الثالث يعني أنك مسؤول عن التعامل مع عمليات استرداد الأموال (chargebacks). يجب أن يستمع الـ webhook handler لأحداث payment.refunded ويقوم تلقائياً بتمييز الصف المقابل في جدول Entitlements كـ Revoked. إذا تخطيت ذلك، فسيكتشف اللاعبون أنه يمكنهم استرداد أموالهم من بطاقة الائتمان والاحتفاظ بالعملة المميزة.
  3. فصل العميل عن الـ Gateway: يجب ألا يتواصل game client أبداً بشكل مباشر مع API الخاص بالـ payment gateway. يجب أن يطلب العميل رمز جلسة دفع من الـ backend الخاص بك، ويفتح الـ web view بهذا الرمز، ويترك الـ backend يتعامل مع التحقق الفعلي من المعاملة.
  4. تنفيذ الـ Graceful Degradation: إذا تعطلت قاعدة بياناتك، يجب أن تظل لعبتك قابلة للعب. قم بتخزين الـ entitlements محلياً على الجهاز باستخدام ملف حفظ مشفر، ولكن تحقق دائماً مقابل الحقيقة في جانب الخادم عندما يحاول اللاعب إنفاق العملة المميزة أو الانضمام إلى مباراة multiplayer.
  5. توحيد مسار العملة الافتراضية: لا تقم بإنشاء "Google Coins" و "Stripe Coins" منفصلة في قاعدة بياناتك. قم بربط جميع معاملات العملات الورقية الواردة بمعرف عملة افتراضية واحد وموحد في الـ backend لمنع حدوث مشاكل كبيرة في منطق واجهة مستخدم لعبتك.

التحقق من واقع البنية التحتية: Build vs. Buy

تعد تسوية Epic ضد Google فوزاً كبيراً لإيرادات المطورين، ولكنها تنقل عبء البنية التحتية مباشرة إلى كاهلك.

يتطلب بناء backend لنظام billing عالي التوفر ومستقل عن المتجر إعداد قواعد بيانات PostgreSQL، وتكوين Redis للـ idempotency caching، وإدارة شهادات SSL للـ webhooks الآمنة، وصيانة خوادم WebSocket لتحديثات العملاء في الوقت الفعلي. بالنسبة لفريق indie صغير، يستغرق هذا بسهولة من 4 إلى 6 أسابيع من هندسة الـ backend المخصصة — وهو وقت يجب قضاؤه في جعل لعبتك ممتعة بالفعل.

هذا هو بالضبط الاحتكاك الهندسي الذي نقضي عليه. مع horizOn، تأتي خدمات الـ backend المعقدة هذه معدة مسبقاً. توفر منصتنا نظام entitlement مستقلاً عن المتجر وجاهزاً للاستخدام، يتعامل بأمان مع الـ server-to-server webhook validation، ويمنع المعاملات المكررة، ويزامن مخازن اللاعبين تلقائياً في الوقت الفعلي. ستحصل على الفوائد المالية لنظام billing الطرف الثالث دون الحاجة إلى أن تصبح مهندس DevOps.

نظرة إلى المستقبل

يمر نظام ألعاب الموبايل البيئي بأهم تغيير هيكلي له منذ أكثر من عقد. الحدائق المسورة تنهار أخيراً، والمطورون الذين يكيفون بنى الـ backend الخاصة بهم لتكون مستقلة عن المنصة سيجنون مكافآت مالية ضخمة من خلال تجنب ضريبة المنصة التقليدية البالغة 30%.

ومع ذلك، فإن هذه الحرية تتطلب مسؤولية تقنية. لم تعد سلطة جانب العميل (client-side authority) قابلة للتطبيق. إذا كنت تريد البقاء في عالم متعدد المتاجر والبوابات، فيجب أن تعامل الـ backend الخاص بك كمصدر مطلق للحقيقة.

هل أنت مستعد لتوسيع نطاق الـ multiplayer backend الخاص بك وتنفيذ entitlements آمنة وعبر المنصات دون كتابة آلاف الأسطر من أكواد البنية التحتية المتكررة؟ جرب horizOn مجاناً ودعنا نتولى هندسة خادمك حتى تتمكن من التركيز على شحن لعبتك.


المصدر: Major Google Play Changes as Epic v Google Ends