PHPackages                             aporat/store-receipt-validator - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. aporat/store-receipt-validator

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

aporat/store-receipt-validator
==============================

PHP receipt validator for Apple App Store and Amazon Appstore

8.0.0(1mo ago)6503.9M↓10.9%151[1 issues](https://github.com/aporat/store-receipt-validator/issues)9Apache-2.0PHPPHP ^8.4CI passing

Since Aug 8Pushed 1mo ago20 watchersCompare

[ Source](https://github.com/aporat/store-receipt-validator)[ Packagist](https://packagist.org/packages/aporat/store-receipt-validator)[ Docs](https://github.com/aporat/store-receipt-validator)[ GitHub Sponsors](https://github.com/aporat)[ RSS](/packages/aporat-store-receipt-validator/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (30)Versions (64)Used By (9)

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

[](#store-receipt-validator)

[![Latest Stable Version](https://camo.githubusercontent.com/0cad93bce8a6169121fe0bb9c6074d95a8d2c51981f428c3a50d383fda066fb3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f61706f7261742f73746f72652d726563656970742d76616c696461746f722e7376673f7374796c653d666c61742d737175617265266c6f676f3d636f6d706f736572)](https://packagist.org/packages/aporat/store-receipt-validator) [![Downloads](https://camo.githubusercontent.com/d12660fcd665ce1d723e4cf7e466912ae6583672ca8fa9cd927a9ff37477f6b3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f61706f7261742f73746f72652d726563656970742d76616c696461746f722e7376673f7374796c653d666c61742d737175617265266c6f676f3d636f6d706f736572)](https://packagist.org/packages/aporat/store-receipt-validator) [![Codecov](https://camo.githubusercontent.com/362723697b4bbdac1861d3aeda134c8029f717b2fffd6e7f04779cd5681a8eb6/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f61706f7261742f73746f72652d726563656970742d76616c696461746f723f7374796c653d666c61742d737175617265)](https://codecov.io/github/aporat/store-receipt-validator) [![GitHub Actions](https://camo.githubusercontent.com/bee45a893aaa42adf1bf1b29aac29949acd00f1b549142695b6216f5c7f75b36/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f61706f7261742f73746f72652d726563656970742d76616c696461746f722f63692e796d6c3f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/bee45a893aaa42adf1bf1b29aac29949acd00f1b549142695b6216f5c7f75b36/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f61706f7261742f73746f72652d726563656970742d76616c696461746f722f63692e796d6c3f7374796c653d666c61742d737175617265) [![License](https://camo.githubusercontent.com/c17c88433c0ab5d1d8f763165142d50731662155a1ed1fe92fcbb676e247d095/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f61706f7261742f73746f72652d726563656970742d76616c696461746f722e7376673f7374796c653d666c61742d737175617265)](LICENSE)

A modern PHP library for validating in-app purchase receipts from the Apple App Store (including legacy iTunes) and Amazon Appstore. Supports both production and sandbox environments with detailed response parsing.

---

✨ Features
----------

[](#-features)

- ✅ Apple App Store **Server API (v2)** support
- ✅ Apple iTunes **Legacy API** support (deprecated by Apple, still available here)
- ✅ Amazon Appstore receipt validation
- ✅ App Store **Server Notifications v1 &amp; v2** parsing
- ✅ Strong typing (PHP 8.4+), enums, and modern error handling
- ✅ PSR-3 compatible logging support
- ✅ Built-in test suite with 100% coverage

---

📦 Requirements
--------------

[](#-requirements)

- PHP &gt;= 8.4

---

📥 Installation
--------------

[](#-installation)

```
composer require aporat/store-receipt-validator
```

---

🚀 Quick Start
-------------

[](#-quick-start)

### 📲 Apple App Store Server API

[](#-apple-app-store-server-api)

```
use ReceiptValidator\AppleAppStore\ReceiptUtility;
use ReceiptValidator\AppleAppStore\Validator as AppleValidator;
use ReceiptValidator\Environment;

// Credentials
$signingKey = file_get_contents($root . '/examples/SubscriptionKey_RA9DAYVX3X.p8');
$keyId = 'RA9DAYVX3X';
$issuerId = 'xxxxxx-xxxx-xxxx-xxxx-xxxxxxx';
$bundleId = 'com.myapp';

$receiptBase64Data = '...'; // your app receipt here

// 🔑 Tip: Apple's Server API does not accept the full app receipt.
// Use ReceiptUtility to extract the latest transaction ID.
$transactionId = ReceiptUtility::extractTransactionIdFromAppReceipt($receiptBase64Data);

$validator = new AppleValidator(
    signingKey: $signingKey,
    keyId: $keyId,
    issuerId: $issuerId,
    bundleId: $bundleId,
    environment: Environment::PRODUCTION
);

try {
    $response = $validator->setTransactionId($transactionId)->validate();
} catch (ValidationException $e) {
    if ($e->getCode() === APIError::INVALID_TRANSACTION_ID) {
        echo "Invalid Transaction ID: {$e->getMessage()}" . PHP_EOL;
    } else {
        echo "Validation failed: {$e->getMessage()}" . PHP_EOL;
    }

    exit(1);
} catch (Exception $e) {
    echo 'Error validating transaction: ' . $e->getMessage() . PHP_EOL;
    exit(1);
}

echo 'Validation successful.' . PHP_EOL;
echo 'Bundle ID: ' . $response->getBundleId() . PHP_EOL;
echo 'App Apple ID: ' . $response->getAppAppleId() . PHP_EOL;

foreach ($response->getTransactions() as $transaction) {
    echo 'Product ID: ' . $transaction->getProductId() . PHP_EOL;
    echo 'Transaction ID: ' . $transaction->getTransactionId() . PHP_EOL;

    if ($transaction->getPurchaseDate() !== null) {
        echo 'Purchase Date: ' . $transaction->getPurchaseDate()->toIso8601String() . PHP_EOL;
    }
}
```

### 🍏 Apple iTunes (Legacy API - Deprecated)

[](#-apple-itunes-legacy-api---deprecated)

```
use ReceiptValidator\Environment;
use ReceiptValidator\iTunes\Validator as iTunesValidator;

$validator = new ITunesValidator($sharedSecret, Environment::PRODUCTION);

try {
    $response = $validator->setReceiptData('BASE64_RECEIPT')->validate();
} catch (Exception $e) {
    echo 'Error: ' . $e->getMessage() . PHP_EOL;
    echo $e->getTraceAsString() . PHP_EOL;
    exit;
}

echo 'Bundle ID: ' . $response->getBundleId() . PHP_EOL;
echo 'Original Purchase Date: ' . $response->getOriginalPurchaseDate()?->toIso8601String() . PHP_EOL;

foreach ($response->getTransactions() as $tx) {
    echo 'Product ID: ' . $tx->getProductId() . PHP_EOL;
    echo 'Transaction ID: ' . $tx->getTransactionId() . PHP_EOL;
    echo 'Original Transaction ID: ' . ($tx->getOriginalTransactionId() ?? 'N/A') . PHP_EOL;

    if ($tx->getPurchaseDate() !== null) {
        echo 'Purchase Date: ' . $tx->getPurchaseDate()?->toIso8601String() . PHP_EOL;
    }
    if ($tx->getExpiresDate() !== null) {
        echo 'Expires Date: ' . $tx->getExpiresDate()?->toIso8601String() . PHP_EOL;
    }
}

foreach ($response->getLatestReceiptInfo() as $tx) {
    echo 'Latest — Product ID: ' . $tx->getProductId() . PHP_EOL;
    echo 'Latest — Transaction ID: ' . $tx->getTransactionId() . PHP_EOL;

    if ($tx->getPurchaseDate() !== null) {
        echo 'Latest — Purchase Date: ' . $tx->getPurchaseDate()?->toIso8601String() . PHP_EOL;
    }
    if ($tx->getExpiresDate() !== null) {
        echo 'Latest — Expires Date: ' . $tx->getExpiresDate()?->toIso8601String() . PHP_EOL;
    }
}
```

### 🛒 Amazon Appstore

[](#-amazon-appstore)

```
use ReceiptValidator\Amazon\Validator;

$validator = new Validator();

try {
    $response = $validator
        ->setDeveloperSecret('SECRET')
        ->setReceiptId('RECEIPT_ID')
        ->setUserId('USER_ID')
        ->validate();
} catch (Exception $e) {
    echo 'Error: ' . $e->getMessage() . PHP_EOL;
    echo $e->getTraceAsString() . PHP_EOL;
    exit;
}

echo 'Receipt is valid.' . PHP_EOL;

foreach ($response->getTransactions() as $transaction) {
    echo 'Product ID: ' . $transaction->getProductId() . PHP_EOL;

    if ($transaction->getPurchaseDate() !== null) {
        echo 'Purchase Date: ' . $transaction->getPurchaseDate()->toIso8601String() . PHP_EOL;
    }
}
```

---

📋 Logging
---------

[](#-logging)

All validators support [PSR-3](https://www.php-fig.org/psr/psr-3/) compatible logging via `setLogger()`. By default, a `NullLogger` is used so no output is produced unless you inject a logger.

```
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$logger = new Logger('receipt-validator');
$logger->pushHandler(new StreamHandler('php://stdout'));

$validator = new AppleValidator($signingKey, $keyId, $issuerId, $bundleId);
$validator->setLogger($logger);
```

The method returns `$this` for fluent chaining:

```
$response = $validator
    ->setLogger($logger)
    ->setTransactionId($transactionId)
    ->validate();
```

### Log levels

[](#log-levels)

LevelEvents`DEBUG`Outgoing API request details (environment, URI, parameters)`INFO`Successful responses; environment retries (e.g. production → sandbox)`WARNING`API error responses, unexpected HTTP status codes`ERROR`Network/connection failures---

📬 Apple App Store Server Notifications
--------------------------------------

[](#-apple-app-store-server-notifications)

### 🔔 V2 Notifications (App Store Server API)

[](#-v2-notifications-app-store-server-api)

```
use ReceiptValidator\AppleAppStore\ServerNotification;
use ReceiptValidator\Exceptions\ValidationException;

public function subscriptions(Request $request): JsonResponse {
    try {
        $notification = new ServerNotification($request->all());

        echo 'Type: ' . $notification->getNotificationType()->value . PHP_EOL;
        echo 'Subtype: ' . ($notification->getSubtype()?->value ?? 'N/A') . PHP_EOL;
        echo 'Bundle ID: ' . $notification->getBundleId() . PHP_EOL;

        $tx = $notification->getTransaction();
        if ($tx !== null) {
            echo 'Transaction ID: ' . $tx->getTransactionId() . PHP_EOL;
        }

        $renewalInfo = $notification->getRenewalInfo();
        if ($renewalInfo !== null) {
            echo 'Auto-Renew Product ID: ' . $renewalInfo->getAutoRenewProductId() . PHP_EOL;
        }
    } catch (ValidationException $e) {
        echo 'Invalid notification: ' . $e->getMessage() . PHP_EOL;
    }
}
```

### 🔔 V1 Notifications (iTunes - Deprecated)

[](#-v1-notifications-itunes---deprecated)

```
use ReceiptValidator\iTunes\ServerNotification;
use ReceiptValidator\Exceptions\ValidationException;

public function subscriptions(Request $request): JsonResponse {
    $sharedSecret = 'your_shared_secret';

    try {
        $notification = new ServerNotification($request->all(), $sharedSecret);

        echo 'Type: ' . $notification->getNotificationType()->value . PHP_EOL;
        echo 'Bundle ID: ' . $notification->getBundleId() . PHP_EOL;

        $transactions = $notification->getLatestReceipt()->getTransactions();

        foreach ($transactions as $tx) {
            echo 'Transaction ID: ' . $tx->getTransactionId() . PHP_EOL;
        }
    } catch (ValidationException $e) {
        echo 'Invalid notification: ' . $e->getMessage() . PHP_EOL;
    }
}
```

---

🧪 Testing
---------

[](#-testing)

```
composer test        # Run tests with PHPUnit
composer lint        # Run code style checks with PHP_CodeSniffer
composer analyze     # Run static analysis with PHPStan
```

---

🙌 Contributing
--------------

[](#-contributing)

Contributions are welcome!
To get started:

1. Fork this repo
2. Create a feature branch
3. Submit a pull request

Found a bug or want a new feature? [Open an issue](https://github.com/aporat/store-receipt-validator/issues)

---

📄 License
---------

[](#-license)

Apache-2.0 License. See [LICENSE](LICENSE).

---

###  Health Score

77

—

ExcellentBetter than 100% of packages

Maintenance90

Actively maintained with recent releases

Popularity65

Solid adoption and visibility

Community41

Growing community involvement

Maturity95

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 65.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~75 days

Recently: every ~58 days

Total

57

Last Release

53d ago

Major Versions

3.5.0 → 4.0.02020-08-04

4.4.3 → 5.0.02025-02-27

5.0.1 → 6.0.02025-04-19

6.1.4 → 7.0.02025-09-17

7.1.0 → 8.0.02026-03-26

PHP version history (13 changes)1.0.0PHP &gt;=5.4

1.1.1PHP &gt;=5.3

1.3.0PHP &gt;=5.5

1.5.0PHP &gt;=5.6

2.0.6PHP &gt;=7.0

2.2.0PHP &gt;=7.1

3.5.0PHP ^7.1

4.0.0PHP ^7.2.5

4.0.2PHP ^7.2.5|^8.0.0

4.1.0PHP ^7.3|^8.0.0

5.0.0PHP ^8.2

6.0.0PHP ^8.3

7.1.0PHP ^8.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/54592564aa6e76cb00fdb16a8b7fadaea333de11da7fd8a739fe4812237a551c?d=identicon)[aporat](/maintainers/aporat)

---

Top Contributors

[![aporat](https://avatars.githubusercontent.com/u/415576?v=4)](https://github.com/aporat "aporat (200 commits)")[![Stafox](https://avatars.githubusercontent.com/u/1101646?v=4)](https://github.com/Stafox "Stafox (16 commits)")[![claude](https://avatars.githubusercontent.com/u/81847?v=4)](https://github.com/claude "claude (11 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (10 commits)")[![lancasterSano](https://avatars.githubusercontent.com/u/5637296?v=4)](https://github.com/lancasterSano "lancasterSano (10 commits)")[![Orkin](https://avatars.githubusercontent.com/u/1061903?v=4)](https://github.com/Orkin "Orkin (10 commits)")[![AlexeyKupershtokh](https://avatars.githubusercontent.com/u/499778?v=4)](https://github.com/AlexeyKupershtokh "AlexeyKupershtokh (8 commits)")[![leemcd56](https://avatars.githubusercontent.com/u/1885663?v=4)](https://github.com/leemcd56 "leemcd56 (4 commits)")[![StyleCIBot](https://avatars.githubusercontent.com/u/11048387?v=4)](https://github.com/StyleCIBot "StyleCIBot (3 commits)")[![aliozkan](https://avatars.githubusercontent.com/u/936116?v=4)](https://github.com/aliozkan "aliozkan (3 commits)")[![srjlewis](https://avatars.githubusercontent.com/u/56001?v=4)](https://github.com/srjlewis "srjlewis (3 commits)")[![grEvenX](https://avatars.githubusercontent.com/u/26375?v=4)](https://github.com/grEvenX "grEvenX (3 commits)")[![gsingh1](https://avatars.githubusercontent.com/u/3026722?v=4)](https://github.com/gsingh1 "gsingh1 (3 commits)")[![whs](https://avatars.githubusercontent.com/u/345483?v=4)](https://github.com/whs "whs (2 commits)")[![ferjul17](https://avatars.githubusercontent.com/u/1574473?v=4)](https://github.com/ferjul17 "ferjul17 (2 commits)")[![gjuric](https://avatars.githubusercontent.com/u/223015?v=4)](https://github.com/gjuric "gjuric (2 commits)")[![yankers](https://avatars.githubusercontent.com/u/5647926?v=4)](https://github.com/yankers "yankers (2 commits)")[![mewm](https://avatars.githubusercontent.com/u/1241415?v=4)](https://github.com/mewm "mewm (2 commits)")[![mpoiriert](https://avatars.githubusercontent.com/u/4175616?v=4)](https://github.com/mpoiriert "mpoiriert (1 commits)")[![amo-mykyta](https://avatars.githubusercontent.com/u/131010721?v=4)](https://github.com/amo-mykyta "amo-mykyta (1 commits)")

---

Tags

amazonapp-storeapplein-app-purchasesitunesphpreceiptreceipt-validationvalidationphpitunesappleIn App PurchaseiapReceipt Validationamazon appstore

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/aporat-store-receipt-validator/health.svg)

```
[![Health](https://phpackages.com/badges/aporat-store-receipt-validator/health.svg)](https://phpackages.com/packages/aporat-store-receipt-validator)
```

###  Alternatives

[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[kreait/firebase-php

Firebase Admin SDK

2.4k39.7M72](/packages/kreait-firebase-php)[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M651](/packages/sylius-sylius)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.2M386](/packages/shopware-core)[theodo-group/llphant

LLPhant is a library to help you build Generative AI applications.

1.5k311.5k5](/packages/theodo-group-llphant)[shopify/shopify-api

Shopify API Library for PHP

4634.8M16](/packages/shopify-shopify-api)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
