Bloga Dön

Google Play Değişiklikleri ve Epic Uzlaşması: Third-Party Mobile Billing Mimarisi

Yayınlanma tarihi 6 Mart 2026
Google Play Değişiklikleri ve Epic Uzlaşması: Third-Party Mobile Billing Mimarisi

Her mobil oyun geliştiricisi aylık gelir paneline bakmış ve kâr marjlarını anında buharlaştıran %30'luk platform ücretini görünce irkilmiştir. Yıllarca Android geliştiricileri katı bir ekosisteme hapsolmuştu: Oyununuzu dünyanın en büyük mobil mağazasında yayınlamak istiyorsanız, onların tescilli billing sistemini kullanmak, mikro işlemlerinizin büyük bir kısmını teslim etmek ve tüm entitlement mimarinizi onların özel API'ları etrafında kurmak zorundaydınız.

Bu dönem resmen sona eriyor. google play changes epic settlement şartlarının getirdiği fırsatlardan tam olarak yararlanmak için geliştiricilerin backend altyapılarını temelden yeniden düşünmeleri gerekiyor.

Epic Games vs. Google hukuk savaşının yakın zamandaki sonucu, Android ekosistemini ardına kadar açan mahkeme kararlı değişikliklerle sonuçlandı. Geliştiriciler artık oyuncuları harici payment gateway'lere yönlendirebilir, zorunlu %30 vergisini baypas edebilir ve hatta doğrudan Google Play içinde barındırılan alternatif uygulama mağazaları aracılığıyla dağıtım yapabilirler.

Ancak bu yeni finansal özgürlük, ciddi bir teknik maliyetle birlikte geliyor. Google Play Billing'den vazgeçerseniz, onun sağladığı otomatik receipt validation, offline caching ve merkezi entitlement takibi özelliklerini kaybedersiniz. Artık oyuncularınızın satın alımlarını birden fazla payment gateway üzerinden güvenli bir şekilde yönetmekten tamamen siz sorumlusunuz.

İşte bu değişikliklerin teknik etkilerine derinlemesine bir bakış ve dolandırıcılığı önleyen, dünya durumlarınızı (world states) senkronize tutan, mağazadan bağımsız (store-agnostic) güvenli bir billing backend'i nasıl mimari edeceğinize dair bir rehber.

Epic vs. Google Uzlaşmasının Teknik Etkisi

Koda dalmadan önce, mahkeme ihtiyati tedbir kararının (Kasım 2024'ten Kasım 2027'ye kadar geçerli) oyununuzun mimarisi için tam olarak neleri değiştirdiğini anlamamız gerekiyor.

1. Harici Ödeme Yönlendirmesi Artık Yasal

Google, bir satın alma işlemini tamamlamak için oyuncuları bir web tarayıcısına yönlendiren bağlantılar içerdiği gerekçesiyle oyununuzu artık yasaklayamaz. Bu, genellikle işlem başına yaklaşık %2,9 ila %5 artı küçük bir sabit ücret alan Stripe, Xsolla veya PayPal gibi ödeme sağlayıcılarını entegre edebileceğiniz anlamına gelir. Mikro işlemlerden ayda 50.000 dolar gelir elde eden bir mid-core indie oyun için, %30 platform ücretinden uzaklaşmak her ay yaklaşık 12.500 dolar tasarruf sağlar.

2. Sideloading ve Üçüncü Taraf Mağazalar

Alternatif uygulama mağazaları artık doğrudan Google Play Store üzerinden dağıtılabiliyor ve Google'ın cihaz üreticilerine Google Play'i özel olarak önceden yüklemeleri için ödeme yapması yasaklandı. Oyuncularınız oyununuzu Epic Games Store, Amazon Appstore veya özel bir yayıncı launcher'ından indirebilir ve tüm bunları aynı Android cihazda oynarken yapabilirler.

3. Tek Kaynaklı Entitlement'ların Sonu

Tarihsel olarak, oyun istemciniz Google Play Billing Library'ye basitçe şu soruyu sorabiliyordu: "Bu kullanıcı premium battle pass'e sahip mi?". Cevap evet ise içeriği açıyordunuz.

Şimdi, bir oyuncu PC'sindeki bir Stripe ödeme bağlantısı üzerinden battle pass satın alabilir, alternatif bir Android mağazasından indirilen oyununuza giriş yapabilir ve içeriğinin orada olmasını bekleyebilir. İstemci tarafı doğrulama (client-side validation) resmen öldü. Backend'inizin tüm oyuncu envanterleri için tek gerçeklik kaynağı (single source of truth) olduğu bir server-authoritative mimariye geçmelisiniz.

Mağazadan Bağımsız Bir Entitlement Backend'i Tasarlamak

Birden fazla payment gateway'i desteklemek için backend'inizin, finansal işlemi oyun içi entitlement'tan ayıran sağlam bir veritabanı şemasına ihtiyacı vardır.

Bir oyuncunun envanterini asla doğrudan belirli bir mağazanın makbuz kimliğine (receipt ID) bağlamayın. Bunun yerine, aracı bir işlem tablosu kullanın.

Önerilen Veritabanı Şeması

Bunu manuel olarak oluşturmak için ilişkisel veritabanınızda (örneğin PostgreSQL) üç temel tabloya ihtiyacınız olacaktır:

  • Users: Temel oyuncu profili.
  • Transactions: Finansal olayı günlüğe kaydeder. GatewayProvider (örneğin "Stripe", "Google", "Xsolla"), GatewayTransactionId, Amount, Currency ve Status (Pending, Completed, Refunded) içerir.
  • Entitlements: Kullanıcının sahip olduğu gerçek oyun içi öğeler. UserId, ItemId, AcquiredViaTransactionId ve RevokedAt içerir.

Bir satın alma gerçekleştiğinde, payment gateway sunucunuza bir webhook ile ulaşır. Sunucunuz webhook'u doğrular, Transactions tablosunda bir Completed kaydı oluşturur ve ardından ilgili öğeleri Entitlements tablosuna ekler.

Güvenli Sunucu Tarafı Webhook Doğrulaması Uygulamak

Bu yeni mimarinin en kritik parçası webhook handler'dır. Oyuncuları üçüncü taraf bir ödeme sayfasına yönlendiriyorsanız, ödeme başarılı olduğunda o harici sağlayıcı backend'inize bir HTTP POST isteği gönderecektir.

Dolandırıcılar korunmasız webhook endpoint'lerini aktif olarak tararlar. Eğer endpoint'iniz kriptografik imzaları doğrulamadan JSON payload'larını körü körüne kabul ederse, saldırganlar "ödeme başarılı" mesajları sahteciliği yapacak ve kendilerine sonsuz premium para birimi vereceklerdir.

İşte Express.js kullanan üretime hazır bir TypeScript örneği. Bu kod parçası, bir Stripe webhook imzasının nasıl güvenli bir şekilde doğrulanacağını, idempotency'nin nasıl sağlanacağını (böylece webhook iki kez tetiklenirse oyunculardan iki kez ücret alınmaz) ve oyuncunun veritabanının nasıl güncelleneceğini gösterir.

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'in Önemi

Yukarıdaki kodun, isteği JSON'a parse etmeden önce tam bayt akışını yakalamak için express.raw() kullandığına dikkat edin. JSON payload'undaki tek bir yanlış yerleştirilmiş boşluk bile eşleşmeyen bir HMAC hash'i ile sonuçlanacaktır.

Bu endpoint'leri güvenli hale getirmek isteğe bağlı değildir. Büyük endüstri olaylarında gördüğümüz gibi, backend'inizi sahte HTTP isteklerine karşı güçlendirmemek (hardening), oyununuzun ekonomisini mahvetmenin garantili bir yoludur. Açıkta kalan API'ların nasıl feci exploit'lere yol açtığına dair daha derin bir bakış için The Star Citizen Data Breach Explained Architecting Game Backends To Survive Compromises analizimizi okuyun.

Gerçek Zamanlı Senkronizasyon Problemini Çözmek

Backend entitlement mantığını çözdük, ancak şimdi bir UX problemiyle karşı karşıyayız.

Oyuncu akışını hayal edin:

  1. Oyuncu Android oyununuzda "1000 Coin Satın Al"a dokunur.
  2. Oyun, cihazın web tarayıcısını özel ödeme sayfanıza açar.
  3. Oyuncu kredi kartıyla satın alma işlemini tamamlar.
  4. Payment gateway sunucunuza bir webhook gönderir.
  5. Oyuncu oyun uygulamanıza geri döner.

Oyun istemcisi satın alma işleminin başarılı olduğunu nasıl anlar? Eğer HTTP polling'e (istemcinin sunucuya her 3 saniyede bir "Satın aldım mı?" diye sormasına) güvenirseniz, cihazın pilini tüketirsiniz ve backend'inizi gereksiz isteklerle döversiniz.

Bunun yerine, backend'inizin güncellenmiş envanter durumunu, veritabanı işleminin commit edildiği milisaniyede istemciye push etmesi gerekir. Bu, kalıcı bir çift yönlü bağlantı gerektirir. Eğer bu altyapıyı sıfırdan kuruyorsanız, veritabanı olaylarınızı dinleyen ve bunları aktif istemci oturumuna broadcast eden bir WebSocket katmanı uygulamanız gerekecektir.

Bunun mimarisiyle uğraşıyorsanız, bu gerçek zamanlı push bildirimlerini nasıl uygulayacağınızı rehberimizden öğrenebilirsiniz: Ditch Http Polling An Unreal Engine Websockets Tutorial For Real Time Backends.

Üçüncü Taraf Mobil Billing İçin 5 En İyi Uygulama

Oyununuzu bu yeni ekosistem değişikliklerinden yararlanmak için standart Google Play Billing kütüphanesinden taşıyorsanız, bu beş mimari en iyi uygulamaya bağlı kalın:

  1. Sıkı Idempotency Uygulayın: Mobil cihazlarda ağ zaman aşımları (network timeouts) sürekli olur. Sunucunuzun yanıt vermesi çok uzun sürerse, bir payment gateway aynı "başarılı" webhook'unu üç kez gönderebilir. Oyunculara yanlışlıkla bir öğenin birden fazla kopyasının verilmediğinden emin olmak için öğeleri vermeden önce her zaman veritabanınızda TransactionId kontrolü yapın.
  2. Chargeback İptallerini Otomatize Edin: Üçüncü taraf billing, chargeback ve iadeleri yönetmekten sizin sorumlu olduğunuz anlamına gelir. Webhook handler'ınız payment.refunded olaylarını dinlemeli ve Entitlements tablonuzdaki ilgili satırı otomatik olarak Revoked olarak işaretlemelidir. Bunu atlarsanız, oyuncular kredi kartlarından iade alıp premium para birimini ellerinde tutabileceklerini fark edeceklerdir.
  3. İstemciyi Gateway'den Ayırın: Oyun istemciniz asla doğrudan payment gateway'in API'ı ile iletişim kurmamalıdır. İstemci backend'inizden bir ödeme oturumu token'ı istemeli, web görünümünü bu token ile açmalı ve backend'in gerçek işlem doğrulamasını yapmasına izin vermelidir.
  4. Graceful Degradation Uygulayın: Veritabanınız çökerse oyununuz hala oynanabilir olmalıdır. Entitlement'ları şifrelenmiş bir save dosyası kullanarak cihazda yerel olarak önbelleğe alın, ancak oyuncu premium para birimi harcamaya veya bir multiplayer maça katılmaya çalıştığında her zaman sunucu tarafındaki gerçekle doğrulayın.
  5. Sanal Para Birimi Pipeline'ınızı Birleştirin: Veritabanınızda ayrı "Google Coin" ve "Stripe Coin" oluşturmayın. Oyununuzun UI mantığında büyük baş ağrılarını önlemek için backend'inizdeki tüm gelen fiat işlemlerini tek bir birleşik sanal para birimi kimliğine eşleyin.

Altyapıyı Kurmak mı Satın Almak mı? (Build vs. Buy)

Epic vs. Google uzlaşması geliştirici geliri için büyük bir kazançtır, ancak altyapı yükünü doğrudan sizin omuzlarınıza kaydırır.

Yüksek düzeyde erişilebilir, mağazadan bağımsız bir billing backend'i oluşturmak; PostgreSQL veritabanlarını kurmayı, idempotency önbelleğe alma için Redis'i yapılandırmayı, güvenli webhook'lar için SSL sertifikalarını yönetmeyi ve gerçek zamanlı istemci güncellemeleri için WebSocket sunucularını sürdürmeyi gerektirir. Küçük bir indie ekip için bu, kolayca 4 ila 6 haftalık özel backend mühendisliği demektir; bu süre aslında oyununuzu eğlenceli hale getirmek için harcanmalıdır.

Bu, tam olarak ortadan kaldırdığımız mimari sürtünmedir. horizOn ile bu karmaşık backend servisleri önceden yapılandırılmış olarak gelir. Platformumuz; sunucudan sunucuya webhook doğrulamasını güvenli bir şekilde yöneten, yinelenen işlemleri önleyen ve oyuncu envanterlerini gerçek zamanlı olarak otomatik olarak senkronize eden, kutudan çıktığı gibi mağazadan bağımsız bir entitlement sistemi sunar. Bir DevOps mühendisi olmak zorunda kalmadan üçüncü taraf billing'in finansal avantajlarını elde edersiniz.

Geleceğe Bakış

Mobil oyun ekosistemi, on yılı aşkın süredir en önemli yapısal değişikliğini yaşıyor. Kapalı bahçeler (walled gardens) sonunda yıkılıyor ve backend mimarilerini platformdan bağımsız olacak şekilde uyarlayan geliştiriciler, geleneksel %30 platform vergisinden kaçınarak büyük finansal ödüller kazanacaklar.

Ancak bu özgürlük teknik sorumluluk gerektirir. İstemci tarafı otoritesi (client-side authority) artık geçerli değildir. Çok mağazalı, çok gateway'li bir dünyada hayatta kalmak istiyorsanız, backend'inizi mutlak gerçeklik kaynağı olarak görmelisiniz.

Binlerce satır boilerplate altyapı kodu yazmadan multiplayer backend'inizi ölçeklendirmeye ve güvenli, platformlar arası entitlement'ları uygulamaya hazır mısınız? horizOn'u ücretsiz deneyin ve sunucu mimarinizi biz halledelim, böylece siz oyununuzu yayınlamaya odaklanabilirsiniz.


Kaynak: Major Google Play Changes as Epic v Google Ends