voltrue2 / in-app-purchase

A Node.js module for in-App-Purchase for iOS, Android, Amazon and Windows.
http://iap.gracenode.org
Other
1.05k stars 289 forks source link

packageName missing in receipt data #196

Open jenni-divvito opened 6 years ago

jenni-divvito commented 6 years ago

Hello,

I'm currently running up against an issue where, for most of the receipts I receive from an android app, the packageName is not included in the data part of the receipt. Looking through other issues on here it seems like it is generally there for others, so I'm not sure what the difference for me is - maybe either because we are still at the stage of using the registered google test accounts, or because of the framework we use on the frontend maybe (react-native-iap), I'm not sure.

Long story short though, we get a receipt that looks almost correct:

{
  "data": "{\"productId\":\"com.an.iap.product.id\",\"purchaseToken\":\"aLongEncodedString",\"purchaseTime\":1532326966225,\"developerPayload\":null}",
  "signature": "anotherLongEncodedString"
}

(data cleaned for anonymity).

We get through the "Google API authenticated" and "Google API access token" points, but then when we try to actually hit the URL we get "No application was found for the given package name." and a 404 from the actual request, which makes sense given

var url = 'https://www.googleapis.com/androidpublisher/v2/applications/' +
            encodeURIComponent(receipt.data.packageName) +
            '/purchases/subscriptions/' +
            encodeURIComponent(receipt.data.productId) +
            '/tokens/' + encodeURIComponent(receipt.data.purchaseToken) +
            '?access_token=' + encodeURIComponent(accessToken);

will have no packageName to slot in there after the '/applications/' part.

So I 100% get that this is not an issue with the in-app-purchase module per se, but, I was wondering whether it would be possible to have a packageName in the configuration? I started off fixing it myself, and found that I was just reimplementing the same stuff you are already doing (figure out if it's an apple or google receipt, figure out if the whole receipt is a string, if so, parse it, figure out if the data prop is a string, if so, parse it etc etc) so that I could check if packageName existed in data, and add it if not, and it felt more natural to have it configurable. I'd be happy to put together a PR for it, just checking if it's something you'd be happy to have in the module before I do that.

Thanks!

voltrue2 commented 6 years ago

Hello

Thank you for reporting this. This is the first time I heard about packageName missing. I wonder what the cause of giving such receipts. Let me research on this a little bit and see what we can do!

Cheers

On Jul 23, 2018 at 16:16, <chris-divvito (mailto:notifications@github.com)> wrote:

Hello,

I'm currently running up against an issue where, for most of the receipts I receive from an android app, the packageName is not included in the data part of the receipt. Looking through other issues on here it seems like it is generally there for others, so I'm not sure what the difference for me is - maybe either because we are still at the stage of using the registered google test accounts, or because of the framework we use on the frontend maybe (react-native-iap), I'm not sure.

Long story short though, we get a receipt that looks almost correct:

{ "data": "{\"productId\":\"com.an.iap.product.id\",\"purchaseToken\":\"aLongEncodedString",\"purchaseTime\":1532326966225,\"developerPayload\":null}", "signature": "anotherLongEncodedString" }

(data cleaned for anonymity).

We get through the "Google API authenticated" and "Google API access token" points, but then when we try to actually hit the URL we get "No application was found for the given package name." and a 404 from the actual request, which makes sense given

var url = 'https://www.googleapis.com/androidpublisher/v2/applications/' + encodeURIComponent(receipt.data.packageName) + '/purchases/subscriptions/' + encodeURIComponent(receipt.data.productId) + '/tokens/' + encodeURIComponent(receipt.data.purchaseToken) + '?access_token=' + encodeURIComponent(accessToken);

will have no packageName to slot in there after the '/applications/' part.

So I 100% get that this is not an issue with the in-app-purchase module per se, but, I was wondering whether it would be possible to have a packageName in the configuration? I started off fixing it myself, and found that I was just reimplementing the same stuff you are already doing (figure out if it's an apple or google receipt, figure out if the whole receipt is a string, if so, parse it, figure out if the data prop is a string, if so, parse it etc etc) so that I could check if packageName existed in data, and add it if not, and it felt more natural to have it configurable. I'd be happy to put together a PR for it, just checking if it's something you'd be happy to have in the module before I do that.

Thanks!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub (https://github.com/voltrue2/in-app-purchase/issues/196), or mute the thread (https://github.com/notifications/unsubscribe-auth/ACKY4eUp8wzOrQiq2WFBdF-_JKobQjQ2ks5uJXhKgaJpZM4Vaer2).

jenni-divvito commented 6 years ago

Thanks, that was a damn quick response!

if it helps, its for a auto-renewing subscription, it's an app from the play store via a closed Beta track, the IAPs are activated in the Store Presence -> In App Purchases part of the Play console, and the frontend module passing the receipts is https://github.com/dooboolab/react-native-iap.

The device in question is running android v6.0

voltrue2 commented 6 years ago

Thank you for the extra info. I will have a look!

Cheers

On Jul 23, 2018 at 16:24, <chris-divvito (mailto:notifications@github.com)> wrote:

Thanks, that was a damn quick response!

if it helps, its for a auto-renewing subscription, it's an app from the play store via a closed Beta track, the IAPs are activated in the Store Presence -> In App Purchases part of the Play console, and the frontend module passing the receipts is https://github.com/dooboolab/react-native-iap.

The device in question is running android v6.0

— You are receiving this because you commented. Reply to this email directly, view it on GitHub (https://github.com/voltrue2/in-app-purchase/issues/196#issuecomment-406964750), or mute the thread (https://github.com/notifications/unsubscribe-auth/ACKY4eERvvcxu2BWknWuifNszrjrpDt3ks5uJXougaJpZM4Vaer2).

jenni-divvito commented 6 years ago

Bad news everybody!

So I had been working on patching around this myself. parsing out the receipt, adding the packageName to data before passing the receipt into RNIap.validate();

Unfortunately, while this fixes the initial problem (a proper URL is now generated), we hit a bigger problem further down the line, when the data is actually sent to the URL. We get back a 400: Invalid value. digging a little deeper on this, I realize that of course it won't work - by changing the data that was hashed to generate the signature, I am invalidating the signature.

This seems to suggest that there may not be a workaround for this from outside the module. In order to keep going for now I'm going to have to fork it and make the packageName (at least as a fallback) configurable, so that it can be used for generating the URL without modifying the actual receipt.

jenni-divvito commented 6 years ago

A bit of a further issue here... the receipts I am getting (for subscription items) also do not contain the autoRenewing property. I have dived into the code of the library on the frontend and can confirm that the data we get out is directly from the com.android.billingclient.api.Purchase.getOriginalJson() method, but it seems to be missing some key information. I am still of the impression that this is entirely to do with the fact that they are test purchases, but the result is that it attempts to use the wrong URL to resolve the receipt (because it considers it to be a product, not a subscription).

I'm going to see how I can resolve this in my fork, just letting you know the progress on debugging in the meantime

voltrue2 commented 6 years ago

Hello

Thank you for letting me know! In the meantime I am looking into how (if we must) we could solve this from the library point of view.

Cheers

On Jul 24, 2018 at 00:19, <chris-divvito (mailto:notifications@github.com)> wrote:

A bit of a further issue here... the receipts I am getting (for subscription items) also do not contain the autoRenewing property. I have dived into the code of the library on the frontend and can confirm that the data we get out is directly from the com.android.billingclient.api.Purchase.getOriginalJson() method, but it seems to be missing some key information. I am still of the impression that this is entirely to do with the fact that they are test purchases, but the result is that it attempts to use the wrong URL to resolve the receipt (because it considers it to be a product, not a subscription).

I'm going to see how I can resolve this in my fork, just letting you know the progress on debugging in the meantime

— You are receiving this because you commented. Reply to this email directly, view it on GitHub (https://github.com/voltrue2/in-app-purchase/issues/196#issuecomment-407306905), or mute the thread (https://github.com/notifications/unsubscribe-auth/ACKY4YpZeLtrZg2Qh0Gb1xxLuV7uYQ8Fks5uJsqOgaJpZM4Vaer2).

RodolfoGS commented 5 years ago

Hi @jenni-divvito, Could you fix the issue? I'm using react-native-iap too and I have the same problem. Thanks!

dancherb commented 5 years ago

Any updates on this @voltrue2 @jenni-divvito? I'm also using react-native-iap and having this problem - thanks for all the work :)

nickgermaine commented 2 years ago

Apparently this is still a thing. I'm trying to validate in a project, and it's giving the "Missing Package Name" error. What's weird is that it did work one time, through my testing, but the very next time it started giving the error again.

Is there any update on this?