Published on

React Native 9장: 인앱 결제 및 구독 시스템 구현

[9장] 인앱 결제 및 구독 시스템 구현 (react-native-iap)


1. 인앱 결제란?

구분설명
소비성 상품1회 구매 후 소모됨 (예: 포인트, 아이템)
비소비성 상품1회 구매 후 영구 보유 (예: 광고 제거)
구독 상품주기적으로 과금 (예: 월간 프리미엄)

Google/Apple 모두 자체 결제 시스템 필수 (외부 결제는 금지)


2. 필수 준비 사항


3. 라이브러리 설치 및 초기 설정

npm install react-native-iap
npx pod-install

iOS 설정

  • Capabilities > In-App Purchase 활성화
  • StoreKit 시뮬레이션 구성 가능

Android 설정

  • billing permission 자동 추가됨

4. 상품 정보 불러오기

import * as RNIap from 'react-native-iap';

const itemSkus = ['premium_monthly', 'remove_ads'];

useEffect(() => {
  RNIap.initConnection().then(async () => {
    const products = await RNIap.getProducts(itemSkus);
    setProducts(products);
  });
}, []);
  • 상품 ID는 콘솔에 등록된 것과 정확히 일치해야 함

5. 결제 실행 및 처리

const purchase = await RNIap.requestPurchase({
  sku: 'premium_monthly',
});
  • 이후 purchaseUpdatedListener로 결과 확인
useEffect(() => {
  const purchaseUpdateSubscription = RNIap.purchaseUpdatedListener((purchase) => {
    if (purchase.transactionReceipt) {
      RNIap.finishTransaction(purchase);
    }
  });

  return () => purchaseUpdateSubscription.remove();
}, []);

6. 구매 복원 (Restore)

iOS에선 필수 기능 (같은 계정으로 재구매 방지)

const restored = await RNIap.getAvailablePurchases();
// 사용자 상태 복구 (광고 제거, 프리미엄 등)

7. 영수증 검증 & 보안

  • 보안을 위해 구매 내역을 서버에서 검증하는 게 원칙
  • iOS: Apple 서버에 영수증 전송
  • Android: Google Play Developer API 사용

서버 없이 처리하면 결제 위변조 위험 있음 → Node.js + Firebase 등 백엔드 구성 필요


8. UI/UX 구성 팁

  • 구매 버튼은 눈에 띄게 + 보상 설명 명확하게
  • 로딩/실패 처리 필수 (에러 메시지 제공)
  • 구매 후 자동 반영 (앱 재시작 없이)

요약

  • 인앱 결제는 소비성, 비소비성, 구독형으로 나뉜다
  • react-native-iap은 크로스 플랫폼으로 구매 요청, 상태 추적, 복원 모두 지원
  • 구매 성공 시 반드시 finishTransaction() 호출
  • 보안을 위해 서버 검증 필수 (실제 앱 운영 시)

심화학습

Q1. 구매 버튼을 여러 번 눌렀을 때 중복 결제가 되지 않게 하려면?
A1. 구매 중 상태를 useState로 관리하고 버튼을 비활성화하거나, 중복 호출을 차단하는 debounce 처리 필요.


Q2. 영수증 검증을 서버 없이 하면 어떤 문제가 생기나요?
A2. 해킹된 디바이스에서 purchase 응답을 위조하거나 변조된 앱에서 기능 잠금을 풀 수 있다. 보안을 신뢰할 수 없게 된다.


Q3. 구독이 만료됐는지 앱에서 실시간으로 어떻게 알 수 있나요?
A3. 앱이 실행될 때마다 getAvailablePurchases()로 현재 상태를 확인하거나, 서버에서 실시간 구독 상태 Webhook을 받아 상태 동기화해야 한다.