반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형
코로나 SDK에서 안드로이드용 In-App Purchase 관련  API를 내 놨습니다.
이제 아이폰,안드로이드폰 모두에서 코로나로 개발한 In-App Purchase기능을 사용할 수 있게 됐습니다.

아래 이번주에 Corona SDK에서 배포한 안드로이드 In-app Billing 튜토리얼을 정리했습니다.

여러분도 참고하세요.

======o ===== o ===== o ===== o ===== o =====

Getting Started with Android In-app Billing

앱을 통해서 돈을 벌 수 있는 방법은 유료 앱으로 publish를 하던가 광고를 달던가 아니면 가상 머니를 사용하는 방법이 있습니다.
그 외에 in-App Billing이 있는데요. 이번에 Corona SDK에서 안드로이드용 In-App Billing 기능을 발표했습니다.

이 in-App Purchase 기능은 모바일 앱을 이용한 많이 애용되는 비지니스 모델인데요 이것을 다른 말로 freemium 이라고 합니다. freemium은 일단 무료로 제공하고 그 외의 고급 기능이나 아이템을 유료로 구매할 수 있도록 하는 것을 말합니다.
모바일 앱의 경우는 다음 레벨로 가거나 특별한 아이템을 구한다던가 virtual currency를 사용하던가 하는 기능을 넣을 수가 있을 겁니다.

유저가 구매를 approve하면 새로운 컨텐츠가 unlock 되거나 외부 소스로부터 다운로드 되던가 할 겁니다.
이 방법을 사용하면 아주 다양한 방법의 수익 모델을 만들어 낼 수 있습니다. 그리고 이번에 Corona SDK에서 안드로이드 용으로 이 기능을 지원했기 때문에 그 다양한 수익 모델을 Corona SDK로 개발하면서도 사용할 수 있습니다.
아이폰 앱에는 이미 이 기능이 지원됐기 때문에 코로나 개발자들은 두개의 시장에서 이 기능을 이용할 수 있게 되겠죠? 이것이 Corona SDK 같은 cross-platform development tool의 매력이라고 할 수 있을 겁니다.

하지만 이 좋은 기능도 개발자나 기획자가 사용할 줄 모르면 아무 소용이 없을 겁니다. 이 기능을 이용하려면 최신버전의 Corona SDK가 있어야 합니다. (현재는 유료 사용자만이 다운 받을 수 있습니다.)



Getting Started

시작하기 전에 여러분이 준비해 두셔야 할 부분이 있습니다.
1. Corona SDK build 2012.769 이후 버전
2. Indie-AndroidCorona Pro 유료 사용자 일 것
3. Android Developer 계정을 가지고 있을 것

1. Android Deveoper Console
안드로이드 내에서 billing이 가능하게 하려면 BILLING 퍼미션이 build.settings에 세팅 돼 있어야 합니다. 그리고 이것을 Android Developer Console에 없로드해서 당신의 앱이 In-App Billing Products를 시작할 수 있도록 만들어 두어야 합니다.
main.lua에 아무런 코딩이 안 돼 있어도 이 작업을 해야 합니다. 그리고 지금 개발이 진행 중이라도 상관없습니다. 어쨌든 우선 이 step을 밟아야 합니다. 여러분의 앱에 In-app 상품을 넣을 수 있으려면 우선 이 과정을 거쳐야 하는게 구글이 만들어 놓은 룰입니다.
당신의 앱이 이미 판매중이거나 마켓에 오픈돼 있는 상태라도 이 기능을 넣으려면 우선 build.settings에 퍼미션을 넣고 업로드 한 다음에 In-App purchase 기능을 개발해야 합니다.
한번 이렇게 해 두면 Android developer console의 해당 앱 밑에 in-app products라는 링크를 클릭해서 이곳에서 올린 in-app 상품을 보실 수가 있습니다.

build.settings에 BILLING 퍼미션을 넣는 방법은 아래와 같습니다.

settings =
{
    orientation =
    {
        default = "landscapeRight",
    },

    android =
    {
        usesPermissions =
        {
            "com.android.vending.BILLING",
        },
    }
}

이 예제에서 주의깊게 보셔야 할 점은 android - usesPermissions의 com.android.vending.BILLING 부분 입니다.
이 부분은 orientation을 지정한 settings 다음에 위치해 있습니다.
 
이렇게 하신 후에 android 앱으로 build하세요. 그리고 그 apk화일을 android developer console에 업로드 하시면 됩니다.

아직까지는 Publish를 하지는 마세요.

그렇게 한 다음부터 In-app 제품을 넣기 위한 Administering In-app Billing Guide를 진행 하실 수 있습니다.

안드로이드 개발자로서 마켓에 앱을 올려보신 분들은 아시겠지만 앱을 다 개발 한 다음에 publish를 해야하는데요. 요즘은 이것을 또 Activate 하는 단계도 생겼더라구요.
혹시 나중에 앱을 다 만들고 나서 마켓에 올리고 테스트 할 때 주의하세요.

Google Documentation

구글 Guide에 대해서는 위에 링크를 걸어 놓기는 했지만 여기에 대해서는 한번 언급하고 넘어가는게 좋을 것 같습니다.

구글에서는 In-app Products를 어떻게 셋업해야 하는지에 대해 꽤 좋은 가이드를 제공하고 있습니다. 그리고 그것을 쉽게 테스트 할 수 있도록 했구요.
만약 여러분이 Android Developer Console쪽에서 어떻게 세팅해야 하는지를 자세히 알고 싶으시면 아래 두 가이드를 참고하세요.

2. The Corona "store" API

이 튜토리얼에서는 구글에서 제공하는 test product identifier들을 사용하겠습니다.
이 테스트 상품에서는 아래 세가지 Action을 가져올 수 있습니다.

- android.test.purchased : 구매가 성공했을 때 얻어 옴
- android.test.canceled : 구매 트랜잭션이 cancel 됐을 때 얻어 옴
- android.test.item_unavailable : 해당 제품 구매가 가능하지 않을 때 얻어 옴

이 테스트 상품의 진짜 nice 한 점은 이렇게 각각 다른 상황에서 여러분들이 이를 어떻게 쉽게 콘트롤 할 수 있을 지 경험할 수 있게 해 준다는 점 입니다. 예를 들어 여러분은 android.test.canceled 상품을 이용해서 유저가 트랜잭션 중 cancel했을 경우에 대한 코딩을 할 수 있게 됩니다.

store.init("google", transactionCallback)

여러분이 코딩을 하면서 이 in-app purchase 기능을 구현하기 위해서는 제일 처음 store.init() API를 사용하게 될 겁니다. 파라미터로는 구글 마켓(얼마전 Google Play로 바뀌었습니다.)을 사용할 거라는 것을 알리는 "google"을 첫번째로 넣고 두번째로는 불러올 함수 명을 넣습니다.

아래 transaction callback listener 함수와 함께 store.init()을 사용하는 방법에 대한 샘플 예제가 있습니다.

local function transactionCallback( event )
    local transaction = event.transaction

    if transaction.state == "purchased" then
            -- Transaction was successful; unlock/download content now
   
    elseif transaction.state == "restored" then
           -- You'll never reach this transaction state on Android.

    elseif transaction.state == "refunded" then
        -- Android-only; user refunded their purchase
        local productId = transaction.productIdentifier
        -- Restrict/remove content associated with above productId now
  
    elseif transaction.state == "cancelled" then
        -- Transaction was cancelled; tell you app to react accordingly here

    elseif transaction.state == "failed" then
            -- Transaction failed; tell you app to react accordingly here
     end

    -- The following must be called after transaction is complete.
    -- If your In-app product needs to download, do not call the following
    -- function until AFTER the download is complete:

    store.finishTransaction( transaction )
end

store.init( "google", transactionCallback )

맨 아래 store.init()이 transactionCallback 함수를 call 하는 보분이 있죠? 이 부분이 Android In-app Billing 이벤트가 발생 했을 때 실행 될 부분입니다.

Handling Refunds

Android In-app billing은 iOS의 In-app billing과 거의 같은데 한가지 refunded라는 트랜잭션 상태가 더 있습니다. iOS와는 다르게 안드로이드 플랫폼에서는 유저가 refund할 수 있도록 해 줍니다. 그래서 유저에게 주었던 contents를 다시 가져오려면 바로 이 refunded 트랜잭션 상태일 때 해야 할 것입니다.

위 샘플에서 보듯이 refunded 트랜잭션 상태에서 받는 중요한 데이터는 event.transaction.productIdentifier입니다. 이 정보를 가지고 여러분은 필요한 작업을 하실 수 있습니다. 아마도 그 필요한 작업은 환불 했을 경우 해당 content를 다시 block 시키는 거겠죠? 아니면 돈을 내고 추가로 다운 받은 파일을 지우는 기능이던가요.

No "restored" State on Android

store.restore() 함수는 로그인 된 유저 계정과 연관된 product id의 리스트를 다시 검색할 수 있도록 해 줍니다. iOS에서는 이 product 리스팅이 transactionCallback listener 의 restored 트랜잭션 상태에서 받을 수 있습니다. 그리고 안드로이드에서는 이 restored 트랜잭션 상태가 없습니다. 대신에 그 상품이 purchased를 다시 실행하면서 그 기능을 할 수 있습니다.
아주 작은 차이이지만 transactionCallback listener 함수를 디자인할 때 잘 고려해서 디자인을 해야 합니다.

Other Transacton Event Data

transaction events와 관계된 다른 모든 데이터들은 iOS의 In-app purchase와 동일합니다. 그러니까 다음 guide를 꼭 봐 주세요.
In-app  Purchase Guide
Transaction Listener Callback Events
그리고 예전에 in-Purchase app 샘플을 분석했던 글을 보시면 도움이 되실겁니다.
코로나 네트워킹 과 웹 서비스 3 (In App Purchase 1)

store.finishTransaction (transaction)

위 샘플 코드에 있는 transactionCallback() 함수에 있는 모두 아주 중요한 것들입니다.
store.finishTransaction은 모든 트랜잭션의 마지막부분에 반드시 call 되야 합니다.
어떤 트랜잭션이 끝났다는 것을 확실히 정의하는 부분입니다.
만약 어떤 파일을 다운로드 받아야 할 때는  어떤 상황이 발생할 까요? 아마도 이 다운로드가 모드 끝나고 나서 store.finishTransaction()이 call 되어야 할 겁니다. (그러려면 어딘가에 network.download() 리스너가 있어야 겠죠.)

만약 이미 코딩은 최초 다운받은 앱에 다 돼 있고 단순히 어떤 content를 unlock 하는 기능만 수행될거면 callback 리스너 마지막 부분에 store.finishTransaction()을 넣으면 되겠죠.

두 경우 모두 첫번째 인수로 event.transaction 테이블을 넘겨줘야 한다는 것을 잊지 마세요.
 store.finishTransaction( event.transaction )

3. Purchasing Products

이제 purchases, refunds, failed/cancelled 같은 트랜잭션들을 어떻게 다뤄야 할 지 알아 보겠습니다. iOS in-app purchase에서와 같이 store.purchase()를 사용해서 트랜잭션을 초기화 합니다. 대개 앱 화면에서 Buy 버튼을 누르면 이벤트 리스너가 감지해서 call할 때 이 동작이 이뤄 집니다.
-- single product purchase
    store.purchase( { "android.test.purchased" } )

-- multi-item purchase
   store.purchase( { "android.test.purchased", "android.test.canceled" } )

여기서도 Google에서 제공하는 테스트 product들을 사용해서 테스트 해 볼 수 있습니다.
좀 더 자세한 정보를 보시려면 store.purchase() documentation 을 참고하세요.

Cross-Platform Development

코로나의 장점은 한번의 코딩으로  아이폰, 안드로이드 용 앱을 만들 수 있는 multi-platform 기능입니다. 이 기능을 좀 더 쉽게 콘트롤 할 수 있도록 코로나에서는 store API에 새로운 프로퍼티를 추가했습니다.
애플의 In-app Purchase는 iOS 디바이스들에서만 가능하고 안드로이드의 In-app Billing은 Google Play에서만 가능합니다. (같은 안드로이드 앱이라도 Nook나 Kindle Fire 에서는 In-app Billing을 사용할 수 없습니다.)
새로 제공되는 기능은 store.availableStores 테이블로 어떤 디바이스 인지를 알수 있는 파라미터 입니다.

아래 예제가 있습니다.

if store.availableStores.apple then
    store.init("apple", transactionCallback)
   
elseif store.availableStores.google then
    store.init("google", transactionCallback)
end

이렇게 코딩을 하면 아이폰용과 안드로이드 용 파일을 따로 관리할 필요가 없겠죠?

iOS의 In-app Purchases와 Android의 In-app Billing은 한가지 크게 다른 개념이 있습니다. 안드로이드에서는 각각의 In-App product들에 대해 정보를 retrieve할 수 없는 반면에 iOS에서는 이 기능이 가능합니다. 이것은 구글의 한계라고 볼 수 있겠죠. 이 의미는 상품의 이름, description같은 정보들을 직접 앱 내에서 혹은 외부 서버에서 개발자들이 직접 관리해야 한다는 얘기 입니다. (만약에 필요하다면요.)

이 다른 점 때문에 store.loadProducts() 함수가 있는데 이것은 iOS in-app purchases에서만 사용될 수 있습니다. 여러분이 iOS,안드로이드 두 플랫폼 모두에서 돌아가는 앱을 개발하고자 한다면 이 함수가 가능한지 여부를 체크하기 위해서 store.canLoadProducts 프로퍼티를 사용하실 수 있습니다. (store.init()에서 pass된 플랫폼이 무엇인가에 따라 true와 false를 return 하게 됩니다.)

 Additional Resources

Android In-app Billing 을 테스트 하시려면 구글에서 제공하는 테스트 상품으로 쉽게 테스트하실 수 있구요. 또 여러분이 만든 상품으로도 쉽게 테스트 하실 수 있습니다. 이번에 새로 제공되는 Corona SDK 내의 InAppPurchase 샘플 코드를 참조하세요.
/SampleCode/Networking/InAppPurchase 에 있습니다.

그리고 예전에 iOS in-app purchase와 관련해서 올려 놓은 In-app Purchase Guide도 보시구요. iOS용 가이드 이지만 대부분이 안드로이드에서도 적용 됩니다. 그리고 각각의 store API 함수에 대한 정보를 보시려면 In-app Purchase API Reference를 보시기를 권장합니다.

이 기능은 Corona Daily Build 2012.760 이후 버전에서만 가능합니다.
현재까지 이 버전은 유료 사용자만 받으실 수 있습니다.

======o ===== o ===== o ===== o ===== o =====

요즘 예전처럼 폭풍집필이 잘 안되네요.
슬럼프인가봐요.. 휴~~~~~~~
여러분의 추천이 큰 힘이 될 수 있을 것 같아요.
추천 부탁드려요.

추천.. 추천.. ~~~ ~~~ 감사.. 감사..
반응형