PHPackages                             laulamanapps/apple-passbook-bundle - 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. [PDF &amp; Document Generation](/categories/documents)
4. /
5. laulamanapps/apple-passbook-bundle

ActiveLibrary[PDF &amp; Document Generation](/categories/documents)

laulamanapps/apple-passbook-bundle
==================================

Generate Apple Passbooks from your Symfony application

v1.1(5y ago)419.4k↓50%2[1 PRs](https://github.com/LauLamanApps/apple-passbook-bundle/pulls)MITPHPPHP &gt;=7.3

Since Dec 7Pushed 3y ago1 watchersCompare

[ Source](https://github.com/LauLamanApps/apple-passbook-bundle)[ Packagist](https://packagist.org/packages/laulamanapps/apple-passbook-bundle)[ RSS](/packages/laulamanapps-apple-passbook-bundle/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (8)Versions (4)Used By (0)

Apple Passbook Bundle
=====================

[](#apple-passbook-bundle)

This package provides Symfony configuration for [LauLamanApps Apple Passbook Package](https://github.com/LauLamanApps/apple-passbook)

[![GithubCi](https://github.com/LauLamanApps/apple-passbook-bundle/workflows/CI/badge.svg)](https://github.com/LauLamanApps/apple-passbook-bundle/actions?query=workflow%3ACI)[![Build Status](https://camo.githubusercontent.com/593aaab073d2064d7b7b145e911f2632d76832a0661f06370afee3b6f3f667fe/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f4c61754c616d616e417070732f6170706c652d70617373626f6f6b2d62756e646c652f6261646765732f6275696c642e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/LauLamanApps/apple-passbook-bundle/build-status/master)[![Code Coverage](https://camo.githubusercontent.com/fea57c910b0e10502b9770ea0199114bc0e94f7b8f93e421b54ce31c5a2b4a1e/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f4c61754c616d616e417070732f6170706c652d70617373626f6f6b2d62756e646c652f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/LauLamanApps/apple-passbook-bundle/?branch=master)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/fcab3cd1f7b06ef1072a8fb0aace830009c54d223a0af2555820d3c6a95d310f/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f4c61754c616d616e417070732f6170706c652d70617373626f6f6b2d62756e646c652f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/LauLamanApps/apple-passbook-bundle/?branch=master)[![Latest Stable Version](https://camo.githubusercontent.com/9794f3f7ffb9398adb39224e44ff344b8ce80ac5f0a79225328f4a1d191259fb/68747470733a2f2f706f7365722e707567782e6f72672f6c61756c616d616e617070732f6170706c652d70617373626f6f6b2d62756e646c652f762f737461626c65)](https://packagist.org/packages/laulamanapps/apple-passbook-bundle)[![License](https://camo.githubusercontent.com/39dc963d73ef7fc3f6f90636bbed071966a4a9254398e0e90a5cf1020bb6b49c/68747470733a2f2f706f7365722e707567782e6f72672f6c61756c616d616e617070732f6170706c652d70617373626f6f6b2d62756e646c652f6c6963656e7365)](https://packagist.org/packages/laulamanapps/apple-passbook-bundle)

Installation
------------

[](#installation)

With [composer](http://packagist.org), add:

```
$ composer require laulamanapps/apple-passbook-bundle
```

Run Tests
---------

[](#run-tests)

To make sure everything works you can run tests:

```
$ make tests-unit
$ make tests-integration
$ make tests-infection
```

Get certificate
---------------

[](#get-certificate)

Head over to the [Apple Developer Portal](https://developer.apple.com/account/resources/certificates/list) to get yourself a certificate to sign your passbooks with.

[Convert](docs/certificate.md) the certificate and key to a .p12 file using the **Keychain Access**

Configure Bundle
----------------

[](#configure-bundle)

```
#config/packages/laulamanapps_apple_passbook.yml

laulamanapps_apple_passbook:
  certificate: '%env(APPLE_PASSBOOK_CERTIFICATE)%'
  password: '%env(APPLE_PASSBOOK_CERTIFICATE_PASSWORD)%'
  team_identifier: '%env(APPLE_PASSBOOK_TEAM_IDENTIFIER)%'
  pass_type_identifier: '%env(APPLE_PASSBOOK_PASS_TYPE_IDENTIFIER)%'
```

Add the ENV variables to the `.env` file

```
##> laulamanapps/apple-passbook-bundle
APPLE_PASSBOOK_CERTIFICATE=path/to/certificate.p12
APPLE_PASSBOOK_CERTIFICATE_PASSWORD=password
APPLE_PASSBOOK_PASS_TYPE_IDENTIFIER=pass.com.your.pass.identifiers
APPLE_PASSBOOK_TEAM_IDENTIFIER=identifier
APPLE_PASSBOOK_WEB_SERVICE_URL='http://example.com/'
##< laulamanapps/apple-passbook-bundle
```

Create &amp; Compile Passbook
-----------------------------

[](#create--compile-passbook)

```
namespace App\Controller;

use LauLamanApps\ApplePassbook\Build\Compiler;
use LauLamanApps\ApplePassbook\GenericPassbook;
use LauLamanApps\ApplePassbook\MetaData\Barcode;
use LauLamanApps\ApplePassbook\Style\BarcodeFormat;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;

final class PassbookController extends AbstractController
{
    /**
     * @var Compiler
     */
    private $passbookCompiler;

    public function __construct(Compiler $passbookCompiler) {
        $this->passbookCompiler = $passbookCompiler;
    }

    /**
     * @Route("/download/passbook/", name="download_passbook")
     */
    public function download(): Response
    {
        $passbook = new GenericPassbook('8j23fm3');
        $passbook->setTeamIdentifier('');
        $passbook->setPassTypeIdentifier('');
        $passbook->setOrganizationName('Toy Town');
        $passbook->setDescription('Toy Town Membership');

        $barcode = new Barcode();
        $barcode->setFormat(BarcodeFormat::pdf417());
        $barcode->setMessage('123456789');
        $passbook->setBarcode($barcode);

        $data = $this->passbookCompiler->compile($passbook);

        $response = new Response($data);
        $response->headers->set('Content-Description', 'File Transfer');
        $response->headers->set('Content-Type', 'application/vnd.apple.pkpass');
        $response->headers->set('Content-Disposition', 'filename="passbook.pkpass"');

        return $response;
    }
}
```

Configure Build in Webservices
------------------------------

[](#configure-build-in-webservices)

This package comes with build in controllers for all Apple passbooks webservice URLs. It is using Symfonys build in `EventDispatcher`.

Enable this by adding the following configuration to the `config/routes/routes.yaml`

```
passbook_routes:
    resource: '@ApplePassbookBundle/Controller/'
    type:     annotation
```

The controllers will dispatch the following events, the following information is available:

```
/* Available on All events */
$event->getPassTypeIdentifier();
$event->getStatus();

/* Available on DeviceRegisteredEvent */
$event->getAuthenticationToken();
$event->getDeviceLibraryIdentifier();
$event->getSerialNumber();

/* Available on DeviceRequestUpdatedPassesEvent */
$event->getAuthenticationToken();
$event->getDeviceLibraryIdentifier();
$event->getPassesUpdatedSince();

/* Available on DeviceUnregisteredEvent */
$event->getAuthenticationToken();
$event->getDeviceLibraryIdentifier();
$event->getSerialNumber();

/* Available on RetrieveUpdatedPassbookEvent */
$event->getAuthenticationToken();
$event->getSerialNumber();
$event->getPassTypeIdentifier();
$event->getUpdatedSince();
```

Now Subscribe to the events:

The idea here is that you handle the event and mark the events as handled by calling setters on the event itself. The event by default has the status `Status::unhandled()`

```
namespace App\Integration\Symfony\EventSubscriber;

use DateTimeImmutable;
use LauLamanApps\ApplePassbook\GenericPassbook;
use LauLamanApps\ApplePassbookBundle\Event\DeviceRegisteredEvent;
use LauLamanApps\ApplePassbookBundle\Event\DeviceRequestUpdatedPassesEvent;
use LauLamanApps\ApplePassbookBundle\Event\DeviceUnregisteredEvent;
use LauLamanApps\ApplePassbookBundle\Event\RetrieveUpdatedPassbookEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

final class ApplePassbookSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            DeviceRegisteredEvent::class => 'onDeviceRegistered',
            DeviceRequestUpdatedPassesEvent::class => 'onDeviceRequestUpdatedPasses',
            RetrieveUpdatedPassbookEvent::class => 'onRetrieveUpdatedPassbook',
            DeviceUnregisteredEvent::class => 'onDeviceUnregistered',
        ];
    }

    public function onDeviceRegistered(DeviceRegisteredEvent $event): void
    {
        $passbook = $this->passbookRepository->getBySerial($event->getSerialNumber());

        if ($event->getAuthenticationToken()  $passbook->getAuthToken()) {
            $event->notAuthorized();

            return;
        }

        /**
         * Save in Database
         */

        $event->deviceRegistered();
    }

    public function onDeviceRequestUpdatedPasses(DeviceRequestUpdatedPassesEvent $event): void
    {
        $passbooks = $this->passbookRepository->getSerialsSince(
            $event->getPassTypeIdentifier(),
            $event->getDeviceLibraryIdentifier(),
            $event->getPassesUpdatedSince()
        );

        if ($passbooks) {
            $serials = [];
            foreach ($passbooks as $passbook) {
                $serials[] = $passbook->getSerialNumber();
            }

            $event->setSerialNumbers($serials, new DateTimeImmutable());

            return;
        }

        $event->notFound();
    }

    public function onRetrieveUpdatedPassbook(RetrieveUpdatedPassbookEvent $event): void
    {
        try {
            $entity = $this->passbookRepository->getBySerial($event->getSerialNumber());
            if ($entity->getAuthToken() !== $event->getAuthenticationToken()) {
                $event->notAuthorized();

                return;
            }

            if ($event->getUpdatedSince() && $entity->getUpdatedAt() < $event->getUpdatedSince()) {
                $event->notModified();

                return;
            }

            $passbook = new GenericPassbook($event->getSerialNumber());
            /* Generate Passbook */

            $event->setPassbook($passbook);
        } catch (NoResultException $e) {
            $event->notFound();
        }
    }

    public function onDeviceUnregistered(DeviceUnregisteredEvent $event): void
    {
        $passbook = $this->passbookRepository->getBySerial($event->getSerialNumber());

        if ($event->getAuthenticationToken()  $passbook->getAuthToken()) {
            $event->notAuthorized();

            return;
        }

        /**
         * Remove from Database
         */

        $event->deviceUnregistered();
    }
}
```

Credits
-------

[](#credits)

This package has been developed by [LauLaman](https://github.com/LauLaman).

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity29

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 91.7% 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 ~224 days

Total

2

Last Release

2131d ago

PHP version history (2 changes)v1.0PHP &gt;=7.2

v1.1PHP &gt;=7.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/930ca3b1756d00a63c8ff3363e81f16f961cf3ef79ff0c9d362670c36d97e456?d=identicon)[LauLaman](/maintainers/LauLaman)

---

Top Contributors

[![LauLaman](https://avatars.githubusercontent.com/u/8283992?v=4)](https://github.com/LauLaman "LauLaman (11 commits)")[![noahlvb](https://avatars.githubusercontent.com/u/6873972?v=4)](https://github.com/noahlvb "noahlvb (1 commits)")

---

Tags

phpappleiphonewalletiospassbookstore cardcouponevent ticketboarding passiPod Touchpkpass

### Embed Badge

![Health badge](/badges/laulamanapps-apple-passbook-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/laulamanapps-apple-passbook-bundle/health.svg)](https://phpackages.com/packages/laulamanapps-apple-passbook-bundle)
```

###  Alternatives

[pkpass/pkpass

PHP PKPass class for iOS Wallet

9733.0M6](/packages/pkpass-pkpass)[eo/passbook

iOS Passbook for PHP

2651.6M2](/packages/eo-passbook)[griffinledingham/php-apple-signin

A simple library to decode and parse Apple Sign In client tokens.

2011.9M1](/packages/griffinledingham-php-apple-signin)[thenextweb/passgenerator

A Laravel package to create Apple Wallet (old Passbook) compatible tickets.

297435.6k](/packages/thenextweb-passgenerator)[chiiya/passes

PHP library for creating iOS and Android Wallet Passes

67243.1k1](/packages/chiiya-passes)[byte5/laravel-passgenerator

A Laravel package to create Apple Wallet (old Passbook) compatible tickets.

8821.3k](/packages/byte5-laravel-passgenerator)

PHPackages © 2026

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