ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 인앱결제 결제 자동 취소 이슈 해결
    프로그래밍/ 안드로이드어플만들기 2023. 12. 22. 20:44
    반응형

     

     

     

    문제

     

    빌링 라이브러리 업데이트 이후 이용자들의 구매가 자동으로 취소가 되고 있는 현상이 발생하였다. 자동으로 취소가 되는 것으로 보니 구매 후 처리가 제대로 되고 있지 않는것 같다. 

     

    참고) 구글 플레이 스토어의 정책에 따라, 모든 구매는 구매 후 일정 시간 내에 acknowledge(구독 상품의 경우) 또는 consume(일회성 상품의 경우) 처리가 되어야 합니다. 만약 이 처리가 제대로 이루어지지 않으면, 구글 플레이 스토어는 구매를 자동으로 취소하고 환불할 수 있습니다. 

     

     

     

     

     

     

    원인

     

    Since v5.0.0 BillingFlowParams.Builder has setProductDetailsParamsList() method which indicates there can be multiple products included within one purchase, so to be consistent with this Purchase has the getProducts() method which returns a list.

     

    Google Play Billing Library v5.0.0부터 BillingFlowParams.Builder에 setProductDetailsParamsList() 메소드가 추가되어 한 번의 결제 흐름에서 여러 상품을 포함할 수 있게 되었습니다. 이 변경으로 인해 Purchase 객체의 getProducts() 메소드는 구매된 상품들의 목록을 반환하는 List<String> 형태로 변경되었습니다.

     

     

    이러한 업데이트는 단일 구매 내에서 여러 상품을 처리할 수 있도록 하는 등 더 유연한 결제 옵션을 제공하기 위함입니다. 그러나 이 변경은 기존 코드에 영향을 미치며, 특히 getProducts().toString()의 결과가 이전과 다르게 나타나게 만들 수 있습니다.

     

     

     

    해결

     

    onPurchasesUpdate 함수에서 product id를 문자열 비교해서 acknowledge(구독 상품의 경우) 또는 consume(일회성 상품의 경우) 처리를 하는 부분이 있는데  getProducts() 메소드가 List<String> 타입을 반환하도록 변경되면서 toString() 메소드를 사용하면 리스트의 내용을 문자열로 변환합니다. 이 경우 리스트에 하나의 요소만 있더라도 결과는 "[element]" 형식으로 반환됩니다.

     

    이 부분에서 조건문에 들어가지 못해서 결재 이후 처리가 제대로 되지 못해서 3일 후에 자동 취소가 된 것이다. 

     

     

    public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> purchases) {
    
    
        // 결제에 성공한 경우.
        if( billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && purchases != null )
        {
    
            Log.d( TAG, "결제에 성공했으며, 아래에 구매한 상품들이 나열될 것 입니다." );
    
            for( Purchase purchase : purchases )
            {
                Log.d( TAG, "결제에 대해 응답 받은 데이터 :"+ purchase.getOriginalJson() );
    
                String productid = purchase.getProducts().toString();
                if(productid.equals("consume")) {
                    ConsumeParams consumeParams =
                            ConsumeParams.newBuilder()
                                    .setPurchaseToken(purchase.getPurchaseToken())
                                    .build();
                    //
                    mBillingClient.consumeAsync(consumeParams, mConsumResListner);
                }
                else if(productid.equals("sub")) {
    
                    if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
                        if (!purchase.isAcknowledged()) {
                            AcknowledgePurchaseParams acknowledgePurchaseParams =
                                    AcknowledgePurchaseParams.newBuilder()
                                            .setPurchaseToken(purchase.getPurchaseToken())
                                            .build();
                            mBillingClient.acknowledgePurchase(acknowledgePurchaseParams, mSubscribeListner);
                        }
                    } else if (purchase.getPurchaseState() == Purchase.PurchaseState.PENDING){
                        //거래 중지 등등 ... 결제관련 문제가 발생했을때
                        Log.d(TAG, "acknowledgePurchase: PENDING");
                    } else {
                        //그외 알 수 없는 에러들...
                        Log.d(TAG, "acknowledgePurchase: UNSPECIFIED_STATE");
                    }
    
                }
            }
        }
        // 사용자가 결제를 취소한 경우.
        else if( billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED )
        {
            Log.d( TAG, "사용자에 의해 결제가 취소 되었습니다." );
    
        }
        // 그 외에 다른 결제 실패 이유.
        else
        {
            Log.d( TAG, "결제가 취소 되었습니다. 종료코드 : " + billingResult.getResponseCode() );
        }
    }

     

     

    해결 방법은 간단하다. 그냥 productid.equals("removead")를 productid.contains("removead")로 변경하였더니 정상적으로 처리가 되었다. 

     

     

     

    참고 : https://stackoverflow.com/questions/72963984/billingclient-purchase-getproducts-returns-multiple-identifiers

     

     

     

     

     

    728x90
    반응형
Designed by Tistory.