Google Wallet Pass Variables

User
We have Google wallet event class
Google Wallet API
that has Text modules defined how I will replace values like number_of_seats when generate google wallet pass
Assistant
In the **Google Wallet API**, when you define a `TextModuleData` block in an **event ticket class**, it can contain placeholders (like `number_of_seats`) that you later replace with actual values **in the event object**, not in the class.

### πŸ”„ How Dynamic Text Works

In the **class**:
You define **placeholders** inside `textModulesData.body` like this:

{
  "textModulesData": [
    {
      "header": "Seats",
      "body": "number_of_seats"
    },
    {
      "header": "Seating Area",
      "body": "ringside"
    }
  ]
}

In the **object**:
You override the `textModulesData` **completely** when you generate a pass, like this:

### βœ… Example: Replace Placeholders in Event Ticket Object

$passObject = [
  'id' => $objectId,
  'classId' => $fullClassId,
  'state' => 'active',
  'textModulesData' => [
    [
      'header' => 'Seats',
      'body' => $order['number_of_seats'] // e.g., "3"
    ],
    [
      'header' => 'Seating Area',
      'body' => $order['seating_area'] // e.g., "Ringside"
    ]
  ],
  ...
];

> πŸ’‘ *Note: This will override the static version in the class and insert real-time data into the object pass.*

### 🧠 Summary

– **Class** = Template
– **Object** = Real data (replaces placeholders like `number_of_seats`)
– Always assign `textModulesData` directly in the object if you need dynamic content per ticket.

Let me know if you want a complete sample with JWT creation in PHP.

User
HOw to dynamcially update name and venue when pass object
Assistant
To dynamically update the **event name**, **venue name**, and **venue address** in a **Google Wallet Event Ticket pass**, you must populate those fields **in the Event Ticket Object**, not the Class.

### βœ… Static vs Dynamic in Google Wallet

| **Field** | **In Class (Template)** | **In Object (Dynamic)** |
|———–|————————–|—————————|
| Event Name | Fixed for all passes | βœ… Can be overridden |
| Venue Name | Fixed in class | βœ… Override in object |
| Text Modules | Defined in class | βœ… Replace fully in object |

### βœ… Example: Overriding Dynamic Fields in Event Object

Here’s how you dynamically assign event name and venue details when generating the pass object (via API or JWT):

{
  "id": "issuerId.eventTicketObjectId",
  "classId": "issuerId.eventTicketClassId",
  "state": "active",
  "eventName": {
    "defaultValue": {
      "language": "en-GB",
      "value": "Fossetts Circus – Manchester Evening"
    }
  },
  "venue": {
    "name": {
      "defaultValue": {
        "language": "en-GB",
        "value": "Manchester City Grounds"
      }
    },
    "address": {
      "defaultValue": {
        "language": "en-GB",
        "value": "123 Circus Road, Manchester, UK"
      }
    }
  },
  "textModulesData": [
    {
      "header": "Seats",
      "body": "4"
    },
    {
      "header": "Seating Area",
      "body": "Ringside"
    }
  ],
  "startDateTime": "2025-08-15T18:00:00Z",
  "endDateTime": "2025-08-15T20:30:00Z"
}

### πŸ”§ If you're using JWT (Passes as Links):

You do this in the payload for JWT:

$payload = [
  'eventTicketObjects' => [
    [
      'id' => "$issuerId.objectId",
      'classId' => "$issuerId.classId",
      'eventName' => [
        'defaultValue' => [
          'language' => 'en-GB',
          'value' => 'Fossetts Circus – Manchester Evening'
        ]
      ],
      'venue' => [
        'name' => [
          'defaultValue' => [
            'language' => 'en-GB',
            'value' => 'Manchester City Grounds'
          ]
        ],
        'address' => [
          'defaultValue' => [
            'language' => 'en-GB',
            'value' => '123 Circus Road, Manchester, UK'
          ]
        ]
      ],
      ...
    ]
  ]
];

### 🧠 Summary

– To make event name/venue dynamic, define them in the **object**, not the class.
– Use the structure `eventName.defaultValue.value` and `venue.name.defaultValue.value`.
– Same applies for `startDateTime`, `endDateTime`, and `textModulesData`.

Let me know if you'd like a PHP code snippet for generating the full JWT for this object.

User
$passObject = [
'id' => $objectId,
'classId' => $fullClassId,
'state' => 'active',
'eventName' => [
'defaultValue' => [
'language' => 'en-US',
'value' => $order['event_venue']
]
],
'eventId' => (string)$order['event_id'],
'venue' => [
'name' => [
'defaultValue' => [
'language' => 'en-US',
'value' => $order['event_venue']
]
],
'address' => [
'defaultValue' => [
'language' => 'en-US',
'value' => $venue_address
]
]
],
'doorsOpenDateTime' => $doorsOpenDateTime,
'startDateTime' => $startDateTime,
'endDateTime' => $endDateTime,
'barcode' => [
'type' => 'qrCode',
'value' => $order['order_code'],
'alternateText' => 'Order: ' . $order['order_code']
],
'ticketHolderName' => $order['customer_name'] ?? '',
// Custom fields for more info
// 'ticketCount' => $ticket_count,
// 'ticketSummary' => $ticket_summary_str,
// 'showtime' => $showtime_formatted,
'seatInfo' => [
'seat' => ['defaultValue'=>[
'language'=>'en-US',
'value'=>$ticket_count
]
]
],
'textModulesData' => [
[
'header'=>'Seating Area',
'body'=>$order['ticket_location']
],
[
'header' => 'Seats',
'body' => $ticket_count
],
[
'header' => 'Tickets',
'body' => $ticket_summary_str
],
[
'header' => 'Showtime',
'body' => $showtime_formatted
]
],
];
I have already passed above object
Assistant
Great β€” your `$passObject` array is correctly structured and follows Google Wallet's `EventTicketObject` schema.

### βœ… You're Doing It Right
You're already dynamically assigning the values such as:
– `eventName` β†’ from `$order['event_venue']`
– `venue.name` and `venue.address`
– `eventId`, `doorsOpenDateTime`, `startDateTime`, `endDateTime`
– `textModulesData` β†’ for dynamic ticket info
– `seatInfo` β†’ using `$ticket_count`

These will override any static placeholders defined in the class.

### πŸ” Just a Few Notes for Best Practice

1. **`eventName` should be a real event title**, not a venue name:

'eventName' => [
       'defaultValue' => [
           'language' => 'en-US',
           'value' => $order['event_name'] // e.g., "Fossetts Circus – Evening Show"
       ]
   ],

If you're using `'event_venue'` here, change it to something like `'event_name'` for clarity.

2. **`eventId`** is optional unless you're managing multiple events programmatically. Your cast to `(string)` is safe.

3. βœ… `seatInfo.seat.defaultValue.value` is correct and shows up on the pass UI automatically.

4. βœ… `textModulesData` will override what you defined in the Class. So your entries for:
– **Seating Area** (`ticket_location`)
– **Seats** (`$ticket_count`)
– **Tickets** (`$ticket_summary_str`)
– **Showtime** (`$showtime_formatted`)
will appear in the order you’ve defined.

### πŸ§ͺ Tip: Validate Your Payload
You can validate your JSON payload using:
– [Google Wallet REST API Try It](https://developers.google.com/wallet/generic/rest/v1/genericobject/insert)
– Or if you're using JWT, paste your final JWT into [jwt.io](https://jwt.io/) and inspect the object structure.

### βœ… Final Thoughts
You're dynamically replacing everything correctly at the **object level**, which is how Google Wallet intends dynamic personalization to work. You're good to go!

Let me know if you want to:
– Add images/logos
– Localize to other languages
– Embed a call-to-action (e.g., `heroImage`, `linksModuleData`)
– Generate a JWT pass link from this object

User
buts its still hsowd event_venue1 and event_venue2 in place of dynamic vqlaues
Assistant
Thanks for clarifying. If your Google Wallet pass **still shows `event_venue1` and `event_venue2`**, despite setting dynamic values in the object like this:

'eventName' => [ 'defaultValue' => ['value' => $order['event_name']] ],
'venue' => [
    'name' => [ 'defaultValue' => ['value' => $order['event_venue']] ],
    'address' => [ 'defaultValue' => ['value' => $venue_address] ]
],

Then the issue is **most likely that the event ticket object is not overriding the values defined in the class**.

### βœ… Explanation: Why This Happens

Google Wallet objects inherit values from their **class**. But:

> πŸ’‘ **Once an object is created**, if you don’t explicitly override a field (e.g., `venue.name`) or if the override is ignored due to formatting, the pass will show the default class value (`event_venue1`, `event_venue2` in your case).

### βœ… Fix Checklist

#### βœ… 1. Ensure your object override is complete
You're using this:

'venue' => [
    'name' => [
        'defaultValue' => [
            'language' => 'en-US',
            'value' => $order['event_venue']
        ]
    ],
    'address' => [
        'defaultValue' => [
            'language' => 'en-US',
            'value' => $venue_address
        ]
    ]
],

This is **correct**.

#### βœ… 2. Make sure you're not just **reusing an old object ID**
If the object already exists and you're **not updating** it, the API will silently keep showing the old data.

πŸ‘‰ **Solution**: Use a new object ID each time or explicitly call the `PATCH` endpoint to update the existing object.

### βœ… How to Test It Fresh

$passObject = [
  'id' => "$issuerId.$objectId", // must be unique!
  ...
];

Generate a **new `$objectId`** for each user or order like:

$objectId = 'eventTicketObject_' . $order['order_code']; // ensure uniqueness

### βœ… 3. Double-check Class Defaults

In your **event ticket class**, if you had set:

"venue": {
  "name": {
    "defaultValue": {
      "value": "event_venue1"
    }
  },
  "address": {
    "defaultValue": {
      "value": "event_venue2"
    }
  }
}

These values will show unless you **override them** at the object level AND that object is new or updated.

### βœ… 4. Final Debug Tip

Use `GET` on your object to inspect it:

GET https://walletobjects.googleapis.com/walletobjects/v1/eventTicketObject/{objectId}

See if it contains your dynamic values or still has `event_venue1`.

### βœ… Summary

| Step | Action |
|——|——–|
| βœ… | Make sure you're using a new `objectId` each time |
| βœ… | Confirm you're passing `venue.name` and `venue.address` with correct structure |
| βœ… | Delete or update the old object if you're reusing `id` |
| βœ… | Use the API `GET` to confirm what the object really contains |

If you want, share your full object ID or JWT payload structure (without credentials), and I’ll tell you exactly where it’s going wrong.

User
'venue' => [
'name' => [
'defaultValue' => [
'language' => 'en-US',
'value' => $order['event_venue']
]
],
'address' => [
'defaultValue' => [
'language' => 'en-US',
'value' => $venue_address
]
]
],
check above correct?
Assistant
Yes βœ… β€” your `venue` block is **structurally correct** and adheres to the [Google Wallet API's `EventTicketObject`](https://developers.google.com/wallet/tickets/events/reference/rest/v1/eventTicketObject) format.

Here’s a breakdown of your structure:

'venue' => [
    'name' => [
        'defaultValue' => [
            'language' => 'en-US',
            'value' => $order['event_venue'] // e.g., "Manchester Arena"
        ]
    ],
    'address' => [
        'defaultValue' => [
            'language' => 'en-US',
            'value' => $venue_address // e.g., "123 Main Street, Manchester"
        ]
    ]
],

This is **100% valid** and should work.

### βœ… What to Double-Check If It's Still Showing `event_venue1`:

1. **Is `$order['event_venue']` and `$venue_address` populated correctly?**
Try logging or dumping the values before passing them in:

var_dump($order['event_venue'], $venue_address);

2. **Are you creating a new `objectId` every time?**
If not, and the object already exists, the new data might not apply unless you:
– `PATCH` the object via API
– or delete and recreate the object

3. **Is the object created using your custom `$passObject`?**
If you're generating a JWT, inspect the payload using [https://jwt.io](https://jwt.io) to make sure the `venue` block is included and matches your data.

4. **Check with a fresh Wallet link** β€” not cached or already saved.

### βœ… Test With Static Value (Optional)
Try hardcoding temporarily:

'value' => 'Test Venue Name'

If this works but your dynamic one doesn’t, then `$order['event_venue']` is empty or wrong.

Would you like me to review your JWT payload or full object generation logic to confirm it's properly injected?

User
Event Ticket Data section name and venue still not updated when I pass it to object
Assistant
Thanks for confirming β€” if the **Event Ticket Data section (name and venue)** still shows the **default class values** like `event_venue1` and `event_venue2` even after passing them dynamically in the object, here's a clear checklist and fix path:

### πŸ” Root Cause

Even though you correctly passed:

'venue' => [
    'name' => [ 'defaultValue' => [ 'language' => 'en-US', 'value' => $order['event_venue'] ] ],
    'address' => [ 'defaultValue' => [ 'language' => 'en-US', 'value' => $venue_address ] ]
],

The **Google Wallet UI sometimes continues to show values from the class** unless:

1. The **object is freshly created**.
2. The **JWT includes the updated fields and is properly encoded**.
3. The fields in the **object match exactly the schema** and are not being ignored due to format mismatch or silent error.

### βœ… Immediate Fix Path

#### βœ… 1. Hardcode the values for testing
Replace dynamic values temporarily:

'venue' => [
    'name' => [
        'defaultValue' => [
            'language' => 'en-US',
            'value' => 'Fossetts Arena'
        ]
    ],
    'address' => [
        'defaultValue' => [
            'language' => 'en-US',
            'value' => '123 Main Street, Brighton, UK'
        ]
    ]
],

**β†’ If this works:** The issue is in your `$order['event_venue']` or `$venue_address` values.

#### βœ… 2. Generate a new object ID
Google Wallet **caches object data**. If you're using the same `id` (`issuerId.objectId`), it may not update values.

Update this:

'id' => "$issuerId.eventObject_" . uniqid(),

#### βœ… 3. Use the Google API `GET` to verify the object
Call:

GET https://walletobjects.googleapis.com/walletobjects/v1/eventTicketObject/{your-object-id}

Check if the returned JSON includes:

"venue": {
  "name": {
    "defaultValue": {
      "value": "Fossetts Arena"
    }
  },
  "address": {
    "defaultValue": {
      "value": "123 Main Street, Brighton, UK"
    }
  }
}

If not β†’ your object is not being created or updated properly.

#### βœ… 4. Confirm if you're using JWT
If you're using a JWT to create the pass, **inspect the payload** at https://jwt.io and confirm that it contains:

"eventTicketObjects": [
  {
    "venue": {
      "name": {
        "defaultValue": {
          "value": "Fossetts Arena"
        }
      }
    }
  }
]

### πŸ§ͺ Optional: Full Test Payload

Use this as your object payload to test:

$passObject = [
    'id' => "$issuerId.eventObject_" . uniqid(),
    'classId' => $fullClassId,
    'state' => 'active',
    'eventName' => [
        'defaultValue' => [
            'language' => 'en-US',
            'value' => 'Fossetts Circus Evening Show'
        ]
    ],
    'venue' => [
        'name' => [
            'defaultValue' => [
                'language' => 'en-US',
                'value' => 'Fossetts Arena'
            ]
        ],
        'address' => [
            'defaultValue' => [
                'language' => 'en-US',
                'value' => '123 Main Street, Brighton, UK'
            ]
        ]
    ],
    ...
];

### βœ… Summary

| Step | Action |
|——|——–|
| βœ… | Hardcode test values to verify it’s not data issue |
| βœ… | Use a new object ID every time (`uniqid()`) |
| βœ… | Confirm via `GET` API or JWT payload that `venue.name` is included |
| βœ… | Regenerate wallet link after every change |

If you're still stuck, feel free to paste:
– Your JWT payload (sanitized)
– Or share the raw response from the `GET` object endpoint

I'll pinpoint the exact problem for you.

User
How to check OOgle api get
Assistant
To **check the Google Wallet API `GET` response** for your Event Ticket Object, follow the steps below. This helps confirm what’s *actually* stored in the object (especially `eventName`, `venue.name`, etc.).

### βœ… Step-by-Step: How to Check Your Object via Google Wallet API

### πŸ” 1. Get OAuth 2.0 Access Token

You need an access token authorized for the Google Wallet API.

#### a. Set up OAuth 2.0 credentials (only once)
– Go to [Google Cloud Console](https://console.cloud.google.com/)
– Enable the **Google Wallet API**
– Create a **Service Account**
– Download the JSON key

#### b. Use this command to get a token:

gcloud auth activate-service-account --key-file=PATH_TO_YOUR_KEY.json
gcloud auth print-access-token

If you don’t use `gcloud`, use this PHP snippet:

$client = new Google_Client();
$client->setAuthConfig('path-to-key.json');
$client->addScope('https://www.googleapis.com/auth/wallet_object.issuer');
$accessToken = $client->fetchAccessTokenWithAssertion()['access_token'];

### πŸ§ͺ 2. Use cURL or Postman to Call the `GET` API

Once you have the access token and the object ID, use this:

curl -X GET 
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" 
  "https://walletobjects.googleapis.com/walletobjects/v1/eventTicketObject/ISSUER_ID.OBJECT_ID"

πŸ” Replace:
– `YOUR_ACCESS_TOKEN` β†’ from step 1
– `ISSUER_ID.OBJECT_ID` β†’ e.g., `issuerId.eventObject_abc123`

### βœ… 3. What to Look For

In the JSON response, verify:

"eventName": {
  "defaultValue": {
    "value": "Fossetts Circus Evening Show"
  }
},
"venue": {
  "name": {
    "defaultValue": {
      "value": "Fossetts Arena"
    }
  },
  "address": {
    "defaultValue": {
      "value": "123 Main Street, Brighton, UK"
    }
  }
}

If it still shows `"event_venue1"`, the object was never updated correctly.

### 🧼 4. Optional: Delete Old Object (if needed)

You can’t truly delete an object, but you can **generate a new one** with a unique ID each time:

$objectId = 'eventObject_' . uniqid(); // New for each user/order

### Need Help?

If you share:
– your issuer ID format
– how you're creating the JWT or inserting the object

I can give you a command or test script tailored to your setup.

Leave a Comment

Your email address will not be published. Required fields are marked *