thenextweb / passgenerator
一个用于创建与 Apple Wallet (旧 Passbook) 兼容票据的 Laravel 包。
Requires
- ext-zip: *
- illuminate/filesystem: ^7.0|^8.0|^9.0|^10.0|^11.0
- illuminate/support: ^7.0|^8.0|^9.0|^10.0|^11.0
- thecodingmachine/safe: ^2.1
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.2
- orchestra/testbench: ^5.0|^6.0|^7.0|^8.0|^9.0
- phpstan/phpstan: ^1.6
- phpunit/phpunit: ^9.3|^10.0
- rector/rector: ^0.12|^0.15
- thecodingmachine/phpstan-safe-rule: ^1.2
README
Passgenerator 是一个 Laravel7+ 包,允许您轻松创建与 Apple Wallet (旧 Passbook) 兼容的通行证。
👉 目录 👈
👮 要求
只需要 Laravel 7+ 和安装并启用 PHP Zip 扩展。
💾 安装
安装此包的最佳和最简单方法是使用 Composer 包管理器。为此,请在项目根目录中运行以下命令
composer require thenextweb/passgenerator
然后,将 Thenextweb\PassGeneratorServiceProvider
提供者添加到 config/app.php
中的 providers 数组
'providers' => [ // ... Thenextweb\PassGeneratorServiceProvider::class, ],
就是这样!
🍎 Apple 文档
从现在起,一些内容在 Apple 文档中解释得更好,所以如果您不确定,请查看以下文档(如果您尚未查看)
📝 配置
要开始使用此包,需要一些 Apple 文件以及一些操作以将它们转换为更友好的格式
-
接下来,您需要创建一个通行证类型 ID。这与应用的包 ID 类似。它将唯一标识一种特定的通行证。它应该采用反向域名样式字符串的形式(即,pass.com.example.appname)。
-
创建通行证类型 ID 后,单击
编辑
并按照说明创建一个新的证书。 -
一旦过程完成,就可以下载通行证证书。但这还不是全部,证书以
.cer
文件的形式下载,需要将其转换为.p12
才能使用。如果您使用的是 Mac,您可以将它导入到 钥匙串访问 并从那里导出。请确保您记得为导出的文件设置的 密码,因为您稍后需要使用它。您也可以使用其他工具转换证书,但请确保导出的 PKCS12 文件中包含私钥。 -
如果您已经进行过 iOS 开发,您可能已经在 Mac 的钥匙串中有了 Apple Worldwide Developer Relations 中间证书。如果没有,它可以从 Apple 网站(以
.cer
格式)下载。此证书需要以.pem
格式导出,您也可以从 钥匙串访问(或您用于管理 OS 上证书的任何工具)中导出。
完成所有这些繁琐的过程后,一切几乎都准备就绪,可以使用此包了。现在最简单的是将以下键添加到您的 .env
文件中
- CERTIFICATE_PATH ➪
.p12
通行证证书的路径。 - CERTIFICATE_PASS ➪ 在导出证书时设置的密码。
- WWDR_CERTIFICATE ➪
.pem
格式 Apple Worldwide Developer Relations 中间证书 的路径。
如果出于某些原因必须修改配置文件(冲突的 env 键、需要动态证书等),可以使用以下命令发布它
// file will be at config/passgenerator.php
php artisan vendor:publish --provider="Thenextweb\PassGeneratorServiceProvider"
🚀 使用
首次创建通行证时,您首先需要创建通行证定义,可以是JSON文件或数组形式。强烈建议您已经阅读了苹果官方文档以及PassKit 包格式参考。
use Thenextweb\PassGenerator; //... $pass_identifier = 'somekindofid'; // This, if set, it would allow for retrieval later on of the created Pass $pass = new PassGenerator($pass_identifier); $pass_definition = [ "description" => "description", "formatVersion" => 1, "organizationName" => "organization", "passTypeIdentifier"=> "pass.com.example.appname", "serialNumber" => "123456", "teamIdentifier" => "teamid", "foregroundColor" => "rgb(99, 99, 99)", "backgroundColor" => "rgb(212, 212, 212)", "barcode" => [ "message" => "encodedmessageonQR", "format" => "PKBarcodeFormatQR", "altText" => "altextfortheQR", "messageEncoding"=> "utf-8", ], "boardingPass" => [ "headerFields" => [ [ "key" => "destinationDate", "label" => "Trip to: BCN-SANTS", "value" => "15/09/2015" ] ], "primaryFields" => [ [ "key" => "boardingTime", "label" => "MURCIA", "value" => "13:54", "changeMessage" => "Boarding time has changed to %@" ], [ "key" => "destination", "label" => "BCN-SANTS", "value" => "21:09" ] ], "secondaryFields" => [ [ "key" => "passenger", "label" => "Passenger", "value" => "J.DOE" ], [ "key" => "bookingref", "label" => "Booking Reference", "value" => "4ZK6FG" ] ], "auxiliaryFields" => [ [ "key" => "train", "label" => "Train TALGO", "value" => "00264" ], [ "key" => "car", "label" => "Car", "value" => "009" ], [ "key" => "seat", "label" => "Seat", "value" => "04A" ], [ "key" => "classfront", "label" => "Class", "value" => "Tourist" ] ], "backFields" => [ [ "key" => "ticketNumber", "label" => "Ticket Number", "value" => "7612800569875" ], [ "key" => "passenger-name", "label" => "Passenger", "value" => "John Doe" ], [ "key" => "classback", "label" => "Class", "value" => "Tourist" ] ], "locations" => [ [ "latitude" => 37.97479, "longitude" => -1.131522, "relevantText" => "Departure station" ] ], "transitType" => "PKTransitTypeTrain" ], ]; $pass->setPassDefinition($pass_definition); // Definitions can also be set from a JSON string // $pass->setPassDefinition(file_get_contents('/path/to/pass.json)); // Add assets to the PKPass package $pass->addAsset(base_path('resources/assets/wallet/background.png')); $pass->addAsset(base_path('resources/assets/wallet/thumbnail.png')); $pass->addAsset(base_path('resources/assets/wallet/icon.png')); $pass->addAsset(base_path('resources/assets/wallet/logo.png')); $pkpass = $pass->create();
现在,一个有效的票据已经准备好了。苹果推荐使用MIME类型来服务于其设备,以下类似的内容应该可以完成这个任务:
return new Response($pkpass, 200, [ 'Content-Transfer-Encoding' => 'binary', 'Content-Description' => 'File Transfer', 'Content-Disposition' => 'attachment; filename="pass.pkpass"', 'Content-length' => strlen($pkpass), 'Content-Type' => PassGenerator::getPassMimeType(), 'Pragma' => 'no-cache', ]);
稍后,如果您的用户需要再次下载通行证,您无需重新创建(避免在加密操作上浪费CPU周期),只需进行类似以下操作:
// If the pass for that ID does not exist, you can then proceed to generate it as done above. $pkpass = PassGenerator::getPass($pass_identifier); if (!$pkpass) { $pkpass = $this->createWalletPass(); } // ...
也有可能检索您文件系统上通行证的实际路径。默认情况下,Passgenerator将复制您的默认文件系统配置(通常以storage_path('app')
为根,但您始终可以使用getPassFilePath($pass_identifier)
来获取实际路径,前提是它存在。
定义
您还可以使用定义对象以编程方式创建/修改通行证。例如:
$coupon = Thenextweb\Definitions\Coupon();
$coupon->setDescription('Coupon description');
$coupon->setSerialNumber('123456');
$coupon->setUserInfo([
'email' => 'user@domain.com',
]);
$coupon->setExpirationDate(Carbon::now()->addMonths(6));
$location = new Location();
$location->setLatitude(40.4378698);
$location->setLongitude(-3.819619);
$coupon->addLocation($location);
$coupon->setMaxDistance(50);
$coupon->setRelevantDate(Carbon::now()->addDays(10));
$coupon->addAuxiliaryField(new Field('key', 'value'));
$coupon->addBackField(new Number('price', 13, [
'currencyCode' => 'EUR',
'numberStyle' => Number::STYLE_DECIMAL
]));
$coupon->addPrimaryField(new Date('created_at', Carbon::now(), [
'dateStyle' => Date::STYLE_FULL,
]));
$barcode = new Barcode('7898466321', Barcode::FORMAT_CODE128);
$coupon->addBarcode($barcode);
$passgenerator->setPassDefinition($coupon);