Android In-app Purchase V3 Error: Authentication is required -


i implementing google in-app purchase v3 , followed steps stated on here in official documentation here. have uploaded app in google playstore alpha testing , have downloaded playstore url real device giving me error

error

authentication required. need sign google account.

enter image description here

my code in-app purchase here:

public class buypointsfragment extends fragment //in app billing variable start      // debug tag, logging         static final string tag = "com.myapp";          // user have premium upgrade?         boolean mispremium = false;          // user have active subscription infinite gas plan?         boolean msubscribedtoinfinitegas = false;          // skus our products: premium upgrade (non-consumable) , gas         // (consumable)         static final string sku_premium = "premium";         static final string sku_gas = "gas";          // sku our subscription (infinite gas)         static final string sku_infinite_gas = "infinite_gas";          // (arbitrary) request code purchase flow         static final int rc_request = 10001;          // graphics gas gauge         static int[] tank_res_ids = {};          // how many units (1/4 tank our unit) fill in tank.         static final int tank_max = 4;          // current amount of gas in tank, in units         int mtank;          // helper object         iabhelper mhelper;        //in app billing variable end    @override     public view oncreateview(layoutinflater inflater, viewgroup container,             bundle savedinstancestate) {     //inapp  load game data             loaddata();              string base64encodedpublickey = "base64key publisher account";              // sanity checks see if developer (that's you!)             // followed             // instructions run sample (don't put these checks on app!)             if (base64encodedpublickey.contains("construct_your")) {                 throw new runtimeexception(                         "please put app's public key in mainactivity.java. see readme.");             }             if (getactivity().getpackagename().startswith("com.myapp.activity")) {                 throw new runtimeexception(                         "please change sample's package name! see readme.");             }              // create helper, passing our context , public key             // verify signatures             log.d(tag, "creating iab helper.");             mhelper = new iabhelper(getactivity(), base64encodedpublickey);              // enable debug logging (for production application, should set             // false).             mhelper.enabledebuglogging(true);              // start setup. asynchronous , specified listener             // called once setup completes.             log.d(tag, "starting setup.");             mhelper.startsetup(new iabhelper.oniabsetupfinishedlistener() {                 public void oniabsetupfinished(iabresult result) {                     log.d(tag, "setup finished.");                      if (!result.issuccess()) {                         // oh noes, there problem.                         complain(getstring(r.string.problem_setting_inapp_billing) + result);                         return;                     }                      // have been disposed of in meantime? if so, quit.                     if (mhelper == null)                         return;                      // iab set up. now, let's inventory of stuff                     // own.                     log.d(tag, "setup successful. querying inventory.");                     mhelper.queryinventoryasync(mgotinventorylistener);                    }             });              //in app billing code end here     } 

//in app billing methods start here

public void inappcall(){      setwaitscreen(true);     log.d(tag, "launching purchase flow gas.");      /*      * todo: security, generate payload here verification. see      * comments on verifydeveloperpayload() more info. since      * sample, use empty string, on production app      * should generate this.      */     string payload = "";      mhelper.launchpurchaseflow(getactivity(), sku_gas, rc_request,             mpurchasefinishedlistener, payload); }      // updates ui reflect model         public void updateui() {             // update car color reflect premium status or lack thereof             // ((imageview)findviewbyid(r.id.free_or_premium)).setimageresource(mispremium             // ? r.drawable.premium : r.drawable.free);              // "upgrade" button visible if user not premium             // findviewbyid(r.id.upgrade_button).setvisibility(mispremium ?             // view.gone : view.visible);              // "get infinite gas" button visible if user not             // subscribed yet             // (r.id.infinite_gas_button).setvisibility(msubscribedtoinfinitegas ?             // view.gone : view.visible);              // update gas gauge reflect tank status             if (msubscribedtoinfinitegas) {                 // ((imageview)findviewbyid(r.id.gas_gauge)).setimageresource(r.drawable.gas_inf);             } else {                 int index = mtank >= tank_res_ids.length ? tank_res_ids.length - 1                         : mtank;                 // ((imageview)findviewbyid(r.id.gas_gauge)).setimageresource(tank_res_ids[index]);             }         }          // enables or disables "please wait" screen.         void setwaitscreen(boolean set) {             // findviewbyid(r.id.screen_main).setvisibility(set ? view.gone :             // view.visible);             // findviewbyid(r.id.screen_wait).setvisibility(set ? view.visible :             // view.gone);         }          void complain(string message) {             log.e(tag, "**** trivialdrive error: " + message);             alert("error: " + message);         }          void alert(string message) {             alertdialog.builder bld = new alertdialog.builder(getactivity());             bld.setmessage(message);             bld.setneutralbutton("ok", null);             log.d(tag, "showing alert dialog: " + message);             bld.create().show();         }          void savedata() {              /*              * warning: on real application, recommend save data in              * secure way prevent tampering. simplicity in sample,              * store data using sharedpreferences.              */              sharedpreferences.editor spe = getactivity().getpreferences(getactivity().mode_private).edit();             spe.putint("tank", mtank);             spe.commit();             log.d(tag, "saved data: tank = " + string.valueof(mtank));         }          void loaddata() {             sharedpreferences sp = getactivity().getpreferences(getactivity().mode_private);             mtank = sp.getint("tank", 2);             log.d(tag, "loaded data: tank = " + string.valueof(mtank));         }          // we're being destroyed. it's important dispose of helper here!         @override         public void ondestroy() {             super.ondestroy();              // important:             log.d(tag, "destroying helper.");             if (mhelper != null) {                 mhelper.dispose();                 mhelper = null;             }         }          // listener that's called when finish querying items ,         // subscriptions own         iabhelper.queryinventoryfinishedlistener mgotinventorylistener = new iabhelper.queryinventoryfinishedlistener() {             public void onqueryinventoryfinished(iabresult result,                     inventory inventory) {                 log.d(tag, "query inventory finished.");                  // have been disposed of in meantime? if so, quit.                 if (mhelper == null)                     return;                  // failure?                 if (result.isfailure()) {                     complain(getstring(r.string.failed_to_query_inventory) + result);                     return;                 }                  log.d(tag, "query inventory successful.");                  /*                  * check items own. notice each purchase, check                  * developer payload see if it's correct! see                  * verifydeveloperpayload().                  */                  // have premium upgrade?                 purchase premiumpurchase = inventory.getpurchase(sku_premium);                 mispremium = (premiumpurchase != null && verifydeveloperpayload(premiumpurchase));                 log.d(tag, "user " + (mispremium ? "premium" : "not premium"));                  // have infinite gas plan?                 purchase infinitegaspurchase = inventory                         .getpurchase(sku_infinite_gas);                 msubscribedtoinfinitegas = (infinitegaspurchase != null && verifydeveloperpayload(infinitegaspurchase));                 log.d(tag, "user "                         + (msubscribedtoinfinitegas ? "has" : "does not have")                         + " infinite gas subscription.");                 if (msubscribedtoinfinitegas)                     mtank = tank_max;                  // check gas delivery -- if own gas, should fill                 // tank                 purchase gaspurchase = inventory.getpurchase(sku_gas);                 if (gaspurchase != null && verifydeveloperpayload(gaspurchase)) {                     log.d(tag, "we have gas. consuming it.");                     mhelper.consumeasync(inventory.getpurchase(sku_gas),                             mconsumefinishedlistener);                     return;                 }                  updateui();                 setwaitscreen(false);                 log.d(tag, "initial inventory query finished; enabling main ui.");             }         };          /** verifies developer payload of purchase. */         boolean verifydeveloperpayload(purchase p) {             string payload = p.getdeveloperpayload();              /*              * todo: verify developer payload of purchase correct.              * same 1 sent when initiating purchase.              *               * warning: locally generating random string when starting purchase              * , verifying here might seem approach,              * fail in case user purchases item on 1 device ,              * uses app on different device, because on other device              * not have access random string              * generated.              *               * developer payload has these characteristics:              *               * 1. if 2 different users purchase item, payload different              * between them, 1 user's purchase can't replayed              * user.              *               * 2. payload must such can verify when app              * wasn't 1 initiated purchase flow (so items              * purchased user on 1 device work on other devices owned              * user).              *               * using own server store , verify developer payloads across              * app installations recommended.              */              return true;         }          // callback when purchase finished         iabhelper.oniabpurchasefinishedlistener mpurchasefinishedlistener = new iabhelper.oniabpurchasefinishedlistener() {             public void oniabpurchasefinished(iabresult result, purchase purchase) {                 log.d(tag, "purchase finished: " + result + ", purchase: "                         + purchase);                  // if disposed of in meantime, quit.                 if (mhelper == null)                     return;                  if (result.isfailure()) {                     complain(getstring(r.string.error_purchase) + result);                     setwaitscreen(false);                     return;                 }                 if (!verifydeveloperpayload(purchase)) {                     complain(getstring(r.string.error_purchase_authenitcity_failed));                     setwaitscreen(false);                     return;                 }                  log.d(tag, "purchase successful.");                  if (purchase.getsku().equals(sku_gas)) {                     // bought 1/4 tank of gas. consume it.                     log.d(tag, "purchase gas. starting gas consumption.");                     mhelper.consumeasync(purchase, mconsumefinishedlistener);                 } else if (purchase.getsku().equals(sku_premium)) {                     // bought premium upgrade!                     log.d(tag, "purchase premium upgrade. congratulating user.");                     alert(getstring(r.string.thank_you_updgraing_premium));                     mispremium = true;                     updateui();                     setwaitscreen(false);                 } else if (purchase.getsku().equals(sku_infinite_gas)) {                     // bought infinite gas subscription                     log.d(tag, "infinite gas subscription purchased.");                     alert("thank subscribing infinite gas!");                     msubscribedtoinfinitegas = true;                     mtank = tank_max;                     updateui();                     setwaitscreen(false);                 }             }         };          // called when consumption complete         iabhelper.onconsumefinishedlistener mconsumefinishedlistener = new iabhelper.onconsumefinishedlistener() {             public void onconsumefinished(purchase purchase, iabresult result) {                 log.d(tag, "consumption finished. purchase: " + purchase                         + ", result: " + result);                  // if disposed of in meantime, quit.                 if (mhelper == null)                     return;                  // know "gas" sku because it's 1                 // consume,                 // don't check sku consumed. if have more                 // 1                 // sku, should check...                 if (result.issuccess()) {                     // consumed, apply effects of item in                     // our                     // game world's logic, in our case means filling gas                     // tank bit                     log.d(tag, "consumption successful. provisioning.");                     mtank = mtank == tank_max ? tank_max : mtank + 1;                     savedata();                     alert("you filled 1/4 tank. tank "                             + string.valueof(mtank) + "/4 full!");                 } else {                     complain("error while consuming: " + result);                 }                 updateui();                 setwaitscreen(false);                 log.d(tag, "end consumption flow.");             }         };          @override         public void onactivityresult(int requestcode, int resultcode, intent data) {             log.d(tag, "onactivityresult(" + requestcode + "," + resultcode + ","                     + data);             if (mhelper == null)                 return;              // pass on activity result helper handling             if (!mhelper.handleactivityresult(requestcode, resultcode, data)) {                 // not handled, handle ourselves (here's you'd                 // perform handling of activity results not related in-app                 // billing...                 super.onactivityresult(requestcode, resultcode, data);             } else {                 log.d(tag, "onactivityresult handled iabutil.");             }         }         //in app billing method end here 

my products managed products in developer account in-app products

enter image description here

edit:

when use android.test.purchased sku works fine , change sku product_id giving me error authentication required. need sign google account.

please make sure product id on playstore in app purchase "test_product" should use same sku in code. , if change sku application, possible sku names must exists on playstore in-app products. once run problem , reason sku item not exists on google playstore in-app products add on playstore , resolved.


Popular posts from this blog

c# - ODP.NET Oracle.ManagedDataAccess causes ORA-12537 network session end of file -

matlab - Compression and Decompression of ECG Signal using HUFFMAN ALGORITHM -

utf 8 - split utf-8 string into bytes in python -