Figyelem! Az alant leírtak már nem működnek (azaz működik maga a kód, de a Google már nem engedi az adott library használatát, hiába 3.x az Anjlab cucca... )
Androidra rengeteg ingyenes, és fizetős alkalmazás is elérhető a Google Play-en. Amennyiben azonban fizetős alkalmazást készítünk, több követelménynek is meg kell felelnünk, ha a Google Play-en szeretnénk terjeszteni. Ez a bejegyzés segítség azoknak, akik szeretnének alkalmazáson belüli vásárlást (IAB, In-App-Billing) megvalósítani az appjaikban. A leírás nagyban az Anjlab Github-os oldalán alapul - a kódrészletek onnan vannak - mivel az ő library-jukra épül, és annak rutinjai mindenhol ugyanúgy működnek. Természetesen nem térek ki minden lehetőségre (így is elég hosszú lesz ), csak annyira, hogy egy egyszerű vásárlást működőképessé lehessen tenni ez alapján.
Az alapvetések :
- A Google Play-en a fizetések a Google BillingClient-en keresztül kell történjenek, különben a Google nem engedi ki az alkalmazást
- A BillingClient nem fog működni debug alkalmazásból; azaz mindenképpen kelleni fog egy fejlesztői fiók, mert abban lehet vásárolható terméket regisztrálni, és az alkalmazást tesztverzióként kiküldeni - a vásárlást csak Play-es tesztverzióban lehet tesztelni
- A BillingClient verziója nem mindegy, ugyanis pár évente váltanak új verzióra, és az új feltöltésekben már az aktuálisat kell használni - most épen a 3.x-et
Többféleképpen megpróbáltam a Google dokumentáció alapján a Billingclient integrációját, de sehogyan nem működött. Mondjuk nekem a Google dokisjai nem annyira jöttek be - nagyon részletesek, de egy kezdő programozónak kissé tömények.
A 3.x Billingclienthez (ami jelenleg használandó) viszont létezik az Anjlab In-App-Billing library-ja is, ami némileg emészthetőbb formában tálálja a Google IAB klienst. Ez néhány egyszerűbb eljárásba sűríti a BillingClient-et, amikben lekezelhető a vásárlás, a vásárolható termékek listázása, és a vásárlás kimenetelétől függően a válasz (sikertelen, sikeres...).
A library használatához a build.gradle file-ba a Maven repository-t fel kell venni :
repositories {
mavenCentral()
}
dependencies {
implementation 'com.anjlab.android.iab.v3:library:1.0.44'
}
A manifest file-ban a BillingClient-hez jogot kell kérnie az alkalmazásnak - külön a usertől, ahogy észrevettem, nem kell.<uses-permission android:name="com.android.vending.BILLING" />
Package szinten importálni kell a megfelelő könyvtárakat :import com.anjlab.android.iab.v3.BillingProcessor;
import com.anjlab.android.iab.v3.SkuDetails;
import com.anjlab.android.iab.v3.TransactionDetails;
Az Activity-nknek (vagy amiből majd meghívjuk a vásárlást) implementálnia kell a BillingHandler-t; valami hasonló módon : public class SomeActivity extends Activity implements BillingProcessor.IBillingHandler {
...
Az alkalmazás onCreate eljárásában példányosítani kell, és fel kell paraméterezni a BillingProcessor-t, a super.onCreate után :BillingProcessor bp;
bp = new BillingProcessor(this, "YOUR LICENSE KEY FROM GOOGLE PLAY CONSOLE HERE", this);
bp.initialize();
A Licence key az a kulcs, amit a Play Console-n akpunk a "Bevételszerzés beállításai" menüben (alul látható egy része) :
Ezt a kulcsot csak ki kell másolni (egy sor a kulcs, tehát nem lehet benne sortörés, és az elején/végén szóköz sem), és beilleszteni a fenti utasításba.
Ha már a Play Console-n vagyunk, érdemes mindjárt termékeket is létrehozni, amiket az appból meg lehet vásárolni. (Ezek később is módosíthatóak persze.)
A termékek létrehozása előtt kell készíteni egy árazási sablont, ami a Play Console bal oldali menüjében, a Bevételszerzés/Árazás menüben található. Ez alapján lehet árakat rendelni a termékekhez.
Termékeket létrehozni egy menüponttal lejjebb, az "Alkalmazáson belüli termékek" pontban lehet. A programkódban majd a termék nevére lesz szükség.
Érdemes valahol a programban ellenőrizni a Google Play Services elérhetőségét, és ennek függvényében engedni, vagy tiltani a vásárlást. Pl. így :
boolean isAvailable = BillingProcessor.isIabServiceAvailable();
if(!isAvailable) {
// continue
}
(A library kínál utasításokat a különböző vásárlási módok elérhetőségének ellenőrzésére is, ami szintén hasznos lehet.)
Az alábbi eljárások már a vásárlás kezeléséről szólnak, szintén az Activity-n belül lehet elhelyezni őket. Ezekbe mehet a saját kódunk, attól függően, hogy az egyes események bekövetkeztekor mit szeretnénk tenni (pl. sikeres vásárlás esetén megköszönni azt, vagy egy játékban lekezelni a vásárolt termékeket, stb.) Elég csak azokat használni, amikre szükség is van.
Az onBillingInitialized akkor fut le, amikor a BillingProcessor inicializálódott@Override
public void onBillingInitialized() {
/*
* Called when BillingProcessor was initialized and it's ready to purchase
*/
}
Az onproductPurchased a sikeres vásárlás után :@Override
public void onProductPurchased(String productId, TransactionDetails details) {
/*
* Called when requested PRODUCT ID was successfully purchased
*/
}
Az onBillingError sikertelen vásárlás esetén :@Override
public void onBillingError(int errorCode, Throwable error) {
/*
* Called when some error occurred. See Constants class for more details
*
* Note - this includes handling the case where the user canceled the buy dialog:
* errorCode = Constants.BILLING_RESPONSE_RESULT_USER_CANCELED
*/
}
Az onPurchaseHistoryRestored a vásárlási előzmények betöltésekor (itt lehet azokat pl. megjeleníteni) :@Override
public void onPurchaseHistoryRestored() {
/*
* Called when purchase history was restored and the list of all owned PRODUCT ID's
* was loaded from Google Play
*/
}
}
Amennyiben külön Activity-ből kezeljük a vásárlást, annak a Result metódusát is érdemes lehet felülírni :@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (!bp.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
A vásárolható termékek tulajonságait a GetPurchaseListingDetails
(előfizetésekre getSubscriptionListingDetails
)hívás adja meg, egy SkuDetails objektumban :SkuDetails sku = bp.getPurchaseListingDetails(PRODUCT_ID);
A sku objektum mezőiben pedig ott lesznek a tulajdonságai :public final String productId;
public final String title;
public final String description;
public final boolean isSubscription;
public final String currency;
public final Double priceValue;
public final String priceText;
...ahol a PRODUCT_ID paraméter a termék neve stringként. A fenti eljárásokkal több termék adatai is lekérhetőek, ha a termékek neveit tartalmazó stringtömböt adunk át nekik.
És itt már majdnem kész is van - már csak vásárolni kell. Ennek a legegyszerűbb esete, egyszeri vásárlás esetén abp.purchase(YOUR_ACTIVITY, "YOUR PRODUCT ID FROM GOOGLE PLAY CONSOLE HERE");
vagy előfizetés esetén abp.subscribe(YOUR_ACTIVITY, "YOUR SUBSCRIPTION ID FROM GOOGLE PLAY CONSOLE HERE");
utasítás. Ezeket bárhonnan meghívhatjuk a programban, ha a BillingProcessor már létezik. (Ugyanígy a termékek tulajdonságait it bármikor lekérhetjük.)
A product id/subscription id a korábban létrehozott termék neve, az Activity pedig amiből hívtuk a vásárlást (pl. this).
Consume típusú vásárlás esetén a bp.consumePurchase("YOUR PRODUCT ID FROM GOOGLE PLAY CONSOLE HERE");
utasítás a megfelelő
(Megadható a purchase-nek több paraméter is, de ezek már bonyolultabb esetek.)
Ezzel a hívással a usernek feljön a Google vásárlási felülete (így néz ki), amin elintézheti a fizetést. A vásárlás végeztével a programunkban meghívódik az onProductPurchased, vagy az onBillingError eljárás.
Továbbra is fontos, hogy a debug verziós app (amit pl. az Android Studio küld ki a telefonra) nem fog tudni vásárolni. A fizetést csak úgy lehet tesztelni, ha a Play-en az alkalmazás zárt/belső/nyílt tesztre feltöltésre kerül, és azon a csatornán publikussá is válik. (Nekem csak a nyílt (béta) teszten kezdett el működni a fizetés - igaz,a többi csatornán hiába volt publikus, az alkalmazást sem tudtam letölteni .) Ez akár több napig is eltarthat.
Nekem már megvan a teszttermék
Amúgy valahogy így néz ki, amikor működik (forrás : medium.com)
Igazából ha jobban megnézzük, nem is bonyolult a dolog. Az előfeltételeknek kell teljesülnie, azaz a megfelelő importoknak, jogoknak, és a Gradle file tartalmának, a Play Console-on léteznie kell a termékeknek. Ha inicializálva van a BillingProcessor, és jó a Play-ről származó licenckulcs, akkor a vásárlásnak simán le kell futnia a purchase() hívásra.
Remélem, valakinek megspórol pár napnyi keresést ez a post (Én elég sokáig küzdöttem vele, mire elkezdett működni.)