Unity3D Android 91 Market Platform SDK Integration - 4. In-app Billing

 91마켓 마지막 포스팅입니다. 그런데 중국 인터넷 시장의 3대 천황중 하나인 바이두(Baidu)에서 91닷컴을 인수해버렸네요. 나중에 91마켓이 작업은 끝났지만 아직은 포스팅하지 않은 바이두 도쿠(Baidu Duoku) SDK에 통합이 될 수도 있겠네요.

 지난 포스팅에서 91 플랫폼 실행, 유저 피드백, 앱 업데이트를 정리했었습니다. 이번에는 91마켓 인앱빌링, 91 머니 충전, 빌링 누락 처리를 정리해보겠습니다.


1. 91마켓 인앱빌링과 91머니 충전

 91마켓의 빌링 방식은 2가지가 있습니다. 동기 구매와 비동기 구매인데요, 동기 구매는 애플의 빌트인 모델과 같이 클라이언트딴만 처리하는 것과 같고 비동기는 자체 서버를 두고 하는 방식입니다. 동기 구매에 대한 것을 정리해봅니다.

 // 빌링 누락 처리를 위한 오더 번호 저장용
 private String strBuyInfoSerial;
...
 public void UniPay_U(final String strProductId, final String strName, final double dPrice, final double dCost, final int iCount, final String strDescription) {
  runOnUiThread(new Runnable() {

   @Override
   public void run() {
    // TODO Auto-generated method stub
    NdBuyInfo buyProductInfo = new NdBuyInfo();
    if (buyProductInfo != null) {
     // 유니크 오더 번호
     strBuyInfoSerial = UUID.randomUUID().toString();
     buyProductInfo.setSerial(strBuyInfoSerial);
     // 상품ID
     buyProductInfo.setProductId(strProductId);
     // 상품 이름
     buyProductInfo.setProductName(strName);
     // 상품 가격(0.01 <= dPrice)
     buyProductInfo.setProductPrice(dPrice);
     // 상품 원가
     buyProductInfo.setProductOrginalPrice(dCost);
     // 구매 수량(iCount > 1 && iCount <= 10000)
     buyProductInfo.setCount(iCount);
     // 상품 설명
     buyProductInfo.setPayDescription(strDescription);

     Log.d(LOG_TAG, "UniPay Request " + strBuyInfoSerial + "-" + strProductId + "-" + strName + "-" + dPrice + "-" + dCost + "-" + iCount + "-" + strDescription);
    
     int iError = NdCommplatform.getInstance().ndUniPay(buyProductInfo, UnityPlayer.currentActivity, new OnPayProcessListener() {
      
      @Override
      public void finishPayProcess(int arg0) {
       // TODO Auto-generated method stub
       JSONObject jsonObj = new JSONObject();
       switch(arg0) {
        // 구매 성공
       case NdErrorCode.ND_COM_PLATFORM_SUCCESS:
 try {
  jsonObj.put("orderserial", strBuyInfoSerial);
 } catch (JSONException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
        Log.d(LOG_TAG, "Pay Success");
        break;
        // 구매 실패
       case NdErrorCode.ND_COM_PLATFORM_ERROR_PAY_FAILURE:
        Log.d(LOG_TAG, "Pay Failed");
        break;
        // 구매 취소
       case NdErrorCode.ND_COM_PLATFORM_ERROR_PAY_CANCEL:
        Log.d(LOG_TAG, "Pay Cancel");
        break;
        // 구매 실패
       default:
        Log.d(LOG_TAG, "Pay Failed " + arg0);
        break;
       }
       
       //strBuyInfoSerial = null;
 try {
  jsonObj.put("result", arg0);
 } catch (JSONException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
       UnityPlayer.UnitySendMessage("Plugin91Manager", "UniPayResult_J", jsonObj.toString());
      }
     });
          
     if (iError != 0) {
      Log.d(LOG_TAG, "NdBuyInfo Error " + iError);
     }
    }
   }
  });
 }
 안드로이드 플러그인 91 마켓 인앱빌링 부분입니다. 구매 성공하면 strBuyInfoSerial라고 유니크한 오더 번호를 유니티3D에 넘겨줘서 서버와 구매 인증을 하는데 사용하도록 합니다.

 public void UniPay(string strProductId, string strName, double dPrice, double dCost, int iCount, string strDescription)
 {
  curActivity.Call("UniPay_U", strProductId, strName, dPrice, dCost, iCount, strDescription);
 }
 
 void UniPayResult_J(string strResult)
 {
  //public static final int ND_COM_PLATFORM_SUCCESS = 0;
  // 구매 성공
  if (strResult == "0")
  {
   this.strLogMsg = "Pay Success";
  }
  // public static final int ND_COM_PLATFORM_ERROR_PAY_FAILURE = -18003;
  // 구매 실패
  else if(strResult == "-18003")
  {
   this.strLogMsg = "Pay Failed";
  }
  // public static final int ND_COM_PLATFORM_ERROR_PAY_CANCEL = -18004;
  // 구매 취소
  else if(strResult == "-18004")
  {
   this.strLogMsg = "Pay Cancel";
  }
  // public static final int ND_COM_PLATFORM_ERROR_UNEXIST_ORDER = -19032;
  // 오더 번호가 존재하지 않음
  else if(strResult == "-19032")
  {
   this.strLogMsg = "Pay UnExist Order";
  }
  // 구매 실패
  else
  {
   this.strLogMsg = "Pay Failed " + strResult;
  }
 }
 플러그인을 호출하고 콜백을 받는 Plugin91Manager 컴포넌트 부분입니다.

  fYpos += 50;
  if (GUI.Button(new Rect(0, fYpos, 100, 50), "UniPay") == true)
  {
   Plugin91Manager.GetInstance().UniPay("testItem001", "MyNameTestItem", 0.01, 1.0, 5, "Test Item Description");
  }
 마지막으로 TestGUI 컴포넌트의 OnGUI입니다.

 UniPay 버튼을 누르면 인자로 넘긴 값의 상품을 구매요청 합니다.

 상품구매가 되었습니다. 녹색을 누르면 구매한 목록 확인 리스트로가고 파란색은 91 마켓 플랫폼을 빠져나갑니다.

 녹색을 누르면 나오는 구매 목록 리스트 화면입니다.

 91 플랫폼을 나오면 유니티에 결과가 전달되어 이렇게 Pay Success라고 되어있습니다.

 91머니 충전은 따로 해줄것이 없습니다. 상품 구매중 91머니가 부족하면 SDK 내부에서 알아서 91머니 충전 페이지를 띄워주고 충전한 후 유저는 다시 상품 구매를 시도하면 됩니다.


2. 빌링 누락 처리

 구매 과정중 유저가 앱을 종료하거나 네트워크 문제등으로 구매 성공 메세지가 클라이언트에 전달 되지 않을 수 있습니다. 이에 대한 최소한의 처리에 대한 내용입니다. 제대로 하려면 위에서 말한 비동기 구매 처리를 해야겠죠.

// 유니크 오더 번호
strBuyInfoSerial = UUID.randomUUID().toString();
 위에서 결제 요청전에 유니크한 구매 번호를 저장했었습니다. 이 값을 91 플랫폼에 요청해서 확인해주면 됩니다. 제대로 하려면 이 값을 변수가 아닌 로컬 어딘가 또는 DB에 저장한 후 앱이 실행된다던지 하는 특정 시점에 해당 값을 읽어와 처리 안된 구매 요청값이 있다면 확인 처리 해줘야겠죠.

 public void CheckBillingMissing_U() {
  
  runOnUiThread(new Runnable() {

   @Override
   public void run() {
    // TODO Auto-generated method stub
    NdCommplatform.getInstance().ndCheckPaySuccess(strBuyInfoSerial, UnityPlayer.currentActivity, new NdCallbackListener() {

     @Override
     public void callback(int arg0, Boolean arg1) {
      // TODO Auto-generated method stub
      JSONObject jsonObj = new JSONObject();
      String strResult = Integer.toString(arg0);
      switch(arg0) {
       // 조회 성공
      case NdErrorCode.ND_COM_PLATFORM_SUCCESS:
       if (arg1 == true) {
        // 구매 성공
 try {
  jsonObj.put("orderserial", strBuyInfoSerial);
 } catch (JSONException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
        Log.d(LOG_TAG, "CheckBillingMissing Pay Success");
       } else {
        // 구매 실패
        strResult = Integer.toString(NdErrorCode.ND_COM_PLATFORM_ERROR_PAY_FAILURE);
        Log.d(LOG_TAG, "CheckBillingMissing Pay Failed");
       }
       break;
       // 오더 번호가 존재하지 않음
      case NdErrorCode.ND_COM_PLATFORM_ERROR_UNEXIST_ORDER:
       Log.d(LOG_TAG, "CheckBillingMissing UnExist Order");
       break;
       // 구매 실패가 아닌 단지 조회 실패.
      default:
       Log.d(LOG_TAG, "CheckBillingMissing GetResult Failed " + arg0);
       break;
      }
      // 일단 구매 번호를 지운다.
      //strBuyInfoSerial = null;
 try {
  jsonObj.put("result", strResult);
 } catch (JSONException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
      UnityPlayer.UnitySendMessage("Plugin91Manager", "UniPayResult_J", jsonObj.toString());
     }
    });
   }
  });
 }
 안드로이드 91 마켓 빌링 누락 처리 부분입니다. 구매 시리얼을 넘겨서 결과가 오면 마찬가지로 구매 시리얼을 유니티3D에 보내고 있습니다.

 public void CheckBillingMissing()
 {
  curActivity.Call("CheckBillingMissing_U");
 }
 Plugin91Manager 컴포넌트 부분입니다.

  fYpos += 50;
  if (GUI.Button(new Rect(0, fYpos, 100, 50), "CheckBilling\nMissing") == true)
  {
   Plugin91Manager.GetInstance().CheckBillingMissing();
  }
 TestGUI 컴포넌트 부분입니다.

 아이템을 하나 구매 후 누락을 체크해본 스샷입니다.

 이것으로 91 마켓 연동 정리를 마무리해봅니다. 91은 플랫폼 수준이라 이외에도 ndEnterFriendCenter, ndEnterAppBBS 같은 API등 처리할게 많이 있습니다. 호출만 해주면 되는 것들이입니다. 91이 바이두에 먹혀서 이 포스팅이 유용할지 모르겠네요. 다음에는 위에서 언급한 바이두 도쿠(Baidu Duoku) SDK 연동을 정리해보겠습니다.

댓글

이 블로그의 인기 게시물

'xxx.exe' 프로그램을 시작할 수 없습니다. 지정된 파일을 찾을 수 없습니다.

goorm IDE에서 node.js 프로젝트로 Hello World Simple Server 만들어 띄워보기

애드센스 수익을 웨스턴 유니온으로 수표대신 현금으로 지급 받아보자.