---
title: "Zakupy w aplikacji na Androida, część 4: kody błędów biblioteki rozliczeniowej i jak nie namieszać przy testach"
description: "W tym samouczku dokładnie przyjrzymy się błędom, związanym z zakupami w aplikacji w Google Play Billing Library i zobaczymy, co może je powodować"
url: "https://adapty.io/pl/blog/android-in-app-purchases-part-4-billing-library-error-codes-and-how-not-to-fail-testing/"
language: "pl"
slug: "android-in-app-purchases-part-4-billing-library-error-codes-and-how-not-to-fail-testing"
category: "adapty-updates"
date: "2021-09-29T00:00:00.000Z"
date_modified: "2021-09-29T00:00:00.000Z"
author: "Vlad Guriev"
---

# Zakupy w aplikacji na Androida, część 4: kody błędów biblioteki rozliczeniowej i jak nie namieszać przy testach

Dzisiaj porozmawiamy o [kodach błędów](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode), które możemy otrzymać z Billing Library w metodzie [getResponseCode()](https://developer.android.com/reference/com/android/billingclient/api/BillingResult#getResponseCode%28)).

Przykład jak przekazaliśmy błędy do naszych wywołań zwrotnych można znaleźć w [tym artykule](https://adapty.io/blog/android-in-app-purchases-google-play-billing-library-part-2/). Rozważaliśmy już jeden z błędów w poprzednich artykułach - chodzi o [**USER_CANCELED**](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#USER_CANCELED), czyli sytuację, gdy użytkownik zamyka okno zakupu bez kupowania czegokolwiek. Poznajmy teraz pozostałe.

## ERROR i DEVELOPER_ERROR

Zacznijmy od błędów zwanych [**ERROR**](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#ERROR) (responseCode 6) oraz [**DEVELOPER_ERROR**](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#DEVELOPER_ERROR) (responseCode 5). W pierwszym przypadku Google pisze w dokumentacji "Krytyczny błąd podczas działania API", w drugim – "Do API dostarczono niewłaściwe argumenty". Dla przykładu, uzyskałem DEVELOPER_ERROR, gdy przekazałem pusty ciąg do konstruktora w [setType()](https://developer.android.com/reference/com/android/billingclient/api/BillingClient#querySkuDetailsAsync%28com.android.billingclient.api.SkuDetailsParams,%20com.android.billingclient.api.SkuDetailsResponseListener)) dla żądania [querySkuDetailsAsync()](https://developer.android.com/reference/com/android/billingclient/api/SkuDetailsParams.Builder#setType%28java.lang.String)).

Jednak nie jest to tak prosta sprawa. Poszedłem dalej i w metodzie [launchBillingFlow()](https://developer.android.com/reference/com/android/billingclient/api/BillingClient#launchBillingFlow%28android.app.Activity,%20com.android.billingclient.api.BillingFlowParams)) zastosowałem zmodyfikowane [SkuDetails](https://developer.android.com/reference/com/android/billingclient/api/SkuDetails) (wyciągnąłem json ze SkuDetails prawdziwego produktu, zamieniłem w nim productID i przekazałem go do nowego konstruktora SkuDetails). De facto jest to nieprawidłowy argument i spodziewałem się, że otrzymam **DEVELOPER_ERROR** ale... Efektem był **ERROR**.

To oczywiście był sztuczny przykład. Przypadek, w którym Google odrzuciło płatność, jest znacznie bliższy rzeczywistości. Jeśli podczas testowania zakupów za pomocą karty testowej wybierzesz "karta testowa, zawsze odrzucaj" w oknie dialogowym zakupu, o czym powiemy ci na końcu artykułu, również otrzymasz **ERROR**, ale z odpowiednim tekstem.

W [trzecim artykule](https://adapty.io/blog/android-in-app-purchases-part-3-retrieving-active-purchases-and-subscription-change/), gdzie opisano zmianę abonamentu, podwyższyliśmy cenę abonamentu rocznego prawie 3 razy dla jednego z trybów proraction (proporcjonalności), ale nie powiedzieliśmy, jaki błąd powinien tam powstać, gdybyśmy tego nie zrobili. Powiemy o tym teraz.

Ponieważ okazuje się, że określony jest tam niewłaściwy tryb proporcji (proration), powinniśmy logicznie uzyskać ten sam **DEVELOPER_ERROR**. Zamiast tego otrzymujemy [**SERVICE_UNAVAILABLE**](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#SERVICE_UNAVAILABLE) (responseCode 2). Otrzymujemy go również, jeśli wpiszemy dowolną liczbę niewłaściwą jako tryb proporcji (jest to int, nie enum, nic nas nie zatrzyma) i jeśli określimy niewłaściwy purchaseToken. Przeglądamy dokumentację dotyczącą **SERVICE_UNAVAILABLE** i ... zaraz, że co?! Widzimy, że "połączenie sieciowe nie działa".

Jednocześnie widzimy również dziwne okno dialogowe:

![](https://adapty.io/wp-content/uploads/2023/01/615371cbae3a194fdd67617c_5n7uqaw9bx5dejwxgqh9sluv3r38yqwegbzbnzj5db9bullr12o2uraffoyko2jn4pjwhsy04xwdwrwxt37pkvgt3q1zgtblivzbagg-91v1ogagpaptqj-av1kdmoqhe96kwy4x3ds0.jpg)

Inną ciekawą rzeczą w przypadku **ERROR** podczas zamykania okna dialogowego **NIE** za pomocą przycisku "OK" (ściślej, za pomocą środków, które są interpretowane jako "nawiguj z powrotem"), **ERROR** przychodzi do [onPurchasesUpdated()](https://developer.android.com/reference/com/android/billingclient/api/PurchasesUpdatedListener#onPurchasesUpdated%28com.android.billingclient.api.BillingResult,%20java.util.List%3Ccom.android.billingclient.api.Purchase%3E)), a w przypadku **SERVICE_UNAVAILABLE** w podobnej sytuacji pojawia się **USER_CANCELED** (ale jeśli klikniesz "OK" w oknie dialogowym, otrzymamy **SERVICE_UNAVAILABLE**, zgodnie z oczekiwaniami).

A w przypadku utraty połączenia z Internetem rzeczywiście przychodzi **SERVICE_UNAVAILABLE**.

## Kody błędów

Oto kilka kodów błędów z małymi komentarzami, można się wyrazić, wyróżnieniami.

- [BILLING_UNAVAILABLE](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#BILLING_UNAVAILABLE) (responseCode 3). Google wyjaśnia, że "wersja API rozliczeń nie jest obsługiwana dla żądanego typu". Udało mi się odtworzyć ten błąd po wylogowaniu się z mojego konta Google, a także podczas korzystania z urządzenia Huawei bez usług Google Play. Może być również odtwarzany na starszych telefonach, w których Google Play nie został zaktualizowany.
- [SERVICE_DISCONNECTED](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#SERVICE_DISCONNECTED) (responseCode -1). Aplikacja jest czasami odłączana od usługi Google Play. Może się to zdarzyć, jeśli Play Store nieoczekiwanie się zaktualizuje. Dlatego radzę się zabezpieczać i połączyć się przed każdym wywołaniem metod Billing Library, jak w poprzednich artykułach. Ponadto, zarówno samo [Google](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#SERVICE_DISCONNECTED), jak i my osobiście radzimy dodać pewne zasady ponownej próby, jeśli ten błąd nadal pojawia się w odpowiedzi.
- [SERVICE_TIMEOUT](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#SERVICE_TIMEOUT) (responseCode -3). Nazwa mówi sama za siebie: zbyt długo czekaliśmy na odpowiedź od Google Play.
- [FEATURE NOT SUPPORTED](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#FEATURE_NOT_SUPPORTED). Jest pięć konstant [FeatureType](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.FeatureType) w klasie BillingClient. Ich dostępność na tym urządzeniu można sprawdzić za pomocą metody [BillingClient.isFeatureSupported (BillingClient.FeatureType.A_NECESSARY_FEATURE)](https://developer.android.com/reference/com/android/billingclient/api/BillingClient#isFeatureSupported%28java.lang.String)). Na moim telefonie (Xiaomi Mi A2 Lite), **FEATURE_NOT_SUPPORTED** został zwrócony tylko dla **SUBSCRIPTIONS_ON_VR**. Jednocześnie dla **IN_APP_ITEMS_ON_VR**, jak również dla wszystkich innych funkcji, zwrócono OK.
- [ITEM_NOT_OWNED](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#ITEM_NOT_OWNED) (responseCode 8). Występuje podczas próby konsumpcji zakupu, którego nie mamy. Być może, nawet wielokrotnie po udanej konsumpcji.
- [ITEM_ALREADY_OWNED](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#ITEM_ALREADY_OWNED) (responseCode 7). Tutaj mamy sytuację wręcz przeciwną - błąd występuje podczas próby zakupu produktu, który już mamy. W takim przypadku wystarczy zaktualizować interfejs użytkownika i sprawić, aby przycisk zakupu nie był klikalny.

## ITEM_UNAVAILABLE

Ostatnim i prawdopodobnie najpopularniejszym błędem na początku ścieżki implementacji zakupów w aplikacji jest [**ITEM_UNAVAILABLE**](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#ITEM_UNAVAILABLE) (responseCode 4). Mówi nam to, że produkt nie jest dostępny w sprzedaży, ale nie wyjaśnia, dlaczego. Powody mogą być bardzo różne: od testowania na niewłaściwym koncie lub urządzeniu po zakup nieaktywnego produktu.

Oto lista kontrolna czynności, które należy wykonać, aby uniknąć tego błędu podczas testowania:

1. Wyślij aplikację z Billing Library na ścieżkę testową. Jest to warunek obowiązkowy; w tym samym czasie można również przetestować kompilacje debugowania z tym samym identyfikatorem aplikacji, ale ważne jest, aby aplikacja z Billing Library została przesłana do Play Console co najmniej jeden raz.
2. Dodaj konta testerów Google do tej ścieżki testowej, co jest szczególnie ważne w testach wewnętrznych lub zamkniętych alfa/beta. W sekcji *Jak testerzy dołączają do testu*, będzie też link, za pomocą którego testerzy powinni przyjąć zaproszenie.
3. Możesz kupić tylko aktywowany produkt. Po utworzeniu produktu w Play Console pojawia się przycisk ***aktywuj***. Proces tworzenia produktu opisaliśmy bardziej szczegółowo w [pierwszym artykule](https://adapty.io/blog/android-in-app-subscriptions/).
4. Upewnij się, że testowanie na urządzeniu odbywa się z konta Google testera (co oznacza, że musi być zarejestrowany jako tester na tej ścieżce testowej i musi mieć wszystkie niezbędne techniczne dostępy). Ten punkt wydaje się być oczywisty, ale różne rzeczy mogą się zdarzyć i musisz to również sprawdzić, jeśli otrzymałeś taki błąd.
5. Identyfikator applicationid kompilacji, który jest używany do testowania zakupu, musi całkowicie odpowiadać identyfikatorowi applicationId z Play Console. Jest to szczególnie ważne dla tych, którzy mają dodany sufiks w swoich kompilacjach debugowania.
6. Dodaj adresy e-mail testerów do sekcji *Setup → License Testing* w lewym menu konta (nie aplikacji), dzięki czemu będą kupować produkty za darmo z karty testowej, a nie z prawdziwej. Kolejną zaletą jest to, że subskrypcje w tym przypadku będą miały [czasu trwania testu](https://developer.android.com/google/play/billing/test#renewals). Nie jest to związane z tym błędem, ale jest to również przydatna kwestia.

## Wnioski

Błędy mogą znacznie skomplikować pracę, dlatego zawsze ważne jest, aby zrozumieć, w jaki sposób mogą one wystąpić. Biorąc pod uwagę, ile kroków musisz przejść, aby uzyskać dostęp do produktów, najprostszym sposobem jest złapanie ITEM_UNAVAILABLE. Dlatego mam nadzieję, że moja lista kontrolna ci pomoże.

[ADAPTY SDK](https://adapty.io/sdk/android/) ułatwi obsługę błędów i zapewni wiele innych zalet: podstawową analitykę subskrypcji, analizę kohortową (cohort analysis), proste testowanie paywalli, integrację z usługami analityki, walidację błędów serwera. Wypróbuj teraz!
