Hi to all! I want to post a small example to verify the signature of an in-app purchase, in order to avoid the use of application like Freedom and Lucky Patcher.
An important note is that this method doesn't work with in-app purchase that uses promotional code.
There are different ways to verify the signature, in this tutorial I will explain the method using the php and i will mention the verification through google api.
CODE
PHP
Note: Public key is available in Google Play Console
GOOGLE API
Another way to verify the purchase is to use Google api and to send the SKU and the purchase Token.
Add this code
And call this url
Note that you need an authorization to download information from this url, you can follow this tutorial
An important note is that this method doesn't work with in-app purchase that uses promotional code.
There are different ways to verify the signature, in this tutorial I will explain the method using the php and i will mention the verification through google api.
CODE
B4X:
Dim bill As BillingManager3 = Utils.BillingManager
bill.Initialize("manager", Utils.billing_key)
bill.DebugLogging = True
Wait For manager_BillingSupported (Supported As Boolean, Message As String)
If Supported = False Then
Log(Message)
Return
End If
bill.GetOwnedProducts
Wait For manager_OwnedProducts (Success As Boolean, purchases As Map)
If Success Then
bill.RequestPayment("your id","inapp","your playload")
Wait For manager_PurchaseCompleted (Success As Boolean, Product As Purchase)
If Success Then
Dim jo As JavaObject = Product
Dim signature As String = jo.RunMethod("getSignature",Null)
Dim purchaseData As String = jo.RunMethod("getOriginalJson",Null)
Dim pkgname As String = "your package name"
Dim su As StringUtils
Dim purchaseData_Base64 As String = su.EncodeBase64(purchaseData.GetBytes("UTF8"))
Dim signature_Base64 As String = su.EncodeBase64(signature.GetBytes("UTF8"))
Dim job As HttpJob
job.Initialize("",Me)
Dim url As String = $"yoursite/yourphp.php?pkg=${pkgname}&js=${purchaseData_Base64}&sgnt=${signature_Base64}"$
job.Download(url)
Wait For (job) Jobdone (job As HttpJob)
If job.Success Then
Log(job.GetString)
End If
job.Release
End If
End If
PHP
B4X:
<?php
$pkg = filter_input(INPUT_GET,'pkg',FILTER_SANITIZE_STRING);
$js = filter_input(INPUT_GET,'js',FILTER_SANITIZE_STRING);
$sgnt = filter_input(INPUT_GET,'sgnt',FILTER_SANITIZE_STRING);
print_r(verifyGoogleOrderLocal($pkg,$js,$sgnt));
function verifyGoogleOrderLocal($packageName, $jsonData_Base64, $signature_base64)
{
$public_keys = array(
'your package name' => 'public key',
'another package name' => 'another public key',
);
if(!$public_keys[$packageName]) {
return array("success"=>0,"reason"=>'no public key defined');
}
$key = get_openssl_key($public_keys[$packageName]);
if(!$key) {
return array("success"=>0,"reason"=>'invalid public key');
}
$json = base64_decode($jsonData_Base64);
$signature = base64_decode($signature_base64);
$result = openssl_verify($json, base64_decode($signature), $key, sha1WithRSAEncryption);
$resp = array('success'=>$result);
if($result==0) $resp['reason'] = 'invalid signature';
// echo '......'.openssl_error_string();
return $resp;
}
function get_openssl_key($publicKey)
{
$key = "-----BEGIN PUBLIC KEY-----\n" . chunk_split($publicKey, 64, "\n") . '-----END PUBLIC KEY-----';
$key = openssl_get_publickey($key);
return $key;
}
?>
Note: Public key is available in Google Play Console
GOOGLE API
Another way to verify the purchase is to use Google api and to send the SKU and the purchase Token.
Add this code
B4X:
Dim parser As JSONParser
parser.Initialize(purchaseData)
Dim root As Map = parser.NextObject
Dim sku As String = root.Get("productId")
Dim purchaseToken As String = root.Get("purchaseToken")
And call this url
B4X:
Dim url As String = $"https://www.googleapis.com/androidpublisher/v2/applications/${pkgname}/purchases/products/${sku}/tokens/${purchaseToken}"$
Note that you need an authorization to download information from this url, you can follow this tutorial
Last edited: