최초 작성일 : 2024.08.29
최종 수정일 : 2024.08.29
1. 개요
React Native에 인앱결제를 도입하기 위해선 이를 지원하는 라이브러리가 필요하다.
가장 유명한 라이브러리가 react-native-iap인데, 문서 설명이 친절하지 않아 hook, 메소드를 하나씩 써보고, 결제 해보고, 로그 확인하며 원하는 동작을 하는지 일일히 확인했었다. (이건 내가 실력이 부족해서, 뭔가 모르는게 있어서 그럴지도 모르겠다)
이것에 대한 내용은 아래 링크에서 볼 수 있다.
https://w-storage.tistory.com/58
[React Native] 지옥의 인앱 결제 도입기(react-native-iap)
이 글은 react-native-iap를 적용한 후기입니다.react-native-iap적용 방법은 아래에서 확인할 수 있습니다.https://w-storage.tistory.com/59 1. 개요이전부터 앱에 인앱결제 도입을 해 보고 싶었다.회사에서 서
w-storage.tistory.com
이 글은 react-native-iap의 완벽한 설명이 아니며, 내가 구독 인앱결제를 적용한 방법을 설명한 것이다.
이 글을 통해 인앱결제를 적용하고자 하는 사람들의 시간을 조금이나마 절약할 수 있길 희망한다.
2. react-native-iap 라이브러리 설치 및 세팅
Github 주소는 아래와 같다.
https://github.com/dooboolab-community/react-native-iap
GitHub - dooboolab-community/react-native-iap: In App Purchase module for React Native!
In App Purchase module for React Native! Contribute to dooboolab-community/react-native-iap development by creating an account on GitHub.
github.com
1) 라이브러리 설치
npm install react-native-iap
or
yarn add react-native-iap
pod install도 진행하자.
cd ios
pod install
cd ..
2) Android 세팅
android/build.gradle파일에 아래와 같이 추가한다.
buildscript {
ext {
...
supportLibVersion = "28.0.0"
androidXAnnotation = "1.1.0"
androidXBrowser = "1.0.0"
kotlinVersion = "1.8.0"
}
}
android/app/build.gradle 파일에 다음과 같이 추가한다.
이 글에 Android는 Playstore결제만 다룬다.
defaultConfig {
...
missingDimensionStrategy "store", "play"
}
android/app/src/main/AndroidManifest.xml파일에 아래의 내용을 추가한다.
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.android.vending.BILLING"/>
...
</manifest>
3) iOS 세팅
XCode에서 In-App Purchase를 추가한다.
2. 상품 생성
1) Android
Play Console에서 수익창출 - 제품 - 정기결제에서 "구독 만들기"버튼으로 상품을 만든다.
2) iOS
apple developer에서 "비즈니스"에 들어가 계좌, 사업자 등록증 등 필요한 양식을 입력한 뒤 제출한다.
애플에서 비즈니스 승인이 완료되면 수익화 - 구독에서 상품을 추가한다.
3. 상품 가져오기
우선, 초기화가 필요하다. App.js나 로그인 이후 메인 화면 등에 init을 추가한다.
const init = await RNIap.initConnection();
useIAP에서 getSubscriptions를 이용하면 상품 정보를 가져올 수 있다.
이후 subscriptions에서 상품 정보를 사용할 수 있다.
import React, { useState } from 'react';
import { View, TouchableOpacity } from 'react-native';
import * as RNIap from 'react-native-iap';
const ScreenName = () => {
const { subscriptions, getSubscriptions } = useIAP();
const skus = ['상품1 id', '상품2 id', ...]; // 반드시 배열 형태여야 함!
useEffect(() => {
await getSubscriptions({ skus: skus }); // getSubscriptions를 호출하면, subscriptions에서 상품 정보를 가져올 수 있다
}, []);
return (
<View>
{subscriptions.length > 0 ? (
<>
{subscriptions.map((product, idx) => (
<TouchableOpacity key = {idx} onPress={() => onPressSubscribeMonthly(product)}>
<Text>{상품명}</Text>
</TouchableOpacity>
))
</>
) : (
<Text>로딩중...</Text>
)}
</View>
)
}
4. 상품 구매하기
RNIap.requestSubscription()을 사용하면 상품 구매를 구현할 수 있다.
이 때 Android와 iOS간에 차이가 있는데, Android의 경우 offerToken을 반드시 전달해줘야 한다.
const onPressSubscribeMonthly = async (productData) => {
const currentProductId = productData.productId;
const offerToken = Platform.OS === 'android' ? productData.subscriptionOfferDetails[0]?.offerToken || null : null;
const request = await RNIap.requestSubscription({ // 상품 결제
sku: currentProductId,
...(offerToken && { subscriptionOffers: [{ sku: currentProductId, offerToken: offerToken }] }),
});
if (request) {
const finalRequest = !Array.isArray(request) ? request : request[0];
await RNIap.finishTransaction({ purchase: finalRequest, isConsumable: false }); // 트랜잭션 완료
}
}
5. 상품 구매정보 가져오기
RNIap.getAvailablePurchases()를 이용해 구매 정보를 가져올 수 있다.
여기서 Android와 iOS의 차이가 있다.
Android
구독중인 경우 : await RNIap.getAvailablePurchases();의 return에 결제 정보가 있음
구독중이 아닌경우(결제 후 취소 포함) : await RNIap.getAvailablePurchases();의 return이 빈 배열
iOS
현재 구독 여부와 관계 없이 await RNIap.getAvailablePurchases();에 지난 결제 정보가 계속 누적된다. 그렇기 때문에 최신 정보를 가져오기 위한 처리가 필요하다.
if (Platform.OS === 'android') {
await RNIap.flushFailedPurchasesCachedAsPendingAndroid();
} else {
await RNIap.clearTransactionIOS();
}
const purchases = await RNIap.getAvailablePurchases();
6. 마무리
지금까지 설명한 내용을 알아내기 위해 수정-빌드-로그확인을 정말 많이 진행했었다.
그 때문에 시간 소요가 엄청났는데 이 글이 이후 인앱결제를 도입하고자 하는 사람들에게 조금이나마 도움이 되었으면 한다.