티스토리 뷰

반응형

구글에서 Android 인앱 결제 라고 하면 다양한 분들이 각자의 입맛에 맞게 올려놓은 것을 확인할 수 있습니다.

저의 입맛에 맛게 간단한 인앱 결제 구현 방법에 대해서 공유 하겠습니다.


권한(Permission) 지정

우선 인앱 결제를 하기 위해서는 권한을 제공해야합니다.

manifests에 인앱 권한을 설정한다음 앱 배포 을 진행합니다.

manifests.xml

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

인앱 결제 필수 조건 인앱 결제를 하기 위해서는 manifests에 인앱 결제 권한이 등록된 앱만 인앱 상품을 등록할 수 있습니다. 필수적으로 권한 추가하여 APK 파일을 Google Play Console Project에 업로드 합니다.

정상적으로 배포(알파, 베타, 프로덕션) 됬을 경우 왼쪽 카테고리의 개발도구 > 서비스 및 API 을 클릭하면 라이선스 및 인앱 결제 항목이 보입니다. 해당 앱의 라이선스키를 잘 보관합니다.

해당 키는 바이너리에 포함하는 Base64 인코딩 RSA 공개 키로써 공백 없이 복사해서 보관해주세요.


Google Play Console 에 인앱 상품 등록

인앱 결제를 하기 위해서는 인앱 상품이 필요합니다. Google Play Console에서 인앱 상품을 등록할 수 있습니다.

인앱 상품 등록을 위해 Google Play Console에 접속합니다.

Google Play Console

왼쪽 카테고리에 보면 앱 정보 가 보입니다. 앱 정보의 인앱 상품을 클릭합니다.

(만약 인앱 결제 항목이 안보인다면 인앱 권한 지정한 APK 을 등록해야 합니다.)


오른쪽 위에 ''관리되는 제품 만들기' '을 통하여 사용자의 인앱 상품 특성에 맞춰서 등록시도합니다.

필자는 소모성 으로 광고제거 기능을 구현할 인앱 상품을 만들었습니다.

인앱 상품 ID는 인앱결제할 때 필수 데이터로 잘 보관 하세요.


Source 구현하기

실질적으로 앱에서 어떻게 구현하는지 알아보겠습니다. 설명보다 코드로 알려드리는 것이 이해하는데 더 편하실 듯하여 코드부터 공유합니다.

우선 Module.app 의 bundle.gradle 에 인앱 라이브러리를 추가 합니다. 필자가 사용한 방식은 오픈 라이브러리를 활용한 인앱을 구현했습니다.

//인앱
implementation 'com.anjlab.android.iab.v3:library:1.0.44'


인앱 초기화

이제는 라이브러리를 기반으로 인앱 구현을 하겠습니다.

/** InApp 초기화 */
private void initInApp(){
   mBillingProcessor = new BillingProcessor(this, getString(R.string.in_app_license_key), this);
}

R.string.in_app_license_key 는 Google Console에서 생성한 라이선스 키를 의미 합니다. this 는 BillingProcessor.IBillingHandler을 의미 합니다.

public class InAppActivity extends BaseActivity implements BillingProcessor.IBillingHandler {

따라서 다음과 같이 IBillingHandler을 implments 을 하여 이벤트핸들러를 처리합니다.


인앱 핸들러

인앱 핸들러에 대해서 알아보겠습니다.

인앱 구매 성공 메소드

인앱 구매 성공했을 때 보여주는 메소드 입니다.

/* 제품 iD를 가진 아이템의 구매 성공 시 호출
* - 보상 지급 또는 comsume 을 할 경우 작업 */
@Override
public void onProductPurchased(@NonNull String productId, @Nullable TransactionDetails details) {
   // 구매한 아이템 정보
   SkuDetails skuDetails = mBillingProcessor.getPurchaseListingDetails(productId);
   showOneButtonDialog(skuDetails.title + getString(R.string.success_purchase), new OnOkListener() {
       @Override
       public void notifyOk() {
           // 사용자 구매 처리 처리
           Log.d(com.kcs.android.test.common.Constants.LOG_TAG,"사용자 구매 처리 처리");
           I.P.setPurchaseInAppForRemoveAD(InAppManageActivity.this, true);
           setResult(Activity.RESULT_OK);
           finish();
      }
  });
}

이 메소드를 호출하기 위해서는 onActivityResultmBillingProcessor.handleActivityResult을 추가해야 합니다.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
   //       super.onActivityResult(requestCode, resultCode, data);
   if (mBillingProcessor.handleActivityResult(requestCode, resultCode, data)) {
       return;
  }
}


구매 이력 있는지 확인 메소드

구매 이력이 있는지 확인하는 메소드 입니다.

/* 구매 이력이 있는지 확인할 때 사용한다.  */
@Override
public void onPurchaseHistoryRestored() {
   //showOneButtonDialog(getString(R.string.exist_purchase_history_restored));
}


인앱 프로세스 중 Error 발생 시 호출 메소드

인앱 프로세스 중 Error 발생 시 호출되는 메소드 입니다.

만약 사용자가 인앱 도중 취소 했을 경우 onBillingError 의 두번째 인자인 Throwable error가 Null로 넘어오는 경우가 있습니다. @Nullable로 어노테이션 명시되어있지만 Null 로 넘어오니 주의해주세요.

@Override
public void onBillingError(int errorCode, @Nullable Throwable error) {
   Log.e(com.kcs.android.test.common.Constants.LOG_TAG,"onBillingError : "+ error.getMessage() + ", Error Code : " + errorCode);
   showOneButtonDialog(getString(R.string.error_purchase), new OnOkListener() {
       @Override
       public void notifyOk() {
           finish();
      }
  });
}


인앱 초기화

BillingProcessor 초기화 할 때 사용합니다. 주석으로 명시되어 있듯이 인앱 상품 ID를 정확히 입력하셔야 초기화 설정이 잘 됩니다.

/* BillingProcessor 초기화 되며, 구매 준비가 되면 호출 된다.
   * - 구매할 아이템 리스트 구성 및 사용자에게 보여주기 코드 구현
   *
   * - 아이템 이름만 가져오는 경우 SkuDetails.title.replaceAll("\\(.*\\)", "")
   * - SkuDetails.priceText: 아이템 가격에 현지 화폐 단위를 붙인 String을 리턴한다. 예를들면 '1.99$'이런 식이다.
   * - SkuDetails.priceLong: 가격을 long 으로 리턴한다. 1.99 이런식이다.
   * - SkuDetails.productId: 제품ID(sku)를 가지고 온다. 이를 통해서 어떤 아이템을 구매했는지 판별 가능하다.
   * */
@Override
public void onBillingInitialized() {
   mProduct = (SkuDetails) mBillingProcessor.getPurchaseListingDetails(mInAppPurchaseItemID);
   String price = "";
   if (mProduct == null){
       mProductId = "0";
  }else{
       mProductId = mProduct.productId;
       price = "\n(" + mProduct.priceText + ")";
  }
   btnPurchase.setText(getString(R.string.txt_in_app_btn_subtitle) + price);
}


인앱 구매하기

인앱에 필요한 Handler 정확히 입력하였다면 준비는 완료되었습니다. 이제 실질적인 구글 인앱을 호출하여 결제가 되도록 유도하겠습니다.

 /** 구매하기 */
private void purchaseProduct(final String productId) {

   if(mBillingProcessor.isPurchased(productId)){
       // 구매하였으면 소비하여 없앤 후 다시 구매하게 하는 로직. 만약 1번 구매 후 계속 이어지게 할 것이면 아래 함수는 주석처리.
       mBillingProcessor.consumePurchase(productId);
  }

   mBillingProcessor.purchase(this, productId);
}


인앱 결제에 필요한 환경설정 및 소스를 완료 하였습니다. 다양한 상품으로 인앱으로 수입성 앱을 많이 개발하길 응원합니다.


인앱 디버깅(Debugging) 하기

인앱을 디버깅하는 방법에 대해서 공유 드리겠습니다.

공유해 드린 방식으로 인앱 설정을 완료하였다고 하여도 디버깅으로 인앱 결제 시도 시 결제가 안된다는 메시지가 나올 것입니다.


인앱 디버깅은 할 수 없는 것인가? 구글에서는 라이선스 테스트를 할 수 있도록 별도의 계정을 등록할 수 있도록 안내하고 있습니다.

  1. Google Play Console 에 접속 하신다음 설정에 접속합니다.

  2. 개발자 계정 > 계정 세부 정보 접속합니다.


3. 라이선스 계정을 추가 합니다.

4. 앱 디버깅 모드에서 인앱 결제를 진행합니다. 라이선스테스트 계정을 추가했을 경우 테스트 구매를 할 수 있습니다.


정리

다양하고 좋은 앱을 개발 할 수 있기를 응원하는 마음으로 제가 편하게 사용하는 방식을 공유 드렸습니다.

1인 개발자 및 Android 개발자 모두를 응원합니다.


참고

android-inapp-billing-v3

반응형
댓글