Adding Tickets to Google Wallet from an Android App
Picture this: a concert attendee approaches the entrance, pulls out their phone, and the lock screen already displays the QR code for their ticket. No PDF attachments, emails, or queues. One of our clients — a music festival organizer — faced a problem: 20% of visitors couldn't find their tickets in email or messengers. After implementing Google Wallet, support requests dropped by 40%. We'll help you integrate this into your mobile app: the server generates a JWT, the app saves the ticket to the wallet, and the status updates in real time. With over five years of experience with payment services, we guarantee quality.
How Google Wallet Works for Tickets
Google Wallet uses two objects: EventTicketClass (event template) and EventTicketObject (specific ticket). The server creates a JWT token with ticket data, signed by a Google service account. The app passes this token to the Wallet API, and the user sees a "Add to Google Wallet" button. After saving, the ticket appears in the wallet even offline.
Why Google Wallet Is More Reliable Than PDF Tickets
PDF tickets are easy to lose, forge, or forget. Google Wallet stores tickets in a secure vault accessible without internet. You can update the status in real time: mark a ticket as used upon entry or change the seat. This boosts security and convenience — users don't search through spam folders. According to Google Wallet API documentation, all data is transmitted over an encrypted channel.
How to Add a Ticket to Google Wallet: Step-by-Step
- Server setup. Create a service account in Google Cloud Console with the
Wallet Object Issuerrole. Get your Issuer ID from Google Pay & Wallet Console. - JWT generation. The server creates a JWT token with ticket data, signed with the private key. The token is valid for one hour.
- Pass the token to the app. The app receives the JWT via API or in the purchase response.
- Check Wallet availability. Use
PayApiAvailabilityStatusto determine if Google Wallet is installed on the device. - Show the button. If the wallet is available, display the official "Add to Google Wallet" button.
- Save the ticket. On tap, call
savePassesViaIntentwith the JWT. The user confirms — the ticket appears in the wallet.
Example JWT Generation in Python
import jwt
from google.oauth2 import service_account
import json
def create_event_ticket_jwt(event_id: str, ticket_id: str, holder_name: str, seat: str) -> str:
credentials = service_account.Credentials.from_service_account_file(
'service-account.json',
scopes=['https://www.googleapis.com/auth/wallet_object.issuer']
)
issuer_id = "YOUR_ISSUER_ID" # from Google Pay & Wallet Console
class_suffix = f"event_{event_id}"
object_suffix = f"ticket_{ticket_id}"
ticket_object = {
"id": f"{issuer_id}.{object_suffix}",
"classId": f"{issuer_id}.{class_suffix}",
"state": "ACTIVE",
"barcode": {
"type": "QR_CODE",
"value": ticket_id,
"alternateText": ticket_id[:8]
},
"ticketHolderName": holder_name,
"seatInfo": {
"seat": {"defaultValue": {"language": "ru", "value": seat}},
"row": {"defaultValue": {"language": "ru", "value": "A"}},
},
"reservationInfo": {
"confirmationCode": ticket_id[:8].upper()
},
"heroImage": {
"sourceUri": {"uri": "https://yourapp.com/event-banner.jpg"}
}
}
payload = {
"iss": credentials.service_account_email,
"aud": "google",
"typ": "savetowallet",
"iat": int(time.time()),
"origins": ["https://yourapp.com"],
"payload": {
"eventTicketObjects": [ticket_object]
}
}
token = jwt.encode(payload, credentials._private_key_pkcs8_pem, algorithm="RS256")
return token
The JWT token is valid for one hour and is passed to the app as a string.
Android (Kotlin) Code
// build.gradle
implementation("com.google.android.gms:play-services-wallet:19.3.0")
class TicketActivity : AppCompatActivity() {
private val walletClient by lazy {
Wallet.getWalletClient(
this,
WalletOptions.Builder()
.setEnvironment(WalletConstants.ENVIRONMENT_PRODUCTION)
.build()
)
}
private val addToWalletLauncher = registerForActivityResult(
ActivityResultContracts.StartIntentSenderForResult()
) { result ->
when (result.resultCode) {
RESULT_OK -> showSuccess()
RESULT_CANCELED -> { /* user cancelled */ }
else -> showError()
}
}
fun addTicketToWallet(jwt: String) {
val request = SavePassesRequest.newBuilder()
.setJwt(jwt)
.build()
walletClient.savePassesViaIntent(request) { apiResult ->
apiResult.intentSender?.let { intentSender ->
addToWalletLauncher.launch(
IntentSenderRequest.Builder(intentSender).build()
)
}
}
}
}
Use the official component per Google guidelines:
<com.google.android.gms.wallet.button.PayButton
android:id="@+id/addToWalletButton"
android:layout_width="match_parent"
android:layout_height="48dp"
app:allowedAuthMethods="PAN_ONLY|CRYPTOGRAM_3DS"
app:buttonType="addToGoogleWallet" />
Before showing the button, check Wallet availability:
walletClient.getPayApiAvailabilityStatus(
PayApiAvailabilityStatusRequest.newBuilder()
.setRequestType(PayApiAvailabilityStatusRequest.RequestType.SAVE_PASSES)
.build()
).addOnSuccessListener { status ->
if (status.isAvailable) {
addToWalletButton.isVisible = true
}
}
What Is Needed to Start Integration?
To get started, you'll need:
- Access to Google Cloud Console to create a service account.
- Issuer ID from Google Pay & Wallet Console.
- A server to generate JWT (one endpoint is enough).
- A mobile app with the ability to add a button.
More about service account setup
The service account is created in the IAM section of Google Cloud Console. Assign it the `Wallet Object Issuer` role. After creation, download the JSON key, which is used on the server to sign JWTs. Ensure the key is stored securely and not committed to repositories.Updating a Ticket After Issuance
If you need to change the QR code or status (e.g., to "used"), send a PATCH request:
from googleapiclient.discovery import build
service = build('walletobjects', 'v1', credentials=credentials)
service.eventticketobject().patch(
resourceId=f"{issuer_id}.{object_suffix}",
body={"state": "COMPLETED"} # ticket used
).execute()
Changes apply in real time on all user devices.
Comparison: Google Wallet vs. PDF Tickets
| Feature | Google Wallet | PDF Ticket |
|---|---|---|
| Offline availability | Yes | No (file needed) |
| Status updates | Real time | Impossible |
| Tamper protection | Cryptographic signature | Easy to forge |
| User convenience | Automatically on phone | Must search in email |
| Push notification integration | Yes | No |
Comparison: EventTicketClass vs. EventTicketObject
| Entity | Purpose | Example |
|---|---|---|
EventTicketClass |
Event template: name, logo, color, location | Concert "Rock Festival" |
EventTicketObject |
Individual ticket: seat, holder name, QR code | Ticket #1234, Row 5, Seat 10 |
Timeline and Cost
Estimated time: 2–3 days. Exact cost is determined after auditing your project. We'll assess your project within a day after you contact us. Get in touch for a consultation.
Conclusion
Google Wallet integration is not only about user convenience but also an additional communication channel: you can update tickets, change seats, or revoke them entirely. Our experience guarantees fast and high-quality implementation. If you want to improve user experience and boost security — contact us. We'll audit your project and propose the best solution. Order Google Wallet integration today.







