aporat / store-receipt-validator

PHP receipt validator for Apple iTunes, Google Play and Amazon App Store
Apache License 2.0
633 stars 153 forks source link

Not able to validate purchase in Google using OAuth approach #123

Closed kshitijsharma97 closed 4 years ago

kshitijsharma97 commented 4 years ago

When I tried to validate the purchase token for my application. I'm getting this response:

{
  "error": {
    "code": 401,
    "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
    "errors": [
      {
        "message": "Login Required.",
        "domain": "global",
        "reason": "required",
        "location": "Authorization",
        "locationType": "header"
      }
    ],
    "status": "UNAUTHENTICATED"
  }
}

Here is code for which I'm getting this response

 $jsonFileDir = Configure::read('IS_WINDOWS')
            ? Configure::read('WEBROOT_DIR') .
                DS .
                Configure::read('IN_APP_PURCHASE.ANDROID.PATH_TO_JSON_FILE')
            : Configure::read('IN_APP_PURCHASE.ANDROID.PATH_TO_JSON_FILE');
        $client = new \Google_Client();
        $client->setApplicationName(
            Configure::read(
                'IN_APP_PURCHASE.ANDROID.YOUR_PURCHASE_VALIDATOR_NAME'
            )
        );
        $client->setAuthConfig($jsonFileDir);
        $client->setScopes([\Google_Service_AndroidPublisher::ANDROIDPUBLISHER]);

        $validator = new PlayValidator(
            new \Google_Service_AndroidPublisher($client)
        );

        try {
            $response = $validator
                ->setPackageName(
                    Configure::read('IN_APP_PURCHASE.ANDROID.PACKAGE_NAME')
                )
                ->setProductId(
                    Configure::read('IN_APP_PURCHASE.ANDROID.PRODUCT_ID')
                )
                ->setPurchaseToken($purchaseToken)
                ->validateSubscription();
        } catch (\Exception $e) {
            return false;
        }

Also When I tried

$token = $client->fetchAccessTokenWithAuthCode(
            '4/1wEjjDaDqw6GGoXGEdHEifLtS1lfBRt0i2FX2fw88SHflrpi7sS4qEs'
        );

I got invalid grant type error.

Please help me.

Stafox commented 4 years ago

I don't know the case and why you need to use OAuth, but suggest try it using service account (because it is only the way when you able to process the data in background).

Gameonn commented 4 years ago

I am also facing error in case of Play store using service account. { "error": { "code": 400, "message": "The purchase token is associated with a non-subscription purchase. Only subscription purchases are supported for this call.", "errors": [ { "message": "The purchase token is associated with a non-subscription purchase. Only subscription purchases are supported for this call.", "domain": "androidpublisher", "reason": "nonSubscriptionToken", "location": "token", "locationType": "parameter" } ] } }

Here is the code that I added in my controller:

$googleClient = new \Google_Client();
 $googleClient->setScopes([\Google_Service_AndroidPublisher::ANDROIDPUBLISHER]);
 $googleClient->setApplicationName('BulletForce');
 $pathToServiceAccountJsonFile = json_decode(Storage::disk('local')->get('keys/bullet-force-288519-1e5e67d29fcf.json'), true);
 $googleClient->setAuthConfig($pathToServiceAccountJsonFile);
 $googleAndroidPublisher = new \Google_Service_AndroidPublisher($googleClient);
 $validator = new \ReceiptValidator\GooglePlay\Validator($googleAndroidPublisher);
 $validator = new PlayValidator(new \Google_Service_AndroidPublisher($googleClient));

        try {
          $response = $validator->setPackageName('com.blayzegames.iosfps')
              ->setProductId('com.blayzegames.iosfps.goldtierone')
              ->setPurchaseToken('afoejlfbjlgagoojbkgljmdk.AO-J1OzsDO_Nj2jVa1IWr_YWTWoEaQzJNi58RF6J9Tdz-ALHJ6f3XkJHwq2afTcBlbYs_2pnFPWDvm9XhtCnrDslNccMLRxzTG3B2Z9hnE0IKqkDg5SM8RLolz0YXDQGfnDPe-L5vIiEuZa-9ZcxMdb3nUrhri3nyg')
              ->validateSubscription();
        } catch (\Exception $e){
          var_dump($e->getMessage());
        }

Please help me.

Stafox commented 4 years ago

@Gameonn just read the error message. It clearly says that your token belong to in-app purchase not subscription.

So, you should validate it as purchase using validatePurchase() instead of validateSubscription()

Gameonn commented 4 years ago

Thanks @Stafox. I already fixed this one.