Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Mobile Pass Laravel Package

spatie/laravel-mobile-pass

Generate Apple Wallet and Google Wallet passes in Laravel (tickets, boarding passes, coupons, membership cards). Create and sign pass files, serve them to users, and push updates to installed passes to keep details current across devices.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/laravel-mobile-pass
    php artisan vendor:publish --provider="Spatie\MobilePass\MobilePassServiceProvider"
    php artisan migrate
    
  2. Configure .env:

    MOBILE_PASS_APPLE_WEBSERVICE_HOST=https://your-app.com
    MOBILE_PASS_APPLE_TEAM_ID=your_apple_team_id
    MOBILE_PASS_APPLE_CERTIFICATE_PATH=/path/to/certificate.p12
    MOBILE_PASS_APPLE_CERTIFICATE_PASSWORD=your_password
    MOBILE_PASS_GOOGLE_ISSUER_ID=your_google_issuer_id
    MOBILE_PASS_GOOGLE_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----
    
  3. First Use Case: Generate a boarding pass for a user:

    use Spatie\MobilePass\PassBuilders\Apple\BoardingPassBuilder;
    
    $pass = BoardingPassBuilder::create()
        ->setSerialNumber('BP12345')
        ->setOrganizationName('Your Company')
        ->setHeaderFields([
            'primary' => 'Boarding Pass',
            'secondary' => 'Flight 123',
        ])
        ->setBarcode('1234567890')
        ->setStoreCardFields([
            'primary' => 'John Doe',
            'secondary' => 'Passenger',
        ])
        ->setExpirationDate('2025-12-31')
        ->build();
    
    $pass->save();
    
  4. Deliver to User:

    return response()->download($pass->pkpassPath());
    // OR for Google Wallet:
    return redirect($pass->addToWalletUrl());
    

Implementation Patterns

Core Workflows

1. Pass Creation & Customization

  • Builder Pattern: Use PassBuilder classes (e.g., BoardingPassBuilder, EventTicketBuilder) for type-specific configurations.

    $pass = (new BoardingPassBuilder())
        ->setHeaderFields(['primary' => 'Event Ticket', 'secondary' => 'Conference 2024'])
        ->setBarcode('EVENT2024')
        ->setExpirationDate('2024-12-31')
        ->setBackFields(['header' => 'Thank You!', 'message' => 'Visit us again.'])
        ->build();
    
  • Dynamic Fields:

    $pass->setStoreCardFields([
        'primary' => $user->name,
        'secondary' => $user->membership_tier,
    ]);
    
  • Images:

    $pass->setLogoImage(Image::fromUrl('https://example.com/logo.png'));
    $pass->setIconImage(Image::fromPath(public_path('images/icon.png')));
    

2. Platform-Specific Handling

  • Apple Wallet:

    • Requires HTTPS for webServiceURL (configured in .env).
    • Supports NFC and iBeacon relevance (new in 1.5.0) for smart interactions.
    • Automatically generates .pkpass bundle.
    • Example for iBeacon relevance:
      $pass->setRelevance([
          'iBeacon' => [
              'uuid' => 'E2C56DB5-DFFB-48D2-B060-D0F5A71096E0',
              'major' => 1,
              'minor' => 1,
              'relevance' => 'immediate',
          ],
      ]);
      
  • Google Wallet:

    • Uses issuerId and privateKey for signing.
    • Supports EventTicket, Loyalty, Offer, and Generic pass types.
    • Requires callback endpoints for updates (handled via GoogleMobilePassSaved events).

3. Updates & Expiry

  • Push Updates:

    $pass->update([
        'expirationDate' => '2025-06-30',
        'barcode' => 'NEWBARCODE123',
    ]);
    // Triggers `PushPassUpdateJob` (queued by default).
    
  • Expiry:

    $pass->expire(); // Marks pass as expired in both Apple/Google systems.
    

4. User Delivery

  • Apple:

    return response()->download($pass->pkpassPath());
    // OR direct download link:
    $pass->addToWalletUrl(); // Returns URL to trigger Safari Wallet preview.
    
  • Google:

    return redirect($pass->addToWalletUrl());
    // OR for direct download:
    $pass->googlePassJsonPath();
    

5. Event-Driven Workflows

  • Listen for Google Wallet events:
    use Spatie\MobilePass\Events\GoogleMobilePassSaved;
    
    GoogleMobilePassSaved::listen(function (GoogleMobilePassSaved $event) {
        // Log or trigger follow-up actions.
    });
    

Integration Tips

1. Database Model Customization

  • Extend the default MobilePass model:
    class CustomMobilePass extends \Spatie\MobilePass\Models\MobilePass
    {
        protected $table = 'custom_mobile_passes';
    }
    
  • Update config/mobile-pass.php:
    'models' => [
        'mobile_pass' => \App\Models\CustomMobilePass::class,
    ],
    

2. Queueing Updates

  • Enable queued updates in .env:
    MOBILE_PASS_QUEUE_CONNECTION=redis
    
  • Dispatch manually:
    $pass->pushUpdate();
    

3. Remote Images

  • Use Image::fromUrl() for dynamic images:
    $pass->setLogoImage(Image::fromUrl($user->profileImageUrl));
    

4. NFC & iBeacon Fields (Apple)

  • Add smart tap fields (NFC):
    $pass->setNfcFields([
        'message' => 'Tap to unlock gate',
        'url' => 'https://example.com/validate',
    ]);
    
  • Add iBeacon relevance (new in 1.5.0):
    $pass->setRelevance([
        'iBeacon' => [
            'uuid' => 'E2C56DB5-DFFB-48D2-B060-D0F5A71096E0',
            'major' => 1,
            'minor' => 1,
            'relevance' => 'immediate',
        ],
    ]);
    

5. Testing

  • Mock the MobilePass model for unit tests:
    $pass = Mockery::mock(\Spatie\MobilePass\Models\MobilePass::class);
    $pass->shouldReceive('save')->once();
    

Gotchas and Tips

Pitfalls

1. Apple Webservice Host

  • Issue: Non-HTTPS MOBILE_PASS_APPLE_WEBSERVICE_HOST throws InvalidConfig::webserviceHostMustBeHttps.
  • Fix: Ensure .env uses https:// (e.g., https://your-app.com).

2. Pass Serial Uniqueness

  • Issue: Apple routes updates by pass_serial. Duplicate serials cause conflicts.
  • Fix: Use UUIDs or database-unique serials:
    $pass->setSerialNumber(Uuid::generate()->toString());
    

3. Google Callback Verification

  • Issue: Google requires ECv2SigningOnly for callback verification (v1.2.0+).
  • Fix: Ensure your Google Wallet setup uses the correct signing key.

4. Image Paths

  • Issue: Remote images must be publicly accessible (CORS-free).
  • Fix: Use Image::fromUrl() with absolute URLs:
    Image::fromUrl('https://cdn.example.com/image.jpg');
    

5. Expiry Handling

  • Issue: Expired passes may still trigger update requests.
  • Fix: Check isExpired() before processing updates:
    if (!$pass->isExpired()) {
        $pass->pushUpdate();
    }
    

6. Database Migration

  • Issue: v1.0.5+ requires pass_serial migration.
  • Fix: Run the provided migration:
    php artisan migrate --path=/vendor/spatie/laravel-mobile-pass/database/migrations
    

7. iBeacon Configuration (New in 1.5.0)

  • Issue: Incorrect iBeacon UUID/major/minor values may cause relevance issues.
  • Fix: Validate UUID format (e.g., E2C56DB5-DFFB-48D2-B060-D0F5A71096E0) and ensure values match your beacon setup.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata