flutter

Flutter - ios 인앱 결제

이나주니 2025. 1. 9. 11:26
반응형

이번엔 ios 인앱 결제에 대해 작성해 보겠습니다.

먼거 코드를 작성 전에 비즈니스 설정을 시작합니다.

 

비즈니스에 접속후 은행 계좌, 통신판매업  등 모두 작성해줍니다.

 

통신 판매업 신고

https://www.gov.kr/mw/AA020InfoCappView.do?HighCtgCD=A09006&CappBizCD=11300000006

 

통신판매업신고 | 민원안내 및 신청 | 정부24

접속량이 많아 접속이 불가능합니다. 잠시 후 다시 접속해주세요

www.gov.kr

 

이후 

 

U.S. Certificate of Foreign Status of Beneficial Owner 이동

Type of Beneficial Owner - Corporation

Title - CEO

 

U.S. Substitute Form W-8BEN-E 이동

Chapter 3 Status (entity type) - Corporation

 

체크

 

활성화 성공

 

이후

규정 준수 - 디지털 서비스법 이동

본인에 맞는걸 선택

 

이 모든것이 끝나면


본인 앱으로 이동 앱내 구입을 선택합니다.

앱내 구입 버튼 클릭

전 비소모품이라서 비소모품을 선택

이후

본인이 원하는 국가 선택

 

기준 국가에 금액을 선택하고 다음을 선택

 

환율에 따라 금액 자동 셋팅

저의 경우는 미국만 금액을 변동했습니다.

 

이후 현지화를 진행합니다,=.

스크린샷 꼭 첨부해주세요

 


이후 인앱 결제 테스트를 잔행합니다.

저의 경우 샌드박스를 활용했습니다.

https://developer.apple.com/kr/help/app-store-connect/test-in-app-purchases/overview-of-testing-in-sandbox/

 

sandbox에서의 테스트 개요 - App Store Connect - 도움말 - Apple Developer

 

developer.apple.com


앱스토어 커넥스에서 사용자 및 엑세스 -> SandBox -> 테스트 계정 추가

해당 계정으로 인앱결제를 테스트 합니다.

 

이후 테스트 폰의 앱스토어에 접속해 로그인 되어있는 계정을 로그아웃 합니다.

그리고 디바이스 설정으로 이동으 appStore로 이동합니다.

샌드박스 계정에 아까 만든 샌드박스 계정을 입력해줍니다.

 


X-CODE 에 접속

Signing& Capabilities 이동

in-App Purchase 선택

 

이후

File- > new-> file... 선택

 

해당 파일 선택

 

이름 설정

 

이러면 아래 원하는 파일이 생김

 

선택후 이동해 빨간색 네모에 보이는 새로고침버튼을 눌러준다

나중에 상품 추가하면 저걸로 새로 소침 해줘야함 

안그럼 자동 동기화는 오래걸림

 

 

※ Storefront and Localization 에서 한국어로 설정하면 오류가 난다.

테스트 모드라서 그런것 같은데 일단 영어로 하고 진행하자!

 

셋팅이 끝났다면

 

 


코드 작성

https://pub.dev/packages/flutter_inapp_purchase

 

flutter_inapp_purchase | Flutter package

In App Purchase plugin for flutter. This project has been forked by react-native-iap and we are willing to share same experience with that on react-native.

pub.dev

 

초기화 설정

// 인앱 결제 객체 초기화
  @override
  void onInit() async {
    iap = InAppPurchase.instance;
    // 판매 중인 상품 정보 가져오기
    getProducts();
    // 구매 업데이트 이벤트 감지
    purchaseUpdatedSubscription = iap.purchaseStream.listen((purchaseDetailsList) {
      // 인앱 결제 상태 업데이트 이벤트 처리
      purchaseDetailsList.forEach((PurchaseDetails purchaseDetails) async {
        if (purchaseDetails.status == PurchaseStatus.purchased) {
          // 구매가 성공했을 때 검증 및 처리
          bool isVerified = await verifyPurchase(purchaseDetails);
          if (isVerified && purchaseDetails.pendingCompletePurchase) {
            SlackApi().sendMessage("*** 후원 성공 [name: ${name.value} : user_seq: ${user_seq.value}] *** : ${purchaseDetails.productID}", true);
            await InAppPurchase.instance.completePurchase(purchaseDetails);
            AllService().addPayment(purchaseDetails, donationPrice.value, donationPriceEn.value);
          }
        } else if (purchaseDetails.status == PurchaseStatus.error) {
          // 에러가 발생한 경우 처리
          if (purchaseDetails.pendingCompletePurchase) {
            SlackApi().sendMessage("*** 후원 에러 [name: ${name.value} : user_seq: ${user_seq.value}] *** : ${purchaseDetails.productID}", false);
            await InAppPurchase.instance.completePurchase(purchaseDetails);
          }
        }
      });
    });
    super.onInit();
    
    
    @override
  void dispose() {
    // 구매 업데이트 이벤트 감지 스트림 중지
    purchaseUpdatedSubscription?.cancel();
    super.dispose();
  }

 

상품 목록 가져오기

 // 판매 중인 상품 정보 읽기
  Future<void> getProducts() async {
    const Set<String> kIds = {
      'donation_500',
    };

    final ProductDetailsResponse response = await iap.queryProductDetails(kIds);
    if (response.notFoundIDs.isNotEmpty) {}
    products = response.productDetails;
  }

 

상품 구매하기

Future<void> buyProduct(ProductDetails product) async {
    final PurchaseParam purchaseParam = PurchaseParam(productDetails: product);
    try {
      await iap.buyConsumable(purchaseParam: purchaseParam, autoConsume: true);
      Get.back();
    } catch (e) {
    }
  }

 

코드 작성이 끝났다면

 


반응형