{"id":22965796,"url":"https://github.com/thenextweb/passgenerator","last_synced_at":"2025-05-16T08:03:22.268Z","repository":{"id":4064436,"uuid":"51759843","full_name":"thenextweb/passgenerator","owner":"thenextweb","description":"A Laravel package to create Apple Wallet passes.","archived":false,"fork":false,"pushed_at":"2025-05-06T01:08:28.000Z","size":246,"stargazers_count":277,"open_issues_count":17,"forks_count":54,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-05-16T08:03:18.579Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thenextweb.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-02-15T14:10:19.000Z","updated_at":"2025-04-18T19:05:56.000Z","dependencies_parsed_at":"2025-05-16T08:03:20.261Z","dependency_job_id":null,"html_url":"https://github.com/thenextweb/passgenerator","commit_stats":{"total_commits":52,"total_committers":12,"mean_commits":4.333333333333333,"dds":0.5961538461538461,"last_synced_commit":"b91de34b512e096cacdea10ced11b226c37beb3c"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thenextweb%2Fpassgenerator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thenextweb%2Fpassgenerator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thenextweb%2Fpassgenerator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thenextweb%2Fpassgenerator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thenextweb","download_url":"https://codeload.github.com/thenextweb/passgenerator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254493381,"owners_count":22080126,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-14T20:16:29.796Z","updated_at":"2025-05-16T08:03:22.239Z","avatar_url":"https://github.com/thenextweb.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Passgenerator\n\nPassgenerator is a Laravel7+ package that allows you to easily create passes compatible with Apple Wallet (former Passbook).\n\n# 👉 Table of Contents 👈\n* [👮 Requirements](#-requirements)\n* [💾 Installation](#-installation)\n* [🍎 Apple docs](#-apple-docs)\n* [📝 Configuration](#-configuration)\n* [🚀 Usage](#-usage)\n\n## 👮 Requirements\n\nOnly things needed are Laravel 7+ and to have the [PHP Zip extension](http://php.net/manual/en/book.zip.php) installed and enabled.\n\n## 💾 Installation\nThe best and easiest way to install the package is using the [Composer](https://getcomposer.org/) package manager. To do so, run this command in your project root:\n\n```sh\ncomposer require thenextweb/passgenerator\n```\n\nThen, add the `Thenextweb\\PassGeneratorServiceProvider` provider to the providers array in `config/app.php`:\n\n```php\n'providers' =\u003e [\n// ...\n    Thenextweb\\PassGeneratorServiceProvider::class,\n],\n```\n\nThat's it!\n\n## 🍎 Apple docs\nFrom now on, some stuff is much better explained on the Apple docs, so when in doubt just check (if you haven't done so) the following documents:\n* [Wallet Portal](https://developer.apple.com/wallet/)\n* [Wallet Developer Guide](https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/PassKit_PG/index.html#//apple_ref/doc/uid/TP40012195)\n* [Crypto Signatures](https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/PassKit_PG/Creating.html#//apple_ref/doc/uid/TP40012195-CH4-SW55)\n* [PassKit Package Format Reference](https://developer.apple.com/library/ios/documentation/UserExperience/Reference/PassKit_Bundle/Chapters/Introduction.html#//apple_ref/doc/uid/TP40012026)\n\n## 📝 Configuration\nTo start using the package some Apple files are needed, as well as some action in order to convert them to more friendly formats:\n\n1. Go to the [Apple Developer page ➵ Identifiers ➵ Pass Type IDs](https://developer.apple.com/account/ios/identifiers/passTypeId/passTypeIdList.action).\n\n2. Next, you need to create a pass type ID. This is similar to the bundle ID for apps. It will uniquely identify a specific kind of pass. It should be of the form of a reverse-domain name style string (i.e., pass.com.example.appname).\n\n3. After creating the pass type ID, click on `Edit` and follow the instructions to create a new Certificate.\n\n4. Once the process is finished, the pass certificate can be downloaded. That's not it though, the certificate is downloaded as `.cer` file, which need to be converted to `.p12` in order to work. If you are using a Mac you can import it into _Keychain Access_ and export it from there. Make sure to *remember the password* you have given to the exported file since you'll have to use it later. You can also use other tools to convert the certificate but be sure it includes the private key on the exported PKCS12 file.\n\n5. If you have made iOS development, you probably have already the _Apple Worldwide Developer Relations Intermediate Certificate_ in your Mac’s keychain. If not, it can be downloaded from the [Apple Website](https://www.apple.com/certificateauthority/) (on `.cer` format). This one needs to be exported as `.pem`, you can also do so from _Keychain Access_ (or whatever tool you use to manage certificates on your OS).\n\n\nOnce all this tedious process has been done, everything is almost ready to start using the package. The easiest now is to add to the following keys to your `.env` file:\n\n* CERTIFICATE_PATH ➪ The path to the `.p12` pass certificate.\n* CERTIFICATE_PASS ➪ The password set to unlock the certificate when it was exported.\n* WWDR_CERTIFICATE ➪ The path to the _Apple Worldwide Developer Relations Intermediate Certificate_ on `.pem` format.\n\nIn case there is a reason the config file must be modified (conflicting env keys, dynamic certificates required...), it can be published with the following command:\n\n```sh\n// file will be at config/passgenerator.php\nphp artisan vendor:publish --provider=\"Thenextweb\\PassGeneratorServiceProvider\"\n```\n\n## 🚀 Usage\nTo create a pass for the first time, you have to first create the pass definition, either as a JSON file or as an array. It is *really* recommended to have already read the [Apple docs](https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/PassKit_PG/YourFirst.html#//apple_ref/doc/uid/TP40012195-CH2-SW1) as well as the [PassKit Package Format Reference](https://developer.apple.com/library/ios/documentation/UserExperience/Reference/PassKit_Bundle/Chapters/Introduction.html#//apple_ref/doc/uid/TP40012026).\n\n```php\n\nuse Thenextweb\\PassGenerator;\n\n//...\n\n$pass_identifier = 'somekindofid';  // This, if set, it would allow for retrieval later on of the created Pass\n\n$pass = new PassGenerator($pass_identifier);\n\n$pass_definition = [\n    \"description\"       =\u003e \"description\",\n    \"formatVersion\"     =\u003e 1,\n    \"organizationName\"  =\u003e \"organization\",\n    \"passTypeIdentifier\"=\u003e \"pass.com.example.appname\",\n    \"serialNumber\"      =\u003e \"123456\",\n    \"teamIdentifier\"    =\u003e \"teamid\",\n    \"foregroundColor\"   =\u003e \"rgb(99, 99, 99)\",\n    \"backgroundColor\"   =\u003e \"rgb(212, 212, 212)\",\n    \"barcode\" =\u003e [\n        \"message\"   =\u003e \"encodedmessageonQR\",\n        \"format\"    =\u003e \"PKBarcodeFormatQR\",\n        \"altText\"   =\u003e \"altextfortheQR\",\n        \"messageEncoding\"=\u003e \"utf-8\",\n    ],\n    \"boardingPass\" =\u003e [\n        \"headerFields\" =\u003e [\n            [\n                \"key\" =\u003e \"destinationDate\",\n                \"label\" =\u003e \"Trip to: BCN-SANTS\",\n                \"value\" =\u003e \"15/09/2015\"\n            ]\n        ],\n        \"primaryFields\" =\u003e [\n            [\n                \"key\" =\u003e \"boardingTime\",\n                \"label\" =\u003e \"MURCIA\",\n                \"value\" =\u003e \"13:54\",\n                \"changeMessage\" =\u003e \"Boarding time has changed to %@\"\n            ],\n            [\n                \"key\" =\u003e \"destination\",\n                \"label\" =\u003e \"BCN-SANTS\",\n                \"value\" =\u003e \"21:09\"\n            ]\n\n        ],\n        \"secondaryFields\" =\u003e [\n            [\n                \"key\" =\u003e \"passenger\",\n                \"label\" =\u003e \"Passenger\",\n                \"value\" =\u003e \"J.DOE\"\n            ],\n            [\n                \"key\" =\u003e \"bookingref\",\n                \"label\" =\u003e \"Booking Reference\",\n                \"value\" =\u003e \"4ZK6FG\"\n            ]\n        ],\n        \"auxiliaryFields\" =\u003e [\n            [\n                \"key\" =\u003e \"train\",\n                \"label\" =\u003e \"Train TALGO\",\n                \"value\" =\u003e \"00264\"\n            ],\n            [\n                \"key\" =\u003e \"car\",\n                \"label\" =\u003e \"Car\",\n                \"value\" =\u003e \"009\"\n            ],\n            [\n                \"key\" =\u003e \"seat\",\n                \"label\" =\u003e \"Seat\",\n                \"value\" =\u003e \"04A\"\n            ],\n            [\n                \"key\" =\u003e \"classfront\",\n                \"label\" =\u003e \"Class\",\n                \"value\" =\u003e \"Tourist\"\n            ]\n        ],\n        \"backFields\" =\u003e [\n            [\n                \"key\" =\u003e \"ticketNumber\",\n                \"label\" =\u003e \"Ticket Number\",\n                \"value\" =\u003e \"7612800569875\"\n            ], [\n                \"key\" =\u003e \"passenger-name\",\n                \"label\" =\u003e \"Passenger\",\n                \"value\" =\u003e \"John Doe\"\n            ], [\n                \"key\" =\u003e \"classback\",\n                \"label\" =\u003e \"Class\",\n                \"value\" =\u003e \"Tourist\"\n            ]\n        ],\n        \"locations\" =\u003e [\n            [\n                \"latitude\" =\u003e 37.97479,\n                \"longitude\" =\u003e -1.131522,\n                \"relevantText\" =\u003e \"Departure station\"\n            ]\n        ],\n        \"transitType\" =\u003e \"PKTransitTypeTrain\"\n    ],\n];\n\n$pass-\u003esetPassDefinition($pass_definition);\n\n// Definitions can also be set from a JSON string\n// $pass-\u003esetPassDefinition(file_get_contents('/path/to/pass.json));\n\n// Add assets to the PKPass package\n$pass-\u003eaddAsset(base_path('resources/assets/wallet/background.png'));\n$pass-\u003eaddAsset(base_path('resources/assets/wallet/thumbnail.png'));\n$pass-\u003eaddAsset(base_path('resources/assets/wallet/icon.png'));\n$pass-\u003eaddAsset(base_path('resources/assets/wallet/logo.png'));\n\n$pkpass = $pass-\u003ecreate();\n\n```\nNow, a valid ticket is already in place. Apple recommends a MIME type to serve it to its devices so something like the following should do:\n\n```php\nreturn new Response($pkpass, 200, [\n    'Content-Transfer-Encoding' =\u003e 'binary',\n    'Content-Description' =\u003e 'File Transfer',\n    'Content-Disposition' =\u003e 'attachment; filename=\"pass.pkpass\"',\n    'Content-length' =\u003e strlen($pkpass),\n    'Content-Type' =\u003e PassGenerator::getPassMimeType(),\n    'Pragma' =\u003e 'no-cache',\n]);\n```\n\nLater on, if your users need to download the pass again, you don't need to create it again (wasting all those CPU cycles on crypto stuff), you can just do something like:\n\n```php\n// If the pass for that ID does not exist, you can then proceed to generate it as done above.\n$pkpass = PassGenerator::getPass($pass_identifier);\nif (!$pkpass) {\n    $pkpass = $this-\u003ecreateWalletPass();\n}\n// ...\n```\n\nIt is also possible to retrieve the actual path to a pass on your filesystem. By default, _Passgenerator_  will copy your default filesystem config (usually rooted on `storage_path('app')` but you can always do `getPassFilePath($pass_identifier)` and retrieve the real path (in case it exists).\n\n### Definitions\nIt is also possible to programatically create/modify a pass using the definitions objects. Eg.-\n\n```\n$coupon = Thenextweb\\Definitions\\Coupon();\n$coupon-\u003esetDescription('Coupon description');\n$coupon-\u003esetSerialNumber('123456');\n\n$coupon-\u003esetUserInfo([\n    'email' =\u003e 'user@domain.com',\n]);\n$coupon-\u003esetExpirationDate(Carbon::now()-\u003eaddMonths(6));\n\n$location = new Location();\n$location-\u003esetLatitude(40.4378698);\n$location-\u003esetLongitude(-3.819619);\n$coupon-\u003eaddLocation($location);\n\n$coupon-\u003esetMaxDistance(50);\n$coupon-\u003esetRelevantDate(Carbon::now()-\u003eaddDays(10));\n\n$coupon-\u003eaddAuxiliaryField(new Field('key', 'value'));\n\n$coupon-\u003eaddBackField(new Number('price', 13, [\n    'currencyCode' =\u003e 'EUR',\n    'numberStyle' =\u003e Number::STYLE_DECIMAL\n]));\n\n$coupon-\u003eaddPrimaryField(new Date('created_at', Carbon::now(), [\n    'dateStyle' =\u003e Date::STYLE_FULL,\n]));\n\n$barcode = new Barcode('7898466321', Barcode::FORMAT_CODE128);\n$coupon-\u003eaddBarcode($barcode);\n\n$passgenerator-\u003esetPassDefinition($coupon);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthenextweb%2Fpassgenerator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthenextweb%2Fpassgenerator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthenextweb%2Fpassgenerator/lists"}