---
title: "사용 지침서: 플러터 (flutter) 앱 내에 인앱 구매를 구현하는 방법"
description: "Adapty의 도움으로 플러터 앱용 인앱 구매."
url: "https://adapty.io/ko/blog/in-app-purchases-for-flutter-apps/"
language: "ko"
slug: "in-app-purchases-for-flutter-apps"
category: "adapty-updates"
date: "2022-01-10T00:00:00.000Z"
date_modified: "2022-01-10T00:00:00.000Z"
author: "Alexey Goncharov"
---

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

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

아키텍처측면에서,Adapty 플러터SDK를포함한 모든 결제 플러그인은 네이티브 (native)라이브러리,스토어킷및 결제 라이브러리의 래퍼입니다.우리의경우에는 [AdaptyiOS](https://github.com/adaptyteam/AdaptySDK-iOS)와[AndroidSDK](https://github.com/adaptyteam/AdaptySDK-Android)라이브러리의래퍼입니다.

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

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

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

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

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

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

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

[![demo page 4 5 1024x286](https://adapty.io/wp-content/uploads/2023/10/demo-page-4-5.png)](https://adapty.io/schedule-demo/)

### iOS 및Android에서구매 생성하기

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

[iOS용구매 생성하기](https://adapty.io/blog/ios-in-app-purchases-1/)

[Android용구매 생성하기](https://adapty.io/blog/android-in-app-subscriptions-part-1/)

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

### 프로젝트생성 및 구성하기

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

![](https://adapty.io/wp-content/uploads/2023/03/61dbfcadde3e1409fe5f8314_iy6l5yif4wtrzqfjzaek9s70lntdy9bul_7h6homozvwghjkvrzry8ohu9pva-7wq18d6lyztyrc3ochoezylyispz580qelit5axr2dlrpu0dat0qjcwdbx2ecgeosqtass0c7w-1.png)

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](https://adapty.io/wp-content/uploads/2023/03/61dbfcadc56e16884ceeda5a_34mxwyuolr8iv5x2uec0mz6-ezswlcwoiag3ixmluw25i8qerq8ybrz_vj0crilc9uwnkrao9asthwrbehotn_8r7j5amw8ruxtuy2eogngkul8qubafsly9dsisdjsapx0kx2m8-1.png)

#### 페이월생성하기

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

![61dbfcae9d2b62d615559378 zn55mgmaz86h7qtmlow pxcwlspih63ifgswsurxtydhjlqyj3gm jqtzo vk8bvb3txn29f7g2oe6o2voyadhruy1lhyyvqvuo6ms5ytfq sl9nf0ixpjtzyjdk0ozq9yzn7cx7 1](https://adapty.io/wp-content/uploads/2023/03/61dbfcae9d2b62d615559378_zn55mgmaz86h7qtmlow-pxcwlspih63ifgswsurxtydhjlqyj3gm-jqtzo-vk8bvb3txn29f7g2oe6o2voyadhruy1lhyyvqvuo6ms5ytfq-sl9nf0ixpjtzyjdk0ozq9yzn7cx7-1.png)

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

### SDK사용방법

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

#### 라이브러리설치하기

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

```dart
dependencies:n  adapty_flutter: ^1.0.4
```

그후 다음을 실행합니다.

```dart
flutter pub get
```

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

```dart
import 'package:adapty_flutter/adapty_flutter.dart';
```

#### 환경설정

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

SDK 키는[Adaptysettings](https://app.adapty.io/settings/general)에서찾을 수 있습니다:

![61dbfcaef59c49d11e233082 lsazt3ucjsc79arcgsxqdhss6j5t7gzc1ozj9kcwzet3 ouvcwuj 63wfcgl1ptjy4xpny8axipncjwfqvyks1yhf88bj2joq3qpn luafk1smbmkclwkxeehl08fbucvxi7d9tx 1](https://adapty.io/wp-content/uploads/2023/03/61dbfcaef59c49d11e233082_lsazt3ucjsc79arcgsxqdhss6j5t7gzc1ozj9kcwzet3-ouvcwuj-63wfcgl1ptjy4xpny8axipncjwfqvyks1yhf88bj2joq3qpn_luafk1smbmkclwkxeehl08fbucvxi7d9tx-1.jpg)

***Info.plist***:

```dart
u0026amp;ltdictu0026amp;gtnt...     nttu0026amp;ltkeyu0026amp;gtAdaptyPublicSdkKeyu0026amp;lt/keyu0026amp;gt
```

AndroidManifest.xml:

```dart
u0026amp;ltapplication ...u0026amp;gt
        ...
        u0026amp;ltmeta-data
               android_name="AdaptyPublicSdkKey"
               android_value="PUBLIC_SDK_KEY" /u0026amp;gtn u0026amp;lt/applicationu0026amp;gt
```

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

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

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

```dart
Futureu0026amp;ltboolu0026amp;gt Adapty.identify(String customerUserId)
```

*Adapty.identify* 는사용자의 ID를검색할 수 있게 합니다.Adapty는이를 구독 및 분석 시스템으로 보내 이 프로필에 이벤트를할당합니다.[Profiles](https://app.adapty.io/profiles/users)안에서*customerUserId* 를통해 고객을 찾을 수도 있습니다.

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

```dart
Futureu0026amp;ltvoidu0026amp;gt Adapty.identify(AdaptyLogLevel value)
```

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

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

#### 페이월검색하기

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

```dart
try {n  final GetPaywallsResult getPaywallsResult = await Adapty.getPaywalls(forceUpdate: Bool);n  final Listu0026amp;ltAdaptyPaywallu0026amp;gt paywalls = getPaywallsResult.paywalls;n } on AdaptyError(adaptyError) {}n  catch(e) {}
```

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

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

#### 구매하기

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

```dart
final Listu0026lt;AdaptyPaywallu003e? paywalls = getPaywallsResult.paywalls;
    myPaywall = paywalls?.firstWhere((paywall) =u003e paywall.developerId == "your_paywall_id", orElse: null);
```

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

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

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

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

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

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

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

구매를복원하려면 *.restorePurchases()* 메소드를사용하십시오:

```dart
try {ntfinal RestorePurchasesResult restorePurchasesResult = await Adapty.restorePurchases();n// "premium" is an identifier of default access level
  if (restorePurchasesResult?.purchaserInfo?.accessLevels['premium']?.isActive ?? false) {
  t// grant access to premium features
  }
} on AdaptyError catch (adaptyError) {}ncatch (e) {}
```

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

#### 구독상태

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

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

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

```dart
try {ntAdaptyPurchaserInfo purchaserInfo = await Adapty.getPurchaserInfo();
   // "premium" is an identifier of default access level
  if (purchaserInfo.accessLevels['premium']?.isActive ?? false) {
  t// grant access to premium features
  }
} on AdaptyError catch (adaptyError) {}ncatch (e) {}
```

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

```dart
Adapty.purchaserInfoUpdateStream.listen((purchaserInfo) {n  print('#Adapty# Purchaser Info Updated');ntif (purchaserInfo.accessLevels['premium'].isActive) {n  t// grant access to premium featuresn  }n});
```

### 결론

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

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