Android In-App Billing : Security.java says Signature Verification Failed
That signature verification error can be caused by:
1.- A wrong public key. Maybe you've forgotten to copy some character. It happens :)
2.- The .apk must be signed. You can't use the debug.keystore, if you do your signature string will be empty.
And remember, for testing In-app billing:
Add Android Market public key to Security.java (
String base64EncodedPublicKey = "your public key here"
)Build in release mode and sign it (If you are using Eclipse, you can use the Export Wizard).
Upload the release version to Android Market, do not publish it, and create the product list.
Install the application onto your device ( adb -d install myapp.apk ) and make a test account primary on your device.
android in app billing purchase verification failed
Replace your verifyPurchase()
method with below one. Use old code that given below, google developer are trying to solve this error in the near future but before they updated their code you should prefer below code.
public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) {
if (signedData == null) {
Log.e(TAG, "data is null");
return false;
}
boolean verified = false;
if (!TextUtils.isEmpty(signature)) {
PublicKey key = Security.generatePublicKey(base64PublicKey);
verified = Security.verify(key, signedData, signature);
if (!verified) {
Log.w(TAG, "signature does not match data.");
return false;
}
}
return true;
}
check this link for more information:
In App billing not working after update - Google Store
Use try to replace OLD CODE method verifyPurchase()
method in your project. But It should be only happens when you are trying to purchase test products. Let me know for the real products purchase also after using this code.
Edit:
Why it happens because we will not get any signature while we are using dummy product like "android.test.purchased". So in the old code it is working good because we were return true even if signature is not given and for the New code we are returning false.
more information about the signature data null or blank from link1 and link2
So I suggest you just replace old code method verifyPurchase()
instead of New Code method.
I think may be New Code will work fine for the real product but not in the dummy product. But yet I have not tested for the real product.
or
use GvS's answer for the test purchases it also the good solution for the new code.
Hope it will solve your problem.
In apps billing signature verification
According to android documentation here it is stated that
The fifth argument contains a ‘developer payload’ string that you can
use to send supplemental information about an order (it can be an
empty string). Typically, this is used to pass in a string token that
uniquely identifies this purchase request. If you specify a string
value, Google Play returns this string along with the purchase
response. Subsequently, when you make queries about this purchase,
Google Play returns this string together with the purchase details.Security Recommendation: It’s good practice to pass in a string that
helps your application to identify the user who made the purchase, so
that you can later verify that this is a legitimate purchase by that
user. For consumable items, you can use a randomly generated string,
but for non-consumable items you should use a string that uniquely
identifies the user.
So , For the product ID SKU_2006 if you initiated the purchase flow with String payload = email+item1;
then Google Play will return the same payload in the response and hence you would get it here as
boolean verifyDeveloperPayload(Purchase p) {
String payload = p.getDeveloperPayload();
..
}
Now , let me define the whole scenario in terms of code :
First , you would initiate a purchase request like below
String payload = getUserEmailFromAndroidAccounts() + itemUniqueId;
mHelper.launchPurchaseFlow(new PurchaseFinishListener(itemUniqueId), SKU_GAS, 10001,
mPurchaseFinishedListener, payload);
If the purchase order is successful, the response data from Google Play is stored in an Purchase object that is passed back to the listener.
private class PurchaseFinishListener implements IabHelper.OnIabPurchaseFinishedListener {
private final String mItemUniqeId;
public PurchaseFinishListener(String itemUniqeId) {
mItemUniqeId = itemUniqeId;
}
public void onIabPurchaseFinished(IabResult result, Purchase purchase)
{
if (result.isFailure()) {
Log.d(TAG, "Error purchasing: " + result);
return;
}
if (!verifyDeveloperPayLoad(mItemUniqeId , purchase)) {
Log.d(TAG, "Authenticity verification failed");
return;
}
// set your product as purchased in your DB or server
}
}
Now your verifyDeveloperPayLoad(purchase) method should look as below :
private boolean verifyDeveloperPayLoad(String itemUniqueId , Purchase purchase) {
String responsePayload = purchase.getDeveloperPayload();
String computedPayload = getUserEmailFromAndroidAccounts() + itemUniqueId;
return responsePayload != null && responsePayload.equals(computedPayload);
}
If you have closely observed code , you would surely understand how is the work flow .
Further information about Subscription based purchase and one time purchase can be obtained from Android site.
Related Topics
Error:Connectionresult{Statuscode=Internal_Error, Resolution=Null}
Error "Activity Class Does Not Exist" When Launching Android App with Adb Shell Am Start
Android Save Checkbox State in Listview with Cursor Adapter
Android Intent.Getstringextra() Returns Null
Android Studio Project Structure (V.S. Eclipse Project Structure)
Using Build Types in Gradle to Run Same App That Uses Contentprovider on One Device
How to Draw Border on Just One Side of a Linear Layout
Mediarecorder Start Failed: -38
Android Devices with Different Height Takes Same Layout Folder
Manipulating Data on Webs in Android
How to Show Toast in Asynctask in Doinbackground
Can the Android Emulator Record and Play Back Audio Using Pc Hardware
Jpeg Images Have Different Pixel Values Across Multiple Devices
Android Emulator Issues in New Versions - the Emulator Process Has Terminated
Android Scale Animation on View