Generating your first pass | laravel-mobile-pass | Spatie

 SPATIE

  Laravel Mobile Pass
======================

spatie.be/open-source

  [Docs](https://spatie.be/docs)  [Laravel-mobile-pass](https://spatie.be/docs/laravel-mobile-pass/v1)  Basic-usage  Generating your first pass

 Version   v1

 Other versions for crawler [v1](https://spatie.be/docs/laravel-mobile-pass/v1)

- [ Introduction ](https://spatie.be/docs/laravel-mobile-pass/v1/introduction)
- [ Support us ](https://spatie.be/docs/laravel-mobile-pass/v1/support-us)
- [ Requirements ](https://spatie.be/docs/laravel-mobile-pass/v1/requirements)
- [ Installation &amp; setup ](https://spatie.be/docs/laravel-mobile-pass/v1/installation-setup)
- [ Getting credentials from Apple ](https://spatie.be/docs/laravel-mobile-pass/v1/getting-credentials-from-apple)
- [ Getting credentials from Google ](https://spatie.be/docs/laravel-mobile-pass/v1/getting-credentials-from-google)
- [ Questions and issues ](https://spatie.be/docs/laravel-mobile-pass/v1/questions-issues)
- [ Changelog ](https://spatie.be/docs/laravel-mobile-pass/v1/changelog)
- [ About us ](https://spatie.be/docs/laravel-mobile-pass/v1/about-us)

Basic usage
-----------

- [ Generating your first pass ](https://spatie.be/docs/laravel-mobile-pass/v1/basic-usage/generating-your-first-pass)
- [ Delivering passes to users ](https://spatie.be/docs/laravel-mobile-pass/v1/basic-usage/handing-out-passes)
- [ Adding images ](https://spatie.be/docs/laravel-mobile-pass/v1/basic-usage/adding-images)
- [ Adding barcodes ](https://spatie.be/docs/laravel-mobile-pass/v1/basic-usage/adding-barcodes)
- [ Pass relevance ](https://spatie.be/docs/laravel-mobile-pass/v1/basic-usage/pass-relevance)
- [ NFC passes ](https://spatie.be/docs/laravel-mobile-pass/v1/basic-usage/nfc)
- [ Updating a pass ](https://spatie.be/docs/laravel-mobile-pass/v1/basic-usage/updating-a-pass)
- [ Retrieving mobile passes ](https://spatie.be/docs/laravel-mobile-pass/v1/basic-usage/retrieving-mobile-passes)
- [ Storing mobile passes ](https://spatie.be/docs/laravel-mobile-pass/v1/basic-usage/storing-mobile-passes)
- [ Expiring passes ](https://spatie.be/docs/laravel-mobile-pass/v1/basic-usage/expiring-passes)
- [ Apple-specific methods ](https://spatie.be/docs/laravel-mobile-pass/v1/basic-usage/apple-specific-methods)
- [ Google-specific methods ](https://spatie.be/docs/laravel-mobile-pass/v1/basic-usage/google-specific-methods)

Available pass types
--------------------

- [ Introduction ](https://spatie.be/docs/laravel-mobile-pass/v1/available-pass-types/introduction)
- [ Boarding pass ](https://spatie.be/docs/laravel-mobile-pass/v1/available-pass-types/boarding-pass)
- [ Event ticket ](https://spatie.be/docs/laravel-mobile-pass/v1/available-pass-types/event-ticket)
- [ Coupon ](https://spatie.be/docs/laravel-mobile-pass/v1/available-pass-types/coupon)
- [ Loyalty card ](https://spatie.be/docs/laravel-mobile-pass/v1/available-pass-types/loyalty)
- [ Generic ](https://spatie.be/docs/laravel-mobile-pass/v1/available-pass-types/generic)

Advanced usage
--------------

- [ Handling errors ](https://spatie.be/docs/laravel-mobile-pass/v1/advanced-usage/handling-errors)
- [ Customizing actions ](https://spatie.be/docs/laravel-mobile-pass/v1/advanced-usage/customizing-actions)
- [ Customizing models ](https://spatie.be/docs/laravel-mobile-pass/v1/advanced-usage/customizing-models)
- [ Reading stored passes ](https://spatie.be/docs/laravel-mobile-pass/v1/advanced-usage/reading-stored-passes)
- [ Listening to Google save and remove events ](https://spatie.be/docs/laravel-mobile-pass/v1/advanced-usage/listening-to-google-save-remove-events)
- [ Hosting your own Google images ](https://spatie.be/docs/laravel-mobile-pass/v1/advanced-usage/hosting-your-own-google-images)
- [ Testing your passes ](https://spatie.be/docs/laravel-mobile-pass/v1/advanced-usage/testing-your-passes)

 Generating your first pass
==========================

###  On this page

1. [ Before you start ](#content-before-you-start)
2. [ Building a pass ](#content-building-a-pass)
3. [ What about Google? ](#content-what-about-google)

Say you're selling event tickets. After checkout, you want the user to tap a button and drop the ticket straight into their iPhone wallet. With this package, that takes a builder call and a redirect.

Before you start
--------------------------------------------------------------------------------------------------------

Grab credentials for the platform(s) you want to support. Each walkthrough lists the environment variables you need to set:

- [Getting credentials from Apple](/docs/laravel-mobile-pass/v1/getting-credentials-from-apple)
- [Getting credentials from Google](/docs/laravel-mobile-pass/v1/getting-credentials-from-google)

If you want to link passes to a user (or any other model) so you can look them up later, add the `HasMobilePasses` trait to that model:

```
use Spatie\LaravelMobilePass\Models\Concerns\HasMobilePasses;

class User extends Model
{
    use HasMobilePasses;
}
```

Once you've associated passes with a model, see [Retrieving mobile passes](/docs/laravel-mobile-pass/v1/basic-usage/retrieving-mobile-passes) for the helper methods that fetch them back.

Building a pass
-----------------------------------------------------------------------------------------------------

Here's an Apple Wallet event ticket:

```
use Spatie\LaravelMobilePass\Builders\Apple\EventTicketPassBuilder;

$mobilePass = EventTicketPassBuilder::make()
    ->setOrganisationName('Fab Four Promotions')
    ->setSerialNumber('BTL-SHEA-0042')
    ->setDescription('The Beatles at Shea Stadium')
    ->addField('event', 'Beatles Live at Shea')
    ->addField('attendee', 'John Lennon', label: 'Name')
    ->addField('seat', 'Floor A, Row 12')
    ->save();
```

Those first arguments (`event`, `attendee`, `seat`) are identifiers you pick. Apple doesn't care what they say, they just have to be unique within the pass so you can refer back to them later when you want to update that specific field. The label that shows up on the pass is the identifier, title-cased. Pass `label:` when you want something different, which is why `'attendee'` reads as `'Name'` on this ticket.

There are a few other zones a field can land in (header, primary, secondary, auxiliary, back), and they change where the field appears on the pass. `addField` drops it in the primary zone, which is the right place most of the time. When you want finer control, reach for `addHeaderField`, `addSecondaryField`, `addAuxiliaryField`, or `addBackField`. See [Apple-specific methods](/docs/laravel-mobile-pass/v1/basic-usage/apple-specific-methods) for the full reference.

Calling `save()` gives you back a `MobilePass` model. Nothing is written to disk; the whole pass (fields, images, barcode) lives as a row in the `mobile_passes` table.

Handing the ticket to the user is as simple as returning the model from a controller. `MobilePass` implements `Responsable`, so Laravel takes care of serving the signed `.pkpass` file:

```
// in a controller
return $mobilePass;
```

The user taps through, sees the pass preview in Apple Wallet, and taps Add. Apple then calls back to your app to register the device against the pass. The package handles that endpoint for you and saves the registration in the `mobile_pass_registrations` table. That link between pass and device is what lets you push updates later. See [Updating a pass](/docs/laravel-mobile-pass/v1/basic-usage/updating-a-pass) for the details.

What about Google?
------------------------------------------------------------------------------------------------------------

Android users live in Google Wallet, and the same package covers that with a matching set of builders. The flow is almost identical, with one extra step up front. Google requires you to declare a Class (a shared template for a batch of passes) before you can issue individual tickets. You do that once per event.

Once the class exists, building a ticket for one attendee looks like this:

```
use Spatie\LaravelMobilePass\Builders\Google\EventTicketPassBuilder;
use Spatie\LaravelMobilePass\Enums\BarcodeType;

$mobilePass = EventTicketPassBuilder::make()
    ->setClass('beatles-shea-1965')
    ->setAttendeeName('John Lennon')
    ->setSection('Floor A')
    ->setRow('12')
    ->setSeat('24')
    ->setBarcode(BarcodeType::Qr, 'TICKET-12345')
    ->save();
```

The `save()` method creates the Object on Google's servers and inserts a row in the same `mobile_passes` table. Handing it to the user is the same one-liner:

```
// in a controller
return $mobilePass;
```

Android users get redirected to the Google Wallet save URL, iPhone users get the `.pkpass` download. The `Responsable` model picks the right response for the platform the pass was built for.

Updating a Google pass works a little differently from Apple. See [Updating a pass](/docs/laravel-mobile-pass/v1/basic-usage/updating-a-pass) for both flows side by side.
