1. 구매후 로직이 필요했다.
이전에 올린 글을 통해서 billing을 2개월 동안 오픈했는데, 사람들이 구매하자마자 계속해서 환불을 했다.
이게 우연의 일치겠지라고 생각을 했는데, 대략 6명 정도가 그랬고, 내 돈이 하늘나라로 날아가는 것을 봐야만 했다.
그래서 코드에 문제가 없는게 아닐까 의심을 하기 시작했다.
onPurchaseUpdate에서 handlePurchase(purchase) 로직을 처리해야 했다.
override fun onPurchasesUpdated(billingResult: BillingResult?, purchases: MutableList<Purchase>?) {
if (billingResult?.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) {
for (purchase in purchases) {
sharedPrefUtils.putStringSharedPref(activity, REMOVE_AD, "on")
handlePurchase(purchase)
}
} else if (billingResult?.responseCode == BillingClient.BillingResponseCode.USER_CANCELED) {
// Handle an error caused by a user cancelling the purchase flow.
} else {
// Handle any other error codes.
}
}
물건을 구매했으며, 소비해야지. 물건을 consume해야하는 로직이 필요했다.
이 로직이 없으니까, 물건을 구매하고 나고, 5분 후에 환불이 되는 것을 발견했고, 이 로직을 추가하고 난 후에 환불이 되지 않는 것을 알았다...
private fun handlePurchase(purchase: Purchase) {
val consumeParams = ConsumeParams
.newBuilder()
.setPurchaseToken(purchase.purchaseToken)
.setDeveloperPayload(purchase.developerPayload)
.build()
billingClient.consumeAsync(consumeParams) { billingResult, purchaseToken -> }
}
그러면, 환불 했으면, SharePrefrence로 지정되어 있는 값은 안 바뀌는데... 내 물건 구매하고 있는 지 확인해봐야하는 거 아닐까?
2. 구매 후, 사용자가 환불 했는 지 알고 싶다.
환불이 되고 난 후, 로직을 생각해본 적이 없다. 팀원분이 환불이 되고 난 후, 로직을 생각해야 한다고 알려주셨고, billingClient를 만들어서, queryPurchaseHistory를 확인해 보고, 구매 내역이 1개라도 있으면, 광고 제거를 안 시키는 로직으로 생각을 하고 있다. 이게 잘 될지 모르겠지만, 우선 이렇게 해야겠다.
fun getPurchaseHistory() {
billingClient.startConnection(object : BillingClientStateListener {
override fun onBillingServiceDisconnected() {
}
override fun onBillingSetupFinished(billingResult: BillingResult?) {
billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP) { billingResult, purchaseHistoryRecordList ->
if(billingResult.responseCode == BillingClient.BillingResponseCode.OK){
if(purchaseHistoryRecordList != null && purchaseHistoryRecordList.size>0){
sharedPrefUtils.putStringSharedPref(activity, REMOVE_AD, "on")
}else{
sharedPrefUtils.putStringSharedPref(activity, REMOVE_AD, "off")
}
}
}
}
})
}
3. BillingManager를 큰 덩어리로 다시 봐보자.
예전에 BillingManager를 Sample로 제공해줬던 것 같은데... v3로 올라가고는 그러지 않는 것 같다. 가장 심플하게 광고제거를 사용하고 있는 BillingManager는 아래와 같다.
BillingManager 로직
package hbs.com.timetablescreen.utils
import android.app.Activity
import com.android.billingclient.api.*
import hbs.com.timetablescreen.utils.MainUtils.REMOVE_AD
class BillingManager(val activity: Activity) : PurchasesUpdatedListener {
private val sharedPrefUtils = SharedPrefUtils()
val billingClient = BillingClient.newBuilder(activity).enablePendingPurchases().setListener(this).build()
fun makeBillingClient(): BillingClient = BillingClient.newBuilder(activity).enablePendingPurchases().setListener(this).build()
fun getPurchaseHistory() {
billingClient.startConnection(object : BillingClientStateListener {
override fun onBillingServiceDisconnected() {
}
override fun onBillingSetupFinished(billingResult: BillingResult?) {
billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP) { billingResult, purchaseHistoryRecordList ->
if(billingResult.responseCode == BillingClient.BillingResponseCode.OK){
if(purchaseHistoryRecordList != null && purchaseHistoryRecordList.size>0){
sharedPrefUtils.putStringSharedPref(activity, REMOVE_AD, "on")
}else{
sharedPrefUtils.putStringSharedPref(activity, REMOVE_AD, "off")
}
}
}
}
})
}
fun processToPurchase() {
val skuList = ArrayList<String>()
skuList.add(REMOVE_AD)
billingClient.startConnection(object : BillingClientStateListener {
override fun onBillingServiceDisconnected() {
}
override fun onBillingSetupFinished(billingResult: BillingResult?) {
val params = SkuDetailsParams.newBuilder()
params.setSkusList(skuList)
params.setType(BillingClient.SkuType.INAPP)
launchBillingFlow(params)
}
})
// Retrieve a value for "skuDetails" by calling querySkuDetailsAsync().
}
override fun onPurchasesUpdated(billingResult: BillingResult?, purchases: MutableList<Purchase>?) {
if (billingResult?.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) {
for (purchase in purchases) {
sharedPrefUtils.putStringSharedPref(activity, REMOVE_AD, "on")
handlePurchase(purchase)
}
} else if (billingResult?.responseCode == BillingClient.BillingResponseCode.USER_CANCELED) {
// Handle an error caused by a user cancelling the purchase flow.
} else {
// Handle any other error codes.
}
}
private fun launchBillingFlow(params: SkuDetailsParams.Builder) {
billingClient.querySkuDetailsAsync(params.build()) { billingResult, skuDetailsList ->
// Process the result.
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
if (skuDetailsList.size > 0) {
val flowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetailsList[0])
.build()
val responseCode = billingClient.launchBillingFlow(activity, flowParams)
}
}
}
}
private fun handlePurchase(purchase: Purchase) {
val consumeParams = ConsumeParams
.newBuilder()
.setPurchaseToken(purchase.purchaseToken)
.setDeveloperPayload(purchase.developerPayload)
.build()
billingClient.consumeAsync(consumeParams) { billingResult, purchaseToken -> }
}
}
Activity 로직
if (id == R.id.nav_purchase_in_app) {
billingManager.processToPurchase();
}
'Android 공부 > Android Library Study' 카테고리의 다른 글
Android Firebase cloud messaging 업그레이드 고군분투 (1) | 2019.11.24 |
---|---|
Android Worker - 매일 알람 만들기 (0) | 2019.11.09 |
안드로이드 인앱결제 - 구매 로직 (2) | 2019.11.09 |
서울시 공공데이터 API를 활용한 Paging Library 사용하기 - 2 (0) | 2019.08.19 |
서울시 공공데이터 API를 활용한 Paging Library 사용하기 - 1 (0) | 2019.08.18 |