{"id":137901,"date":"2021-09-29T00:00:00","date_gmt":"2021-09-29T00:00:00","guid":{"rendered":"https:\/\/adapty.io\/pl-android-in-app-purchases-part-4-billing-library-error-codes-and-how-not-to-fail-testing\/"},"modified":"2021-09-29T00:00:00","modified_gmt":"2021-09-29T00:00:00","slug":"android-in-app-purchases-part-4-billing-library-error-codes-and-how-not-to-fail-testing","status":"publish","type":"post","link":"https:\/\/adapty.io\/pl\/blog\/android-in-app-purchases-part-4-billing-library-error-codes-and-how-not-to-fail-testing\/","title":{"rendered":"Zakupy w aplikacji na Androida, cz\u0119\u015b\u0107 4: kody b\u0142\u0119d\u00f3w biblioteki rozliczeniowej i jak nie namiesza\u0107 przy testach"},"content":{"rendered":"\n

Dzisiaj porozmawiamy o kodach b\u0142\u0119d\u00f3w<\/a>, kt\u00f3re mo\u017cemy otrzyma\u0107 z Billing Library w metodzie  getResponseCode()<\/a>.<\/p>\n\n\n\n

Przyk\u0142ad jak przekazali\u015bmy b\u0142\u0119dy do naszych wywo\u0142a\u0144 zwrotnych mo\u017cna znale\u017a\u0107 w tym artykule<\/a>. Rozwa\u017cali\u015bmy ju\u017c jeden z b\u0142\u0119d\u00f3w w poprzednich artyku\u0142ach – chodzi o USER_CANCELED<\/strong><\/a>, czyli sytuacj\u0119, gdy u\u017cytkownik zamyka okno zakupu bez kupowania czegokolwiek. Poznajmy teraz pozosta\u0142e.<\/p>\n\n\n\n\n\n

ERROR i DEVELOPER_ERROR<\/h2>\n\n\n\n

Zacznijmy od b\u0142\u0119d\u00f3w zwanych ERROR<\/strong><\/a> (responseCode 6) oraz DEVELOPER_ERROR<\/strong><\/a> (responseCode 5). W pierwszym przypadku Google pisze w dokumentacji „Krytyczny b\u0142\u0105d podczas dzia\u0142ania API”, w drugim \u2013 „Do API dostarczono niew\u0142a\u015bciwe argumenty”. Dla przyk\u0142adu, uzyska\u0142em DEVELOPER_ERROR, gdy przekaza\u0142em pusty ci\u0105g do konstruktora w setType()<\/a> dla \u017c\u0105dania querySkuDetailsAsync()<\/a>.<\/p>\n\n\n\n

Jednak nie jest to tak prosta sprawa. Poszed\u0142em dalej i w metodzie launchBillingFlow()<\/a> zastosowa\u0142em zmodyfikowane SkuDetails<\/a> (wyci\u0105gn\u0105\u0142em json ze SkuDetails prawdziwego produktu, zamieni\u0142em w nim productID i przekaza\u0142em go do nowego konstruktora SkuDetails). De facto jest to nieprawid\u0142owy argument i spodziewa\u0142em si\u0119, \u017ce otrzymam DEVELOPER_ERROR<\/strong> ale… Efektem by\u0142 ERROR<\/strong>.<\/p>\n\n\n\n

To oczywi\u015bcie by\u0142 sztuczny przyk\u0142ad. Przypadek, w kt\u00f3rym Google odrzuci\u0142o p\u0142atno\u015b\u0107, jest znacznie bli\u017cszy rzeczywisto\u015bci. Je\u015bli podczas testowania zakup\u00f3w za pomoc\u0105 karty testowej wybierzesz „karta testowa, zawsze odrzucaj” w oknie dialogowym zakupu, o czym powiemy ci na ko\u0144cu artyku\u0142u, r\u00f3wnie\u017c otrzymasz ERROR<\/strong>, ale z odpowiednim tekstem.<\/p>\n\n\n\n

W trzecim artykule<\/a>, gdzie opisano zmian\u0119 abonamentu, podwy\u017cszyli\u015bmy cen\u0119 abonamentu rocznego prawie 3 razy dla jednego z tryb\u00f3w proraction (proporcjonalno\u015bci), ale nie powiedzieli\u015bmy, jaki b\u0142\u0105d powinien tam powsta\u0107, gdyby\u015bmy tego nie zrobili. Powiemy o tym teraz.<\/p>\n\n\n\n

Poniewa\u017c okazuje si\u0119, \u017ce okre\u015blony jest tam niew\u0142a\u015bciwy tryb proporcji (proration), powinni\u015bmy logicznie uzyska\u0107 ten sam DEVELOPER_ERROR<\/strong>. Zamiast tego otrzymujemy SERVICE_UNAVAILABLE<\/strong><\/a> (responseCode 2). Otrzymujemy go r\u00f3wnie\u017c, je\u015bli wpiszemy dowoln\u0105 liczb\u0119 niew\u0142a\u015bciw\u0105 jako tryb proporcji (jest to int, nie enum, nic nas nie zatrzyma) i je\u015bli okre\u015blimy niew\u0142a\u015bciwy purchaseToken. Przegl\u0105damy dokumentacj\u0119 dotycz\u0105c\u0105 SERVICE_UNAVAILABLE<\/strong> i … zaraz, \u017ce co?! Widzimy, \u017ce „po\u0142\u0105czenie sieciowe nie dzia\u0142a”.<\/p>\n\n\n\n

Jednocze\u015bnie widzimy r\u00f3wnie\u017c dziwne okno dialogowe:<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

Inn\u0105 ciekaw\u0105 rzecz\u0105 w przypadku ERROR<\/strong> podczas zamykania okna dialogowego NIE<\/strong> za pomoc\u0105 przycisku „OK” (\u015bci\u015blej, za pomoc\u0105 \u015brodk\u00f3w, kt\u00f3re s\u0105 interpretowane jako „nawiguj z powrotem”), ERROR<\/strong> przychodzi do onPurchasesUpdated()<\/a>, a w przypadku SERVICE_UNAVAILABLE<\/strong> w podobnej sytuacji pojawia si\u0119 USER_CANCELED<\/strong> (ale je\u015bli klikniesz „OK” w oknie dialogowym, otrzymamy SERVICE_UNAVAILABLE<\/strong>, zgodnie z oczekiwaniami).<\/p>\n\n\n\n

A w przypadku utraty po\u0142\u0105czenia z Internetem rzeczywi\u015bcie przychodzi SERVICE_UNAVAILABLE<\/strong>.<\/p>\n\n\n\n

Kody b\u0142\u0119d\u00f3w<\/h2>\n\n\n\n

Oto kilka kod\u00f3w b\u0142\u0119d\u00f3w z ma\u0142ymi komentarzami, mo\u017cna si\u0119 wyrazi\u0107, wyr\u00f3\u017cnieniami.<\/p>\n\n\n\n