원스토어 인앱 SDK를 임의로 글로벌 스토어로 연동하는 옵션
이 기능은 Java SDK v21.01.00 버전부터 적용됩니다.
<application> 태그 직속 하위에 위치하며, 아래와 같은 요소를 추가합니다.
<manifest>
<application>
<activity>
</activity>
<!-- Options for in-app testing on your global store -->
<meta-data android:name="onestore:dev_option" android:value="global" />
</application>
</manifest>
배포 빌드 버전에서는 이 옵션을 반드시 삭제해야 합니다.
앱에서 원스토어 인앱 결제 라이브러리 적용하기
로그 레벨 설정
import 'package:flutter_onestore_inapp/flutter_onestore_inapp.dart';
class _HomePageState extends State<HomePage> {
@override
void initState() {
super.initState();
// 앱 개발 시 필요에 의해 SDK & Plugin의 로그 레벨을 변경하면 좀 더 자세한 정보를 얻을 수 있습니다.
// WARNING! Release Build 시엔 로그 레벨 세팅을 제거 바랍니다. (default: Level.info)
OneStoreLogger.setLogLevel(LogLevel.verbose);
}
}
상수
값
VERBOSE
2
DEBUG
3
INFO (default)
4
WARN
5
ERROR
6
배포 빌드 버전에서는 보안에 취약할 수 있으니 이 옵션을 삭제해야 합니다.
로그인 요청하기
원스토어 인앱 결제는 로그인 기반으로 구동되는 서비스입니다. 앱 최초 시작 시 구매 라이브러리의 API 호출하기 전에 로그인을 유도합니다. 구매 라이브러리 요청 시 토큰 만료나 다른 여러 가지 사항을 미연에 방지할 수 있습니다.
성공적으로 구매 완료되어 응답을 받았다면, 사용자는 소비(Consume) 또는 확인(Acknowledge) 작업을 하는 것이 매우 중요합니다.
3일 이내에 구매를 확인(acknowledge) 또는 소비(consume)를 하지 않으면 사용자에게 상품이 지급되지 않았다고 판단되어 자동으로 환불됩니다.
import 'package:flutter_onestore_inapp/flutter_onestore_inapp.dart';
class MyPurchaseManager {
final PurchaseClientManager _clientManager = PurchaseClientManager.instance;
final List<ProductDetail> _products = [];
// 상품 상세 정보에서 ProductType.inapp인 것만 필터링 된 데이터
List<ProductDetail> get consumableProducts => _products
.where((element) => element.productType == ProductType.inapp)
.toList();
// 상품 상세 정보에서 ProductType.subs인 것만 필터링 된 데이터
List<ProductDetail> get subscriptionProducts => _products
.where((element) => element.productType == ProductType.subs)
.toList();
void _listenToPurchasesUpdated(List<PurchaseData> purchasesList) {
if (purchasesList.isNotEmpty) {
for (var element in purchasesList) {
if (consumableProducts.any((p) => p.productId == element.productId)) {
/// [ProductType.inapp] 상품은 [consumePurchase] 호출하여 소비합니다.
} else if (subscriptionProducts.any((p) => p.productId == element.productId)) {
/// [ProductType.subs] 상품은 [acknowledgePurchase] 호출하여 확인합니다.
}
}
}
}
}
소비하기 (Consume)
소모성 상품: 구매 요청 → 응답 → 아이템 지급 → consumePurchase
기간제 상품: 구매 요청 → 응답 → 아이템 지급 → acknowledgePurchase → 일정 기간이 지난 후 → consumePurchase
Parameter
Type
Description
purchaseData
import 'package:flutter_onestore_inapp/flutter_onestore_inapp.dart';
class MyPurchaseManager {
final PurchaseClientManager _clientManager = PurchaseClientManager.instance;
Future<void> consumePurchase(PurchaseData purchaseData) async {
await _clientManager
.consumePurchase(purchaseData: purchaseData)
.then((iapResult) {
// IapResult를 통해 해당 API의 성공 여부를 판단할 수 있습니다.
if (iapResult.isSuccess()) {
fetchPurchases([ProductType.inapp]);
}
});
}
}
확인하기 (Acknowledge)
Parameter
Type
Description
purchaseData
import 'package:flutter_onestore_inapp/flutter_onestore_inapp.dart';
class MyPurchaseManager {
final PurchaseClientManager _clientManager = PurchaseClientManager.instance;
Future<void> acknowledgePurchase(PurchaseData purchaseData) async {
await _clientManager
.acknowledgePurchase(purchaseData: purchaseData)
.then((iapResult) {
// IapResult를 통해 해당 API의 성공 여부를 판단할 수 있습니다.
if (iapResult.isSuccess()) {
fetchPurchases([ProductType.subs]);
}
});
}
}
구매 내역 조회하기
PurchaseClientManager.queryPurchases() API를 사용하여 소비되지 않은 구매 내역을 요청합니다.
구매 완료 후 데이터를 처리하는 것만으로는 앱이 모든 구매를 처리하는 것을 보장하기에 충분하지 않습니다. 앱에서 사용자가 구매한 모든 항목을 인식하지 못할 수 있습니다.
앱에서 구매 추적을 놓치거나 구매를 인식하지 못할 수 있는 몇 가지 시나리오는 다음과 같습니다.
구매 중 네트워크 문제: 사용자가 구매를 성공적으로 완료하고 원스토어에서 확인을 받았지만 기기가 구매 알림을 받기 전에 네트워크 연결이 끊어졌을 경우
여러 기기: 사용자는 한 기기에서 항목을 구입한 후 기기를 전환할 때 이 항목이 표시되기를 기대합니다.
이러한 상황에 대처하려면 구매 내역 조회하기 API를 상황에 맞게 호출해야 합니다.
어플리케이션 처음 구동시
어플리케이션이 백그라운드에서 포그라운드로 재 진입했을 경우
상점 진입 시
어플리케이션의 상황에 맞게 사용해 주세요.
Parameter
Type
Description
productType
import 'package:flutter_onestore_inapp/flutter_onestore_inapp.dart';
class MyPurchaseManager {
final PurchaseClientManager _clientManager = PurchaseClientManager.instance;
Future<void> fetchPurchases(ProductType type) async {
await _clientManager
.queryPurchases(productType: type)
.then((response) {
if (response.iapResult.isSuccess()) {
if (type == ProductType.inapp) {
for (var purchaseData in response.purchasesList) {
consumePurchase(purchaseData);
}
} else if (type == ProductType.subs) {
for (var purchaseData in response.purchasesList) {
if (!purchaseData.isAcknowledged) {
acknowledgePurchase(purchaseData);
}
}
}
} else {
_handleError('fetchPurchases($type)', response.iapResult);
}
});
}
}
정기 결제 관리 화면 열기
PurchaseClientManager.launchManageSubscription() API를 사용하여 구독 상품의 상세 페이지로 이동합니다.
구독 상품의 설정 변경은 유저의 몫으로 관리 메뉴에서 할 수 있는 것들은 아래와 같습니다.