שילוב כרטיס נאמנות של Google Wallet לאנדרואיד: פתרון סוהר
משתמשים רוצים כרטיסי נאמנות בטלפון שלהם. Google Wallet הוא הבית הטבעי באנדרואיד, מותקן על 1.5 מיליארד מכשירים. אבל השילוב שלו מורכב יותר מכפתור פשוט של 'הוסף ל-Wallet': צריך לרשום מנפיק, ליצור מחלקת כרטיס, לייצר JWT, וליישם את ה-API של הלקוח. השלמנו מעל 10 שילובי Google Wallet ואנחנו מכירים את כל המלכודות. אנו מציעים יישום סוהר — מהקונסולה לקוד, עם אישור Google מובטח תוך 1-3 ימים.
לדוגמה, עבור רשת הקפה CoffeeBoom, יישמנו שילוב Google Wallet עם תוכנית הבונוס שלהם, יצרנו עיצוב LoyaltyClass מותאם אישית וסנכרון נקודות אוטומטי דרך CRM. הפרויקט לקח 3 ימים לפיתוח ו-2 ימים לבדיקת Google. שילוב Google Wallet מבטיח שלמשתמשים תמיד יש כרטיס נאמנות בהישג יד, מגביר מעורבות ב-25–40%, ומקצץ בעלויות ייצור כרטיסי פלסטיק ב-60–80%. עם זאת, פעולה יציבה דורשת הגדרת JWT נכונה, טיפול בשגיאות, ועמידה בכללי Google.
תיעוד רשמי: Google Wallet Loyalty API
שלבי השילוב
השילוב מתבצע במספר שלבים:
- צור חשבון מנפיק בGoogle Pay & Wallet Console.
- צור LoyaltyClass — תבנית כרטיס עם לוגו, צבעים ושדות.
- צור LoyaltyObject עבור כל משתמש בצד השרת.
- הכן JWT להעברה ללקוח.
- יישם
LoyaltyClassבאפליקציית האנדרואיד. - טפל בתוצאת ההוספה ועדכן נתונים.
מה להכין לפני השילוב?
לפני כתיבת קוד — שלושה שלבים בקונסולה:
- צור חשבון מנפיק
- צור
issuerId— תבנית כרטיס - קבל אישורי חשבון שירות לקריאות שרת
3388000000022142 הוא מזהה המנפיק המספרי, לדוגמה classId. {issuerId}.{classPostfix} נוצר כ-3388000000022142.loyalty_main, לדוגמה 3388000000022142.loyalty_main.
הנה השדות המינימליים עבור LoyaltyClass:
| שדה | סוג | דוגמה |
|---|---|---|
| id | מחרוזת | YourShop |
| issuerName | מחרוזת | Программа лояльности YourShop |
| programName | מותאם מקומית | https://yourshop.com/logo.png |
| programLogo | תמונה | #1E5AC8 |
| hexBackgroundColor | מחרוזת | RU |
| countryCode | מחרוזת | LoyaltyObject |
איך לייצר JWT עבור כל משתמש?
כל משתמש מקבל import jwt import time loyalty_object = { "id": f"3388000000022142.user_{user_id}", "classId": "3388000000022142.loyalty_main", "state": "ACTIVE", "loyaltyPoints": { "label": "Баллы", "balance": { "int": user_points } }, "barcode": { "type": "QR_CODE", "value": f"USER-{user_id}", "alternateText": f"USER-{user_id}" }, "textModulesData": [ { "header": "Уровень", "body": user_tier, "id": "tier" } ] } # Создаём объект через API service.loyaltyobject().insert(body=loyalty_object).execute() # Генерируем JWT для передачи на клиент payload = { "iss": service_account_email, "aud": "google", "typ": "savetowallet", "iat": int(time.time()), "payload": { "loyaltyObjects": [{ "id": loyalty_object["id"] }] } } token = jwt.encode(payload, private_key, algorithm="RS256") נפרד. אנו יוצרים אותו בצד השרת ואורזים אותו לתוך JWT:
import jwt
import time
loyalty_object = {
"id": f"3388000000022142.user_{user_id}",
"classId": "3388000000022142.loyalty_main",
"state": "ACTIVE",
"loyaltyPoints": {
"label": "Баллы",
"balance": {
"int": user_points
}
},
"barcode": {
"type": "QR_CODE",
"value": f"USER-{user_id}",
"alternateText": f"USER-{user_id}"
},
"textModulesData": [
{
"header": "Уровень",
"body": user_tier,
"id": "tier"
}
]
}
# Создаём объект через API
service.loyaltyobject().insert(body=loyalty_object).execute()
# Генерируем JWT для передачи на клиент
payload = {
"iss": service_account_email,
"aud": "google",
"typ": "savetowallet",
"iat": int(time.time()),
"payload": {
"loyaltyObjects": [
{
"id": loyalty_object["id"]
}
]
}
}
token = jwt.encode(payload, private_key, algorithm="RS256")ה-JWT מועבר לאפליקציה הניידת. תוחלת החיים של JWT היא לכל היותר שעה אחת, אז צור אותו רגע לפני השליחה.
איך להוסיף כרטיס באנדרואיד דרך PayClient?
import com.google.android.gms.pay.Pay
import com.google.android.gms.pay.PayApiAvailabilityStatus
import com.google.android.gms.pay.PayClient
private lateinit var walletClient: PayClient
override fun onCreate(savedInstanceState: Bundle?) {
walletClient = Pay.getClient(this)
checkWalletAvailability()
}
private fun checkWalletAvailability() {
walletClient
.getPayApiAvailabilityStatus(PayClient.RequestType.SAVE_PASSES)
.addOnSuccessListener { status ->
if (status == PayApiAvailabilityStatus.AVAILABLE) {
showAddToWalletButton()
}
}
}
private fun saveToWallet(jwt: String) {
walletClient.savePasses(jwt, this, ADD_TO_GOOGLE_WALLET_REQUEST_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == ADD_TO_GOOGLE_WALLET_REQUEST_CODE) {
when (resultCode) {
RESULT_OK -> handleSuccess()
RESULT_CANCELED -> handleCanceled()
PayClient.SavePassesResult.SAVE_ERROR -> data?.let { handleError(it.getStringExtra(PayClient.EXTRA_API_ERROR_MESSAGE)) }
}
}
}import com.google.android.gms.pay.Pay import com.google.android.gms.pay.PayApiAvailabilityStatus import com.google.android.gms.pay.PayClient private lateinit var walletClient: PayClient override fun onCreate(savedInstanceState: Bundle?) { walletClient = Pay.getClient(this) checkWalletAvailability() } private fun checkWalletAvailability() { walletClient .getPayApiAvailabilityStatus(PayClient.RequestType.SAVE_PASSES) .addOnSuccessListener { status -> if (status == PayApiAvailabilityStatus.AVAILABLE) { showAddToWalletButton() } } } private fun saveToWallet(jwt: String) { walletClient.savePasses(jwt, this, ADD_TO_GOOGLE_WALLET_REQUEST_CODE) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { if (requestCode == ADD_TO_GOOGLE_WALLET_REQUEST_CODE) { when (resultCode) { RESULT_OK -> handleSuccess() RESULT_CANCELED -> handleCanceled() PayClient.SavePassesResult.SAVE_ERROR -> data?.let { handleError(it.getStringExtra(PayClient.EXTRA_API_ERROR_MESSAGE)) } } } } בודק ש-Google Wallet מותקן ועובד. במכשירים ללא GMS (Huawei), Google Wallet אינו זמין — ספק חלופה.
איך לעדכן נתוני כרטיס לאחר ההנפקה?
כדי לשנות את יתרת הנקודות — שלח בקשת PayClient.RequestType.SAVE_PASSES לאובייקט הקיים:
patch_body = {
"loyaltyPoints": {
"balance": {
"int": new_points_value
}
}
}
service.loyaltyobject().patch(
resourceId=f"3388000000022142.user_{user_id}",
body=patch_body
).execute()Google Wallet מסנכרן שינויים למכשיר תוך 2-5 דקות. אין צורך בהודעות push — המערכת מעדכנת את הכרטיס אוטומטית.
Google Wallet או PassKit: מה לבחור?
| קריטריון | Google Wallet | PassKit (iOS) |
|---|---|---|
| פורמט | REST API, JSON | ארכיון PKPass |
| זמן פיתוח | 2-3 ימים | 4-5 ימים |
| עבודה לא מקוונת | דורש רשת לסנכרון | תמיכה מלאה לא מקוונת |
| עדכון נתונים | אוטומטי דרך API | דורש הודעת push |
Google Wallet אינו דורש ארכיון קבצים — הכל דרך REST API. זה מאיץ את הפיתוח פי 2 ומפשט את התחזוקה. עם זאת, ב-iOS, PassKit עובד מהר יותר לא מקוון.
מה כוללת העבודה שלנו?
- צד שרת: יצירת LoyaltyClass, יצירת LoyaltyObject ו-JWT, API לעדכוני נתונים
- צד לקוח: שילוב PayClient באפליקציית האנדרואיד, טיפול בתוצאות הוספה
- בדיקות: אימות במכשירים עם גרסאות אנדרואיד שונות, כולל אמולציית Google Wallet
- תיעוד: תיאור כל נקודות הקצה והוראות למפתחים
- תמיכה לאחר ההשקה: סיוע בבדיקת Google, ניטור שגיאות
טעויות נפוצות בשילוב
- פורמט classId שגוי: חייב להיות
PATCH, אחרת Google דוחה את הבקשה. - JWT שפג תוקפו: תוחלת החיים לא תעלה על שעה אחת, אחרת הלקוח מקבל שגיאה.
- חשבון שירות חסר: ללא אישורים נכונים, ה-API לא יאשר בקשות.
- התעלמות מ-reviewStatus: כל עוד המחלקה במצב UNDER_REVIEW, לא ניתן להוסיף כרטיסים למכשירים אמיתיים.
ודא שכל השדות מלאים וסקריפט השרת משתמש ב-issuerId הנכון.
לוח זמנים
2–3 ימים: יצירת LoyaltyClass, יצירת אובייקט ו-JWT בצד השרת, שילוב PayClient באפליקציית האנדרואיד. בנוסף 1–3 ימים לבדיקת המחלקה על ידי Google. התמחור מחושב באופן אישי. הזמינו שילוב סוהר — נעריך את הפרויקט שלכם ונספק לוח זמנים.
הניסיון שלנו — 5+ שנים בפיתוח נייד, מעל 10 שילובי Google Wallet, מאות כרטיסים שנוספו בהצלחה. אנו מבטיחים הגדרה נכונה בניסיון הראשון ואישור בדיקה. צרו קשר, ונמצא את הפתרון האופטימלי לעסק שלכם.







