5

My question is similar to this one. However, I am using the API Java Client Library with a service account, making calls to the API from my server.

My code is following this guide, which is very simple. However, I can't seem to get an appropriate error for my request. This is how I build my AndroidPublisher:

val credential = GoogleCredential.fromStream(FileInputStream(
        "/path/to/json"
)).createScoped(Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER))

androidPublisher = AndroidPublisher.Builder(httpTransport, JSON_FACTORY, credential)
        .setApplicationName(packageName)
        .build()

Where the JSON is generated from the Developer Console, under Service Accounts. This is how I make my request:

androidPublisher.purchases().subscriptions().get(packageName, "valid-sku", "invalid-token").execute()

My subscription ID is valid but my token is invalid. I expect an error such as "invalid token" in the response. However, what I get is:

com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
  "code" : 400,
  "errors" : [ {
    "domain" : "global",
    "message" : "Invalid Value",
    "reason" : "invalid"
  } ],
  "message" : "Invalid Value"
}

Is that a generic error because of the invalid token or is it an authentication issue? If it an authentication issue, how do I solve it? If it is an invalid token issue, how am I supposed to know?

Some more information:

  • I get the same error when trying to make that call from the API Explorer as well (this time using a Client ID and API Key instead of Service Account).
  • I have not delegated domain-wide access to the service account. Do I have to for some reason?
  • I can successfully make other calls to the API such as inappproducts.list
pavlos163
  • 2,219
  • 3
  • 27
  • 70

5 Answers5

7

So, the reason that happened was just because the purchaseToken I was using was wrong.

I did not expect that to be the reason as I thought that in the case of an invalid token, I would receive a "token invalid" error (or something similar). As it turns out, the responses given by Google are pretty inconsistent (a 404 could also be given for an invalid token).

pavlos163
  • 2,219
  • 3
  • 27
  • 70
6

From my experiences, if you have HTTP 400 error with Invalid Value then that purchase or subscription is FRAUD.

You can check out Order Id part of those purchases. Probably in the format of XXXXXXXXXXXX.XXXXXXXXXXXX which is wrong and should be GPA.XXXX.XXXXX.XXXXX.XXX

  • I don't really count the X char number. I just added to show the logic.
Berkay Turancı
  • 3,056
  • 3
  • 28
  • 41
  • Do you have any idea how users get this fraudulent Order ID? – Joe Okatch Apr 11 '20 at 21:33
  • 1
    @JoeOkatch there are several ways for that. Since they are not legal I will not share the links directly. However you can google it as "How can we h..k the in-app purchases in Google Play Store?" You will come up something like; "Patcher" – Berkay Turancı Apr 13 '20 at 12:09
  • 1
    @BerkatTuranci very much appreciated. I have been getting these fraudulent codes lately. We are always learning something new. – Joe Okatch Apr 13 '20 at 20:34
  • @BerkatTuranci also another question if you don't mind...Is it normal for the console to indicate orders as "charged 0" even though api json is OK? – Joe Okatch Apr 13 '20 at 21:38
  • 1
    @JoeOkatch if you are using subscription and allow free usage trial time then it is okay. For the first trial period you can see 0 price for charged. And normal payment for the second recurrence. – Berkay Turancı Apr 14 '20 at 07:33
  • @BerkatTuranci Oh, I see. I just realised that we left the free trial mode on in the console. Much appreciated. – Joe Okatch Apr 14 '20 at 15:51
6

In my case the problem was that I was calling:

purchases.products.get

Instead of:

purchases.subscriptions.get
Mr Stanev
  • 1,512
  • 1
  • 16
  • 22
1

Scratched my head for a few hours, ALL my parameters were correct, and then well.. I realized that I was barking up the wrong tree (endpoint)

https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/subscriptions/{subscriptionId}/tokens/{token}

is not this

https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/products/{productId}/tokens/{token}

/purchases/subscriptions/.. vs /purchases/products/..

-1

For all those who run into this problem, 99% of you need to publish the application for internal testers.

Follow this guide: https://support.google.com/googleplay/android-developer/answer/6062777?hl=en

enter image description here

  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/28546688) – Tomerikoo Mar 16 '21 at 19:14
  • You're right, I changed my answer, I hope to help someone in the future, it took me a long time to find this solution. – Ardito ITA Mar 16 '21 at 19:56