jolicode / wallet-kit
Manage Apple & Google wallets
Requires
- php: >=8.3
- symfony/serializer: ^7.4 || ^8.0
Requires (Dev)
- phpunit/phpunit: ^12.0
This package is not auto-updated.
Last update: 2026-04-22 20:50:02 UTC
README
WalletKit
One fluent API to model Apple Wallet and Google Wallet payloads in typed PHP.
Overview
Wallet Kit helps you build the JSON payloads wallet platforms expect. It focuses on modeling and normalization (via Symfony Serializer): it does not sign Apple passes, bundle .pkpass files, call Google Wallet APIs, or tokenize Samsung Wallet payloads.
- PHP 8.3+
- symfony/serializer ^7.4 || ^8.0
π οΈ Builder
The Jolicode\WalletKit\Builder namespace provides a fluent API centered on WalletPass. Build a WalletPlatformContext with ->withApple(...), ->withGoogle(...), and/or ->withSamsung(...), then call build() to obtain a BuiltWalletPass (apple(), google(), samsung()). You can then normalize these models using Symfony Serializer along with this package's normalizers.
Cookbook (single-store appleOnly / googleOnly, every vertical, shared options, exceptions): docs/builder-examples.md.
Example β all platforms
$context = (new WalletPlatformContext()) ->withApple( teamIdentifier: 'ABCDE12345', passTypeIdentifier: 'pass.com.example.coupon', serialNumber: 'COUPON-001', organizationName: 'Example Shop', description: 'Spring sale coupon', ) ->withGoogle( classId: '3388000000012345.example_offer_class', objectId: '3388000000012345.example_offer_object', defaultReviewStatus: ReviewStatusEnum::APPROVED, defaultGoogleObjectState: StateEnum::ACTIVE, ) ->withSamsung( refId: 'coupon-samsung-001', appLinkLogo: 'https://example.com/logo.png', appLinkName: 'Example Shop', appLinkData: 'https://example.com', ); $built = WalletPass::offer( $context, title: '15% off', provider: 'Example Shop', redemptionChannel: RedemptionChannelEnum::BOTH, ) ->withBackgroundColorRgb('rgb(30, 60, 90)') ->addAppleBarcode(new Barcode( altText: 'Coupon', format: BarcodeFormatEnum::QR, message: 'SAVE15-2026', messageEncoding: 'utf-8', )) ->build(); // $built->apple() β Pass (coupon) // $built->google() β OfferClass + OfferObject // $built->samsung() β Card (coupon) // Then normalize with Symfony Serializer + this library's normalizers.
π Apple Wallet
Apple's model maps to a single tree: either use the builder above or build a Pass manually (see src/Pass/Apple/) and normalize it to the structure that becomes pass.json inside a pass package. Images, manifest, and cryptographic signing are still your responsibility.
π€ Google Wallet
Google's API splits each pass type into two resources: a class (shared template) and an object (one per holder). The object references the class through classId. This library exposes both sides under src/Pass/Android/ for: EventTicket, Flight, Generic, GiftCard, Loyalty, Offer, and Transit. The builder returns that pair from BuiltWalletPass::google().
π± Samsung Wallet
Samsung Wallet uses a single unified JSON envelope: a Card containing type, subType, and a data array of card entries with attributes (type-specific fields). This library models 8 Samsung card types under src/Pass/Samsung/: BoardingPass, EventTicket, Coupon, GiftCard, Loyalty, Generic, DigitalId, and PayAsYouGo. The builder maps the 7 cross-platform verticals to their Samsung equivalents and returns a Card from BuiltWalletPass::samsung(). DigitalId and PayAsYouGo are Samsung-only types β build them directly via the model classes.
Install
composer require jolicode/wallet-kit
Package layout
Jolicode\WalletKit\Pass\Appleβ Apple Walletpass.jsonpayloadsJolicode\WalletKit\Pass\Androidβ Google Wallet class and object payloadsJolicode\WalletKit\Pass\Samsungβ Samsung Wallet card payloadsJolicode\WalletKit\Builderβ Fluent builders (WalletPass, β¦) for Apple, Google, Samsung, or allJolicode\WalletKit\Exceptionβ Builder context andBuiltWalletPassaccessor exceptions
API spec checks (with Castor)
When Castor is available, you can verify that tracked baselines still match the Google Wallet discovery document, the Apple pass.json phpstan shapes, and the Samsung Wallet model shapes in this repo:
| Command | Purpose |
|---|---|
castor spec:check:google |
Fetches the live Wallet Objects discovery and compares its revision to tools/spec/google-wallet-baseline.json. |
castor spec:baseline:google |
After you update Android models for a new discovery revision, refreshes that JSON baseline. |
castor spec:check:apple |
Regenerates a key list from src/Pass/Apple/Model @phpstan-type array shapes and diffs it against tools/spec/apple-pass-keyset.json. |
castor spec:baseline:apple |
Rewrites apple-pass-keyset.json from the current phpstan definitions (run after intentional model changes). |
castor spec:check:samsung |
Regenerates a key list from src/Pass/Samsung/Model @phpstan-type array shapes and diffs it against tools/spec/samsung-wallet-keyset.json. |
castor spec:baseline:samsung |
Rewrites samsung-wallet-keyset.json from the current phpstan definitions (run after intentional model changes). |
Scripts live under tools/spec/ and are also invoked by CI (spec-check job).
Next steps
The library today stops at typed payloads and normalization. Planned extensions include:
- Apple
.pkpasspackaging β assemble the pass bundle (images,pass.json, manifest), handle localized resources (*.lproj, string tables), and optionally integrate signing so a complete.pkpasscan be produced from the models you already build. - Google Wallet API client β HTTP integration to create, update, and patch classes and objects (REST), including the service-account JWT flow Google expects, so you can go from
BuiltWalletPass::google()to live passes without wiring the client yourself. - Push notifications & in-wallet updates β APNs integration to trigger Apple Wallet pass refreshes (silent/empty push so PassKit pulls a new
pass.jsonfrom your web service), Google Wallet support for API-driven updates plus user-visible messages / notification hooks where the platform exposes them, and Samsung Wallet push updates via the Partner API, so pass changes actually reach holders' devices across all three platforms. - Samsung Wallet tokenization & Partner API β JWT token generation for card payloads, HTTP integration with the Samsung Wallet Partner API to create, update, and expire cards, and card-state lifecycle management, so you can go from
BuiltWalletPass::samsung()to live cards without wiring the client yourself.
Other directions that often sit next to βwalletβ libraries (for later consideration):
- Apple PassKit Web Service β register/update HTTP endpoints, authentication token handling, and glue between your backend and the APNs flow above.
- Issuance UX helpers β stable patterns for Add to Apple Wallet / Save to Google Pay / Add to Samsung Wallet links, deep links, and optional JWT flows where platforms require them.
- Operational tooling β fixtures for integration tests, optional CLI or Castor tasks that mirror production steps (e.g. dry-run Google calls, local
.pkpassinspection).
Contributions or design discussion for any of the above are welcome.
License
View the LICENSE file attached to this project.