인앱 결제 테스트 : android.test.purchased 이미 소유


122

현재 향후 앱에 대한 인앱 결제를 테스트하고 있으며 테스트 항목 "android.test.purchased"를 처음으로 성공적으로 "구매"한 후 다시 구매하려고 할 때마다 응답 코드 7을받습니다. 이미이 항목을 소유하고 있음을 의미합니다.

12-15 23 : 02 : 14.149 : E / IabHelper (19829) : 인앱 결제 오류 : 항목을 구매할 수 없음, 오류 응답 : 7 : 항목이 이미 소유 됨

내가 이해 한 바에 따르면이 구매는 항상 가능해야합니다. 개발자가 자신의 앱을 테스트 할 수 있도록?

그렇지 않은 경우 상태를 소유하지 않음으로 "재설정"하려면 어떻게해야합니까? Google 인앱 결제 샘플의 util 패키지를 사용하고 있습니다.


1
내 모집은 바이스 구절입니다 .. 이미 소유 한 메시지가 필요하지만 구매를 허용 할 때마다
Sandeep P

답변:


109

이 코드를 스레드에 추가하여 소비 요청을 시작하십시오.

int response = mService.consumePurchase(3, getPackageName(), purchaseToken);

여기에서 구매 테스트를 위해 purchaseToken은

purchaseToken = "inapp:" + getPackageName() + ":android.test.purchased";

if (response == 0)

그러면 소비가 성공합니다.

또한 mService를 공개하는 것을 잊지 마십시오.

IabHelper.Java

다음과 같이 액세스 할 수 있습니다.

int response = mHelper.mService.consumePurchase(3, getPackageName(), purchaseToken);

2
이것이 작동하는 전설, @psykhi가 실제로 당신에게 포인트를 주었어야했습니다. 나는 그것을 소비하려고했지만 구매 토큰을 알아낼 수 없었다. 감사합니다
Blundell

1
감사합니다! @prasharonnet
Y2i

1
이것은 엄청난 시간 절약입니다. 완전한. 감사.
PrivusGuru 2011

13
mService 란 무엇입니까? mHelper? 하지만 ConsumerPurchase ()를 찾을 수 없습니다
Bagusflyer 2014-08-18

1
mService는 인앱 구매를 위해 시작된 구매 서비스와 결합 된 IInAppBillingService.aidl 인터페이스의 객체입니다.
Aashutosh Sharma

92

특별한 소비 코드를 작성할 필요가 없습니다. Google Play Store 데이터를 지우려면 adb 명령을 사용하십시오.

adb shell pm clear com.android.vending

1
고마워요 내가 앱을 지워야하는 트릭을 했으므로 전체 답변을 사용할 수 있습니다. 이것은 나에게 올바른 접근 방식입니다.
sivi

이것은 많은 사람들에게 올바른 접근 방식입니다. 앱에 코드를 추가하고 재배포하는 데 더 많은 시간이 소요됩니다 (의도 한 말장난).
Michael Labbé 2015 년

9
이는 테스트 기기에 적합한 솔루션이지만주의하세요. Google Play 스토어 앱의 모든 설정을 재설정합니다. 그래서 나는 내 개인 장치에서 그것을하지 않을 것입니다.
racs

7
아니! 이것은 나쁜 생각입니다. 다른 제품과 다른 앱의 인앱 구매를 잃었습니다. 좋은 것은 인앱 구매를 테스트하려면 제품을 소비해야한다는 것입니다. 시나리오는 구매 용과 구매 용으로 두 가지를 생성하는 것입니다. 안건.
Rahul Mandaliya

2
@RahulMandaliya 앱은 이미 구매 한 항목을 파악하기 위해 getPurchases () API를 사용하여 캐시 지우기에 대해 탄력적이어야합니다.
mttmllns

66

android.test.purchased 항목은 일반 ID처럼 작동합니다. 다시 구매하려면 코드의 어딘가에서 소비해야합니다. Google 문서는이 문제에 대해 오해의 소지가 있으며 테스트 목적으로 끝없이 구입할 수있는 또 다른 정적 ID를 추가해야한다고 생각합니다.


인벤토리 호출을 사용하여 Purchase 객체를 가져온 다음 소비합니다. 일단 머리를 돌리면 꽤 쉽습니다.
slott

3
@mttmlins의 아래 답변을 보거나 vvse.com/blog/blog/2016/08/26/을 읽으십시오
IgorGanapolsky

완전히 사실이 아닙니다. 사용하지 않은 테스트 아이템이 있지만 billingClient.queryPurchases()그 미사용 아이템을 반환하지 않는 경우가 있습니다 . 그래서 지금은 얻을 수 없어서 아이템을 소비 할 수 없습니다.purchaseToken 그것을
Jemshit Iskenderov

28

인앱 버전 3 :

IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {

    public void onQueryInventoryFinished(IabResult result, Inventory inventory) {

        .....................

        if (inventory.hasPurchase(SKU_CONTENT)) {

            mHelper.consumeAsync(inventory.getPurchase(SKU_CONTENT), null);
        }
    }
};

사진은 천 단어의 가치가 있으므로, 완전한 작동하는 베어 본 코드 조각은 천 'Add this code to a thread. . . '.
Androidcoder dec.

11

버전 3-가장 빠른 해결 방법 : Google Play 스토어의 캐시를 지우면 "android.test.purchased"를 다시 사용할 수 있습니다.


시스템에 설치된 다른 앱에도 영향을주지 않습니까?
IgorGanapolsky

1
@IgorGanapolsky, 아니. 시뮬레이션 된 구매 만 영향을받습니다. "실제"구매는 Google 서버에 저장되며 수정되지 않습니다.
Denis

1
Google Play에서 앱 데이터를 지 웠지만 작동하지 않습니다. 테스트 구매 세부 정보가 여전히 존재합니다.
Srikar Reddy

2
"설정 / 응용 프로그램 관리자 /"를 통해 @Richard를 사용하거나 메뉴에서 Google Play 스토어 아이콘을 화면 상단의 "정보"버튼으로 드래그합니다. 마지막으로 "캐시 지우기"버튼을 클릭하십시오.
Denis

1
저에게 가장 좋은 대답입니다. 모든 다른 사람은 좋다, 그러나 이것은 확실히 해결하는 가장 빠른 방법입니다
이그나시오 로다

10

나는 adb 쉘을 사용했습니다.

adb shell pm clear com.android.vending

9

이것이 우리가 아이템을 소비하는 방법입니다

 consume.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    String purchaseToken = "inapp:" + getPackageName() + ":android.test.purchased";
                    try {
                        Log.d("","Running");
                        int response = mService.consumePurchase(3, getPackageName(), purchaseToken);
                        if(response==0)
                        {
                            Log.d("Consumed","Consumed");
                        }else {
                            Log.d("","No"+response);
                        }
                    }catch (RemoteException e)
                    {
                        Log.d("Errorr",""+e);
                    }

                }
            });
            t.start();
        }
    });

나를 위해 일했습니다- android.test.purchase문제를 일으키는 어떤 시점에서 사용했습니다 . 인앱 결제의 인벤토리 작업은 오류를 던지고 완료되지 않았습니다. 이것을 일회성으로 실행하면 실제 SKU를 다시 사용하고 이전처럼 계속할 수 있습니다. 감사합니다
Jon

1
훌륭한 대답입니다. 정적 응답과 함께 작동 = 인앱 결제가 활성화 된 APK가 Google Play에 업로드되기 전.
infero

감사! 나를 위해 일했습니다.
AndroidMechanic-Viral Patel 2015 년

6

내 생각에 프로그램이 항목을 소비하도록 설계되지 않은 경우 외부 공급 업체의 메모리를 지우기 위해 코드를 조정할 필요가 없습니다. 이렇게하면 코드가 더 취약 해지고 소프트웨어에 속하지 않는 코드를 추가하고 제거하는 데 많은 시간을 소비해야하므로 이와 같은 솔루션을 구현하는 것은 나쁜 설계입니다.

android.test.purchased를 지우는 데 도움이 된 최고의 솔루션은

adb uninstall com.yourapp.name

그리고

adb shell pm clear com.android.vending

현금을 지우고 앱 설정을 탐색하거나 코드를 변경할 필요가 없었습니다. Windows 시스템의 경로 변수에 adb를 추가해야했습니다. 그래서 예, 어쨌든 필요할 것 같은 adb를 사용해야합니다.

C : \ ... \ android-sdk \ platform-tools를 추가하기 만하면됩니다. 환경 변수의 Windows 경로에서 Mac과 Linux OS에서도 매우 간단하다고 생각합니다. 누군가가 앱 결제에서 Android를 구현하는 데 며칠을 덜 소비하는 데 도움이되기를 바랍니다.


uninstallandroid.test.purchased sku 를 지우는 데는 필요하지 않습니다 .
IgorGanapolsky

4

가장 큰 문제는 android.test.purchased아이템 을 소비해야한다는 것 입니다. 그러나이 항목은 쿼리 인벤토리에서 사용할 수 없으므로 정상적인 흐름을 사용하여 소비 할 수 없습니다.

따라서 IabHelper클래스 에서 IabHelper를 사용하는 경우 IabHelper에서 IInAppBillingService액세스 할 수 있도록 mService를 일시적 으로 public 으로 변경할 수 있습니다 .

그런 다음 수업에서 이렇게 소비 할 수 있습니다.

int response = mHelper.mService.consumePurchase(3, getPackageName(), "inapp:"+getPackageName()+":android.test.purchased");

성공하면 응답은 0이됩니다.

도움이 되었기를 바랍니다.


Tangent : 관리되는 항목에 대해 환불을 처리 할 수 ​​있나요 (테스트 계정 사용-대시 보드에 표시되지 않음)?
에드 리

당신은 호출 할 수 있습니다 consumeAsync()android.test.purchased . 그것에는 문제가 없습니다.
IgorGanapolsky

간단한 테스트의 경우 IabHelper를 사용하는 경우 가능한 가장 좋은 방법입니다. 나를 도와 주었다.
Rúben 2017 년

2

테스트 목적으로 gp 구매 흐름을 초기화하는 메서드를 호출하기 전에 구입 한 모든 제품을 지우는 코드를 삽입하는 것이 좋습니다. 한 번에 하나의 항목 만 테스트 할 때 특히 편안합니다. 예 :

PurchasesResult purchasesResult = mBillingClient.queryPurchases(BillingClient.SkuType.INAPP);
    for (Purchase sourcePurchase : purchasesResult.getPurchasesList()) {
        if(sourcePurchase != null){

            ConsumeResponseListener listener = new ConsumeResponseListener() {
                @Override
                public void onConsumeResponse(String outToken, @BillingResponse int responseCode) {

                    System.out.println("all consumed");
                }
            };
            mBillingClient.consumeAsync(sourcePurchase.getPurchaseToken(), listener);
        }else{
            System.out.println("null");
        }
    }

// and then initiate whole process with clear "shoping basket"

BillingFlowParams.Builder builder = new BillingFlowParams.Builder()
        .setSku(itemName).setType(BillingClient.SkuType.INAPP);

2

Google Play 콘솔로 이동하여 주문 관리 탭을 엽니 다. 여기에서 테스트 구매를 환불 / 취소 할 수 있습니다.


1

테스트 환경에있는 경우

1) android.test.purchased의 경우, 안드로이드 기기 (인벤토리 소모)를 다시 시작하여 위조 결제를 초기화 할 수 있습니다.

2) InApp util에는 Security.java라는 파일이 있습니다. 임시로 다음과 같이 만듭니다. 테스트 결제 (가짜)는 보안 예외로 인해 항상 거짓을 반환하기 때문에.

public static boolean verifyPurchase(String base64PublicKey,
                                     String signedData, String signature) {
    return true; }

그런 다음 OnIabPurchaseFinishedListener에서 fechInvForconsumeItem ()을 호출하십시오.

IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
            = new IabHelper.OnIabPurchaseFinishedListener() {
        public void onIabPurchaseFinished(IabResult result,
                                          Purchase purchase)
        {
            if (result.isFailure()) {
                // Handle error
                Log.e("123","Failure");

                return;
            }
            else if (purchase.getSku().equals(ITEM_SKU)) {
                Log.e("123","PURCAsed");
                fechInvForconsumeItem(); // Restart device if not consume

            }

        }
    };

fechInvForconsumeItem ()은

    public void fechInvForconsumeItem() {
    mHelper.queryInventoryAsync(mReceivedInventoryListener);
}
IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
        = new IabHelper.QueryInventoryFinishedListener() {
    public void onQueryInventoryFinished(IabResult result,
                                         Inventory inventory) {


        if (result.isFailure()) {
            // Handle failure
            Log.e("11","Failure");



        } else {
            Log.e("11","suc");
            mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU),
                    mConsumeFinishedListener);
        }


    }
};

소비 리스너 (현재)

    IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
        new IabHelper.OnConsumeFinishedListener() {
            public void onConsumeFinished(Purchase purchase,
                                          IabResult result) {

                if (result.isSuccess()) {
                } else {
                    // handle error
                    Log.e("11","sucConsume");
                }
            }
        };

0
IabHelper.QueryInventoryFinishedListener 
       mQueryFinishedListener = new IabHelper.QueryInventoryFinishedListener() {
       public void onQueryInventoryFinished(IabResult result, Inventory inventory)   
       {
          if (result.isFailure()) {
             return;
           }          
          try {

                if(inventory.hasPurchase("product_sku_id"))
                {   
                     isItemEnable= true;
                     mHelper.consumeAsync(inventory.getPurchase("product_sku_id"),null);            
                }
                else
                {
                       isItemEnable = false;
                }           

            } catch (Exception e) {
                e.printStackTrace();
            }
       }

    };

-1

제 경우에는 Google이 해당 항목에 대한 구매를 기록하지 않는 것 같습니다. 대신 Google Play 서비스의 로컬 사본이 구매를 캐시합니다. 이렇게하면 동일한 장치에서 두 번째 요청이있을 때 android.test.purchased already owned나타납니다. 그러나 다른 장치를 사용하거나 장치를 재설정하면 캐시가 지워지고 구매를 반복 할 수 있습니다.


-1

제 경우에는 앱 캐시를 지우면됩니다. 캐시를 지운 후 다시 구매 흐름을 시작할 수있었습니다.

내 장치 (4.4.2)에서 "설정-> 응용 프로그램 관리자"로 이동했습니다. 다음으로 "다운로드 됨"탭에서 앱을 선택한 다음 "캐시 지우기"를 선택했습니다.


-2

이것은 소모품과 비 소모품의 차이입니다. 비 소모성 품목 (여기서 다루는 것처럼 보이는 것)은 지속적으로 상태를 추적하는 반면, 소모품은 여러 번 구매할 수 있습니다. 다시 테스트하려면 Play 관리 콘솔로 이동하여 판매를 취소 / 환불해야합니다.


1
그러나 문제는 이러한 "가짜"품목에 대한 "권한"이 없으며 실제 구매가 아니기 때문에 판매 상태를 어디에서 변경할 수 있는지 알 수 없습니다. 구글 문서는 (가) android.test.purchased에 대해 말한다 : 이 제품 ID로 인앱 결제 요청을 할 때, 구글 플레이 응답 비록 당신이 성공적으로 항목을 구입. 그래서 나는 꽤 혼란 스러워요 : /
psykhi

아직 정적 응답 테스트를하고 있습니까? 그렇다면 어떤 정적 응답이 전송되는지 변경하기 만하면됩니다. 취소 가능한 주문으로 실제 구매를 수행하는 "자신의 제품 ID를 사용하여 인앱 구매 테스트"를 수행하는 것처럼 들립니다.
addaon dec

나는 여전히 정적 ID로 붙어 있습니다. 내가 원하는 것은 android.test.purchased ID로 인앱 구매를 테스트 할 수있는 것입니다. Google 문서에서 이해 한 내용에서 항상 작동해야 할 때 처음으로 작동했습니다. 명확하지 않으면 죄송합니다!
psykhi

내 오해, 죄송합니다. 그 경우 ... 모르겠어요. 매번 성공을 거두어야하는데, 당신이보고있는 사건을 본 적이 없습니다. 죄송합니다.
addaon dec

숙면을 취한 후 문제를 다시 살펴볼 것입니다 :) 도와 주셔서 감사합니다!
psykhi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.