php-pkpass

repository·master·Indexed 21 days ago

https://github.com/tschoffelen/php-pkpass

A PHP library for creating, signing, and packaging Apple Wallet passes (.pkpass) and financial orders (.order) according to Apple's specifications. It provides the PKPass class for individual passes, the FinanceOrder class for financial transactions, and the PKPassBundle class for grouping multiple passes into a .pkpasses file. Requires PHP 7.0+ and the PHP ZIP extension.

Tokens
8.4K
Snippets
30
Records
37
Agent score
75%

What's inside php-pkpass

  1. Create a bundle of multiple passes with PKPassBundle

    master

    The PKPassBundle class allows you to group multiple PKPass instances into a single .pkpasses file. This format is a ZIP archive containing multiple signed .pkpass files, enabling iOS to import all included passes simultaneously when the file is opened.

    Note: The .pkpasses format is only supported for direct import into Apple Wallet by iOS Safari. Other browsers or platforms do not support this format.

    use PKPass\PKPass;
    use PKPass\PKPassBundle;
    
    $pass1 = new PKPass('/path/to/certificate.p12', 'password');
    $pass2 = new PKPass('/path/to/certificate.p12', 'password');
    
    $bundle = new PKPassBundle();
    $bundle->add($pass1);
    $bundle->add($pass2);
  2. Required and recommended files for FinanceOrder

    master

    Every Apple Wallet Order must include an icon.png file. If this file is missing, the create() method will throw a PKPassException.

    Required:

    • icon.png (29×29 points)

    Recommended assets:

    • icon@2x.png (58×58 points)
    • icon@3x.png (87×87 points)
    • logo.png (max 160×50 points)
    • logo@2x.png (max 320×100 points)
    • logo@3x.png (max 480×150 points)
  3. Configure the example.php sample

    master

    To run the provided examples/example.php demo, follow these steps:

    1. Upload your requested .p12 certificate to your server.
    2. In examples/example.php, update line 22 with the correct path to your certificate and its password.
    3. Update line 29 with your passTypeIdentifier.
    4. Update line 31 with your teamIdentifier (found in the Apple Developer Portal).
    5. Upload all files and navigate to the example.php URL on your iPhone.
    // examples/example.php
    // Line 22: Set path and password
    // Line 29: Set passTypeIdentifier
    // Line 31: Set teamIdentifier
  4. Obtain an APNs Auth Key from Apple

    master

    To send push notifications to update Wallet passes, you must generate an APNs Auth Key in your Apple Developer account. This key allows your server to authenticate with the Apple Push Notification service (APNs).

    1. Sign in to the Apple Developer Account.
    2. Navigate to Certificates, Identifiers & Profiles and select Keys from the left menu.
    3. Create a new key: Click the + button, enter a Key Name, and enable Apple Push Notifications service (APNs). Click Continue and then Register.
    4. Download the AuthKey: Download the .p8 file (e.g., AuthKey_XXXXXXXXXX.p8). Note: This file can only be downloaded once.
    5. Collect required identifiers:
      • Team ID: Found in the top-right corner of your developer account.
      • Key ID: Visible in the Keys list.
      • Bundle ID / Pass Type Identifier: The identifier used for your Wallet Pass certificate (e.g., pass.com.example.demo).
  5. Use the FinanceOrder class to create Apple Wallet Orders

    master

    The FinanceOrder class is used to create Apple Wallet Orders for financial transactions (purchases, invoices, receipts). It extends PKPass but specifically generates .order files using SHA-256 hashing, order.json as the payload, and the application/vnd.apple.finance.order MIME type.

    To create an order, you must provide a valid P12 certificate, set the order data (as an array or JSON), and include the required icon.png file.

    use PKPass\FinanceOrder;
    
    try {
        // 1. Initialize with certificate
        $order = new FinanceOrder('/path/to/certificate.p12', 'password');
        
        // 2. Set order data
        $orderData = [
            'schemaVersion' => '1.0',
            'orderTypeIdentifier' => 'order.com.mycompany.myorder',
            'orderIdentifier' => 'ORDER12345',
            // ... other order fields
        ];
        $order->setData($orderData);
        
        // 3. Add required files (icon.png is mandatory)
        $order->addFile('/path/to/icon.png');
        $order->addFile('/path/to/logo.png');
        
        // 4. Add localization (optional)
        $order->addLocaleStrings('en', [
            'ORDER_TOTAL' => 'Total'
        ]);
        
        // 5. Generate the .order file content
        $orderContent = $order->create(false);
        file_put_contents('myorder.order', $orderContent);
        
    } catch (PKPassException $e) {
        echo 'Error creating order: ' . $e->getMessage();
    }
  6. Install php-pkpass via Composer

    master

    To install the library in your project, run the following command in your root directory:

    composer require pkpass/pkpass

    Alternatively, you can manually add the following line to your composer.json file:

    "pkpass/pkpass": "^2.0.0"
  7. Handle errors when creating a PKPassBundle

    master

    When working with PKPassBundle, wrap your logic in try-catch blocks to handle potential exceptions:

    • InvalidArgumentException: Occurs if you attempt to add() an object that is not a PKPass instance.
    • RuntimeException: Occurs if ZIP operations fail or if there are filesystem errors during save() or output().
    try {
        $bundle = new PKPassBundle();
        $bundle->add($pass1);
        $bundle->save('/path/to/bundle.pkpasses');
    } catch (InvalidArgumentException $e) {
        echo 'Invalid pass object: ' . $e->getMessage();
    } catch (RuntimeException $e) {
        echo 'Bundle creation failed: ' . $e->getMessage();
    }
  8. Request a Pass Certificate (.p12) from Apple

    master

    To sign passes, you must generate a certificate from the Apple Developer portal:

    1. Go to the iOS Provisioning portal.
    2. Create a new Pass Type ID and note the Pass ID.
    3. Edit the new Pass Type ID and generate a certificate. Important: Do not choose a name for the Certificate; leave it empty.
    4. Download the .cer file and drag it into Keychain Access on a Mac.
    5. Filter by Certificates in Keychain Access.
    6. Locate your certificate and click the triangle to reveal the associated private key.
    7. Select both the certificate and the private key, right-click, and choose Export 2 items….
    8. Set a password and save the resulting .p12 file.
  9. Requirements for php-pkpass

    master

    Before using the library, ensure your environment meets these requirements:

    • PHP: Version 7.0 or higher.
    • PHP ZIP extension: Must be installed (often included by default).
    • Filesystem Access: The application must have permission to write temporary cache files.
  10. Configure the Push class

    master

    The PKPass\Push constructor accepts an associative array with the following configuration keys:

    • teamId: Your Apple Developer Team ID.
    • keyId: The Key ID associated with your .p8 file from the Apple Developer portal.
    • authKey: The absolute or relative file path to your downloaded .p8 AuthKey file.
    • bundleId: Your Pass Type Identifier (e.g., pass.com.example.demo).
  11. Troubleshoot FinanceOrder errors

    master

    All FinanceOrder operations that can fail throw a PKPassException. Wrap your logic in a try-catch block to handle errors.

    Common issues:

    • Missing certificate: Verify the $certificatePath and $certificatePassword are correct.
    • Invalid order data: Ensure the data passed to setData() is a valid array or JSON structure.
    • Missing icon.png: You must add an icon.png file using addFile() or addFileContent().
    • File not found: Ensure all local file paths provided to addFile() exist.
    • Invalid localization: Ensure addLocaleStrings() receives a non-empty array.
    try {
        $order->setData($orderData);
        $order->addFile('/path/to/icon.png');
        $orderContent = $order->create(false);
    } catch (PKPassException $e) {
        echo 'Error: ' . $e->getMessage();
    }
  12. Fix OpenSSL 'Could not read certificate file' errors

    master

    If you encounter 'Could not read certificate file', your OpenSSL version may have deprecated older hashes. You can resolve this by converting your .p12 file to a new format compatible with OpenSSL v3+ using these commands:

    1. Decrypt the existing file: openssl pkcs12 -legacy -in key.p12 -nodes -out key_decrypted.tmp
    2. Re-export with modern algorithms: openssl pkcs12 -in key_decrypted.tmp -export -out key_new.p12 -certpbe AES-256-CBC -keypbe AES-256-CBC -iter 2048

    Use the resulting key_new.p12 in your pass generation logic.

    openssl pkcs12 -legacy -in key.p12 -nodes -out key_decrypted.tmp
    openssl pkcs12 -in key_decrypted.tmp -export -out key_new.p12 -certpbe AES-256-CBC -keypbe AES-256-CBC -iter 2048