HMS In-App Purchase Kit

Cengizhan Özcan
Huawei Developers - Türkiye
11 min readJul 20, 2020

Günümüzde birçok mobil uygulama kullanıcılarına özel bir servis sağlamak için uygulama içi sanal ürün veya özel üyelik satma işlemi gerçekleştirir. Kullanıcıların satın alma işlemleri için geliştiricilerin kendi ödeme sistemlerini oluşturması ve güvenliğini sağlaması için çok büyük zaman harcaması gerekir. Ödeme sistemlerinin bu gibi zorluklarını ve sorumluluklarını ortadan kaldırmak ve geliştiricinin sadece uygulama özelinde efor sarf etmesini sağlayabilmek için Huawei Mobil Servisinin sunduğu In-App Purchase Kit bir çözüm olarak karşımıza çıkar.

  1. Huawei In-App Purchase Kit Nedir?

Huawei In-App Purchase (IAP), kullanıcılara uygulama içi satın alımları ve uygulama içi ödeme işlemlerini kolaylaştırmayı sağlayan servisleri sunar. Kullanıcılar bir kerelik sanal ürünler veya abonelikler dahil olmak üzere çeşitli ürünleri doğrudan uygulama üzerinden satın alabilir. Huawei In-App Purchase ayrıca Huawei uygulamaları (AppGallery, Temalar vb.) ile ilgili harici uygulamalardan ürün ve servis satın almalarına olanak tanır.

Kullanıcılara sağlanacak ürünlerin belirlenmesi, ücretlerin ve konumlara göre dillerin yönetilmesi için Huawei In-App Purchase Ürün Yönetim Sistemi sağlar. (Product Management System (PMS)). PMS ile kullanıcıların istikrarlı bir gelir elde edebilmesi için abonelik ilişkilerinin, abonelik sürelerinin, abone olunan ürünlerin ve tanıtım etkinliklerinin yönetimini sağlar.

IAP 3 farklı ürün tipini destekler. Bunlar:

2. Huawei In-App Purchase Özellikleri Nelerdir?

  • Kolay erişim ve test için sanal alan sağlanır.

HUAWEI IAP’ye hızlı ve kolay bir şekilde erişebilmek için kapsamlı erişim prosedürü kılavuzu ve korumalı alan test yapılandırması sağlanır.

  • Dünya çapında kullanım için dil ve para birimleri desteği içerir.

Kullanıcıların bulunduğu konumlara göre para birimleri ve bölgenin dili kullanılarak in-app purchase da gösterilir. 78 dil ve para birimini 170’den fazla ülke ve bölgede destekler.

  • Yüksek güvenlik, yüksek güvenilirlik ve 7/24 izleme imkânı sağlar.

Veri transferi gerçekleştirilirken verileri şifrelemek için TLS protokolü kullanılır ve RSA algoritması ile kullanıcı bilgilerini ele geçirilmesini önlemek için imzalanır. Ayrıca veriler arka planda kaydedilmeden önce şifrelenir ve anonimleştirilir.

Sunucular için küme (cluster) dağıtımı ve yedekleme mimarisi benimsenmiştir. Ayrıca 7/24 gerçek zamanlı sistem izleme, bir hatanın bulunması ve işlemleri için yardım sağlanır.

  • Global ödemeler için birden fazla ödeme yöntemini içerir.

Kullanıcılar banka kartları, Alipay, WeChat, doğrudan operatör faturalandırması ve Huawei puanlarıyla ödeme yapabilir. Banka Kartları, Çin’deki büyük bankaların yanı sıra Visa ve Mastercard’ı kapsar. Doğrudan operatör faturalandırması Çin dışındaki birçok büyük operatör tarafından desteklenir. Kullanıcılar banka kartlarını ve telefon numaralarını HUAWEI kimliklerine bağlayabilir ve daha önce belirledikleri ödeme şifrelerini girerek ödeme yapabilir.

Aşağıdaki tablo konumlara göre desteklenen ödeme yöntemleridir:

3. Huawei In-App Purchase Kit Projeye nasıl entegre edilir?

Huawei IAP Kiti projeye entegre etmeden önce birkaç gereksinime sahip olunması gerekir. Bunlar;

  • Android Studio 3.0 or later
  • Java SDK 1.7 or later
  • HMS Core (APK) 3.0.0.300 or later
  • HMS Core SDK 4.0.0.300 or later

3.1 AppGallery Connect’te Yeni Uygulama Oluşturma

Huawei In-App Purchase Kiti uygulamada kullanabilmek için öncelikle AppGallery Connect Console’da oturum açıp My apps bölümüne tıklanması gerekir.

Açılan sayfada yeni bir uygulama oluşturalım.

Yeni uygulama oluşturma bölümünde zorunlu olan alanları dolduralım.

Başarılı bir şekilde uygulamamızı oluşturduktan sonra App Information bölümü otomatik olarak gösterilecektir. Bu bölümde AppGallery sistemi tarafından uygulamamıza atanan App ID ve App Secret değerlerini görebiliriz.

Develop bölümüne tıkladığımız zaman karşımıza uygulamamızda kullandığımız package name için iki seçenek çıkar. Manuel olarak package name’mizi giriyoruz ve Save butonuna tıklıyoruz.

Açılan sayfada agconnect-services.json dosyasını tıklayarak indirelim ve Android Studio üzerinden app kök dizinine kopyalayalım.

Uygulamamızda SHA256 parmak izini oluşturmak için Android Studio üzerinden bir imza dosyası oluşturalım. Android Studio üzerinden Build bölümünden Generate Signed Bundle / APK ya tıklayalım.

Açılan popup üzerinden APK’ yı seçelim ve Next butonuna tıklayalım.

Yeni bir imza dosyası oluşturmak için Create New butonuna tıklayalım.

JKS dosyasını oluşturmak için tüm alanları dolduralım.

Başarılı bir şekilde imza dosyasını oluşturduktan sonra Generate Signed Bundle or APK sayfası otomatik olarak karşımıza çıkar. Next butonuna tıklayalım.

Açılan ekranda V1 (Jar Signature) ve V2 (Full APK Signature) seçeneklerini seçelim. Finish butonuna tıklayalım.

Başarılı bir şekilde imzalı bir APK dosyası oluşturduk. Şimdi İmzalı Sertifika Parmak İzini oluşturalım.

Terminal açalım.

Oluşturduğumuz JKS dosyasının bulduğu dizine gidelim. Dizinin içinde

keytool -list -v -keystore inapppurchaseexample.jks

terminal komutunu çalıştıralım ve istenilen şifreye JKS dosyasını oluştururken kullandığımız şifreyi girelim.

Oluşturulann SHA256 parmak izini kopyalayalım ve AppGallery üzerinden General information bölümünden SHA-256 certificate fingerprint alanına kopyalayalım ve kayıt edelim.

App dizininde build.gradle dosyasına oluşturduğumuz imza dosyasının bilgilerini ekleyelim.

Şimdi projemizi açalım ve root dizinindeki build.gradle dosyasını açalım ve buildscript -> repositories bölümüne HMS Core SDK için Maven repository adresini ekleyelim.

App dizinindeki build.gradle dosyasına agconnect plugin ve implementation bağımlılıklarını ekleyelim.

Projemizi senkronize edelim. Bir hata oluşursa ağ bağlantılarımızı veya build.gradle dosyalarını tekrar gözden geçirelim. Bu adımları tamamladıktan sonra başarılı bir şekilde HMS In-App Purchase Kit servisini uygulamamıza eklemiş oluyoruz.

AppGallery de Manage APIs bölümünde In-App Purchase Kit imizi aktive edelim.

In-App Purchase Kit i aktive etmeye çalıştığımızda karşımıza Satıcı Servisini etkileştirmemizi ve Huawei Developer Satıcı Servis Sözleşmesini imzalamamızı isteyen bir ekran çıkar. Merchant Service e tıklayalım.

Açılan sayfada sözleşmeyi okuyup kabul edelim.

Huawei Satış Servisinin geliştiriciye ödeme yapabilmesi için banka hesap bilgilerini eksiksiz girelim.

Submit butonuna tıkladıktan sonra girdiğimiz bilgilerin doğruluğunu onaylayalım ve tekrardan Submit butonuna tıklayalım.

Huawei banka hesap bilgilerimizin doğruluğunu teyit etmek için bilgileri inceleyip 1 ila 2 iş günü içerisinde geri dönüş yapıyor.

Ürün Ekleme

Kullanıcılar tarafından satın alınmasını istediğimiz ürün veya servislerin iki farklı türü vardır. İlk tür olarak abonelik gerektirmeyen ürün veya servisler, ikinci tür olarak abonelik gerektiren ürün veya servislerdir. Bu yazımızda ele alacağımız tür abonelik gerektirmeyen türdür.

Abonelik gerektirmeyen tür kendi içinde tüketilebilir ve tüketilemez olarak ikiye ayrılır. Adım adım tüketilebilir (consumable) ürün veya servisimizi oluşturalım.

AppGallery Connect adresine gidelim ve uygulamamızı seçelim. Açılan sayfada Operate tabına tıklayalım ve Product Management bölümüne girelim. Burada ürünümüzü eklemek için Add Product butonuna tıklayalım.

Açılan sayfada gerekli parametreleri dolduralım.

Product ID: Ürün ait benzersiz kimlik. Kimlik sadece büyük harfler (A-Z), küçük harfler (a-z), sayı (0–9), alt çizgi ( _ ) ve nokta (.) içerebilir. Maksimum 148 karakter olabilir. Ürün kimliği sonradan değiştirilemez. Ürün silinse dahi tekrardan kullanılamaz.

Language: Ürün isim ve açıklamasında kullanılacak olan dil. Her dil için ürün ismi ve açıklaması belirtilmelidir.

Product Name: Ürün ismi. Maksimum 50 karakter olabilir. Özel karakter kullanılamaz. ( # “ & / ? $ ^ * : ) \ < > , | % + )

Product Description: Ürün açıklaması. Maksimum 100 karakter olabilir. Özel karakter kullanılamaz. ( # “ & / ? $ ^ * : ) \ < > , | % + )

Ürünümüzün bilgilerini girdikten sonra Save butonuna tıklayalım. Butona tıkladıktan sonra View and edit butonuna tıklayıp ürün fiyat bilgisini girebiliriz.

Para biriminin Turkey (TRY) seçip ürün fiyatını (vergiler dahil) belirtelim. Fiyatımızı değiştirdikten sonra diğer para birimlerine karşılık gelen miktarı otomatik olarak belirlemek için Convert prices butonuna tıklayabiliriz. Ayrıca istediğimiz para birimlerine istediğimiz fiyatı girebiliriz. Ürün fiyatını belirttikten sonra Save butonuna tıklayalım.

Ürünümüzü oluşturduktan sonra oluşturulan ürünlerin listesini görmek için tekrardan Product Management bölümüne girelim. Burada oluşturduğumuz ürünü kullanıcılara gösterebilmek için Activate butonuna tıklayalım. Böylelikle ürünümüzü oluşturmuş oluyoruz.

Huawei IAP Desteğini Kontrol Etme

Huawei In-App Purchase’ ı uygulamada kullanmadan önce, oturum açmış olan Huawei kimliğinin Huawei IAP’nin bulunduğu bir konumda olup olmadığını kontrol etmek için IAP’ ye bir isEnvReady isteği gönderelim.

İstek sonucu başarılı olursa, uygulamada şu anda oturum açmış olan Huawei kimlikli kullanıcının bulunduğu konumun Huawei IAP’yi desteklediğini belirten bir IsEnvReadyResult örneğini alır.

İstek sonucu başarısız olursa, IAP hata objesi döner. Eğer bu obje IapApiException ise, isteğin sonuç kodunu getStatusCode() metodunu kullanarak alalım.

Sonuç kodu OrderStatusCode.ORDER_HWID_NOT_LOGIN ise (Huawei kimliği ile oturum açmamışsa), Huawei Kimliği ile oturum açma sayfasını açmak için IapApiException nesnesindeki status’ü kullanalım. Daha sonra Activity’nin onActivityResult metodundan sonucu elde edelim. Eğer returnCode, OrderStatusCode.SUCCESS ise Huawei kimliği ile oturum açmış kullanıcının bulunduğu konum Huawei IAP’yi desteklediğini anlamış oluruz. Eğer returnCode farklı ise desteklemediğini anlamış oluruz.

Ürün Bilgisini Gösterme

AppGallery Connect üzerinden oluşturulan ürünleri detaylı bir şekilde uygulamada elde edebilmek için obtainProductInfo API’ sini kullanmamız gerekir.

API’yi kullanabilmek için ilk önce bir ProductInfoReq objesi oluşturalım. ProductIdList listesine AppGallery Connect üzerinden oluşturduğumuz ürünlerin product ID lerini ekleyelim. Request objemizin priceType’ını 0 olarak yani tüketilebilir (consumable) olarak belirleyelim.

Oluşturduğumuz bu objeyi obtainProductInfo API’nda request objesi olarak kullanalım. OnSuccessListener ve OnFailureListener callbacklerini kullanarak yolladığımız isteğin sonucuna ulaşabiliriz.

Eğer istek sonucu başarılı ise, Huawei IAP ProductInfoResult objesini geri döner. Bu objenin getProductInfoList metodunu kullanarak ürün bilgilerinin bulunduğu ProductInfo obje listesine ulaşabiliriz. Böylelikle uygulamamızda satın alınmasını istediğimiz ürünlerin bilgisini detaylı bir şekilde (ücret, açıklama ve isim) gösterebiliriz.

Satın Alma İşlemini Başlatma

Uygulama üzerinden doğrudan kullanıcının ürünü satın alabilmesi için createPurchaseIntent API sini kullanarak satın alma isteği başlatalım.

İlk olarak PurchaseIntentReq objesini oluşturalım. Satın alınmak istenilen ürününün product ID’sini PurchaseIntentReq objesinde belirleyelim. PriceType olarak yine tüketilebilir (consumable) tipi belirleyelim. Bir sonraki adım olarak setDeveloperPayload methodu ile satıcı servisinde (Merchant Service) yapılan satış ile ilgili bilgiyi belirleyelim. Daha sonra createPurchaseIntent isteğini yollayalım.

Eğer istek başarılı ise, uygulama istek sonucu PurchaseIntentResult objesi geri döner. Bu objenin getStatus metodunu kullanarak Status objesini elde edelim. Uygulamamızda ödeme sayfasını gösterebilmek için Status objesinin startResolutionForResult metodunu kullanalım.

Uygulama Huawei IAP’nin ödeme sayfasını açıp, kullanıcının ise ödeme sürecini başarıyla tamamlamasından (ödeme süreci bir ürünün satın alınması veya ödemenin iptal edilmesi olabilir) sonra Huawei IAP onActivityResult metoduna ödeme sonucunu döner. Burada sonuç bilgisini elde edebilmek için parsePurchaseResultInfoFromIntent metodunu kullanarak PurchaseResultInfo objesine ulaşabiliriz.

Eğer satın alma işlemi başarılı ise, satın alma bilgisini PurchaseResultInfo objesinin getInAppPurchaseData methodunu kullanarak elde edilen InAppPurchaseData objesi üzerinden öğrenebiliriz. Yapılan işlem ile ilgili imza bilgisini PurchaseResultInfo üzerinden getInAppDataSignature metodu ile elde edebiliriz. Elde edilen imzanın doğruluğunu teyit etmek ve gelen cevapta bir karışıklık olup olmadığını kontrol etmek için AppGallery Connect üzerinden ulaşabileceğimiz public key i kullanarak sunucu tarafında uygulayacağımız metot ile bakabiliriz. Bu metot sunucu tarafında olacağı için bu yazımızda üzerinde daha fazla durmayacağım. Fakat detaylı bilgiye buradan ulaşabilirsiniz.

Kullanıcı tüketilebilir (consumable) bir ürün satın aldıysa ve eğer atılan istek sonucu cevap olarak ödeme hatası döndüyse burada teslimatın başarılı olup olmadığına bakılır. Bu kısmı yazının ilerleyen yerlerinde daha detaylı bir şekilde anlatıyor olacağım.

Satın Alma İşlemini Onaylama

Kullanıcı ürün ya da servisi satın aldığında, uygulama ödemenin başarılı olup olmadığını InAppPurchaseData objesinin purchaseState değişkininden kontrol edebilir. Eğer purchaseState 0 ise (satın alınmış), uygulama kullanıcıya satılan ürün veya servisi teslim eder ve Huawei IAP’ye bir teslimat onay isteği yollar.

Tüketilebilir ürünler için ilk olarak InAppPurchaseData objesinden JSON formatından purchaseToken’ ı parse ederek ürünün ya da servisin teslimat durumu kontrol edilir. Ürün ya da servisin kullanıcıya teslim edilme durumu başarılı ve teslim edilen ürünün veya servisin purchaseToken’ı elde edildiyse, uygulama Huaweı IAP sunucusunda teslimat durumunu güncellemek için consumeOwnedPurchase API’sini kullanır. Bu API’yi kullanmak için purchaseToken istek objesinde (ConsumeOwnedPurchaseReq) belirtilir. İstek başarılı olduktan sonra, Huawei IAP sunucusunda ürün durumu sıfırlanır ve böylelikle ürün tekrardan satın alınabilir duruma gelir.

Tüketilemez (non-consumable) ilgili onaylama durumlarını yazının ilerleyen kısmında anlatıyor olacağım.

Tüketilebilir Ürünlerin Tekrardan Teslimatı

Bazı durumlarda ödeme tamamlandıktan sonra bir hata oluşabilir. (örn internetin çekmemesi veya işlemin durdurulması) Bu gibi durumlarda uygulama ürünün ödemesi başarılımı değil mi kontrolünü yapamaz ve ürün kullanıcıya sağlıklı bir şekilde kullanıcıya teslim edilemeyebilir. Bu durumda Huawei IAP geliştiricilere tüketilebilir ürünlere tekrardan teslimat API’si sağlar. Grafik tekrardan teslimat sürecinin nasıl olduğunu gösterir.

Satın alınma işlemi sırasında bir hata oluşursa ve hata kodu -1 veya 60051 ise, satın alınmış fakat teslim edilmemiş ürün satın alma bilgilerine obtainOwnedPurchases API’ sini kullanarak ulaşabiliriz. OwnedPurchasesReq istek objesini oluştururken priceType’ı 0 yani tüketilebilir ürün olarak belirleyelim.

Eğer bu API’ya başarılı bir şekilde istek atılırsa, IAP cevap olarak OwnedPurchasesResult objesini döner. Bu cevap objesi ile satın alma bilgisi, imza bilgisi ve satın alınmış fakat teslim edilememiş tüm ürünlere erişilebilir. İlk olarak AppGallery Connect üzerinden ulaşabileceğimiz public key i kullanarak sunucu tarafında uygulayacağımız metot ile bakabiliriz. Bu metot sunucu tarafında olacağı için bu yazımızda üzerinde daha fazla durmayacağım. Fakat detaylı bilgiye buradan ulaşabilirsiniz. Satın alma bilgisinin her biri JSON formatında string karakterlerinden oluşur. Bu karakterlerlerin içerdiği parametrelere InAppPurchaseData objesinden ulaşılabilir. InAppPurchaseData stringi üzerinden purchaseState parametresini parse edelim. Eğer purchaseState parametresi 0 ise, satın alma işlemi başarılıdır. Burada bu satın alma işlemi için gerekli ürün veya servisimizi tekrardan teslim edelim.

Bu adımdan sonra tekrardan Huawei IAP sunucusunda ürün durumunu sıfırlamak ve ürünün tekrardan satın alınabilir duruma gelmesi için Satın Alma İşlemini Onaylama başlığında anlatılan consumeOwnedPurchase API’ sine istek yollayabiliriz.

Tüketilemez Ürün ya da Servislerin Teslim Edilmesi

Uygulamamız tüketilemez ürünleri kullanıcılara sağlıyorsa, geliştirici kullanıcının önceden satın aldığı ürünlerin bilgisini elde etmek için uygulama açılırken obtainOwnedPurchases API’sini kullanabilir. Eğer satın alınan ürün bilgisi cevap olarak döndüyse, purchaseState parametresinin 0 olduğuna bakarak satın alınan ürünleri doğrulayabiliriz.

İlk olarak OwnedPurcaseReq istek objesini oluşturalım. İstek objesinde priceType’ı 1 (non-consumable) olarak belirtelim.

İkinci adım olarak kullanıcının satın almış olduğu tüketilemez ürün veya servis bilgisini elde etmek için obtainOwnedPurchase API’ sini oluşturduğumuz istek objesi ile çağıralım.

Son olarak dönen sonuç üzerinden purchaseState parametresine bakarak ürünün veya servisin kullanıcıya teslim edilip edilmemesini bakalım.

Satın Alma Geçmişi

Uygulamada kullanıcının satın almış olduğu ürün veya servislerin geçmişini elde edebilmek için obtainOwnedPurchaseRecord API’ını kullanabiliriz.

İlk olarak OwnedPurchaseReq istek objesini oluşturalım. Geçmiş satın almalarını öğrenmek istediğimiz ürün veya servis tipini setPriceType metodu ile belirleyelim.

0: Tüketilebilir (Consumable)

1: Tüketileme (Non-Consumable)

2: Abonelik (Subscription)

Oluşturduğumuz istek objesiyle obtainOwnedPurchaseRecord API’sını çağıralım.

Kaynaklar

--

--