본문 바로가기

안드로이드/자바

[안드로이드/Android] 인앱결제의 모든것

반응형

해당 포스팅은 구버전으로 최신 버전으로 작성한 포스팅을 참고해주세요 ! ( 21.8.23 ) 

 

[AOS] 인앱 결제 라이브러리 3 적용 및 AIDL 마이그레이션 ( + 광고 제거 기능 구현 )

※신규앱의 경우 8월부터, 업데이트의 경우 11월부터 Billing Library 버전 3 이상을 사용해야 업로드 가능합니다. 마이그레이션 하시는 분들중 뭘 지워야할지 헷갈리신다면 기존에 추가한 모든걸 삭

superwony.tistory.com

 

 

 

 



안녕하세요. 오랜만에 포스팅을 쓰네요. 
그동안 포스팅 올릴만한 내용을 찾지 못한것도 있고..사실 공부를 게을리 했다는게 맞는 표현이겠네요. 
오늘은 제가 개발중인 앱에 인앱결제를 넣기위한 포스팅입니다.
(해당 포스트는 IAB v3 기준으로 작성되었습니다)

 

작성일지

최초 작성 17.07.25

1차 수정 18.02.03 ( 부족한 내용 추가 및 문맥 수정 )

 

1. 사전 준비

1-1. 어플리케이션 생성

1-2. 라이센스 키 

2. 앱내 인앱 구현 

2-1. 라이브러리 추가

2-2. 파일추가

2-3. 권한추가

2-4. 클래스 세팅

3. 출시 

3-1. 인앱상품 생성

3-2. 베타 및 알파버전 출시 

이처럼 2가지로 나눠지고 제가 다른 글들을 참고하면서 제 관점대로 바꾸어 작성하기때문에 지극히 주관적인 내용이기때문에

 

다른 분들도 참고만 하시는걸 추천합니다.

 

 

 

1. 사전준비 

 

1-1. 어플리케이션 생성 

먼저 인앱 결제를 하기 위해선 구글 개발자 콘솔에 등록하고자 하는 앱이나 테스트용 어플리케이션을 생성해야 합니다. 혹여나 개발자 계정이 없으신분은 따로 등록 후 진행하셔야 합니다. 

링크를 통해 프로젝트 콘솔로 이동합니다.  콘솔 우측 상단 애플리케이션 만들기로 프로젝트를 생성합니다.

 

1-2. 라이센스키 

인앱을 구현하는데 필요한 유틸인 IabHelper 인스턴스를 생성할때 넘겨주는 인자값으로 라이센스 키가 필요하다. 

 링크에 사전에 등록한 어플리케이션 - > 개발 도구 - > 서비스 및 API 에 라이선스키를 복사하시면 됩니다.

 

 

2. 앱내 인앱 구현

 

2-1. 라이브러리 추가

먼저 안드로이드 스튜디오에 SDK Manager에 있는 Google Play Billing Library를 다운받습니다.

다운받으신 후 sdk 매니저 경로에 있는  <SDK Path>/extras/google/play_billing/IInAppBillingService.aidl 파일을 복사합니다. 

프로젝트 내부 main 폴더의 하위에 'aidl' 디렉토리를 생성 후 해당 디렉 토리 내부에 com.android.vending.billing 패키지를 생성후, 

복사한 파일 'IInAppBillingService.aidl' 붙여넣기 합니다. 

IInAppBillingService.aidl 는 In-App Billing 버전 3 서비스로의 요청이 정의되어 있는 Android Interface Definition Language(AIDL)입니다.

이 인터페이스를 사용해 IPC(Inter-Process Communication) 메소드 호출을 함으로써 구매 요청을 할 수 있습니다.

 

2-2. 파일추가

<SDK Path>/extras/google/play_billing/samples/TrivialDrive/src/com/example/android/trivialdrivesample/util 폴더 속 모든 클래스들을 프로젝트 패키지 하위 적절한 곳으로 복사하세요

 

2-3. 권한 추가

인앱 구현을 위한 AndroidManifest.xml 파일에 퍼미션을 추가합니다.

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

 

2-4. 클래스 세팅

먼저 인앱을 사용하기전 Google Play와의 통신을 위한 ServcieConnection을 가지고 있어야 합니다. ( 18.02.03 service 변수 추가 )

//inapp
private String PUBLIC_KEY = "license key";
IInAppBillingService mService;
IabHelper iaphelper;

  • 'public_key'는 1-2 라이센스 키에 해당하며, 키를 통해 무단배포 방지 및 구매 품목 확인이 가능합니다.
  • 'mService' 는 실제 아이템을 구매하도록 해주는 서비스라고 생각하시면 될 것 같습니다.
  • 'iaphelper' 구매 및 구매목록등을 관리하는 클래스로 유틸성을 띄고 있습니다.

 

2-4-1 BindService

일반적으로 서비스와 동일합니다.

Intent intent=new Intent("com.android.vending.billing.InAppBillingService.BIND");
intent.setPackage("com.android.vending");
bindService(intent, mServiceConn, Context.BIND_AUTO_CREATE);

※롤리팝(5.0) 부터 인텐트 생성시 명시적으로 생성하지 않으면 아래와같은 오류가 발생합니다.

java.lang.IllegalArgumentException: Service Intent must be explicit: Intent

 

2-4-2 Setup

iaphelper = new IabHelper(this, PUBLIC_KEY);
iaphelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
@Override
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
Common.ShowToast(context, "문제 발생");
return;
}

if (iaphelper == null) return;
iaphelper.queryInventoryAsync(mGotInventoryListener);
}
});

 

2-4-3 보유중인 아이템 체크

/**
* 보유중인 아이템 체크
*/
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
@Override
public void onQueryInventoryFinished(IabResult result, Inventory inv) {

if (iaphelper == null) return;
if (result.isFailure()) {
//getPurchases() 실패했을때

return;
}
//해당 아이템 구매 여부 체크
Purchase purchase = inv.getPurchase(SKU_ITEM);

if (purchase != null && verifyDeveloperPayLoad(purchase)) {
//해당 아이템을 가지고 있는 경우.
//아이템에대한 처리를 한다.
alreadyBuyedItem();

/**
* 재구매가 가능한 경우는 아래와 같이 구매 목록을 소비와 동시에 그에 맞는 이벤트를 실행해
* 사용자가 같은 아이템을 재 구매 가능하도록 해야합니다.
* 저는 1회성 아이템이므로 소비과정은 생략하겠습니다.
*/
// iaphelper.consumeAsync(inv.getPurchase(SKU_ITEM), );

}
}
};

 

2-4-4 아이템 구매

private void buyItem(String item) {
    try {
        Bundle buyIntentBundle = mService.getBuyIntent(3, getPackageName(), item, "inapp", payLoad);
        PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
        if (pendingIntent != null) {
            iaphelper.launchPurchaseFlow(this, item, 1001, mPurchaseFinishedListener, payLoad);
        } else {
            // 결제가 막혔다면
            Common.ShowToast(context, "구매실패.");
        }

    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

결제가 막힌 경우는 여러가지가 존재하지만 

한가지 예로는 구매한 아이템을 소비하는 과정을 거치지 않았을때도 발생하는걸 확인했습니다.

또 item 파라미터는 스토어 아이템 아이디 값입니다.

 

2-4-5 구매 종료

IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
    @Override
    public void onIabPurchaseFinished(IabResult result, Purchase info) {
        if (iaphelper == null) return;

        if (result.isFailure()) {
            Common.ShowToast(context, "구매 실패, 정상 경로를 이용해주세요.");
            return;
        } else {

            if(verifyDeveloperPayLoad(info)){
                //보낸 신호와 맞는경우
                if(info.getSku().equals(SKU_ITEM)){
                    Common.ShowToast(context, "감사합니다. 앞으로 광고 없는 버전이용이 가능합니다.");
                    alreadyBuyedItem();
                }else{
                    Common.ShowToast(context, "구매 실패, 정상 경로를 이용해주세요.");
                }
                WLog.e(TAG, "구매성공" );
            }else{

                Common.ShowToast(context, "구매 실패, 정상 경로를 이용해주세요.");
                return;
            }
        }
    }
};

저는 광고제거용으로 1회성 아이템이기 때문에 다음과 같이 처리했습니다. 해당 리스너는 

결제가 성공하면 onActivityResult로 진입후 헬퍼의 handleActivityResult를 통해 호출됩니다.

 

2-4-6 성공 여부

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (iaphelper == null) return;
    if (!iaphelper.handleActivityResult(requestCode, resultCode, data)) {
        //처리할 결과물이 아닐 경우 이곳으로 빠져 기본처리를 하도록한다
        super.onActivityResult(requestCode, resultCode, data);
    } 

}

 

3. 출시

 

3-1. 인앱상품생성

인앱결제로 판매할 상품을 등록해야합니다. 

1번에서 등록한 어플리케이션의 상세로 들어가서 앱정보 > 인앱제품 에서 등록하실 수 있습니다.

새제품을 클릭해보면 다음과 같은 화면을 볼 수 있습니다. 

 

사진을 보시면 제품 유형이 관리되는 제품/구독으로 나뉩니다.  관리되는 제품은 1회성 아이템으로 반복구매가 어려운 이벤트성 아이템입니다. 하지만 구매 확인과 소모를 통해 재 구입이 가능하도록 하여 일반 게임에서 볼 수 있는 흔한 아이템입니다. 그리고 구독은 음원 스트리밍 앱에서 매월 자동 결제 되는것과 같은 아이템입니다. 

제품 id는 구매시 사용되는 고유 아이디로 중복및 변경이 불가능하기 때문에 제품 추가시 충분히 고려 후 만들어야 합니다.

 

 

3-2. 베타및 알파버전 출시

인앱결제 테스트를 위해서는 어플리케이션을 베타 혹은 알파 버전으로 출시를 해야만 실질적으로 테스트가 가능합니다.

 

베타 버전 출시에 관련해서는 다른 포스팅이나 해당 포스팅의 내용을 수정해서 뵙도록 하겠습니다.

링크를 통해 테스트 관련 포스팅을 참고해주세요 

[ 2017.11.1 베타 테스트 관련 포스팅 링크 추가]

 

 

 

 

참조 http://theeye.pe.kr/archives/2130

 

※필자 본인을 위한 포스팅으로써 다소 미흡할 수 있습니다. 그래도 궁금하신점이 있으시다면 최대한 도움을 드리도록 하겠습니다.

 

 

 

 

반응형