Samouczek: jak zaimplementować zakupy w aplikacji stworzonej za pomocą Flutter
Updated: 20 marca, 2023
Flutter to stosunkowo nowy framework opracowany przez Google, który pozwala szybko tworzyć aplikacje wieloplatformowe. Innym popularnym frameworkiem jest React Native od Facebooka. Aplikacje Flutter są tworzone jednocześnie dla iOS i Androida. Dlatego też biblioteka zakupu musi być kompatybilna zarówno z StoreKit, jak i z Billing Library.
Pod względem architektury, każda wtyczka płatności, w tym nasz ADAPTY Flutter SDK – jest opakowaniem (wrapper) wokół bibliotek natywnych, StoreKit i Billing Library. W naszym przypadku jest to wrapper wokół naszych bibliotek Adapty iOS oraz Android SDK.
Biblioteki open source do zakupów w aplikacji w aplikacjach opartych na Flutter
Popularne rozwiązania do zakupów w aplikacjach Flutter to wtyczki open source in_app_purchase (opracowana przez zespół odpowiedzialny za Flutter) oraz flutter_inapp_purchase (wtyczka nieoficjalna).
Wtyczki te zostały wykonane w celu realizacji zakupów po stronie klienta. Nie są one wyposażone w weryfikację potwierdzeń zakupu po stronie serwera (server-side). Musisz skonfigurować własną infrastrukturę po stronie serwera, aby sprawdzać potwierdzenia (receipts) i zbierać analizy płatności dotyczące odnowień, zwrotów, wersji próbnych, anulowań i tak dalej.
Co więcej, biblioteki te są zwykle wolno aktualizowane i często nie obsługują nowych funkcji sklepu. Aby wymienić tylko kilka podobnych kwestii, w tej chwili brakuje im ofert promocyjnych (promo offers), funkcji pay-as-you-go i funkcji pay upfront dla iOS.
Ponieważ nasza biblioteka kontaktuje się z naszym serwerem, zawiera je wszystkie:
- Walidacja serwerowa zakupu;
- Pełna obsługa funkcji płatności natywnych;
- DRY syntax;
- Analityka subskrypcji i zakupów oraz inne zbieranie danych;
- Testy A/B (A/B tests), a także szybkie eksperymentowanie z zakupami, cenami i okresami promocyjnymi;
- Paywalle i oferty promocyjne.
Aby ten artykuł był krótki i łatwy do przeczytania, podamy linki do kilku artykułów, które wcześniej napisaliśmy na temat kroków, które należy podjąć przed rozpoczęciem pracy nad zakupami w ramach aplikacji, stworzonej za pomocą Flutter.
Tworzenie zakupów na iOS i Androida
Najpierw musisz utworzyć konto dewelopera, jeśli go jeszcze nie posiadasz. Następnie musisz utworzyć cotygodniowy zakup dla systemów iOS i Android. Wyjaśniliśmy, jak to zrobić w naszych poprzednich artykułach:
Tworzenie zakupów dla Androida
Po zakończeniu możesz rozpocząć tworzenie i konfigurowanie projektu.
Tworzenie i konfigurowanie projektu
Aby Twoje zakupy działały zarówno w Twojej implementacji, jak i w naszym systemie, musisz wypełnić te dane techniczne.
W przypadku systemu iOS musisz:
- Określić identyfikator pakietu (Bundle ID), aby połączyć projekt Adapty ze swoją aplikacją;
- Skonfigurować powiadomienia serwera (Server Notifications) App Store w App Store Connect, dzięki czemu będziesz powiadamiany o zdarzeniach subskrypcji (subscription events);
- Określ App Store Shared Secret, którego serwer Adapty użyje do nawiązania połączenia z serwerami Apple i weryfikacji potwierdzeń zakupu.
W przypadku systemu Android należy podać zarówno nazwę pakietu (Package Name), jak i plik klucza konta usługi (Service Account Key File). Nazwa pakietu to identyfikator pakietu iOS (iOS Bundle ID) dla Androida. Musisz użyć tego samego, co zostało użyte w kodzie. Można to znaleźć w pliku /android/app/build.gradle, który znajduje się w katalogu android.defaultConfig.applicationId.
Konfigurowanie produktów i paywalli
Produkt Adapty zawiera je z różnych sklepów. Na razie mowa tylko o App Store i Google Play, ale w przyszłości wprowadzimy inne sklepy. Ideą tego podejścia jest ułatwienie gromadzenia statystyk między platformami, a także umożliwienie pracy z podmiotami najwyższego poziomu, w przeciwieństwie do identyfikatorów.
Paywall jest abstrakcyjnym podmiotem, który zawiera tablicę produktów i zdalny plik konfiguracyjny (który jest plikiem JSON zawierającym metadane określone w pulpicie nawigacyjnym). Twardo kodujesz paywall ID do aplikacji – ten identyfikator jest używany do pobierania pliku konfiguracyjnego i danych produktów. Możesz edytować oba bez konieczności aktualizacji aplikacji. W zwykłym scenariuszu projektujesz paywall i wypełniasz go danymi otrzymanymi od nas.
Tworzenie produktu
Skorzystajmy z konsoli Google Play i App Store Connect, aby stworzyć produkt odpowiadający tygodniowej subskrypcji. Wypełnij identyfikator powiązanych produktów, które możesz pobrać z systemów płatności. Ważne jest, aby pamiętać, że ponieważ App Store Connect nie ma interfejsu API, musisz to zrobić ręcznie. Na szczęście tylko raz.
Tworzenie paywalla
Podczas tworzenia paywalla najważniejsze jest podanie jego identyfikatora w wygodnym formacie. Identyfikator ten będzie później używany przez zestaw SDK do żądania danych paywall. Wierzymy, że jest to dobre podejście: dzięki tej architekturze nie ma potrzeby kodowania produktów po stronie klienta. Możesz być elastyczny w zarządzaniu produktem, wersjami, testach itp. Alternatywną opcją byłby Firebase JSON z zestawem wbudowanych produktów. Nie zapewnia to walidacji błędów i nie jest tak przyjazne dla użytkownika.
Voila! Po utworzeniu produktu i paywalla jesteś teraz gotowy do pierwszego zakupu. Przejdźmy do instalacji SDK.
Jak korzystać z SDK
Przyjrzyjmy się głównym funkcjom, których będziemy potrzebować do skonfigurowania i korzystania z subskrypcji.
Instalacja biblioteki
Najpierw musisz dodać bibliotekę adapty_flutter do swojego projektu. Aby to zrobić, dodaj następującą zależność do swojego pliku pubspec.yaml:
dependencies:
adapty_flutter: ^1.0.4
Następnie uruchom:
flutter pub get
Stąd możesz zaimportować Adapty SDK do swojej aplikacji w ten sposób:
import 'package:adapty_flutter/adapty_flutter.dart';
Konfiguracja
Musisz skonfigurować aplikację do pracy z Adapty. Aby to zrobić, dodaj oznaczenie AdaptyPublicSdkKey ze swoim publicznym kluczem SDK do Info.plist (dla iOS) lub do AndroidManifest.xml (dla Androida).
Klucz SDK znajdziesz w ustawieniach Adapty:
Info.plist:
<dict>
...
<key>AdaptyPublicSdkKey</key>
AndroidManifest.xml:
<application ...>
...
<meta-data
android:name="AdaptyPublicSdkKey"
android:value="PUBLIC_SDK_KEY" />
</application>
Następnie aktywuj SDK, wywołując ten kod po stronie Flutter – np. w metodzie main() swojego projektu:
void main() {
runZoned(() async {
Adapty.activate();
final installId = await Service.getOrCreateInstallId();
await Adapty.identify(***customer-user-id***);
await Adapty.setLogLevel(AdaptyLogLevel.verbose);
runApp(MyApp());
});
}
Pusta funkcja Adapty.activate() aktywuje bibliotekę Adapty_Flutter:
Future<bool> Adapty.identify(String customerUserId)
Adapty.identify pozwala odzyskać identyfikator użytkownika. Adapty przesyła je do systemów subskrypcyjnych i analitycznych w celu przypisania zdarzeń do tego profilu. Będziesz mógł również znaleźć swoich klientów poprzez customerUserId w Profiles.
Adapty rejestruje komunikaty o błędach i inne ważne dane, aby pomóc ci zrozumieć, co się dzieje.
Future<void> Adapty.identify(AdaptyLogLevel value)
Funkcja pozwala wybrać jedną z trzech możliwych wartości:
- AdaptyLogLevel.none (ustawienie domyślne): nic nie będzie rejestrowane.
- AdaptyLogLevel.errors: rejestrowane będą tylko komunikaty o błędach.
- AdaptyLogLevel.verbose: będą rejestrowane wywołania metod, żądania i odpowiedzi API oraz komunikaty o błędach.
Pobieranie paywalli
Aby pobrać listę paywalli, uruchom ten kod:
try {
final GetPaywallsResult getPaywallsResult = await Adapty.getPaywalls(forceUpdate: Bool);
final List<AdaptyPaywall> paywalls = getPaywallsResult.paywalls;
} on AdaptyError(adaptyError) {}
catch(e) {}
Funkcja Adapty.getPaywalls() zwraca obiekt GetPaywallsResult zawierający:
- Paywalle: tablica paywalli ( AdaptyPaywall ). Model zawiera listę produktów, paywall ID, zawartość niestandardową i kilka innych wartości.
Dokonywanie zakupów
W poprzednim kroku pobraliśmy tablicę paywall. Teraz poszukamy tego, którego potrzebujesz, aby wyświetlić te produkty w interfejsie użytkownika. Załóżmy, że ten paywall ma nazwę your_paywall_id:
final List<AdaptyPaywall>? paywalls = getPaywallsResult.paywalls;
myPaywall = paywalls?.firstWhere((paywall) => paywall.developerId == "your_paywall_id", orElse: null);
Następnie, korzystając z tablicy produktów z pola produkty, wyświetlamy wszystkie jej elementy. Załóżmy, że użytkownik chce kupić pierwszy produkt. Dla uproszczenia przyjmiemy, że jest to pierwszy element tablicy produktów.
final AdaptyProduct? product = myPaywall?.products?.first;
Aby zainicjować zakup, należy powołać się na funkcję makePurchaseResult. (Pamiętaj, aby otoczyć go w blok try-catch, aby nadal otrzymywać wszystkie komunikaty o błędach z SDK.)
final MakePurchaseResult makePurchaseResult = await Adapty.makePurchase(product);
Po pomyślnym wykonaniu funkcji, zmienna makePurchaseResult przyjmie wynik jako swoją wartość. Oto jak sprawdzić poziom dostępu po zakończeniu zakupu:
final isPremium = makePurchaseResult?.purchaserInfo?.accessLevels['premium']?.isActive ?? false;
Zauważ, że AdaptyErrorCode.paymentCancelled oznacza, że użytkownik sam anulował zakup, co oznacza, że nie jest to faktyczny komunikat o błędzie.
Aby przywrócić zakupy, użyj metody .restorePurchases()
try {
final RestorePurchasesResult restorePurchasesResult = await Adapty.restorePurchases();
// "premium" is an identifier of default access level
if (restorePurchasesResult?.purchaserInfo?.accessLevels['premium']?.isActive ?? false) {
// grant access to premium features
}
} on AdaptyError catch (adaptyError) {}
catch (e) {}
Należy wziąć pod uwagę, że zarówno MakePurchaseResult, jak i obiekty RestorePurchasesResult zawierają purchaserInfo. Obiekt ten zawiera dane o poziomach dostępu, subskrypcjach i zakupach. Zazwyczaj możesz sprawdzić, czy użytkownik może uzyskać dostęp do funkcji premium Twojej aplikacji, sprawdzając poziom dostępu.
Status subskrypcji
Aby uniknąć konieczności sprawdzania poprzez cały wcześniejszy łańcuch transakcji, wprowadzamy termin „poziom dostępu.” Poziom dostępu to oznaczenie, które wyjaśnia, do jak wielu funkcji aplikacji użytkownik może uzyskać dostęp. Jeśli nie dokonał on jeszcze żadnych zakupów, jego poziom dostępu będzie zerowy. W przeciwnym razie będzie on taki, jak określiłeś dla swojego produktu.
Na przykład możesz mieć dwa poziomy dostępu, a mianowicie srebrny i złoty. Różne zakupy odblokowują różne poziomy dostępu i funkcje. Większość aplikacji ma tylko jeden poziom dostępu.
Aby sprawdzić, czy subskrypcja jest aktywna, wystarczy sprawdzić, czy użytkownik ma aktywny poziom dostępu. Możesz użyć metody the.getPurchaserInfo() aby to zrobić:
try {
AdaptyPurchaserInfo purchaserInfo = await Adapty.getPurchaserInfo();
// "premium" is an identifier of default access level
if (purchaserInfo.accessLevels['premium']?.isActive ?? false) {
// grant access to premium features
}
} on AdaptyError catch (adaptyError) {}
catch (e) {}
Możesz również subskrybować strumień .purchaserInfoUpdateStream , aby na czas dowiadywać się o wszelkich zmianach w poziomie dostępu subskrybenta. Jak to zrobić:
Adapty.purchaserInfoUpdateStream.listen((purchaserInfo) {
print('#Adapty# Purchaser Info Updated');
if (purchaserInfo.accessLevels['premium'].isActive) {
// grant access to premium features
}
});
Wnioski
Zaprojektowaliśmy nasze SDK w taki sposób, aby pomóc Ci szybko zintegrować płatności z aplikacją. Co więcej, staraliśmy się również uprościć wszystkie inne kroki, które mogą być konieczne, takie jak testy A/B, analizy i dalsze integracje.
Zapewniamy pełną funkcjonalność zakupową bezpłatnie, jeśli przychody wynoszą mniej niż 10 000 USD miesięcznie. Zaoszczędź sobie miesięcy pracy i skup się na najważniejszej rzeczy: swoim produkcie.