Покупки в Android приложении — Play Billing Library
И как это до сих пор на Хабре нет статьи об этом? Не дело, надо исправлять.
Есть 2 способа добавить In-App покупки в Android-приложение — старый и новый. До 2017 года все пользовались библиотекой от anjlab, но с июня 2017 года ситуация изменилась, Google выпустила собственную библиотеку для внутренних покупок и подписок — Play Billing Library. Сейчас последний считается стандартом.
Play Billing Library это очень просто.
Добавьте разрешение в манифесте.
Создайте инстанс BillingClient и начните соединение.
В метод onPurchasesUpdated() мы попадаем когда покупка осуществлена, в методе onBillingSetupFinished() можно запросить информацию о товарах и покупках.
Запросить информацию о товарах. Поместите querySkuDetails() в onBillingSetupFinished().
В коде вы могли заметить понятие SKU, что это? SKU — от английского Stock Keeping Unit (идентификатор товарной позиции).
Теперь в mSkuDetailsMap у нас лежит вся информация о товарах (имя, описание, цена), зарегистрированных в Play Console данного приложения (об этом позже). Обратите внимание на эту строку skuList.add(mSkuId);, здесь мы добавили id товара из Play Console, перечислите здесь все товары, с которыми вы хотите взаимодействовать. У нас товар один —sku_id_1.
Все готово к тому, чтобы выполнить запрос на покупку. Передаем id товара. Запустите этот метод, например, по клику на кнопку.
Теперь, запустив этот метод, вы увидите вот такое диалоговое окно (прим. картинки из Интернета).
Теперь если пользователь купит товар — его ему надо предоставить. Добавьте метод payComplete() и осуществите в нем действия, предоставляющие доступ к купленному товару. Например, если пользователь покупал отключение рекламы, сделайте в этом методе так, чтобы реклама больше не показывалась.
Все хорошо, но если пользователь перезапустит приложение, наша программа ничего не знает о покупках. Надо запросить информацию о них. Сделайте это в onBillingSetupFinished().
В purchasesList попадает список всех покупок, сделанных пользователем.
Делаем проверку: если товар куплен — выполнить payComplete().
Готово. Осталось это приложение опубликовать в Play Console и добавить товары. Как добавить товар: Описание страницы приложения > Контент для продажи > Создать ограниченный контент.
Примечание 1: Вы не сможете добавить товар пока не загрузите билд приложения в Play Console.
Примечание 2: Чтобы увидеть диалоговое окно о покупке, вам надо загрузить билд в Play Console, добавить товар и подождать какое-то время (
30 минут — 1 час — 3 часа), пока товар обновится, только после этого появится диалоговое окно и можно будет осуществить покупку.
Примечание 3: Ошибка Please fix the input params. SKU can’t be null — товар в Play Console еще не успел обновиться, подождите.
Примечание 4: Вы можете столкнуться с ошибкой Error «Your transaction cannot be completed», в логах как response code 6 пока будете тестировать. По каким причинам это происходит мне точно неизвестно, но по моим наблюдениям это происходит после частых манипуляций с покупкой и возвратом товара. Чтобы это починить перейдите в меню банковских карт и передобавьте вашу карту. Как этого избежать? Добавьте ваш аккаунт в Play Console в качестве тестировщика и покупайте только с тестовой карточки.
(Кстати, на Хабре работает система донейтов по кнопке под статьёй — прим. модератора).
Источник
Android get all purchases
Android In-App Billing v3 Library
This is a simple, straight-forward implementation of the Android v4 In-app billing API.
It supports: In-App Product Purchases (both non-consumable and consumable) and Subscriptions.
This project is looking for maintainers.
For now only pull requests of external contributors are being reviewed, accepted and welcomed. No more bug fixes or new features will be implemented by the Anjlab team.
If you are interesting in giving this project some ❤️ , please chime in!
v4 API Upgrade Notice
Originally this was Google’s v2 Billing API implementation, for those who interested all source code kept safe here.
If you got your app using this library previously, here is the Migration Guide.
You project should build against Android 4.0 SDK at least.
Add this Android In-App Billing v3 Library to your project:
- If you guys are using Eclipse, download latest jar version from the releases section of this repository and add it as a dependency
- If you guys are using Android Studio and Gradle, add this to you build.gradle file:
- Create instance of BillingProcessor class and implement callback in your Activity source code. Constructor will take 3 parameters:
- Context
- Your License Key from Google Developer console. This will be used to verify purchase signatures. You can pass NULL if you would like to skip this check (You can find your key in Google Play Console -> Your App Name -> Services & APIs)
- IBillingHandler Interface implementation to handle purchase results and errors (see below)
- Call purchase method for a BillingProcessor instance to initiate purchase or subscribe to initiate a subscription:
That’s it! A super small and fast in-app library ever!
And don’t forget to release your BillingProcessor instance!
Instantiating a BillingProcessor with late initialization
The basic new BillingProcessor(. ) actually binds to Play Services inside the constructor. This can, very rarely, lead to a race condition where Play Services are bound and onBillingInitialized() is called before the constructor finishes, and can lead to NPEs. To avoid this, we have the following:
Testing In-app Billing
Here is a complete guide. Make sure you read it before you start testing
Check Play Market services availability
Before any usage it’s good practice to check in-app billing services availability. In some older devices or chinese ones it may happen that Play Market is unavailable or is deprecated and doesn’t support in-app billing.
Simply call static method BillingProcessor.isIabServiceAvailable() :
Please notice that calling BillingProcessor.isIabServiceAvailable() (only checks Play Market app installed or not) is not enough because there might be a case when it returns true but still payment won’t succeed. Therefore, it’s better to call bp.isConnected() after initializing BillingProcessor :
or call isSubscriptionUpdateSupported() for checking update subscription use case:
Consume Purchased Products
You can always consume made purchase and allow to buy same product multiple times. To do this you need:
Restore Purchases & Subscriptions
Getting Listing Details of Your Products
To query listing price and a description of your product / subscription listed in Google Play use these methods:
As a result you will get a callback call including List data with one SkuDetails object with the following info included:
To get info for multiple products / subscriptions on one query, just pass a list of product ids:
where arrayListOfProductIds is a ArrayList containing either IDs for products or subscriptions.
Getting Purchase Info Details
PurchaseInfo object is passed to onProductPurchased method of a handler class. However, you can always retrieve it later calling these methods:
As a result you will get a PurchaseInfo object with the following info included:
Handle Canceled Subscriptions
Call bp.getSubscriptionPurchaseInfo(. ) and check the purchaseData.autoRenewing flag. It will be set to False once subscription gets cancelled. Also notice, that you will need to call periodically bp.loadOwnedPurchasesFromGoogleAsync() method in order to update subscription information
Promo Codes Support
You can use promo codes along with this library. Promo codes can be entered in the purchase dialog or in the Google Play app. The URL https://play.google.com/redeem?code=YOUR_PROMO_CODE will launch the Google Play app with the promo code already entered. This could come in handy if you want to give users the option to enter a promo code within your app.
Protection Against Fake «Markets»
There are number of attacks which exploits some vulnerabilities of Google’s Play Market. Among them is so-called Freedom attack: Freedom is special Android application, which intercepts application calls to Play Market services and substitutes them with fake ones. So in the end attacked application thinks that it receives valid responses from Play Market.
In order to protect from this kind of attack you should specify your merchantId , which can be found in your Payments Merchant Account. Selecting Settings->Public Profile you will find your unique merchantId
WARNING: keep your merchantId in safe place!
Then using merchantId just call constructor:
Later one can easily check transaction validity using method:
P.S. This kind of protection works only for transactions dated between 5th December 2012 and 21st July 2015. Before December 2012 orderId wasn’t contain merchantId and in the end of July this year Google suddenly changed orderId format.
The necessary proguard rules are already added in the library. No further configurations are needed.
The contents in the consumer proguard file contains:
Copyright 2021 AnjLab
Licensed under the Apache License, Version 2.0 (the «License»); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an «AS IS» BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
- Fork it
- Create your feature branch ( git checkout -b my-new-feature )
- Commit your changes ( git commit -am ‘Add some feature’ )
- Push to the branch ( git push origin my-new-feature )
- Create New Pull Request
About
A lightweight implementation of Android In-app Billing Version 3
Источник
Android in-app purchases, part 1: configuration and adding to the project
In-app purchases and especially subscriptions are the most popular methods to monetize an app. On the one hand, a subscription allows a developer to develop content and a product, on the other hand, they help a user to get a more high-quality app in general. In-app purchases are subject to 30% commission, but if a user has been subscribed for more than a year or an app earns less than $1Рњ per year, the commission is 15%.
This is the first article from the series dedicated to in-app purchases in Android apps. In this series, we will cover the topics starting with the creation of in-app purchases and up to server validation and analytics:
In this article, we’ll explain how to:В В
- Create a product in Google Play Console;
- Configure subscriptions: how to specify duration, price, trials;В
- Get a list of products in an app.В
Creating subscription
Before we start, make sure you:
- Have a developer account for Google Play.
- Have signed all agreements and are ready to start working.В В
Now, let’s get down to business and create our first product.В В
Switch to your developer account and choose an app.
Then, in the menu on the left, find the Products section, select Subscriptions and press Create a Subscription.В
Then, we’ll see the subscription configurator. Here are some important points.В В В
- Create the ID that will be used in the app. It’s a good idea to add a subscription period or some other useful information to ID, thus, you can create products in one style, as well as analyzing sales statistics will be easier.
- The name of the subscription that a user will see in the store.В В
- Subscription description. A user will see it, too.В В
Scroll down and choose the subscription period. In our case, it’s a week. Set up the price.В В
Usually, you set the price in the basic account currency, and the system converts the price automatically. But you can also edit the price for a specific country manually.В В
Please notice that Google shows the tax for every country. It’s great, App Store Connect doesn’t do so.В В
Scroll down and choose (if needed):В
- Free trial period.
- Introductory price, which is an offer for the first payment periods.В В
- Grace period. If a user has payment issues, you can still provide them with premium access for some number of days.
- An opportunity to resubscribe from the Play Store, not from the app, after cancellation.В
Comparing the purchase process in Play Console and App Store Connect
Regardless of the fact that subscriptions are monetized more effectively on iOS, Play Console’s admin board is more convenient, it’s organized and localized better, and it works faster.
The process of product creation is made as simple as possible. Here we told how to create products on iOS.
Getting a list of products in an app
Once the products are created, let’s work on the architecture for accepting and processing purchases. In general, the process looks like this:В В В
- Add a Billing Library.
- Develop a class for interaction with products from Google Play.
- Implement all methods to process purchases.В В
- Add server validation of a purchase.В В
- Collect analytics.
In this part, let’s take a closer look at the first two points.В В
Adding Billing Library to a project:
At the time of this writing, the latest version is 4.0.0. You can replace it with any other version at any moment.В В
Let’s create a wrapper class that will cover the logic of interaction with Google Play and initialize BillingClient from Billing Library in it. Let’s call this class BillingClientWrapper.
This class will implement PurchasesUpdatedListener interface. We will override a method for it now – onPurchasesUpdated(billingResult: BillingResult, purchaseList: MutableList
?) – it’s needed right after a purchase is made, but we will describe the implementation process in the next article.В
Google recommends to avoid having more than one active connection between BillingClient and Google Play to prevent a callback about a purchase made from being executed several times. Thus, you should have one unique BillingClient in a singleton class. The class in the example isn’t a singleton, but we can use dependency injection (for example, with the help of Dagger or Koin) in the way, allowing only one instance to exist at a single point in time.В
To make any request with Billing Library, BillingClient must have an active connection with Google Play at the moment when the request is being made, but the connection may be lost at some moment. For the sake of convenience, let’s write a wrapper allowing to make any requests only when the connection is active.В В В
To get the products, we need their IDs that we set in the market. But it’s not enough for a request, we also need the product type (subscriptions or one-time purchases) that’s why we can get a general list of products by “combining” the results of two requests.В В В
The request for products is asynchronous, so we need a callback that will either provide us with a list of products or return an error model. When an error occurs, Billing Library returns one of its BillingResponseCodes, as well as debugMessage. Let’s create callback interface and a model for an error:В В
Here’s a code for a private method for getting data about a specific type of products and a public method that will “combine” the results of two requests and provide a user with the final list of products or display an error message.В В
Thus, we got valuable information about the products (SkuDetails) where we can see localized names, prices, product type, as well as billing period and information about introductory price and trial period (if it’s available for this user) for subscriptions. Here’s what the final class looks like:В В В
That’s all for today. In the next articles, we’re going to tell you about purchase implementation, testing, and error handling.В В
Источник