Report: State of in-app subscriptions in the US 2023 Get a report

사용 지침서: 플러터 (flutter) 앱 내에 인앱 구매를 구현하는 방법

Alexey Goncharov

Updated: 10월 14, 2023

3 min read

Content

62fdf15a5a9626b86649d085 jp android tutorial 1 configuration 6 3

플러터(Flutter)는Google에서개발한 비교적 새로운 프레임워크로,다중플랫폼 앱을 빠르게 만들 수 있습니다.다른인기 있는 프레임워크는 페이스북이 만든 리액트네이티브 (ReactNative)입니다..플러터앱은 iOS와Android를동시에 지원하도록 만들어졌습니다.따라서구매 라이브러리는 스토어킷 (StoreKit)및결제 라이브러리와 모두 호환되어야 합니다.

아키텍처측면에서,Adapty 플러터SDK를포함한 모든 결제 플러그인은 네이티브 (native)라이브러리,스토어킷및 결제 라이브러리의 래퍼입니다.우리의경우에는 AdaptyiOSAndroidSDK라이브러리의래퍼입니다.

플러터기반 앱의 인앱 구매 (in-apppurchase)를위한 오픈 소스 라이브러리

플러터앱에서 구매를 위한 인기 있는 솔루션은 오픈 소스플러그인인 in_app_purchase(플러터팀에서 개발)와flutter_inapp_purchase(비공식플러그인)입니다.

이플러그인은 클라이언트 측 구매를 구현하기 위해만들어졌습니다.이플러그인에는 서버 측 (server-side)영수증검증 (receiptvalidation) 기능이없습니다.영수증을검증하고 갱신,환불,평가판,취소등에 관한 결제 분석을 수집하려면,자체서버 측 인프라를 설정해야 합니다.

게다가,이러한라이브러리는 일반적으로 새로운 스토어 기능을 지원하는데 느립니다.이중 몇 가지만 들자면,현재프로모션 할인,종량과금제 (pay-as-you-go)기능및 iOS용선불1지불(payupfront) 기능이없습니다.

우리라이브러리는 우리 서버와 통신하기 때문에,다음기능이 모두 포함되어 있습니다.

  • 구매 서버 검증;
  • 완전한 네이티브 결제 기능 지원;
  • DRY 문법;
  • 구독과 구매 분석 및 기타 데이터 수집
  • A/B 테스트 (A/B tests)는 물론 구매, 가격 책정 및 프로모션 기간에 대한 빠른 실험
  • 페이월 (Paywalls) 및 프로모션 할인.

이기사를 간단하고 쉽게 하기 위해서,플러터앱 구매 작업을 시작하기 전 취해야 할 몇 가지 단계에대해 이전에 작성한 몇 가지 기사를 링크합니다.

iOS 및Android에서구매 생성하기

먼저,개발자계정이 없다면 만들어야 합니다.다음으로iOS와Android모두에대한 주간 구매를 생성해야 합니다.이전기사에서 이 작업을 수행하는 방법을 설명했습니다.

iOS용구매 생성하기

Android용구매 생성하기

완료되면프로젝트 생성 및 환경 설정을 시작할 수 있습니다.

프로젝트생성 및 구성하기

구현시와 시스템에서 모두 구매를 실행하려면,이러한기술 세부 정보를 입력해야 합니다.

61dbfcadde3e1409fe5f8314 iy6l5yif4wtrzqfjzaek9s70lntdy9bul 7h6homozvwghjkvrzry8ohu9pva 7wq18d6lyztyrc3ochoezylyispz580qelit5axr2dlrpu0dat0qjcwdbx2ecgeosqtass0c7w 1

iOS의경우 다음이 필요합니다.

  • 번들 ID를 지정하여 Adapty 프로젝트를 앱에 연결합니다.
  • App Store Connect에서 App Store 서버 알림 (Server Notifications)을 설정하면, 구독 이벤트에 대한 알림을 받을 수 있습니다.
  • App Store 공유 암호 (Shared Secret)를 지정합니다. Adapty 서버가 Apple 서버에 대한 연결을 설정하고 영수증을 검증하는 데 공유 암호를 사용할 것입니다.

Android의경우 패키지 이름과 서비스 계정 키 파일을 모두 지정해야합니다.패키지이름은 Android용iOS 번들ID입니다.코드에사용된 것과 동일한 것을 사용해야 합니다./android/app/build.gradle 파일에서찾을 수 있는데,android.defaultConfig.applicationId경로에위치합니다.

제품및 페이월 구성하기

Adapty제품은다양한 상점의 제품을 압축합니다.지금은AppStore와GooglePlay뿐이지만,앞으로다른 스토어도 소개할 예정입니다.이접근 방식의 이면에 있는 아이디어는,플랫폼간 통계 수집을 더 쉽게 하고,식별자가아닌 최상위 엔터티로서 작업할 수 있도록 하는 것입니다.

페이월은제품 어레이와 원격 구성 파일 (대시보드에서지정한 메타데이터가 포함된 JSON파일)을포함하는 추상 엔티티입니다.페이월ID를앱에 하드 코딩합니다.이ID는구성 파일 및 제품 데이터를 검색하는 데 사용됩니다.앱을업데이트하지 않고도 이 두 가지를 모두 편집할 수있습니다.일반적인시나리오에서는 페이월을 디자인하고 우리에게서 받은데이터로 채웁니다.

제품생성하기

GooglePlay Console과App StoreConnect를사용하여 주간 구독에 해당하는 제품을 만들어 보겠습니다.해당제품의 ID를입력하는데,결제시스템에서 검색할 수 있습니다.App Store Connect에는API가없으므로 수동으로 수행해야 함에 주의하십시오.그래도한 번만 하면 됩니다.

61dbfcadc56e16884ceeda5a 34mxwyuolr8iv5x2uec0mz6 ezswlcwoiag3ixmluw25i8qerq8ybrz vj0crilc9uwnkrao9asthwrbehotn 8r7j5amw8ruxtuy2eogngkul8qubafsly9dsisdjsapx0kx2m8 1

페이월생성하기

페이월을만들 때 중요한 것은 ID를편리한 형식으로 지정하는 것입니다.이식별자는 나중에 SDK에서페이월 데이터를 요청하는 데 사용됩니다.우리는이것이 좋은 접근 방식이라고 생각합니다.이아키텍처를 사용하면 클라이언트 측에서 제품을 하드코딩할 필요가 없습니다.제품관리,버전관리,테스트등을 유연하게 수행할 수 있습니다.대체옵션은 제품 세트가 내장된 파이어베이스 JSON입니다.하지만이것은 오류 검증을 제공하지 않으며 사용자 친화적이지않습니다.

61dbfcae9d2b62d615559378 zn55mgmaz86h7qtmlow pxcwlspih63ifgswsurxtydhjlqyj3gm jqtzo vk8bvb3txn29f7g2oe6o2voyadhruy1lhyyvqvuo6ms5ytfq sl9nf0ixpjtzyjdk0ozq9yzn7cx7 1

자!제품과페이월을 만들었으면,이제첫 번째 구매를 위한 준비가 되었습니다.SDK 설치를진행해 봅시다.

SDK사용방법

구독구성과 사용에 필요한 주요 기능을 살펴보겠습니다.

라이브러리설치하기

먼저adapty_flutter라이브러리를프로젝트에 추가합니다.그렇게하려면 다음 종속성을 pubspec.yaml파일에추가하십시오:

dependencies:   adapty_flutter: ^1.0.4

그후 다음을 실행합니다.

flutter pub get

여기에서부터는다음과 같이 AdaptySDK를앱으로 가져올 수 있습니다.

import 'package:adapty_flutter/adapty_flutter.dart';

환경설정

Adapty와함께 작동하도록 앱을 구성해야 합니다.이렇게하기 위해서 공개 SDK키와함께 AdaptyPublicSdkKey플래그를(iOS의경우)Info.plist또는(Android의경우)AndroidManifest.xml안에추가합니다.

SDK 키는Adaptysettings에서찾을 수 있습니다:

61dbfcaef59c49d11e233082 lsazt3ucjsc79arcgsxqdhss6j5t7gzc1ozj9kcwzet3 ouvcwuj 63wfcgl1ptjy4xpny8axipncjwfqvyks1yhf88bj2joq3qpn luafk1smbmkclwkxeehl08fbucvxi7d9tx 1

Info.plist:

&ltdict&gt 	...      		&ltkey&gtAdaptyPublicSdkKey&lt/key&gt

AndroidManifest.xml:

&ltapplication ...&gt         ...         &ltmeta-data                android:name="AdaptyPublicSdkKey"                android:value="PUBLIC_SDK_KEY" /&gt  &lt/application&gt

다음으로플러터 측에서,예를들면 프로젝트의 main()메소드에서이 코드를 호출하여 SDK를활성화합니다.

void main() {    runZoned(() async {      Adapty.activate();      final installId = await Service.getOrCreateInstallId();      await Adapty.identify(***customer-user-id***);      await Adapty.setLogLevel(AdaptyLogLevel.verbose);      runApp(MyApp());   });  }

보이드Adapty.activate()기능은Adapty_Flutter라이브러리를활성화시킵니다.

Future&ltbool&gt Adapty.identify(String customerUserId)

Adapty.identify는사용자의 ID를검색할 수 있게 합니다.Adapty는이를 구독 및 분석 시스템으로 보내 이 프로필에 이벤트를할당합니다.Profiles안에서customerUserId를통해 고객을 찾을 수도 있습니다.

Adapty는오류 메시지 및 기타 중요한 데이터를 기록하여 진행상황을 이해하도록 도와줍니다.

Future&ltvoid&gt Adapty.identify(AdaptyLogLevel value)

함수는세 가지 가능한 값 중 하나를 선택하도록 합니다.

  • AdaptyLogLevel.none (기본 설정): 아무것도 기록되지 않습니다.
  • AdaptyLogLevel.errors: 오류 메시지만 기록됩니다.
  • AdaptyLogLevel.verbose: 메소드 호출, API 요청 및 응답, 오류 메시지가 기록됩니다.

페이월검색하기

페이월목록을 검색하려면 다음 코드를 실행하세요.

try {   final GetPaywallsResult getPaywallsResult = await Adapty.getPaywalls(forceUpdate: Bool);   final List&ltAdaptyPaywall&gt paywalls = getPaywallsResult.paywalls;  } on AdaptyError(adaptyError) {}   catch(e) {}

Adapty.getPaywalls()함수는다음을 포함하는 GetPaywallsResult객체를반환합니다.

  • 페이월: 페이월 어레이( AdaptyPaywall ). 모델에는 제품 목록, 페이월 ID, 사용자 지정 페이로드 및 기타 몇 가지 값이 포함됩니다.

구매하기

이전단계에서 페이월 어레이를 검색했습니다.이제UI에해당 제품을 표시하기 위해 필요한 제품을 찾겠습니다.이페이월의 이름을 your_paywall_id:이라고가정합시다

final List<AdaptyPaywall>? paywalls = getPaywallsResult.paywalls;     myPaywall = paywalls?.firstWhere((paywall) => paywall.developerId == "your_paywall_id", orElse: null);

다음으로제품 필드의 제품 어레이를 사용하여 모든 항목을표시합니다.사용자가첫 번째 제품을 구매하고 싶어한다고 생각해 봅시다.간단하게하기 위해,제품어레이의 첫 번째 항목으로 가정합니다.

final AdaptyProduct? product = myPaywall?.products?.first;

구매를시작하려면,makePurchaseResult함수를호출합니다.(SDK로부터모든 오류 메시지를 계속 수신하려면 이것을 try-catch블록으로래핑해야 합니다.)

final MakePurchaseResult makePurchaseResult = await Adapty.makePurchase(product);

함수가성공적으로 실행되면,makePurchaseResult 변수는그 결과를 값으로 사용합니다.구매완료 후 접근 권한 수준을 확인하는 방법은 다음과같습니다.

final isPremium = makePurchaseResult?.purchaserInfo?.accessLevels['premium']?.isActive ?? false;

AdaptyErrorCode.paymentCancelled는사용자가 직접 구매를 취소했음을 의미하며,이는실제 오류 메시지가 아니라는 것을 기억하십시오.

구매를복원하려면 .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) {}

MakePurchaseResultRestorePurchasesResult객체둘 다 purchaserInfo를포함한다는 것을 고려하십시오.이객체에는 접근 권한 수준,구독및 구매에 대한 데이터가 포함되어 있습니다.일반적으로,접근권한 수준을 확인하여 사용자가 앱의 프리미엄 기능에접근할 수 있는지 여부를 알 수 있습니다.

구독상태

이전거래 내역 전체를 확인하지 않아도 되도록,”접근권한 수준”이라는용어를 도입했습니다.접근권한 수준은 사용자가 접근할 수 있는 앱 기능의 정도를설명하는 플래그입니다.아직구매하지 않은 경우 접근 권한 수준은 null이됩니다.구매한경우라면,귀하가제품에 대해 지정한 것이 됩니다.

예를들어,실버와골든의 두 가지 접근 권한 수준을 가질 수 있습니다.다른구매는 다른 접근 권한 수준과 기능의 잠금을 해제합니다.대부분의앱에는 하나의 접근 권한 수준만 있습니다.

구독이활성 상태인지 확인하려면 사용자에게 활성 접근 권한수준이 있는지 확인하기만 하면 됩니다.그렇게하기 위해서 .getPurchaserInfo()메소드를사용할 수 있습니다:

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) {}

또한.purchaserInfoUpdateStream스트림을구독하여 구독자 접근 권한 수준의 변경 사항을 적시에알 수 있습니다.방법은다음과 같습니다.

Adapty.purchaserInfoUpdateStream.listen((purchaserInfo) {   print('#Adapty# Purchaser Info Updated'); 	if (purchaserInfo.accessLevels['premium'].isActive) {   	// grant access to premium features   } });

Subscribe to Adapty newsletter

Get fresh paywall ideas, subscription insights, and mobile app news every month!

결론

우리는결제를 앱에 신속하게 통합하는 데 도움이 되는 방식으로SDK를디자인했습니다. 또한AB 테스트,분석및 더 많은 통합과 같이 수행해야 할 다른 모든 단계를단순화하기 위해 노력했습니다.

월수익이 $10,000미만인경우,전체구매 기능을 무료로 제공합니다.몇개월의 작업 시간을 절약하고,가장중요한 당신의 제품에 집중하십시오.