store-receipt-validator
=======

[![Latest Stable Version](https://poser.pugx.org/aporat/store-receipt-validator/version.png)](https://packagist.org/packages/aporat/store-receipt-validator) [![Composer Downloads](https://poser.pugx.org/aporat/store-receipt-validator/d/total.png)](https://packagist.org/packages/aporat/store-receipt-validator)
[![Build Status](https://travis-ci.org/aporat/store-receipt-validator.png?branch=master)](https://travis-ci.org/aporat/store-receipt-validator)
[![Code Coverage](https://scrutinizer-ci.com/g/aporat/store-receipt-validator/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/aporat/store-receipt-validator/?branch=master)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/aporat/store-receipt-validator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/aporat/store-receipt-validator/?branch=master)
[![License](https://poser.pugx.org/aporat/store-receipt-validator/license.svg)](https://packagist.org/packages/aporat/store-receipt-validator)

PHP library that can be used to validate base64 encoded iTunes in app purchase receipts.


## Requirements ##

* PHP >= 7.0

## Getting Started ##

The easiest way to work with this package is when it's installed as a
Composer package inside your project. Composer isn't strictly
required, but makes life a lot easier.

If you're not familiar with Composer, please see <http://getcomposer.org/>.

1. Add iap-validator to your application's composer.json.

        {
            ...
            "require": {
                "aporat/store-receipt-validator": "dev-master"
            },
            ...
        }

2. Run `php composer install`.

3. If you haven't already, add the Composer autoload to your project's
   initialization file. (example)

        require 'vendor/autoload.php';


## Quick Example ##

### iTunes ###

```php

use ReceiptValidator\iTunes\Validator as iTunesValidator;

$validator = new iTunesValidator(iTunesValidator::ENDPOINT_PRODUCTION); // Or iTunesValidator::ENDPOINT_SANDBOX if sandbox testing

$receiptBase64Data = ' ';

try {
  $response = $validator->setReceiptData($receiptBase64Data)->validate();
  // $sharedSecret = '1234...'; // Generated in iTunes Connect's In-App Purchase menu
  // $response = $validator->setSharedSecret($sharedSecret)->setReceiptData($receiptBase64Data)->validate(); // use setSharedSecret() if for recurring subscriptions
} catch (Exception $e) {
  echo 'got error = ' . $e->getMessage() . PHP_EOL;
}

if ($response->isValid()) {
  echo 'Receipt is valid.' . PHP_EOL;
  echo 'Receipt data = ' . print_r($response->getReceipt()) . PHP_EOL;
} else {
  echo 'Receipt is not valid.' . PHP_EOL;
  echo 'Receipt result code = ' . $response->getResultCode() . PHP_EOL;
}
```

### Play Store ###

Get the refresh token from [OAuth2 flow](https://developers.google.com/android-publisher/authorization).

```php
use ReceiptValidator\GooglePlay\Validator as PlayValidator;

$client = new \Google_Client();
$client->setApplicationName('...');
$client->setAuthConfig('...');
$client->setScopes('...');

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

try {
  $response = $validator->setPackageName('PACKAGE_NAME')
    ->setProductId('PRODUCT_ID')
    ->setPurchaseToken('PURCHASE_TOKEN')
    ->validatePurchase();
} catch (Exception $e){
  var_dump($e->getMessage());
  // example message: Error calling GET ....: (404) Product not found for this application.
}
// success
```

Or [Using a service account](https://developers.google.com/android-publisher/getting_started#using_a_service_account)

Create service account [Service Account flow](https://developers.google.com/identity/protocols/OAuth2ServiceAccount)

```php
$googleClient = new \Google_Client();
$googleClient->setScopes([\Google_Service_AndroidPublisher::ANDROIDPUBLISHER]);
$googleClient->setApplicationName('Your_Purchase_Validator_Name');
$googleClient->setAuthConfig($pathToServiceAccountJsonFile);

$googleAndroidPublisher = new \Google_Service_AndroidPublisher($googleClient);
$validator = new \ReceiptValidator\GooglePlay\Validator($googleAndroidPublisher);

try {
  $response = $validator->setPackageName('PACKAGE_NAME')
      ->setProductId('PRODUCT_ID')
      ->setPurchaseToken('PURCHASE_TOKEN')
      ->validateSubscription();
} catch (\Exception $e){
  var_dump($e->getMessage());
  // example message: Error calling GET ....: (404) Product not found for this application.
}
// success
```


### Amazon App Store ###

```php
use ReceiptValidator\Amazon\Validator as AmazonValidator;
use ReceiptValidator\Amazon\Response as ValidatorResponse;

$validator = new AmazonValidator;

$response = null;
try {
  $response = $validator->setDeveloperSecret("DEVELOPER_SECRET")->setReceiptId("RECEIPT_ID")->setUserId("USER_ID")->validate();

} catch (Exception $e) {
  echo 'got error = ' . $e->getMessage() . PHP_EOL;
}

if ($response instanceof ValidatorResponse && $response->isValid()) {

  echo 'Receipt is valid.' . PHP_EOL;


  foreach ($response->getPurchases() as $purchase) {
    echo 'getProductId: ' . $purchase->getProductId() . PHP_EOL;

    if ($purchase->getPurchaseDate() != null) {
      echo 'getPurchaseDate: ' . $purchase->getPurchaseDate()->toIso8601String() . PHP_EOL;
    }
  }
} else {
  echo 'Receipt is not valid.' . PHP_EOL;
  echo 'Receipt result code = ' . $response->getResultCode() . PHP_EOL;
}

```