- Shared context (dual-platform examples)
- Apple-only and Google-only snippets
- 1. Generic pass
- 2. Offer / coupon
- 3. Loyalty / store card
- 4. Event ticket
- 5. Flight (boarding pass)
- 6. Transit (bus, rail, ferry, …)
- 7. Gift card
- Portable options (all builders)
- Limitations
This page shows one end-to-end example per vertical supported by WalletPass. Examples below use a dual-platform context; you can target any combination by chaining ->withApple(...), ->withGoogle(...), and/or ->withSamsung(...).
After build(), you get a BuiltWalletPass:
$built->apple()→ ApplePassforpass.json(throwsApplePassNotAvailableExceptionif the context had no Apple slice)$built->google()->issuerClass/$built->google()->passObject→ Google class and object (throwsGoogleWalletPairNotAvailableExceptionif there was no Google slice)$built->samsung()→ SamsungCardenvelope (throwsSamsungCardNotAvailableExceptionif there was no Samsung slice)
Serialize with Symfony Serializer and the normalizers from this package (see tests/Builder/BuilderTestSerializerFactory.php for a full list).
<?php
declare(strict_types=1);
use Jolicode\WalletKit\Builder\WalletPlatformContext;
use Jolicode\WalletKit\Pass\Android\Model\Shared\ReviewStatusEnum;
use Jolicode\WalletKit\Pass\Android\Model\Shared\StateEnum;
$context = (new WalletPlatformContext())
->withApple(
teamIdentifier: 'YOUR_TEAM_ID',
passTypeIdentifier: 'pass.com.example.app',
serialNumber: 'UNIQUE-SERIAL-001',
organizationName: 'Example Airlines',
description: 'Boarding pass SFO → LHR',
)
->withGoogle(
classId: '3388000000012345.example_flight_class',
objectId: '3388000000012345.example_flight_object',
defaultReviewStatus: ReviewStatusEnum::APPROVED,
defaultObjectState: StateEnum::ACTIVE,
);Apple-only (no Google or Samsung needed). After build(), use only $built->apple(); $built->google() and $built->samsung() throw.
use Jolicode\WalletKit\Builder\WalletPlatformContext;
use Jolicode\WalletKit\Builder\WalletPass;
use Jolicode\WalletKit\Pass\Apple\Model\Field;
use Jolicode\WalletKit\Pass\Apple\Model\PassStructure;
use Jolicode\WalletKit\Pass\Android\Model\Generic\GenericTypeEnum;
$appleContext = (new WalletPlatformContext())->withApple(
teamIdentifier: 'YOUR_TEAM_ID',
passTypeIdentifier: 'pass.com.example.app',
serialNumber: 'SN-APPLE-ONLY',
organizationName: 'Example Org',
description: 'Membership',
);
$built = WalletPass::generic($appleContext)
->withPassStructure(new PassStructure(
primaryFields: [new Field(key: 'member', value: 'Jane', label: 'Member')],
))
->withGenericType(GenericTypeEnum::GYM_MEMBERSHIP)
->build();
$pass = $built->apple();Google-only (requires issuerName for class payloads when no Apple context provides an organization name). After build(), use $built->google(); $built->apple() throws. You can still call addAppleBarcode() to supply a barcode for the Google object.
use Jolicode\WalletKit\Builder\WalletPlatformContext;
use Jolicode\WalletKit\Builder\WalletPass;
use Jolicode\WalletKit\Pass\Android\Model\Offer\RedemptionChannelEnum;
use Jolicode\WalletKit\Pass\Apple\Model\Barcode;
use Jolicode\WalletKit\Pass\Apple\Model\BarcodeFormatEnum;
$googleContext = (new WalletPlatformContext())->withGoogle(
classId: '3388000000012345.example_offer_class',
objectId: '3388000000012345.example_offer_object',
issuerName: 'Example Shop',
);
$built = WalletPass::offer(
$googleContext,
title: '10% off',
provider: 'Example Shop',
redemptionChannel: RedemptionChannelEnum::INSTORE,
)->addAppleBarcode(new Barcode(
altText: 'Promo',
format: BarcodeFormatEnum::QR,
message: 'SAVE10',
messageEncoding: 'utf-8',
))->build();
$pair = $built->google();Samsung-only (Samsung requires appLinkLogo, appLinkName, appLinkData on all card types). After build(), use $built->samsung(); $built->apple() and $built->google() throw.
use Jolicode\WalletKit\Builder\WalletPlatformContext;
use Jolicode\WalletKit\Builder\WalletPass;
use Jolicode\WalletKit\Pass\Android\Model\Offer\RedemptionChannelEnum;
use Jolicode\WalletKit\Pass\Apple\Model\Barcode;
use Jolicode\WalletKit\Pass\Apple\Model\BarcodeFormatEnum;
$samsungContext = (new WalletPlatformContext())->withSamsung(
refId: 'coupon-samsung-001',
appLinkLogo: 'https://example.com/logo.png',
appLinkName: 'Example Shop',
appLinkData: 'https://example.com',
);
$built = WalletPass::offer(
$samsungContext,
title: '10% off',
provider: 'Example Shop',
redemptionChannel: RedemptionChannelEnum::INSTORE,
)->addAppleBarcode(new Barcode(
altText: 'Promo',
format: BarcodeFormatEnum::QR,
message: 'SAVE10',
messageEncoding: 'utf-8',
))->build();
$card = $built->samsung();All three platforms — Apple + Google + Samsung in a single build.
use Jolicode\WalletKit\Builder\WalletPlatformContext;
use Jolicode\WalletKit\Builder\WalletPass;
use Jolicode\WalletKit\Pass\Android\Model\Offer\RedemptionChannelEnum;
use Jolicode\WalletKit\Pass\Android\Model\Shared\ReviewStatusEnum;
use Jolicode\WalletKit\Pass\Android\Model\Shared\StateEnum;
$allContext = (new WalletPlatformContext())
->withApple(
teamIdentifier: 'YOUR_TEAM_ID',
passTypeIdentifier: 'pass.com.example.app',
serialNumber: 'SN-ALL-001',
organizationName: 'Example Shop',
description: 'Promotional offer',
)
->withGoogle(
classId: '3388000000012345.example_offer_class',
objectId: '3388000000012345.example_offer_object',
defaultReviewStatus: ReviewStatusEnum::APPROVED,
defaultObjectState: StateEnum::ACTIVE,
)
->withSamsung(
refId: 'offer-samsung-001',
appLinkLogo: 'https://example.com/logo.png',
appLinkName: 'Example Shop',
appLinkData: 'https://example.com',
);
$built = WalletPass::offer($allContext, '20% off', 'Example Shop', RedemptionChannelEnum::BOTH)->build();
$applePass = $built->apple();
$googlePair = $built->google();
$samsungCard = $built->samsung();Use case: membership card, insurance card, or any pass that does not fit a specialized vertical.
<?php
declare(strict_types=1);
use Jolicode\WalletKit\Builder\WalletPass;
use Jolicode\WalletKit\Pass\Android\Model\Generic\GenericTypeEnum;
use Jolicode\WalletKit\Pass\Apple\Model\Barcode;
use Jolicode\WalletKit\Pass\Apple\Model\BarcodeFormatEnum;
use Jolicode\WalletKit\Pass\Apple\Model\Field;
use Jolicode\WalletKit\Pass\Apple\Model\PassStructure;
$built = WalletPass::generic($context)
->withPassStructure(new PassStructure(
primaryFields: [
new Field(key: 'member', value: 'Jane Doe', label: 'Member'),
],
secondaryFields: [
new Field(key: 'id', value: 'MEM-8842', label: 'ID'),
],
))
->withGenericType(GenericTypeEnum::GYM_MEMBERSHIP)
->withGoogleCardTitle('Gym membership')
->addAppleBarcode(new Barcode(
altText: 'Member ID',
format: BarcodeFormatEnum::QR,
message: 'MEM8842',
messageEncoding: 'utf-8',
))
->withGoogleHexBackgroundColor('#1a237e')
->withGrouping('membership-2026', 0)
->build();Use case: promotional offer redeemable in store, online, or both.
<?php
declare(strict_types=1);
use Jolicode\WalletKit\Builder\WalletPass;
use Jolicode\WalletKit\Pass\Android\Model\Offer\RedemptionChannelEnum;
use Jolicode\WalletKit\Pass\Apple\Model\Barcode;
use Jolicode\WalletKit\Pass\Apple\Model\BarcodeFormatEnum;
$built = WalletPass::offer(
$context,
title: '20% off next visit',
provider: 'Example Coffee',
redemptionChannel: RedemptionChannelEnum::INSTORE,
)
->withBackgroundColorRgb('rgb(40, 80, 120)')
->addAppleBarcode(new Barcode(
altText: 'Promo',
format: BarcodeFormatEnum::PDF417,
message: 'PROMO-2026-04',
messageEncoding: 'iso-8859-1',
))
->withGoogleValidityWindow('2026-04-01T00:00:00', '2026-06-30T23:59:59')
->build();Use case: points program or store loyalty card (Apple storeCard, Google Loyalty).
<?php
declare(strict_types=1);
use Jolicode\WalletKit\Builder\WalletPass;
$built = WalletPass::loyalty($context, programName: 'Gold Rewards')
->withAccount(accountName: 'Alex Martin', accountId: 'GLD-991122')
->withAppleWebService(
url: 'https://api.example.com/v1/passes/',
authenticationToken: 'opaque-shared-secret',
)
->withGrouping('loyalty-tier-gold', 2)
->build();Use case: concert, match, or venue ticket.
<?php
declare(strict_types=1);
use Jolicode\WalletKit\Builder\WalletPass;
use Jolicode\WalletKit\Pass\Apple\Model\Barcode;
use Jolicode\WalletKit\Pass\Apple\Model\BarcodeFormatEnum;
$built = WalletPass::eventTicket($context, eventName: 'Indie Fest 2026')
->withTicketHolderName('Sam Rivera')
->withTicketNumber('EVT-7F3A-9910')
->addAppleBarcode(new Barcode(
altText: 'Entry',
format: BarcodeFormatEnum::QR,
message: 'EVT7F3A9910',
messageEncoding: 'utf-8',
))
->build();Use case: airline boarding pass (Apple boardingPass with air transit, Google Flight).
<?php
declare(strict_types=1);
use Jolicode\WalletKit\Builder\WalletPass;
use Jolicode\WalletKit\Pass\Android\Model\Flight\AirportInfo;
use Jolicode\WalletKit\Pass\Android\Model\Flight\BoardingAndSeatingInfo;
use Jolicode\WalletKit\Pass\Android\Model\Flight\FlightCarrier;
use Jolicode\WalletKit\Pass\Android\Model\Flight\FlightHeader;
use Jolicode\WalletKit\Pass\Android\Model\Flight\ReservationInfo;
$built = WalletPass::flight(
$context,
passengerName: 'Jordan Smith',
reservationInfo: new ReservationInfo(
confirmationCode: 'XK4P2Q',
eticketNumber: '0123456789',
),
flightHeader: new FlightHeader(
carrier: new FlightCarrier(carrierIataCode: 'ZZ'),
flightNumber: '412',
),
origin: new AirportInfo(airportIataCode: 'CDG', gate: 'K42'),
destination: new AirportInfo(airportIataCode: 'JFK', terminal: '4'),
)
->withBoardingAndSeatingInfo(new BoardingAndSeatingInfo(
boardingGroup: '2',
sequenceNumber: '042',
))
->withAppleForegroundColor('rgb(255, 255, 255)')
->build();Use case: ground or sea transit ticket (Apple boardingPass with mapped transitType, Google Transit).
<?php
declare(strict_types=1);
use Jolicode\WalletKit\Builder\WalletPass;
use Jolicode\WalletKit\Pass\Android\Model\Shared\StateEnum;
use Jolicode\WalletKit\Pass\Android\Model\Transit\TransitTypeEnum;
use Jolicode\WalletKit\Pass\Android\Model\Transit\TripTypeEnum;
$built = WalletPass::transit(
$context,
transitType: TransitTypeEnum::RAIL,
tripType: TripTypeEnum::ONE_WAY,
)
->withTicketNumber('TCK-RAIL-884499')
->withGoogleObjectState(StateEnum::ACTIVE)
->build();Google TransitTypeEnum cases (BUS, RAIL, TRAM, FERRY, …) are mapped to the closest Apple TransitTypeEnum (for example RAIL / TRAM → TRAIN).
Use case: Google Gift card object. Apple has no dedicated gift-card type: the builder emits a storeCard with card-oriented fields.
<?php
declare(strict_types=1);
use Jolicode\WalletKit\Builder\WalletPass;
$built = WalletPass::giftCard($context, cardNumber: '6034932523842700')
->withPin('4829')
->withGoogleHexBackgroundColor('#4e342e')
->build();These methods come from CommonWalletBuilderTrait and are available on every vertical builder:
| Method | Role |
|---|---|
addAppleBarcode |
Adds a barcode on the Apple pass; the first one is mirrored on Google unless you override. |
withGoogleBarcodeOverride |
Forces the Google object barcode. |
withAppleBackgroundColor / withGoogleHexBackgroundColor |
Colors per platform. |
withBackgroundColorRgb |
Sets Apple RGB and derives Google hex when possible. |
withAppleForegroundColor / withAppleLabelColor |
Apple-only styling. |
withGrouping |
Apple groupingIdentifier + Google GroupingInfo. |
withAppleWebService |
Apple pass update web service URL and token. |
withAppleAppLaunchUrl / withAppleAssociatedStoreIdentifiers |
Associated app hints (Apple). |
withAppleExpiration |
Apple expiration / voided. |
withGoogleValidTimeInterval / withGoogleValidityWindow |
Google validity window. |
withGoogleReviewStatus / withGoogleObjectState |
Overrides context defaults for Google class/object lifecycle. |
withAppLinkData / withGoogleLinksModuleData |
Links and app deep links (Google; Apple where mapped). |
mutateApple(callable) |
Escape hatch to tweak the Apple Pass before build() returns. |
mutateSamsung(callable) |
Escape hatch to tweak the Samsung Card before build() returns. |
- The library does not sign
.pkpassbundles, call Google Wallet REST APIs, or tokenize Samsung Wallet payloads. - Apple, Google, and Samsung models differ: not every field exists on all sides. Use
mutateApple,mutateSamsung, or adjust the returned Google class/object afterbuild()for platform-specific details. - A
WalletPlatformContextwith no platform slice will produce aBuiltWalletPasswhere all accessors throw. Google contexts without anissuerNamemust have an Apple context to fall back on (viaorganizationName). - Samsung Digital ID and Pay As You Go card types have no Apple/Google equivalent and are not exposed through
WalletPassfactory methods. Build them directly via the Samsung model classes undersrc/Pass/Samsung/Model/.