Apple Wallet (formerly Passbook) allows users to store and manage various passes, such as boarding passes, tickets, and membership cards. Creating a membership card for Apple Wallet can enhance user engagement and provide a seamless experience. In this guide, we'll walk you through the process of generating Apple Wallet Passes (Passbook Passes) using Node.js.
Before you begin, ensure you have the following:
Apple Wallet passes require specific certificates to ensure security and authenticity. Follow these steps to generate the necessary certificates:
Create a Pass Type ID:
Download the WWDR Certificate:
Convert the .cer to .pem (if necessary):
openssl x509 -in AppleWWDRCA.cer -inform DER -out AppleWWDRCA.pem -outform PEM
Export Your Pass Type ID Certificate as .p12:
Initialize your Node.js project and install the necessary dependencies.
# Create and navigate to your project directory mkdir apple-wallet-pass cd apple-wallet-pass # Initialize a new Node.js project npm init -y # Install required packages npm install express @walletpass/pass-js dotenv
Note: We've added the dotenv package to manage environment variables securely.
Create a server that generates and serves the Apple Wallet pass.
Project Structure:
apple-wallet-pass/ ├── certificates/ │ ├── pass.p12 │ └── AppleWWDRCA.pem ├── pass-model/ │ ├── pass.json │ ├── icon.png │ └── logo.png ├── .env ├── server.js └── package.json
Configure Environment Variables:
Create a .env file to store sensitive information.
PASS_CERT_PATH=./certificates/pass.p12 WWDR_CERT_PATH=./certificates/AppleWWDRCA.pem PASS_CERT_PASSPHRASE=your-passphrase PORT=3000
Create server.js:
// server.js require('dotenv').config(); const express = require('express'); const { Pass } = require('@walletpass/pass-js'); const fs = require('fs'); const path = require('path'); const app = express(); // Load certificates const passCert = fs.readFileSync( path.resolve(__dirname, process.env.PASS_CERT_PATH), ); const wwdrCert = fs.readFileSync( path.resolve(__dirname, process.env.WWDR_CERT_PATH), ); // Route to generate the pass app.get('/membership-pass', async (req, res) => { try { const pass = new Pass({ model: path.join(__dirname, 'pass-model'), // Path to pass-model directory certificates: { wwdr: wwdrCert, // Apple WWDR Certificate signerCert: passCert, // Pass Type ID Certificate signerKey: passCert, // Same as passCert for .p12 files signerKeyPassphrase: process.env.PASS_CERT_PASSPHRASE, // Passphrase for the .p12 file }, }); // Set pass fields pass.setType('generic'); // Use 'generic' for membership cards pass.setPassFields({ primaryFields: [ { key: 'name', label: 'MEMBER', value: 'Alex Hobday' }, ], secondaryFields: [ { key: 'membership', label: 'Membership ID', value: 'MEM123456' }, { key: 'balance', label: 'Balance', value: '$50.00' }, ], }); // Optional: Set barcode pass.setBarcodes([ { format: 'PKBarcodeFormatQR', message: 'MEM123456', messageEncoding: 'iso-8859-1', }, ]); // Customize appearance pass.setBackgroundColor('rgb(0, 0, 0)'); pass.setForegroundColor('rgb(255, 255, 255)'); pass.setLabelColor('rgb(255, 255, 255)'); pass.setLogoText('Membership Card'); // Generate the pass const passStream = await pass.generate(); // Send the pass as a downloadable file res.type('application/vnd.apple.pkpass'); res.setHeader( 'Content-Disposition', 'attachment; filename=membership.pkpass', ); passStream.pipe(res); } catch (error) { console.error('Error generating pass:', error); res.status(500).json({ error: 'Failed to generate pass' }); } }); // Start the server const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); });
Security Tip: Always handle errors gracefully and avoid exposing sensitive error details to users.
The pass model defines the structure and appearance of your Apple Wallet pass.
Create pass-model/pass.json:
{ "formatVersion": 1, "passTypeIdentifier": "pass.com.yourcompany.membership", "serialNumber": "123456789", "teamIdentifier": "YOUR_TEAM_ID", "organizationName": "Your Company", "description": "Membership Card", "backgroundColor": "rgb(0,0,0)", "logoText": "Membership", "foregroundColor": "rgb(255,255,255)", "barcode": { "format": "PKBarcodeFormatQR", "message": "MEM123456", "messageEncoding": "iso-8859-1" }, "generic": { "primaryFields": [ { "key": "name", "label": "MEMBER", "value": "Alex Hobday" } ], "secondaryFields": [ { "key": "membership", "label": "Membership ID", "value": "MEM123456" }, { "key": "balance", "label": "Balance", "value": "$50.00" } ] } }
Important: Replace "pass.com.yourcompany.membership" with your actual Pass Type ID and "YOUR_TEAM_ID" with your Apple Developer Team ID.
Add Required Images:
Place the following images in the pass-model directory. Ensure they meet Apple's PassKit image requirements.
icon.png: 29x29 pixels (mandatory)
logo.png: 160x50 pixels (mandatory)
Image Formats: Use PNG format without transparency for the images.
Now that everything is set up, you can test the generation of your Apple Wallet membership pass.
Start the Server:
node server.js
Access the Pass Generation Endpoint:
Open your browser or use a tool like Postman to navigate to:
http://localhost:3000/membership-pass
This should prompt a download of the membership.pkpass file.
Add the Pass to Apple Wallet:
Creating a membership card for Apple Wallet using Node.js involves generating secure Passbook passes, setting up a server to handle pass generation, and customizing the pass model to fit your brand and requirements. By following this guide, you can integrate Apple Wallet into your application, providing users with a convenient and modern way to access their membership information.
For more advanced features, consider exploring Apple's PassKit Framework and integrating additional functionalities like push updates and location-based notifications.
Happy coding!