{"id":137944,"date":"2021-03-24T00:00:00","date_gmt":"2021-03-24T00:00:00","guid":{"rendered":"https:\/\/adapty.io\/pt-android-in-app-purchases-google-play-billing-library-part-2\/"},"modified":"2021-03-24T00:00:00","modified_gmt":"2021-03-24T00:00:00","slug":"android-in-app-purchases-google-play-billing-library-part-2","status":"publish","type":"post","link":"https:\/\/adapty.io\/pt\/blog\/android-in-app-purchases-google-play-billing-library-part-2\/","title":{"rendered":"Compras no aplicativo para Android, parte 2: processamento de compras com a Biblioteca Google Play de Faturamento."},"content":{"rendered":"\n

No artigo anterior, criamos uma classe de wrapper para trabalhar com a Biblioteca de Faturamento:<\/p>\n\n\n\n

<\/path><\/path><\/svg><\/span>
import<\/span> <\/span>android.content.Context<\/span><\/span>\nimport<\/span> <\/span>com.android.billingclient.api.*<\/span><\/span>\nclass<\/span> <\/span>BillingClientWrapper<\/span>(<\/span>context<\/span>:<\/span> <\/span>Context<\/span>)<\/span> <\/span>:<\/span> <\/span>PurchasesUpdatedListener<\/span> <\/span>{<\/span><\/span>\n   <\/span>interface<\/span> <\/span>OnQueryProductsListener<\/span> <\/span>{<\/span><\/span>\n       <\/span>fun<\/span> <\/span>onSuccess<\/span>(<\/span>products<\/span>:<\/span> <\/span>List<\/span><<\/span>SkuDetails<\/span>><\/span>)<\/span><\/span>\n       <\/span>fun<\/span> <\/span>onFailure<\/span>(<\/span>error<\/span>:<\/span> <\/span>Error<\/span>)<\/span><\/span>\n   <\/span>}<\/span><\/span>\n   <\/span>class<\/span> <\/span>Error<\/span>(<\/span>val<\/span> <\/span>responseCode<\/span>:<\/span> <\/span>Int<\/span>,<\/span> <\/span>val<\/span> <\/span>debugMessage<\/span>:<\/span> <\/span>String<\/span>)<\/span><\/span>\n   <\/span>private<\/span> <\/span>val<\/span> billingClient <\/span>=<\/span> <\/span>BillingClient<\/span><\/span>\n       <\/span>.<\/span>newBuilder<\/span>(<\/span>context<\/span>)<\/span><\/span>\n       <\/span>.<\/span>enablePendingPurchases<\/span>()<\/span><\/span>\n       <\/span>.<\/span>setListener<\/span>(<\/span>this<\/span>)<\/span><\/span>\n       <\/span>.<\/span>build<\/span>()<\/span><\/span>\n   <\/span>fun<\/span> <\/span>queryProducts<\/span>(<\/span>listener<\/span>:<\/span> <\/span>OnQueryProductsListener<\/span>)<\/span> <\/span>{<\/span><\/span>\n       <\/span>val<\/span> skusList <\/span>=<\/span> <\/span>listOf<\/span>(<\/span>"<\/span>premium_sub_month<\/span>"<\/span>,<\/span> <\/span>"<\/span>premium_sub_year<\/span>"<\/span>,<\/span> <\/span>"<\/span>some_inapp<\/span>"<\/span>)<\/span><\/span>\n       queryProductsForType<\/span>(<\/span><\/span>\n           skusList<\/span>,<\/span><\/span>\n           <\/span>BillingClient<\/span>.<\/span>SkuType<\/span>.<\/span>SUBS<\/span><\/span>\n       <\/span>)<\/span> <\/span>{<\/span> billingResult<\/span>,<\/span> skuDetailsList <\/span>-><\/span><\/span>\n           <\/span>if<\/span> <\/span>(<\/span>billingResult<\/span>.<\/span>responseCode <\/span>==<\/span> <\/span>BillingClient<\/span>.<\/span>BillingResponseCode<\/span>.<\/span>OK<\/span>)<\/span> <\/span>{<\/span><\/span>\n               <\/span>val<\/span> products <\/span>=<\/span> skuDetailsList <\/span>?:<\/span> <\/span>mutableListOf<\/span>()<\/span><\/span>\n               queryProductsForType<\/span>(<\/span><\/span>\n                   skusList<\/span>,<\/span><\/span>\n                   <\/span>BillingClient<\/span>.<\/span>SkuType<\/span>.<\/span>INAPP<\/span><\/span>\n               <\/span>)<\/span> <\/span>{<\/span> billingResult<\/span>,<\/span> skuDetailsList <\/span>-><\/span><\/span>\n                   <\/span>if<\/span> <\/span>(<\/span>billingResult<\/span>.<\/span>responseCode <\/span>==<\/span> <\/span>BillingClient<\/span>.<\/span>BillingResponseCode<\/span>.<\/span>OK<\/span>)<\/span> <\/span>{<\/span><\/span>\n                       products<\/span>.<\/span>addAll<\/span>(<\/span>skuDetailsList <\/span>?:<\/span> <\/span>listOf<\/span>())<\/span><\/span>\n                       listener<\/span>.<\/span>onSuccess<\/span>(<\/span>products<\/span>)<\/span><\/span>\n                   <\/span>}<\/span> <\/span>else<\/span> <\/span>{<\/span><\/span>\n                       listener<\/span>.<\/span>onFailure<\/span>(<\/span><\/span>\n                           <\/span>Error<\/span>(<\/span>billingResult<\/span>.<\/span>responseCode<\/span>,<\/span> billingResult<\/span>.<\/span>debugMessage<\/span>)<\/span><\/span>\n                       <\/span>)<\/span><\/span>\n                   <\/span>}<\/span><\/span>\n               <\/span>}<\/span><\/span>\n           <\/span>}<\/span> <\/span>else<\/span> <\/span>{<\/span><\/span>\n               listener<\/span>.<\/span>onFailure<\/span>(<\/span><\/span>\n                   <\/span>Error<\/span>(<\/span>billingResult<\/span>.<\/span>responseCode<\/span>,<\/span> billingResult<\/span>.<\/span>debugMessage<\/span>)<\/span><\/span>\n               <\/span>)<\/span><\/span>\n           <\/span>}<\/span><\/span>\n       <\/span>}<\/span><\/span>\n   <\/span>}<\/span><\/span>\n   <\/span>private<\/span> <\/span>fun<\/span> <\/span>queryProductsForType<\/span>(<\/span><\/span>\n       <\/span>skusList<\/span>:<\/span> <\/span>List<\/span><<\/span>String<\/span>><\/span>,<\/span><\/span>\n       <\/span>@BillingClient.SkuType<\/span> <\/span>type<\/span>:<\/span> <\/span>String<\/span>,<\/span><\/span>\n       <\/span>listener<\/span>:<\/span> <\/span>SkuDetailsResponseListener<\/span><\/span>\n   <\/span>)<\/span> <\/span>{<\/span><\/span>\n       onConnected <\/span>{<\/span><\/span>\n           billingClient<\/span>.<\/span>querySkuDetailsAsync<\/span>(<\/span><\/span>\n               <\/span>SkuDetailsParams<\/span>.<\/span>newBuilder<\/span>().<\/span>setSkusList<\/span>(<\/span>skusList<\/span>).<\/span>setType<\/span>(<\/span>type<\/span>).<\/span>build<\/span>(),<\/span><\/span>\n               listener<\/span><\/span>\n           <\/span>)<\/span><\/span>\n       <\/span>}<\/span><\/span>\n   <\/span>}<\/span><\/span>\n   <\/span>private<\/span> <\/span>fun<\/span> <\/span>onConnected<\/span>(<\/span>block<\/span>:<\/span> <\/span>()<\/span> <\/span>-><\/span> <\/span>Unit<\/span>)<\/span> <\/span>{<\/span><\/span>\n       billingClient<\/span>.<\/span>startConnection<\/span>(<\/span>object<\/span> <\/span>:<\/span> <\/span>BillingClientStateListener<\/span> {<\/span><\/span>\n           override fun onBillingSetupFinished<\/span>(<\/span>billingResult<\/span>:<\/span> <\/span>BillingResult<\/span>)<\/span> {<\/span><\/span>\n               block<\/span>()<\/span><\/span>\n           }<\/span><\/span>\n           override fun onBillingServiceDisconnected<\/span>()<\/span> {<\/span><\/span>\n               <\/span>\/\/<\/span> <\/span>Try<\/span> to restart the connection on the next request to<\/span><\/span>\n               <\/span>\/\/<\/span> <\/span>Google<\/span> <\/span>Play<\/span> by calling the startConnection<\/span>()<\/span> method<\/span>.<\/span><\/span>\n           }<\/span><\/span>\n       }<\/span>)<\/span><\/span>\n   <\/span>}<\/span><\/span>\n   <\/span>override<\/span> <\/span>fun<\/span> <\/span>onPurchasesUpdated<\/span>(<\/span>billingResult<\/span>:<\/span> <\/span>BillingResult<\/span>,<\/span> <\/span>purchaseList<\/span>:<\/span> <\/span>MutableList<\/span><<\/span>Purchase<\/span>><\/span>?<\/span>)<\/span> <\/span>{<\/span><\/span>\n       <\/span>\/\/ here come callbacks about new purchases<\/span><\/span>\n   <\/span>}<\/span><\/span>\n}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n

Vamos prosseguir com a implementa\u00e7\u00e3o da compra e melhorar nossa classe.<\/p>\n\n\n\n\n\n

Como criar uma tela de assinatura<\/h2>\n\n\n\n

Qualquer aplicativo que apresente compras no aplicativo tem uma tela de paywall. Existem pol\u00edticas do Google<\/a> que definem o n\u00famero m\u00ednimo de elementos e textos instrucionais que devem estar presentes nas telas. Segue um resumo. Na tela do paywall, \u00e9 necess\u00e1rio ser expl\u00edcito sobre as condi\u00e7\u00f5es de assinatura, custos e dura\u00e7\u00e3o, assim como especificar se a assinatura \u00e9 necess\u00e1ria para utilizar o aplicativo (app). Deve-se tamb\u00e9m evitar for\u00e7ar seus usu\u00e1rios a realizar qualquer a\u00e7\u00e3o adicional para rever as condi\u00e7\u00f5es. <\/p>\n\n\n\n

Vamos usar como exemplo uma tela de paywall simplificada:<\/p>\n\n\n

\n
\"\"
Exemplo de paywall no Android<\/em><\/figcaption><\/figure><\/div>\n\n\n

\u200dTemos os seguintes elementos na tela do paywall:<\/p>\n\n\n\n