PHPackages                             aporat/laravel-appstore-purchases - 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. [API Development](/categories/api)
4. /
5. aporat/laravel-appstore-purchases

ActiveLibrary[API Development](/categories/api)

aporat/laravel-appstore-purchases
=================================

Laravel package for handling App Store purchase receipts, subscriptions and notifications

2.0.0(9mo ago)31.7k↑55.6%MITPHPPHP ^8.3CI passing

Since May 2Pushed 3w ago1 watchersCompare

[ Source](https://github.com/aporat/laravel-appstore-purchases)[ Packagist](https://packagist.org/packages/aporat/laravel-appstore-purchases)[ Docs](https://github.com/aporat/laravel-appstore-purchases)[ GitHub Sponsors](https://github.com/aporat)[ RSS](/packages/aporat-laravel-appstore-purchases/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (3)Dependencies (7)Versions (5)Used By (0)

Laravel App Store Purchases
===========================

[](#laravel-app-store-purchases)

A Laravel package for validating in-app purchase receipts, managing subscriptions, and handling server notifications from Apple, iTunes, and Amazon App Stores.

[![Latest Stable Version](https://camo.githubusercontent.com/dc4c56247d3713200b1eabaf3f1aa1f2efdf57fbd2589222f050011632e0a7ac/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f61706f7261742f6c61726176656c2d61707073746f72652d7075726368617365732e7376673f7374796c653d666c61742d737175617265266c6f676f3d636f6d706f736572)](https://packagist.org/packages/aporat/laravel-appstore-purchases)[![Downloads](https://camo.githubusercontent.com/d15a2c4e5215bac10405403ac9ccb426f0c085820c79f51f68a0f3a0c620d3ec/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f61706f7261742f6c61726176656c2d61707073746f72652d7075726368617365732e7376673f7374796c653d666c61742d737175617265266c6f676f3d636f6d706f736572)](https://packagist.org/packages/aporat/laravel-appstore-purchases)[![codecov](https://camo.githubusercontent.com/efe7ea2368d8a2cc60c8424fe0066802a8991315951c830227961c4276087d46/68747470733a2f2f636f6465636f762e696f2f6769746875622f61706f7261742f6c61726176656c2d61707073746f72652d7075726368617365732f67726170682f62616467652e7376673f746f6b656e3d44343443553254445538)](https://codecov.io/github/aporat/laravel-appstore-purchases)[![Laravel Version](https://camo.githubusercontent.com/40236e2476ff414887c1d4654db9142ebac4bce19aac8cd02eb1c6d2762deb09/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31332e782d6f72616e67652e7376673f7374796c653d666c61742d737175617265)](https://laravel.com/docs/13.x)[![GitHub Actions](https://camo.githubusercontent.com/ef0cee131f2375846f9add458080933639e4f5c2f347d33b93ec25d18a1af0e8/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f61706f7261742f6c61726176656c2d61707073746f72652d7075726368617365732f63692e796d6c3f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/ef0cee131f2375846f9add458080933639e4f5c2f347d33b93ec25d18a1af0e8/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f61706f7261742f6c61726176656c2d61707073746f72652d7075726368617365732f63692e796d6c3f7374796c653d666c61742d737175617265)[![License](https://camo.githubusercontent.com/cac5a18ae466f816f88b8f086d426239cd37b7fb5228039a63b4d02cc71430ee/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f61706f7261742f6c61726176656c2d61707073746f72652d7075726368617365732e7376673f7374796c653d666c61742d737175617265)](https://github.com/aporat/laravel-appstore-purchases/blob/master/LICENSE)

---

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

[](#-features)

- Dispatches Laravel events for all App Store Server Notification types
- Built-in receipt validators for Apple and Amazon
- Simple configuration via Laravel’s container and config files
- Supports Apple App Store Server API (AppTransaction, Get Transaction Info, etc.)
- Optional PSR-3 request/response logging via any Laravel log channel

---

🛠 Installation
--------------

[](#-installation)

```
composer require aporat/laravel-appstore-purchases
```

---

⚙️ Configuration
----------------

[](#️-configuration)

Publish the config file:

```
php artisan vendor:publish --tag=config --provider="Aporat\AppStorePurchases\AppStorePurchasesServiceProvider"
```

Then update `config/appstore-purchases.php` with your store credentials:

```
use ReceiptValidator\Environment;

return [
    'validators' => [
        'apple' => [
            'validator' => 'apple-app-store',
            'key_path' => app_path('../resources/keys/authkey_ABC123XYZ.p8'),
            'key_id' => 'ABC123XYZ',
            'issuer_id' => 'DEF456UVW',
            'bundle_id' => 'com.example',
            'environment' => Environment::SANDBOX,
        ],
        'itunes' => [
            'validator' => 'itunes',
            'shared_secret' => 'SHARED_SECRET',
            'environment' => Environment::SANDBOX,
        ],
        'amazon' => [
            'validator' => 'amazon',
            'developer_secret' => 'DEVELOPER_SECRET',
            'environment' => Environment::SANDBOX,
        ],
    ],
];
```

---

🪵 Logging
---------

[](#-logging)

Logging is disabled by default. To enable it, set the `APPSTORE_LOG_CHANNEL` environment variable to any Laravel log channel name:

```
APPSTORE_LOG_CHANNEL=stack
```

This applies to all validators. When enabled, the underlying HTTP client emits structured log entries at the following levels:

LevelWhen`debug`Outgoing request details (method, URI, environment, query params)`info`Successful responses`warning`API error responses (non-2xx with an error body)`error`Connection failures and exceptions### Per-validator channel

[](#per-validator-channel)

You can also set a different log channel for an individual validator by adding a `log_channel` key to its config. This takes precedence over the global setting:

```
'validators' => [
    'apple' => [
        'validator'   => 'apple-app-store',
        'log_channel' => 'daily',   // overrides APPSTORE_LOG_CHANNEL for this validator
        // ...
    ],
],
```

---

📬 Receiving Notifications
-------------------------

[](#-receiving-notifications)

Add a route to handle server notifications from Apple:

```
use Aporat\AppStorePurchases\Http\Controllers\AppleAppStoreServerNotificationController;

Route::prefix('server-notifications')->middleware([])->group(function () {
    Route::post('apple-appstore-callback', AppleAppStoreServerNotificationController::class);
});
```

**Security Recommendation**: Add rate limiting middleware to the notification endpoint to prevent abuse:

```
Route::prefix('server-notifications')->middleware(['throttle:60,1'])->group(function () {
    Route::post('apple-appstore-callback', AppleAppStoreServerNotificationController::class);
});
```

This controller automatically dispatches Laravel events for **all Apple App Store Server Notification types**, including:

- `ConsumptionRequest`
- `GracePeriodExpired`
- `OfferRedeemed`
- `PurchaseRefundDeclined`
- `PurchaseRefunded`
- `PurchaseRefundReversed`
- `PurchaseRevoked`
- `SubscriptionCreated`
- `SubscriptionExpired`
- `SubscriptionFailedToRenew`
- `SubscriptionPriceIncrease`
- `SubscriptionRenewalChanged`
- `SubscriptionRenewalChangedPref`
- `SubscriptionRenewalExtended`
- `SubscriptionRenewalExtension`
- `SubscriptionRenewed`
- `ExternalPurchaseToken`
- `OneTimeCharge`
- `Test`

---

📦 Events
--------

[](#-events)

All App Store notification types are dispatched as Laravel events and extend a base `PurchaseEvent` class.

### Example: Handling a Subscription Renewal

[](#example-handling-a-subscription-renewal)

```
use Aporat\AppStorePurchases\Events\SubscriptionRenewed;

Event::listen(SubscriptionRenewed::class, function ($event) {
    $transaction = $event->notification->getTransaction();

    $receipts = SubscriptionReceipt::getByTransaction($transaction->getOriginalTransactionId());

    foreach ($receipts as $receipt) {
        $account = Account::find($receipt->account_id);
        $account->processSubscription($transaction);
    }
});
```

---

✅ Manual Receipt Validation
---------------------------

[](#-manual-receipt-validation)

You can validate a transaction ID manually:

```
$validator = AppStorePurchases::get('apple');
$response = $validator->validate($transactionId);
```

If you have a raw app receipt, extract the transaction ID first:

```
use Aporat\AppStorePurchases\Facades\AppStorePurchases;
use ReceiptValidator\AppleAppStore\Validators\AppleAppStoreValidator;
use ReceiptValidator\AppleAppStore\ReceiptUtility;

$validator = AppStorePurchases::get('apple');

if ($validator instanceof AppleAppStoreValidator) {
    $transactionId = ReceiptUtility::extractTransactionIdFromAppReceipt($rawAppReceipt);
    $response = $validator->validate($transactionId);
}
```

###  Health Score

45

—

FairBetter than 91% of packages

Maintenance78

Regular maintenance activity

Popularity24

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 69.6% 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 ~69 days

Total

3

Last Release

283d ago

Major Versions

1.0.2 → 2.0.02025-09-17

PHP version history (2 changes)1.0.0PHP ^8.4

2.0.0PHP ^8.3

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/415576?v=4)[A Porat](/maintainers/aporat)[@aporat](https://github.com/aporat)

---

Top Contributors

[![aporat](https://avatars.githubusercontent.com/u/415576?v=4)](https://github.com/aporat "aporat (32 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (8 commits)")[![claude](https://avatars.githubusercontent.com/u/81847?v=4)](https://github.com/claude "claude (6 commits)")

---

Tags

laravelappleapp\_store

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/aporat-laravel-appstore-purchases/health.svg)

```
[![Health](https://phpackages.com/badges/aporat-laravel-appstore-purchases/health.svg)](https://phpackages.com/packages/aporat-laravel-appstore-purchases)
```

###  Alternatives

[defstudio/telegraph

A laravel facade to interact with Telegram Bots

815320.5k3](/packages/defstudio-telegraph)[riclep/laravel-storyblok

A Laravel wrapper around the Storyblok API to provide a familiar experience for Laravel devs

6277.0k5](/packages/riclep-laravel-storyblok)[simplestats-io/laravel-client

Analytics for Laravel. Track visitors, registrations, and payments. Discover which channels actually drive revenue, not just traffic. Server-side, GDPR compliant, ad-blocker proof.

5019.3k](/packages/simplestats-io-laravel-client)

PHPackages © 2026

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