Open edmundsiah81 opened 5 years ago
We have used Billprocessor & also included merchant ID, yet he still able to transact google pay without paying. May we know how to prevent this malware?
Its easy. You can crack any app with "Lucky Patcher". To be 100% sure, you have to check the purchase token on your server side if it is valid.
Hi Anjlab,
Thanks, we manage to solve this through server side verification.
Thanks for responding back to us.
On Mon, Mar 4, 2019, 4:22 PM Isy notifications@github.com wrote:
Its easy. You can crack any app with "Lucky Patcher". To be 100% sure, you have to check the purchase token on your server side if it is valid.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/anjlab/android-inapp-billing-v3/issues/389#issuecomment-469160003, or mute the thread https://github.com/notifications/unsubscribe-auth/AjoGcHS8NWvArhju6LwWFclRl2qcSJ5qks5vTNfFgaJpZM4bTR9M .
Hi edmundsiah,
I am having same issue with someone purchasing my in-app subscriptions. There are no transactions logged to Google Play, but my analytics software has logged successful purchases and the user has access to premium content. May I know more about your solution please? This is new to me. I do have server-side capability. I just need to understand what pattern you used to catch/prevent this.
Thank you!
Hi Steven,
You need to use the token thats provided by in-app purchase, send it to your server, using your server to rest api with google https://www.googleapis.com/androidpublisher/v2/applications/packageName/inappproducts/sku
if token is authentic from google in app purchase, you will receive proper response from google, else if its a fake token, you will receive an error response.
Based on the google verification response, you can choose whether to honour your users in app purchase.
Hope my explanation helps
Thank you very much! This is very helpful! One part I am confused about is the parameters that are sent to the API. If the API only takes packageName and sku as inputs, then how does it associate the return data with a particular user? The sku is just the product identifier, right? It is not the unique transaction identifier. So does this API rely on the currently logged in user's Google credentials? Sorry if my question is a bit novice!
You have to send the Token from the purchase to you server and check it there. ` String developerPayload = details.purchaseInfo.purchaseData.developerPayload; String responseData = details.purchaseInfo.responseData; JSONObject responseObject; String token = ""}
try {
responseObject = new JSONObject(responseData);
token = responseObject.get("purchaseToken").toString();
} catch (JSONException e) {}`
Now send the token to your server. On the Server side you can check with php:
` public function getApiUrl() { return "https://www.googleapis.com/androidpublisher/v3/applications/com.yourcopany.app/purchases/subscriptions/adfree/tokens/"; }
public function getTokenInfo() {
$chUrl = $this->getApiUrl() . $this->getUserToken() . "?access_token=" . $this->getCurrentToken();
$ch = curl_init($chUrl);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$this->setApiRespone($response);
$this->checkRespone();
}
`
The respnose is a JSON:
{ "kind": "androidpublisher#productPurchase", "purchaseTimeMillis": long, "purchaseState": integer, "consumptionState": integer, "developerPayload": string, "orderId": string, "purchaseType": integer }
Now you have the Data from the google API to check if this was legit. But you have to register a API key in the google dev console.
Here the tutorial for the api key: https://developers.google.com/android-publisher/authorization
Here the tutotial for the inapp stuff: https://developers.google.com/android-publisher/api-ref/purchases/products/get
you will than get a token and an refresh_token. The token is 3600 seconds valid. After you have to use the refresh token to get a new one.
This is very tricky to code. i have implemented it, so if you have ny question feel free to ask. Happy coding.
This is great thank you so much! I will go through it carefully and let you know if I have any questions. May I ask which part is tricky? Is it the server-side piece? Or did you mean specifically the refresh token part? Going through it now. Thank you again!
The tricky part is to get the token and the refresh_token. I was always getting only the token without the refresh_token. Than you alsow have to do some steps which are not described there. You have to go to your play console and in settings you have to link the PLAY CONSOLE API with the GOOGLE DEV API. Here the link https://play.google.com/apps/publish/?account=YOUACCOUNTID#ApiAccessPlace replace YOUACCOUNTID with yours. VERY IMPORTANT!! You have to create the inapp product which you whant to check AFTER you createt the API token. If you do not do this step you are not able to check the tokens. So you have to create the inapp purchases again.
Inapp products which are created bevor the token will not be work with the token you created. Stupid... but yeah this is life :D
That's a really important tip about needing to set up the in-app purchases again. This is going to be a much bigger project than I thought. I'm going to start working on getting the API set up first.
Unfortunately, the API documentation (at least for how to set it up) appears to be outdated. And also, from what I can tell, it is telling me that in order to set up OAuth verification I need to configure a consent screen for my users. I wasn't aware that would be required. This is getting hairy really quickly!
Thank you again!
Consent screen? What do you mean with consent screen?
Let me show you some screen shots. Maybe I am doing something wrong. I am home from work sick today and my brain isn't at 100% :)
After I add the Google Play Android Developer API, I finally find this screen which appear to be the right place, but I am not sure. The instructions at the link above didn't get me here. I was unable to use them as they seem to be outdated.
From that page, I click on "Create Credentials" because again, I see nothing that says "Create an OAuth 2.0 client ID". This is as close as I can find, which makes me wonder if I am guessing correctly. Here's the screen I get:
It seems to be some sort of wizard to help you determine what kind of credentials you need. Instead of using the wizard, I opted to skip by clicking "client ID". When I do that, it takes me to this page:
That screen is where it tells me that I "must first set a product name on the consent screen". To comply with this command, I click on "Configure consent screen" and I am presented with the following screen:
Note the part on that screen that says it can take weeks for Oauth verification to be complete: "The verification process may take up to several weeks, and you will receive email updates as it progresses."
I must be doing something wrong. This isn't anything like what I expected.
No this is unimportant! You only need to fill the name of the application. This is only for one time usage. You will get a token and a refresh token. After this you will never need this again.
Got it! I have my client ID and now on to the "Generating a refresh token" portion. Thank you!
OK so I have created my token now and also linked PLAY CONSOLE API with the GOOGLE DEV API. Before I create all new products (there are actually 12 of them and they are recurring subscriptions and I will need a code release to coincide with them), what should the next steps be? Do you have any re-usable code that I could use? I have PHP running on my webserver. And regarding those auto-renewing subscription products, if people have already purchased them, it will be very tricky to provide a good user experience to them because their products will no longer appear in the list of products inside the app. That is, I don't want to add 12 new ones and not take away the 12 old ones because the page would appear to have 12 duplicates on it. Does that make sense?
Wow. This is very tricky in your situation. The only thing you can do is duplicate the products and than make an app update so you can check your new subscribers. The old subscribers have to renew their subscribtion bevor you can check their subscribtion. Very tricky situation. Be carefull while coding :D. I can share my code tomorow with you. You have to make a logic for you old sunscrtiptions like a bool value in your database like "oldsubscribtion true".
Yes, it is going to be very tricky. And the open number of subscriptions is growing every day. I think I may be able to keep the old subscriptions in place, yet remove them from being purchased on my Purchase page. Then perhaps I can cancel or refund them from within Google Play and ask them to subscribe again. I hate to do that. Actually, they are all paying members, so maybe it is best just to let the stay. It's just that their currently purchased subscriptions won't show up as "Subscribed" anymore on my Purchase page, which isn't ideal. This is never easy when messing around with people's money. Google should do a better job of making sure cheats and swindlers cannot get away with stuff like this. It's why I like developing for iPhone better :). Thank you again for your help!
OK so I have created my token now and also linked PLAY CONSOLE API with the GOOGLE DEV API. Before I create all new products (there are actually 12 of them and they are recurring subscriptions and I will need a code release to coincide with them), what should the next steps be? Do you have any re-usable code that I could use? I have PHP running on my webserver. And regarding those auto-renewing subscription products, if people have already purchased them, it will be very tricky to provide a good user experience to them because their products will no longer appear in the list of products inside the app. That is, I don't want to add 12 new ones and not take away the 12 old ones because the page would appear to have 12 duplicates on it. Does that make sense?
Hi Steven,
Why can't you code in a way that for those who have purchased using old products to direct them to old productsID & for those new ones to direct to the new product ID. You definitely have your own users ID to identify who have already subscribe your products in your database.
with this, users who have subscribed will not have bad experience until they renew.
Sorry for the missing info of the parameters to include in my previous sharing
for those in CAPS are the parameters you need to fill in based on your project.
I suppose you already know how to get the access token.
Could you please share a working example please, in PHP? The documentation and SO answers make it extremely confusing, especially the refresh token part.
I went the service account way and have a json file with me. How to use that?
Forget the JSON file. Dosent work with that. I will make a turorial with working PHP and JAVA code. I will update you in this thread.
@isipisi281 Can you please post your full working php code?
I got it by myself ;)
How can I bypass in-app purchases on Free Fire online game....plis help me what tool can I use on termux
Hi,
We received hack from users about to purchase without paying. No transaction found at google and there is a token received. What happen? please help