Google Wallet (formerly known as Google Pay Passes) allows users to store and manage various passes, such as loyalty cards, event tickets, and membership cards. Creating a membership card for Google Wallet can enhance user engagement and provide a seamless experience. In this guide, we'll walk you through the process of generating Google Wallet Passes using Node.js.
Before you begin, ensure you have the following:
To interact with the Google Wallet API, you need to set up a project in Google Cloud and configure the necessary services.
Security Tip: Store your service account credentials securely and avoid committing them to version control systems.
Initialize your Node.js project and install the necessary dependencies.
# Create and navigate to your project directory mkdir google-wallet-pass cd google-wallet-pass # Initialize a new Node.js project npm init -y # Install required packages npm install express google-auth-library jsonwebtoken axios dotenv
Note: We've added the dotenv package to manage environment variables securely.
Google Wallet membership cards are based on a Class template. First, you need to define this class using the Wallet API.
Project Structure:
google-wallet-pass/ ├── service-account.json ├── pass-model/ │ └── images/ │ ├── logo.png ├── .env ├── class.js ├── object.js ├── server.js └── package.json
Configure Environment Variables:
Create a .env file to store sensitive information.
GOOGLE_APPLICATION_CREDENTIALS=./service-account.json WALLET_API_BASE_URL=https://walletobjects.googleapis.com/walletobjects/v1 PORT=3000
Create class.js:
// class.js require('dotenv').config(); const { GoogleAuth } = require('google-auth-library'); const axios = require('axios'); const fs = require('fs'); const path = require('path'); // Initialize Google Auth const auth = new GoogleAuth({ keyFile: process.env.GOOGLE_APPLICATION_CREDENTIALS, scopes: ['https://www.googleapis.com/auth/wallet_object.issuer'], }); // Define the Membership Class const membershipClass = { id: 'issuerId.membershipClassId', // Replace with your issuer ID and unique class ID issuerName: 'Your Company Name', programName: 'Loyalty Membership', programLogo: { sourceUri: { uri: 'https://your-domain.com/path-to-logo.png', // URL to your program logo }, }, textModulesData: [ { header: 'Membership Details', body: 'Welcome to our membership program. Enjoy exclusive benefits and rewards!', }, ], linksModuleData: { uris: [ { uri: 'https://your-website.com', description: 'Visit our website for more information', }, ], }, reviewStatus: 'underReview', // Set to 'active' once approved by Google }; // Function to create Membership Class async function createMembershipClass() { try { const client = await auth.getClient(); const accessToken = await client.getAccessToken(); const response = await axios.post( `${process.env.WALLET_API_BASE_URL}/loyaltyClass`, membershipClass, { headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', }, }, ); console.log('Membership class created successfully:', response.data); } catch (error) { console.error( 'Error creating membership class:', error.response ? error.response.data : error.message, ); } } // Execute the function createMembershipClass();
Important: Replace "issuerId.membershipClassId" with your actual issuer ID and a unique class ID.
Run class.js to Create the Class:
node class.js
After successful execution, Google will review your class. Once approved, you can set reviewStatus to active to make it available for creating objects.
Once the class is approved, you can create membership card Objects for individual users. These objects contain specific user information and are linked to the class.
Create object.js:
// object.js require('dotenv').config(); const { GoogleAuth } = require('google-auth-library'); const jwt = require('jsonwebtoken'); const fs = require('fs'); const path = require('path'); // Initialize Google Auth const auth = new GoogleAuth({ keyFile: process.env.GOOGLE_APPLICATION_CREDENTIALS, scopes: ['https://www.googleapis.com/auth/wallet_object.issuer'], }); // Define the Membership Object const membershipObject = { id: 'issuerId.membershipObjectId', // Replace with your issuer ID and unique object ID classId: 'issuerId.membershipClassId', // Replace with your class ID state: 'active', accountId: '123456789', // Unique identifier for the user accountName: 'John Doe', barcode: { type: 'qrCode', value: '123456789', }, textModulesData: [ { header: 'Membership Info', body: 'Thank you for being a loyal member!', }, ], infoModuleData: { labelValueRows: [ { columns: [ { label: 'Points', value: '100', }, ], }, ], }, }; // Function to create Membership Object async function createMembershipObject() { try { const client = await auth.getClient(); const accessToken = await client.getAccessToken(); const response = await axios.post( `${process.env.WALLET_API_BASE_URL}/loyaltyObject`, membershipObject, { headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', }, }, ); console.log('Membership object created successfully:', response.data); } catch (error) { console.error( 'Error creating membership object:', error.response ? error.response.data : error.message, ); } } // Execute the function createMembershipObject();
Important: Replace "issuerId.membershipObjectId" with your actual issuer ID and a unique object ID. Ensure that classId matches the ID of the class you created earlier.
Run object.js to Create the Object:
node object.js
This will create a membership object linked to your class. You can generate a Save URL for users to add this pass to their Google Wallet.
You can use Express to serve the membership card creation via a URL. This allows users to add their membership card to Google Wallet seamlessly.
Create server.js:
// server.js require('dotenv').config(); const express = require('express'); const { GoogleAuth } = require('google-auth-library'); const jwt = require('jsonwebtoken'); const axios = require('axios'); const path = require('path'); const app = express(); // Initialize Google Auth const auth = new GoogleAuth({ keyFile: process.env.GOOGLE_APPLICATION_CREDENTIALS, scopes: ['https://www.googleapis.com/auth/wallet_object.issuer'], }); // Function to create Membership Object and generate Save URL async function generateSaveUrl(userData) { // Define the Membership Object based on user data const membershipObject = { id: `issuerId.${userData.userId}`, // Unique object ID classId: 'issuerId.membershipClassId', // Your class ID state: 'active', accountId: userData.userId, accountName: userData.name, barcode: { type: 'qrCode', value: userData.membershipId, }, textModulesData: [ { header: 'Membership Info', body: 'Thank you for being a loyal member!', }, ], infoModuleData: { labelValueRows: [ { columns: [ { label: 'Points', value: `${userData.points}`, }, ], }, ], }, }; try { const client = await auth.getClient(); const accessToken = await client.getAccessToken(); // Create the membership object await axios.post( `${process.env.WALLET_API_BASE_URL}/loyaltyObject`, membershipObject, { headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', }, }, ); // Generate JWT for Save to Wallet const serviceAccount = require( path.resolve(process.env.GOOGLE_APPLICATION_CREDENTIALS), ); const privateKey = serviceAccount.private_key; const issuerId = serviceAccount.client_email; const tokenPayload = { iss: issuerId, aud: 'google', origins: ['https://your-domain.com'], typ: 'savetowallet', payload: { loyaltyObjects: [membershipObject], }, }; const token = jwt.sign(tokenPayload, privateKey, { algorithm: 'RS256' }); const saveUrl = `https://pay.google.com/gp/v/save/${token}`; return saveUrl; } catch (error) { console.error( 'Error generating Save URL:', error.response ? error.response.data : error.message, ); throw new Error('Failed to generate Save URL'); } } // Route to add membership to Google Wallet app.get('/add-to-wallet', async (req, res) => { // Example user data. In a real application, retrieve this from your database. const userData = { userId: 'uniqueUserId123', name: 'Jane Smith', membershipId: 'MEM123456', points: 250, }; try { const saveUrl = await generateSaveUrl(userData); res.redirect(saveUrl); // Redirect the user to Google Wallet to save the pass } catch (error) { res.status(500).send('Error generating Google Wallet pass.'); } }); // Start the server const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); });
Note: Replace 'https://your-domain.com' with your actual domain. Ensure that userData is fetched dynamically based on your application's logic.
Run the Server:
node server.js
Access the Pass Generation Endpoint:
Open your browser and navigate to:
http://localhost:3000/add-to-wallet
This should redirect you to Google Wallet's interface to save the pass.
Start the Server:
Ensure your server is running.
node server.js
Access the Pass Generation Endpoint:
Open your browser or use a tool like Postman to navigate to:
http://localhost:3000/add-to-wallet
This should redirect you to Google Wallet's interface, prompting you to add the membership card.
Verify in Google Wallet:
Creating a membership card for Google Wallet using Node.js involves setting up a Google Cloud project, defining a membership class, creating membership objects, and serving them to users. By following this guide, you can integrate Google Wallet into your application, providing users with a convenient and modern way to access their membership information.
For more advanced features, consider exploring Google's Wallet Objects API and integrating additional functionalities like push updates and loyalty points management.
Happy coding!