«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Archives
Today
Total
관리 메뉴

올해는 머신러닝이다.

flutter에서 인앱 결제 구독 단계별 성명 본문

스터디/Flutter

flutter에서 인앱 결제 구독 단계별 성명

행복한 수지아빠 2025. 2. 16. 19:36

Flutter에서 인앱 결제 구독(IAP, In-App Purchase)을 구현하는 방법을 단계별로 설명해 줄게.


---

1. 패키지 설치

Flutter에서 인앱 결제를 구현하려면 in_app_purchase 패키지를 사용해야 해.

dependencies:
  flutter:
    sdk: flutter
  in_app_purchase: ^3.1.10

설치 후 패키지 가져오기

import 'package:in_app_purchase/in_app_purchase.dart';
import 'package:in_app_purchase/store_kit_wrappers.dart';


---

2. Google Play 및 App Store 설정

구독을 구현하려면 Google Play Console 및 App Store Connect에서 설정이 필요해.

(1) Google Play 설정

1. Google Play Console에 로그인


2. 앱 등록 후 ‘인앱 제품’ → ‘구독’ 메뉴에서 상품 추가


3. 제품 ID(예: premium_subscription ) 설정


4. 가격 및 기간(월/년) 설정 후 저장


5. 라이선스 키 및 Google Play Billing Library 활성화



Android 설정 추가

android/app/src/main/AndroidManifest.xml에 추가:

<uses-permission android:name="com.android.vending.BILLING"/>


---

(2) iOS 설정

1. App Store Connect에서 앱 추가


2. 앱에 ‘구독’ 상품 추가 (비소모성 상품)


3. App Store 계약 및 세금 정보 설정


4. 구독 테스트 계정(Sandbox) 추가



iOS 설정 추가

ios/Runner/Info.plist에 추가:

<key>SKAdNetworkItems</key>
<array>
  <dict>
    <key>SKAdNetworkIdentifier</key>
    <string>cstr6suwn9.skadnetwork</string>
  </dict>
</array>

ios/Podfile 수정:

platform :ios, '12.0'


---

3. Flutter에서 인앱 결제 로직 구현

(1) 초기화 및 구독 상품 불러오기

final InAppPurchase _iap = InAppPurchase.instance;
late StreamSubscription<List<PurchaseDetails>> _subscription;
List<ProductDetails> _products = [];

void initStore() async {
  final bool available = await _iap.isAvailable();
  if (!available) return;

  const Set<String> _productIds = {'premium_subscription'};
  ProductDetailsResponse response = await _iap.queryProductDetails(_productIds);
  _products = response.productDetails;

  _subscription = _iap.purchaseStream.listen((purchaseDetailsList) {
    _handlePurchase(purchaseDetailsList);
  }, onDone: () {
    _subscription.cancel();
  });
}


---

(2) 구독 버튼 구현

void _buyProduct(ProductDetails product) {
  final PurchaseParam purchaseParam = PurchaseParam(productDetails: product);
  _iap.buyNonConsumable(purchaseParam: purchaseParam);
}

@override
Widget build(BuildContext context) {
  return ListView(
    children: _products
        .map((product) => ListTile(
              title: Text(product.title),
              subtitle: Text(product.price),
              trailing: ElevatedButton(
                onPressed: () => _buyProduct(product),
                child: Text('구독하기'),
              ),
            ))
        .toList(),
  );
}


---

(3) 결제 상태 처리

void _handlePurchase(List<PurchaseDetails> purchaseDetailsList) {
  for (var purchaseDetails in purchaseDetailsList) {
    if (purchaseDetails.status == PurchaseStatus.pending) {
      // 결제 대기 중 UI 업데이트
    } else if (purchaseDetails.status == PurchaseStatus.purchased ||
        purchaseDetails.status == PurchaseStatus.restored) {
      // 서버 검증 후 액세스 권한 부여
    } else if (purchaseDetails.status == PurchaseStatus.error) {
      // 결제 실패 처리
    }

    if (purchaseDetails.pendingCompletePurchase) {
      _iap.completePurchase(purchaseDetails);
    }
  }
}


---

(4) 구독 상태 확인 (복원 기능)

void restorePurchases() async {
  final QueryPurchaseDetailsResponse response = await _iap.queryPastPurchases();
  for (var purchase in response.pastPurchases) {
    _handlePurchase([purchase]);
  }
}

복원 버튼 추가

ElevatedButton(
  onPressed: restorePurchases,
  child: Text('구독 복원'),
)


---

4. 테스트 방법

1. Android

Play Store에 테스트 계정 등록 후 결제 테스트

‘구독 취소’ 시 5분 단위로 갱신됨 (테스트 환경)



2. iOS

Sandbox Tester 계정 생성 후 로그인하여 테스트





---

5. 서버 검증 및 영수증 처리 (선택 사항)

구독 정보는 백엔드에서 검증하는 것이 안전해. Google과 Apple의 서버를 통해 영수증 검증을 수행할 수 있어.

Google Play: Google Play Developer API

Apple: App Store Server API


백엔드 없이 구현할 수도 있지만, 보안 및 환불 처리 등을 고려하면 서버 검증이 추천돼.


---

결론

이제 Flutter에서 인앱 결제 구독을 구현할 수 있어!