Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Android™ Runtime Development

Reply
Contributor
varunagp1988
Posts: 42
Registered: ‎11-11-2013
My Device: Black berry Play book
Accepted Solution

In-App billing V2 RESTORE TRANSACTIONS not working

I have installed app from Blackberry World and purchased the app, now i uninstall the app and install it again.

 

I should be able to restore my purchased item but its not.

 

1) My purchased item is MANAGED.

2) I have 2 buttons BUY and RESTORE button.

 

Here is my code:

 

onClick of RESTORE i am calling this :

 

mBillingService.restoreTransactions();

 But nothing happens.

 

 /**
     * A {@link PurchaseObserver} is used to get callbacks when Android Market sends
     * messages to this application so that we can update the UI.
     */
    private class DungeonsPurchaseObserver extends PurchaseObserver {
	public DungeonsPurchaseObserver(Handler handler) {
	    super(BlackBerryInAppPurchaseActivity.this, handler);
	}

	@Override
	public void onBillingSupported(boolean supported, String type) {
	    if (Consts.DEBUG) {
		Log.i(TAG, "supported: " + supported);
	    }
	    Toast.makeText(getApplicationContext(), " billing supported: " + supported, 2000).show();
	    if (type == null || type.equals(Consts.ITEM_TYPE_INAPP)) {
		if (supported) {
		    restoreDatabase();
		} else {
		    showDialog(DIALOG_BILLING_NOT_SUPPORTED_ID);
		}
	    } else {
		showDialog(DIALOG_SUBSCRIPTIONS_NOT_SUPPORTED_ID);
	    }
	}

	@Override
	public void onPurchaseStateChange(PurchaseState purchaseState, String itemId, int quantity, long purchaseTime, String developerPayload) {
	    if (Consts.DEBUG) {
		Log.i(TAG, "onPurchaseStateChange() itemId: " + itemId + " " + purchaseState);
	    }
	    Toast.makeText(getApplicationContext(), "onPurchaseStateChange() itemId: " + itemId + " " + purchaseState, 2000).show();
	    if (purchaseState == PurchaseState.PURCHASED) {
		mOwnedItems.add(itemId);
		Toast.makeText(getApplicationContext(), "Hiding the button as the item is purchased " + itemId + " " + purchaseState, 2000).show();
	    }
	    mOwnedItemsCursor.requery();
	    if (itemId.equals(mSku)) {
		switch (purchaseState) {

		case PURCHASED:
		    Toast.makeText(getApplicationContext(), " Already purchased itemId: " + itemId + " " + purchaseState, 2000).show();
		    break;

		default:
		    Toast.makeText(getApplicationContext(), " Item NOT Purchased itemId: " + itemId + " " + purchaseState, 2000).show();
		    break;

		}
	    }
	}

	@Override
	public void onRequestPurchaseResponse(RequestPurchase request, ResponseCode responseCode) {
	    if (Consts.DEBUG) {
		Log.d(TAG, request.mProductId + ": " + responseCode);
	    }
	    Toast.makeText(getApplicationContext(), "request.mProductId " + responseCode, 2000).show();
	    if (responseCode == ResponseCode.RESULT_OK) {
		if (Consts.DEBUG) {
		    Log.i(TAG, "purchase was successfully sent to server");
		}
		//Update the UI
		logProductActivity(request.mProductId, "sending purchase request");
	    } else if (responseCode == ResponseCode.RESULT_USER_CANCELED) {
		if (Consts.DEBUG) {
		    Log.i(TAG, "user canceled purchase");
		}
		logProductActivity(request.mProductId, "dismissed purchase dialog");
	    } else {
		if (Consts.DEBUG) {
		    Log.i(TAG, "purchase failed");
		}
		Toast.makeText(getApplicationContext(), "purchase failed" + responseCode, 2000).show();
		logProductActivity(request.mProductId, "request purchase returned " + responseCode);
	    }
	}

	@Override
	public void onRestoreTransactionsResponse(RestoreTransactions request, ResponseCode responseCode) {
	    if (responseCode == ResponseCode.RESULT_OK) {
		if (Consts.DEBUG) {
		    Log.d(TAG, "completed RestoreTransactions request");
		}
		// Update the shared preferences so that we don't perform
		// a RestoreTransactions again.
		SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
		SharedPreferences.Editor edit = prefs.edit();
		edit.putBoolean(DB_INITIALIZED, true);
		edit.commit();
	    } else {
		if (Consts.DEBUG) {
		    Log.d(TAG, "RestoreTransactions error: " + responseCode);
		}
	    }
	}
    }

 In onCreate():

 

mHandler = new Handler();
	mDungeonsPurchaseObserver = new DungeonsPurchaseObserver(mHandler);
	mBillingService = new BillingService();
	mBillingService.setContext(this);

	mPurchaseDatabase = new PurchaseDatabase(this);
	
	// Check if billing is supported.
	ResponseHandler.register(mDungeonsPurchaseObserver);
	if (!mBillingService.checkBillingSupported()) {
	    showDialog(DIALOG_CANNOT_CONNECT_ID);
	}

 

/**
     * Wrapper class that sends a RESTORE_TRANSACTIONS message to the server.
     */
    class RestoreTransactions extends BillingRequest {
	long mNonce;

	public RestoreTransactions() {
	    // This object is never created as a side effect of starting this
	    // service so we pass -1 as the startId to indicate that we should
	    // not stop this service after executing this request.
	    super(-1);
	}

	@Override
	protected long run() throws RemoteException {
	    mNonce = Security.generateNonce();
	    Toast.makeText(getApplicationContext(), "RestoreTransactions()", Toast.LENGTH_LONG).show();
	    Bundle request = makeRequestBundle("RESTORE_TRANSACTIONS");
	    request.putLong(Consts.BILLING_REQUEST_NONCE, mNonce);
	    Bundle response = mService.sendBillingRequest(request);
	    //The RESPONSE_CODE key provides you with the status of the request
	    Integer responseCodeIndex = (Integer) response.get("RESPONSE_CODE");
	    Toast.makeText(getApplicationContext(), "RestoreTransactions(): RESPONSE CODE :" + responseCodeIndex, Toast.LENGTH_LONG).show();
	    logResponseCode("restoreTransactions", response);
	    return response.getLong(Consts.BILLING_RESPONSE_REQUEST_ID, Consts.BILLING_RESPONSE_INVALID_REQUEST_ID);
	}

	@Override
	protected void onRemoteException(RemoteException e) {
	    super.onRemoteException(e);
	    Security.removeNonce(mNonce);
	}

	@Override
	protected void responseCodeReceived(ResponseCode responseCode) {
	    ResponseHandler.responseCodeReceived(BillingService.this, this, responseCode);
	}
    }

    public BillingService() {
	super();
    }

    public void setContext(Context context) {
	attachBaseContext(context);
    }

    /**
     * We don't support binding to this service, only starting the service.
     */
    @Override
    public IBinder onBind(Intent intent) {
	return null;
    }

    @Override
    public void onStart(Intent intent, int startId) {
	handleCommand(intent, startId);
    }

    /**
     * The {@link BillingReceiver} sends messages to this service using intents.
     * Each intent has an action and some extra arguments specific to that action.
     * @param intent the intent containing one of the supported actions
     * @param startId an identifier for the invocation instance of this service
     */
    public void handleCommand(Intent intent, int startId) {
	String action = intent.getAction();
	if (Consts.DEBUG) {
	    Log.i(TAG, "handleCommand() action: " + action);
	}
	if (Consts.ACTION_CONFIRM_NOTIFICATION.equals(action)) {
	    String[] notifyIds = intent.getStringArrayExtra(Consts.NOTIFICATION_ID);
	    confirmNotifications(startId, notifyIds);
	} else if (Consts.ACTION_GET_PURCHASE_INFORMATION.equals(action)) {
	    String notifyId = intent.getStringExtra(Consts.NOTIFICATION_ID);
	    getPurchaseInformation(startId, new String[] { notifyId });
	} else if (Consts.ACTION_PURCHASE_STATE_CHANGED.equals(action)) {
	    String signedData = intent.getStringExtra(Consts.INAPP_SIGNED_DATA);
	    // String signature = intent.getStringExtra(Consts.INAPP_SIGNATURE);
	    purchaseStateChanged(startId, signedData);
	} else if (Consts.ACTION_RESPONSE_CODE.equals(action)) {
	    long requestId = intent.getLongExtra(Consts.INAPP_REQUEST_ID, -1);
	    int responseCodeIndex = intent.getIntExtra(Consts.INAPP_RESPONSE_CODE, ResponseCode.RESULT_ERROR.ordinal());
	    ResponseCode responseCode = ResponseCode.valueOf(responseCodeIndex);
	    checkResponseCode(requestId, responseCode);
	}
    }

 

 /** This is the action we use to bind to the MarketBillingService. */
    public static final String MARKET_BILLING_SERVICE_ACTION = "com.android.vending.billing.MarketBillingService.BIND";

    // Intent actions that we send from the BillingReceiver to the
    // BillingService.  Defined by this application.
    public static final String ACTION_CONFIRM_NOTIFICATION = "com.android.vending.billing.CONFIRM_NOTIFICATION";
    public static final String ACTION_GET_PURCHASE_INFORMATION = "com.android.vending.billing.GET_PURCHASE_INFORMATION";
    public static final String ACTION_RESTORE_TRANSACTIONS = "com.android.vending.billing.RESTORE_TRANSACTIONS";

    // Intent actions that we receive in the BillingReceiver from Market.
    // These are defined by Market and cannot be changed.
    public static final String ACTION_NOTIFY = "com.android.vending.billing.IN_APP_NOTIFY";
    public static final String ACTION_RESPONSE_CODE = "com.android.vending.billing.RESPONSE_CODE";
    public static final String ACTION_PURCHASE_STATE_CHANGED = "com.android.vending.billing.PURCHASE_STATE_CHANGED";

 

What i am missing here?

 

 

 

Retired
gbeukeboom
Posts: 2,559
Registered: ‎10-16-2009
My Device: BlackBerry Z10

Re: In-App billing V2 RESTORE TRANSACTIONS not working

Hi there,

 

Does this question mean you managed to get purchases working successfully?

 

Have you debugged the below code? Note that if purchases are made when sandbox testing then no transactions are logged, so there would be no transactions to restore.

Garett
@garettBeuk
--
Goodbye everybody!
Contributor
varunagp1988
Posts: 42
Registered: ‎11-11-2013
My Device: Black berry Play book

Re: In-App billing V2 RESTORE TRANSACTIONS not working

[ Edited ]

Hello gbeukeboom,

 

Thanks for replying.

 

1) I did not get what do youmean by this "Note that if purchases are made when sandbox testing then no transactions are logged, so there would be no transactions to restore".

 

How to Test Restore Transaction ? i am stuck here.

 

  I have an app upload app in draft state with MANAGED goods (SKU), i have download the app from BB World and Purchased it and i have uninstalled and again installed it and trying to restore the purchased item.

 

I am using on BB PlayBook (Version 2.1.0.1753).

 

2) No i havent solved this issue till now, i am able to purchase the item successfully but after purchase then i uninstall the app and install it again  from BB app world, initially it calls restore transactions and after that nothing happens.

 

I even have a restore button, onclick of that i am calling mBillingService.restoreTransactions();

 

 Initially when the activity loads and onClick of my restore button get these responses:

 

1) restoreDatabase() called --------> when we call restoreDatabase().

2) RestoreTransactions(): RESPONSE CODE : 0. ------------> When we get response from this makeRequestBundle("RESTORE_TRANSACTIONS");

3) RestoreTransactions error: RESULT_ERROR --------------> when it calls onRestoreTransactionsResponse()

 

I am sending request like this :

 

mBillingService.requestPurchase(mSku, Consts.ITEM_TYPE_INAPP, null), once i call this after that it also calls onPurchaseStateChange(), and it gives me "purchase was successfully sent to server".

 

But when i am restoring it will not call onPurchaseStateChange() and gives give the Error: RESULT_ERROR and i am not able to proceed further please help me.

 

Retired
gbeukeboom
Posts: 2,559
Registered: ‎10-16-2009
My Device: BlackBerry Z10

Re: In-App billing V2 RESTORE TRANSACTIONS not working

What happens if you install the app, make a purchase then immediately try to restore purchases? Does the item you just purchased get restored?

 

Do not exit the application in the above test.

Garett
@garettBeuk
--
Goodbye everybody!
Contributor
varunagp1988
Posts: 42
Registered: ‎11-11-2013
My Device: Black berry Play book

Re: In-App billing V2 RESTORE TRANSACTIONS not working

[ Edited ]

Yes did the changes reuploaded the app on BB dev console with a different version.

 

Download app from BB world, installed, i have purchased it(i get BB purcahase window), and i click on RESTORE button but i get this response:

 

1) RestoreTransactions(): RESPONSE CODE : 0. ------------> When we get response from this makeRequestBundle("RESTORE_TRANSACTIONS");

2) RestoreTransactions error: RESULT_ERROR --------------> when it calls onRestoreTransactionsResponse()

 

Its not Restoring my purchase.

 

In my manifest file:

<uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="com.android.vending.BILLING" />

<service android:name="com.android.vending.billing.BillingService" />

        <receiver android:name="com.android.vending.billing.BillingReceiver" >
            <intent-filter>
                <action android:name="com.android.vending.billing.IN_APP_NOTIFY" />
                <action android:name="com.android.vending.billing.RESPONSE_CODE" />
                <action android:name="com.android.vending.billing.PURCHASE_STATE_CHANGED" />
            </intent-filter>
        </receiver>

 

What might be the the issue? or am i missing something here?

 

I did not get what do you mean by this "Note that if purchases are made when sandbox testing then no transactions are logged, so there would be no transactions to restore".

 

EDIT 1 :

 

In ResponseHandler class we have this:

 

 public static void responseCodeReceived(Context context, RestoreTransactions request, ResponseCode responseCode) {
	if (sPurchaseObserver != null) {
	    sPurchaseObserver.onRestoreTransactionsResponse(request, responseCode);
	}
    }

 So What i to just test it i manually added :

 

sPurchaseObserver.onRestoreTransactionsResponse(request, ResponseCode.RESULT_OK);

 And tested the app, and now it restores.

 

So i am still unable to find Whats the bug in my code of implementation?

Retired
gbeukeboom
Posts: 2,559
Registered: ‎10-16-2009
My Device: BlackBerry Z10

Re: In-App billing V2 RESTORE TRANSACTIONS not working

The Payment APIs are 100% Google. Have you verified that your app works as expected on an Android device? 

Garett
@garettBeuk
--
Goodbye everybody!
Contributor
varunagp1988
Posts: 42
Registered: ‎11-11-2013
My Device: Black berry Play book

Re: In-App billing V2 RESTORE TRANSACTIONS not working

[ Edited ]

Yes its working fine in Google play.

 

In BB also i am able to make purchases but they are not charged, in that case how can i test Restore functionality?

 

And is there anything wrong in code above? or in my reponses.

Retired
gbeukeboom
Posts: 2,559
Registered: ‎10-16-2009
My Device: BlackBerry Z10

Re: In-App billing V2 RESTORE TRANSACTIONS not working

You can only test restoring from the device cache. I'll need to verify with our Android dev team to verify whether the Android Runtime has been configured to restore from the server or device cache. If the server then you will be unable to test on BlackBerry, but as mentioned before this is using the Android APIs, so if you have tested on an Android device then you have tested already.

Garett
@garettBeuk
--
Goodbye everybody!
Contributor
varunagp1988
Posts: 42
Registered: ‎11-11-2013
My Device: Black berry Play book

Re: In-App billing V2 RESTORE TRANSACTIONS not working

Yes please let me know.

 

And also what might be the possibility that i am getting this error RESULT_ERROR? when restoring.

 

 

Contributor
varunagp1988
Posts: 42
Registered: ‎11-11-2013
My Device: Black berry Play book

Re: In-App billing V2 RESTORE TRANSACTIONS not working

[ Edited ]
If you require i can give you my app id for you to test, i can give you my entire code as a Zip so that you can point out if there is any bug in code. i mean you are free and willing to take up.