1. Giriş
Bu codelab'de tek seferlik ürün oluşturmaya, uygulamanızı Play Faturalandırma Kitaplığı (PBL) ile entegre etmeye ve satın alma işlemlerindeki düşüşlerin nedenlerini analiz etmeye odaklanacaksınız.
Kitle
Bu codelab, Play Faturalandırma Kitaplığı'nı (PBL) kullanan veya tek seferlik ürünlerinden para kazanmak için PBL'yi kullanmak isteyen Android uygulaması geliştiricilerine yöneliktir.
Öğrenecekleriniz...
- Google Play Console'da tek seferlik ürün oluşturma
- Uygulamanızı PBL ile entegre etme
- PBL'de tüketilebilir ve tüketilemez tek seferlik ürün satın alma işlemlerini işleme
- Satın alma sürecindeki düşüşleri analiz etme
İhtiyacınız olanlar...
- Geliştirici hesabı ile Google Play Console'a erişim Geliştirici hesabınız yoksa hesap oluşturmanız gerekir.
- Bu codelab için GitHub'dan indirebileceğiniz bir örnek uygulama.
- Android Studio.
2. Örnek uygulamayı oluşturma
Örnek uygulama, aşağıdaki yönleri gösteren eksiksiz kaynak koduna sahip, tamamen işlevsel bir Android uygulaması olacak şekilde tasarlanmıştır:
- Uygulamayı PBL ile entegre etme
- Tek seferlik ürünleri getirme
- Tek seferlik ürünler için satın alma akışlarını başlatın
- Aşağıdaki faturalandırma yanıtlarına yol açan satın alma senaryoları:
BILLING_UNAVAILABLE
USER_CANCELLED
OK
ITEM_ALREADY_OWNED
Aşağıdaki demo videosunda, örnek uygulamanın dağıtılıp çalıştırıldıktan sonra nasıl görüneceği ve davranacağı gösterilmektedir.
Ön koşullar
Örnek uygulamayı oluşturup dağıtmadan önce aşağıdakileri yapın:
- Google Play Console geliştirici hesabı oluşturun. Zaten bir geliştirici hesabınız varsa bu adımı atlayın.
- Play Console'da yeni bir uygulama oluşturun. Uygulama oluştururken örnek uygulama için istediğiniz uygulama adını belirtebilirsiniz.
- Android Studio'yu yükleyin.
Derleme
Bu derleme adımının amacı, örnek uygulamanın imzalı bir Android App Bundle dosyasını oluşturmaktır.
Android uygulama paketini oluşturmak için aşağıdaki adımları uygulayın:
- GitHub'dan örnek uygulamayı indirin.
- Örnek uygulamayı oluşturun. Oluşturmadan önce örnek uygulamanın paket adını değiştirin ve ardından oluşturun. Play Console'da başka uygulamaların paketleri varsa örnek uygulama için sağladığınız paket adının benzersiz olduğundan emin olun.
Not: Örnek uygulamayı oluşturduğunuzda yalnızca yerel test için kullanabileceğiniz bir APK dosyası oluşturulur. Ancak, uygulama çalıştırıldığında ürünler ve fiyatlar getirilmez. Bunun nedeni, ürünlerin Play Console'da yapılandırılmamış olmasıdır. Bu yapılandırmayı bu codelab'in ilerleyen bölümlerinde yapacaksınız. - İmzalı bir Android App Bundle oluşturun.
Bir sonraki adım, Android uygulama paketini Google Play Console'a yüklemektir.
3. Play Console'da tek seferlik ürün oluşturma
Google Play Console'da tek seferlik ürünler oluşturmak için Play Console'da bir uygulamanızın olması gerekir. Play Console'da bir uygulama oluşturun ve daha önce oluşturulan imzalı uygulama paketini yükleyin.
Uygulama oluşturma
Uygulama oluşturmak için:
- Geliştirici hesabınızı kullanarak Google Play Console'da oturum açın.
- Uygulama oluştur'u tıklayın. Uygulama oluştur sayfası açılır.
- Uygulama adını girin, varsayılan dili ve uygulamayla ilgili diğer ayrıntıları seçin.
- Uygulama oluştur'u tıklayın. Bu işlem, Google Play Console'da bir uygulama oluşturur.
Artık örnek uygulamanın imzalı uygulama paketini yükleyebilirsiniz.
İmzalı uygulama paketini yükleyin
- İmzalı uygulama paketini Google Play Console'un dahili test kanalına yükleyin. Para kazanmayla ilgili özellikleri Play Console'da yalnızca yükleme işleminden sonra yapılandırabilirsiniz.
- Test edin ve yayınlayın > Test > Dahili sürüm > Yeni sürüm oluştur'u tıklayın.
- Bir sürüm adı girin ve imzalı uygulama paketi dosyasını yükleyin.
- Sonraki'yi ve ardından Kaydet ve yayınla'yı tıklayın.
Artık tek seferlik ürünlerinizi oluşturabilirsiniz.
Tek seferlik ürün oluşturma
Tek seferlik ürün oluşturmak için:
- Google Play Console'da soldaki gezinme menüsünden Google Play ile para kazanın > Ürünler > Tek seferlik ürünler'e gidin.
- Tek seferlik ürün oluştur'u tıklayın.
- Aşağıdaki ürün ayrıntılarını girin:
- Ürün kimliği: Benzersiz bir ürün kimliği girin.
one_time_product_01
yazın. - (İsteğe bağlı) Etiketler: Alakalı etiketler ekleyin.
- Ad: Ürün adı girin. Örneğin,
Product name
. - Açıklama: Ürün açıklaması girin. Örneğin,
Product description
. - (İsteğe bağlı) Simge görseli ekleyin: Ürününüzü temsil eden bir simge yükleyin.
- Ürün kimliği: Benzersiz bir ürün kimliği girin.
- İleri'yi tıklayın.
- Satın alma seçeneği ekleyin ve bölgesel kullanılabilirliğini yapılandırın. Tek seferlik ürünler için en az bir satın alma seçeneği gerekir. Bu seçenek, yetkinin nasıl verileceğini, fiyatını ve bölgesel stok durumunu tanımlar. Bu codelab'de ürün için standart Satın al seçeneğini ekleyeceğiz.Satın alma seçeneği bölümünde aşağıdaki ayrıntıları girin:
- Satın alma seçeneği kimliği: Satın alma seçeneği kimliği girin. Örneğin,
buy
. - Satın alma türü: Satın al'ı seçin.
- (İsteğe bağlı) Etiketler: Bu satın alma seçeneğine özel etiketler ekleyin.
- (İsteğe bağlı) Gelişmiş seçenekleri yapılandırmak için Gelişmiş seçenekler'i tıklayın. Bu codelab'in amacı doğrultusunda gelişmiş seçenekler yapılandırmasını atlayabilirsiniz.
- Satın alma seçeneği kimliği: Satın alma seçeneği kimliği girin. Örneğin,
- Stok durumu ve fiyatlandırma bölümünde Fiyatları ayarla > Fiyatlandırmayı toplu olarak düzenle'yi tıklayın.
- Ülke / bölge seçeneğini belirleyin. Bu işlem tüm bölgeleri seçer.
- Devam'ı tıklayın. Fiyat girmeniz için bir iletişim kutusu açılır. 10 ABD doları girip Uygula'yı tıklayın.
- Kaydet'i ve ardından Etkinleştir'i tıklayın. Bu işlem, satın alma seçeneğini oluşturup etkinleştirir.
Bu codelab'de kullanmak üzere aşağıdaki ürün kimliklerine sahip 3 ek tek seferlik ürün oluşturun:
- consumable_product_01
- consumable_product_02
- consumable_product_03
Örnek uygulama, bu ürün kimliklerini kullanacak şekilde yapılandırılmıştır. Farklı ürün kimlikleri sağlayabilirsiniz. Bu durumda, sağladığınız ürün kimliğini kullanmak için örnek uygulamayı değiştirmeniz gerekir.
Google Play Console'da örnek uygulamayı açın ve Play ile para kazanma > Ürünler > Tek seferlik ürünler'e gidin. Ardından Tek seferlik ürün oluştur'u tıklayın ve 3-9 arasındaki adımları tekrarlayın.
Tek seferlik ürün oluşturma videosu
Aşağıdaki örnek videoda, daha önce açıklanan tek seferlik ürün oluşturma adımları gösterilmektedir.
4. PBL ile entegrasyon
Şimdi uygulamanızı Play Faturalandırma Kitaplığı (PBL) ile nasıl entegre edeceğinizi göreceğiz. Bu bölümde, entegrasyonla ilgili üst düzey adımlar açıklanmakta ve her adım için bir kod snippet'i sağlanmaktadır. Bu snippet'leri, gerçek entegrasyonunuzu uygularken yol gösterici olarak kullanabilirsiniz.
Uygulamanızı PBL ile entegre etmek için aşağıdaki adımları uygulayın:
- Örnek uygulamaya Play Faturalandırma Kitaplığı bağımlılığını ekleyin.
dependencies { val billing_version = "8.0.0" implementation("com.android.billingclient:billing-ktx:$billing_version") }
- BillingClient'ı başlatın. BillingClient, uygulamanızda bulunan ve Play Faturalandırma Kitaplığı ile iletişim kuran istemci SDK'sıdır. Aşağıdaki kod snippet'inde faturalandırma istemcisinin nasıl başlatılacağı gösterilmektedir.
protected BillingClient createBillingClient() { return BillingClient.newBuilder(activity) .setListener(purchasesUpdatedListener) .enablePendingPurchases(PendingPurchasesParams.newBuilder().enableOneTimeProducts().build()) .enableAutoServiceReconnection() .build(); }
- Google Play'e bağlanın.Aşağıdaki kod snippet'inde Google Play'e nasıl bağlanılacağı gösterilmektedir.
public void startBillingConnection(ImmutableList<Product> productList) { Log.i(TAG, "Product list sent: " + productList); Log.i(TAG, "Starting connection"); billingClient.startConnection( new BillingClientStateListener() { @Override public void onBillingSetupFinished(BillingResult billingResult) { if (billingResult.getResponseCode() == BillingResponseCode.OK) { // Query product details to get the product details list. queryProductDetails(productList); } else { // BillingClient.enableAutoServiceReconnection() will retry the connection on // transient errors automatically. // We don't need to retry on terminal errors (e.g., BILLING_UNAVAILABLE, // DEVELOPER_ERROR). Log.e(TAG, "Billing connection failed: " + billingResult.getDebugMessage()); Log.e(TAG, "Billing response code: " + billingResult.getResponseCode()); } } @Override public void onBillingServiceDisconnected() { Log.e(TAG, "Billing Service connection lost."); } }); }
- Tek seferlik ürün ayrıntılarını getirin.Uygulamanızı PBL ile entegre ettikten sonra tek seferlik ürün ayrıntılarını uygulamanıza getirmeniz gerekir. Aşağıdaki kod snippet'i, tek seferlik ürün ayrıntılarını uygulamanıza nasıl getireceğinizi gösterir.
private void queryProductDetails(ImmutableList<Product> productList) { Log.i(TAG, "Querying products for: " + productList); QueryProductDetailsParams queryProductDetailsParams = QueryProductDetailsParams.newBuilder().setProductList(productList).build(); billingClient.queryProductDetailsAsync( queryProductDetailsParams, new ProductDetailsResponseListener() { @Override public void onProductDetailsResponse( BillingResult billingResult, QueryProductDetailsResult productDetailsResponse) { // check billingResult Log.i(TAG, "Billing result after querying: " + billingResult.getResponseCode()); // process returned productDetailsList Log.i( TAG, "Print unfetched products: " + productDetailsResponse.getUnfetchedProductList()); setupProductDetailsMap(productDetailsResponse.getProductDetailsList()); billingServiceClientListener.onProductDetailsFetched(productDetailsMap); } }); }
ProductDetails
getirme işlemi, aşağıdakine benzer bir yanıt verir:{ "productId": "consumable_product_01", "type": "inapp", "title": "Shadow Coat (Yolo's Realm | Play Samples)", "name": "Shadow Coat", "description": "A sleek, obsidian coat for stealth and ambushes", "skuDetailsToken": "<---skuDetailsToken--->", "oneTimePurchaseOfferDetails": {}, "oneTimePurchaseOfferDetailsList": [ { "priceAmountMicros": 1990000, "priceCurrencyCode": "USD", "formattedPrice": "$1.99", "offerIdToken": "<--offerIdToken-->", "purchaseOptionId": "buy", "offerTags": [] } ] }, { "productId": "consumable_product_02", "type": "inapp", "title": "Emperor Den (Yolo's Realm | Play Samples)", "name": "Emperor Den", "description": "A fair lair glowing with molten rock and embers", "skuDetailsToken": "<---skuDetailsToken--->", "oneTimePurchaseOfferDetails": {}, "oneTimePurchaseOfferDetailsList": [ { "priceAmountMicros": 2990000, "priceCurrencyCode": "USD", "formattedPrice": "$2.99", "offerIdToken": "<--offerIdToken-->", "purchaseOptionId": "buy", "offerTags": [] } ] }
- Faturalandırma akışını başlatın.
public void launchBillingFlow(String productId) { ProductDetails productDetails = productDetailsMap.get(productId); if (productDetails == null) { Log.e( TAG, "Cannot launch billing flow: ProductDetails not found for productId: " + productId); billingServiceClientListener.onBillingResponse( BillingResponseCode.ITEM_UNAVAILABLE, BillingResult.newBuilder().setResponseCode(BillingResponseCode.ITEM_UNAVAILABLE).build()); return; } ImmutableList<ProductDetailsParams> productDetailsParamsList = ImmutableList.of( ProductDetailsParams.newBuilder().setProductDetails(productDetails).build()); BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList(productDetailsParamsList) .build(); billingClient.launchBillingFlow(activity, billingFlowParams); }
- Satın alma işlemlerini algılayıp işleme. Bu adımda yapmanız gerekenler:
- Satın alma işlemini doğrulama
- Kullanıcıya yararlanma hakkı verme
- Kullanıcıyı bilgilendirme
- Satın alma süreci hakkında Google'ı bilgilendirme
private void handlePurchase(Purchase purchase) { // Step 1: Send the purchase to your secure backend to verify the purchase following // https://developer.android.com/google/play/billing/security#verify // Step 2: Update your entitlement storage with the purchase. If purchase is // in PENDING state then ensure the entitlement is marked as pending and the // user does not receive benefits yet. It is recommended that this step is // done on your secure backend and can combine in the API call to your // backend in step 1. // Step 3: Notify the user using appropriate messaging. if (purchase.getPurchaseState() == PurchaseState.PURCHASED) { for (String product : purchase.getProducts()) { Log.d(TAG, product + " purchased successfully! "); } } // Step 4: Notify Google the purchase was processed. // For one-time products, acknowledge the purchase. // This sample app (client-only) uses billingClient.acknowledgePurchase(). // For consumable one-time products, consume the purchase // This sample app (client-only) uses billingClient.consumeAsync() // If you have a secure backend, you must acknowledge purchases on your server using the // server-side API. // See https://developer.android.com/google/play/billing/security#acknowledge if (purchase.getPurchaseState() == PurchaseState.PURCHASED && !purchase.isAcknowledged()) { if (shouldConsume(purchase)) { ConsumeParams consumeParams = ConsumeParams.newBuilder().setPurchaseToken(purchase.getPurchaseToken()).build(); billingClient.consumeAsync(consumeParams, consumeResponseListener); } else { AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); billingClient.acknowledgePurchase( acknowledgePurchaseParams, acknowledgePurchaseResponseListener); } } }
5. Satın alma sürecindeki bırakmaları analiz etme
Bu codelab'de şu ana kadar Play Faturalandırma yanıtları USER_CANCELLED, BILLING_UNAVAILABLE, OK ve ITEM_ALREADY_OWNED gibi yanıtlar gibi sınırlı senaryolara odaklandı. Ancak Play Faturalandırma, çeşitli gerçek dünya faktörleri tarafından tetiklenebilen 13 farklı yanıt kodu döndürebilir.
Bu bölümde, USER_CANCELLED
ve BILLING_UNAVAILABLE
hata yanıtlarının nedenleri ayrıntılı olarak açıklanmakta ve uygulayabileceğiniz olası düzeltici işlemler önerilmektedir.
USER_CANCELED yanıt hata kodu
Bu yanıt kodu, kullanıcının satın alma işlemini tamamlamadan önce satın alma akışı kullanıcı arayüzünden çıktığını gösterir.
Olası nedenler | Hangi işlemleri yapabilirsiniz? |
|
|
BILLING_UNAVAILABLE yanıt hata kodu
Bu yanıt kodu, kullanıcının ödeme sağlayıcısı veya seçtiği ödeme şekliyle ilgili bir sorun nedeniyle satın alma işleminin tamamlanamadığı anlamına gelir. Örneğin, kullanıcının kredi kartının süresi dolmuş veya kullanıcı, desteklenmeyen bir ülkede bulunuyor. Bu kod, Play Faturalandırma sisteminin kendisiyle ilgili bir hatayı göstermez.
Olası nedenler | Hangi işlemleri yapabilirsiniz? |
|
|
Yanıt hata kodları için yeniden deneme stratejileri
Play Faturalandırma Kitaplığı'ndaki (PBL) kurtarılabilir hatalar için etkili yeniden deneme stratejileri, oturumdaki kullanıcı etkileşimleri (ör. satın alma işlemi sırasında) ile arka plan işlemleri (ör. uygulama devam ettirildiğinde satın alma işlemlerini sorgulama) gibi bağlama göre değişir. Bu stratejileri uygulamak önemlidir. Çünkü belirli BillingResponseCode
değerleri, yeniden denemeyle çözülebilecek geçici sorunları ifade ederken diğerleri kalıcıdır ve yeniden deneme gerektirmez.
Kullanıcı oturumdayken karşılaşılan hatalar için kullanıcı deneyimindeki kesintiyi en aza indirmek amacıyla belirli bir maksimum deneme sayısına sahip basit bir yeniden deneme stratejisi kullanılması önerilir. Buna karşılık, yeni satın alma işlemlerini onaylama gibi hemen yürütülmesini gerektirmeyen arka plan işlemleri için üstel geri çekilme yaklaşımı önerilir.
Belirli yanıt kodları ve bunlara karşılık gelen önerilen yeniden deneme stratejileri hakkında ayrıntılı bilgi için BillingResult yanıt kodlarını işleme başlıklı makaleyi inceleyin.
6. Sonraki adımlar
- Play faturalandırma entegrasyonunuzdan en iyi şekilde nasıl yararlanacağınızı öğrenin.
- Kullanıcılar bu ürünleri satın almaya başladığında güvenli arka uçta satın alma işlemlerini doğrulama ve işleme ile ilgili en iyi uygulamaları uyguladığınızdan emin olun.
Referans belgeleri
7. Tebrikler!
Tebrikler! Google Play Console'da başarılı bir şekilde gezinerek yeni bir tek seferlik ürün oluşturdunuz, faturalandırma yanıt kodlarını test ettiniz ve satın alma işlemlerindeki düşüşleri analiz ettiniz.
Anket
Bu codelab ile ilgili geri bildiriminiz bizim için çok değerli. Anketimizi tamamlamak için birkaç dakikanızı ayırabilirsiniz.