הלקוח — חברה עם 100+ עובדים, שתי כניסות, שלוש רמות גישה. כרטיסי נייר אבדו וזויפו; ביקורת הראתה כי ל-30% מהעובדים הייתה גישה לאזורי השרתים. האתגר המרכזי היה אינטגרציה עם מערכת בקרת הגישה הקיימת (ACS) ויצירת אובייקטי כרטיס העומדים בדרישות האבטחה. פתרנו זאת ביומיים: הקמנו שרשרת מ-Active Directory ל-Google Wallet באמצעות JWT ו-REST API. יישמנו קוד QR בטלפון, התראה אוטומטית על פקיעת תוקף, וניהול מרכזי דרך API. לאחר הפיילוט, הלקוח הפחית את עלויות ההדפסה ב-80% והגדיל את האבטחה. כעת הכרטיסים מתעדכנים תוך שניות — פשוט משנים את הסטטוס ב-AD. הכרטיס עובד במצב לא מקוון — לאחר השמירה, הנתונים זמינים ללא אינטרנט. צרו קשר להערכת הפרויקט שלכם — ניתן הערכה ראשונית תוך יום.
אילו בעיות אנו פותרים
ניהול תקופות תוקף של כרטיסים
ב-Google Wallet, לכל כרטיס יש validTimeInterval. אנו מגדירים תאריכי התחלה וסיום, ו-Wallet מודיע למשתמש 3 ימים לפני פקיעת התוקף. אין צורך בלוגיקת שרת — הכל נמצא באובייקט.
העברת כרטיסים בין מכשירים
המגבלה של ONE_USER_ONE_DEVICE מונעת העתקת הכרטיס למכשירים אחרים. המשתמש אינו יכול לשתף את הכרטיס עם עמית — האבטחה גבוהה.
אינטגרציה עם מערכות בקרת גישה
אנו מחברים את Google Wallet ל-Active Directory או ל-1C. כאשר רמת הגישה משתנה, כותרת הכרטיס מתעדכנת אוטומטית באמצעות בקשת PATCH. זמן תגובה — דקות.
כרטיס לא מקוון
לאחר השמירה, הכרטיס זמין במלואו במצב לא מקוון: תמונות, טקסט, ברקוד. לפי התיעוד הרשמי של Google Wallet API, שמירה מקומית במטמון מבטיחה פעולה לא מקוונת. התראות על פקיעת תוקף דורשות חיבוריות, אך הכרטיס עצמו נפתח ללא רשת.
איך אנו עושים זאת
טכנולוגיות
- Google Wallet API (GenericObject, GenericClass)
- אסימוני JWT להעברת נתונים ל-Wallet
- חשבון שירות עם הרשאות מנפיק
- Android: Wallet SDK, Kotlin + Coroutines
- שרת: Python (Flask/FastAPI) או Kotlin/Java
פרמטרים מרכזיים של GenericObject
| שדה | תיאור | דוגמה |
|---|---|---|
classId |
הפניה למחלקת הכרטיס | issuerId.classSuffix |
id |
מזהה אובייקט ייחודי | issuerId.objectSuffix |
validTimeInterval |
תקופת תוקף | {"start":"2025-01-01T00:00Z","end":"2025-12-31T23:59Z"} |
barcode |
ברקוד לסריקה | {"type":"QR_CODE","value":"user123"} |
state |
סטטוס הכרטיס | ACTIVE / EXPIRED |
notifications |
הגדרות התראות | {"expiryNotification":{"enableNotification":true}} |
יצירת מחלקה
יש ליצור את המחלקה פעם אחת דרך REST API. JWT יוצר רק את האובייקט, לא את המחלקה. דוגמה:
def create_generic_class(class_suffix: str) -> dict:
issuer_id = "YOUR_ISSUER_ID"
return {
"id": f"{issuer_id}.{class_suffix}",
"issuerName": "Your Company",
"reviewStatus": "UNDER_REVIEW",
"enableSmartTap": False,
"multipleDevicesAndHoldersAllowedStatus": "ONE_USER_ONE_DEVICE"
} יצירת JWT
JWT מכיל payload עם אובייקט הכרטיס. אנו חותמים עליו עם חשבון השירות. אפליקציית Android קוראת ל-Wallet API עם האסימון הזה.
הוספת כרטיס למכשיר
class PassActivity : AppCompatActivity() {
private val walletClient by lazy {
Wallet.getWalletClient(
this,
WalletOptions.Builder()
.setEnvironment(WalletConstants.ENVIRONMENT_PRODUCTION)
.build()
)
}
private val savePassLauncher = registerForActivityResult(
ActivityResultContracts.StartIntentSenderForResult()
) { result ->
when (result.resultCode) {
RESULT_OK -> {
analytics.track("wallet_pass_added")
binding.addToWalletBtn.text = "Уже в Wallet"
binding.addToWalletBtn.isEnabled = false
}
RESULT_CANCELED -> Unit
}
}
fun onAddToWalletClicked() {
viewModel.generatePassJwt().observe(this) { jwt ->
walletClient.savePassesViaIntent(
SavePassesRequest.newBuilder()
.setJwt(jwt)
.build()
) { result ->
result.intentSender?.let {
savePassLauncher.launch(IntentSenderRequest.Builder(it).build())
} ?: run {
binding.addToWalletBtn.isEnabled = false
}
}
}
}
} תהליך העבודה
- ניתוח דרישות: אילו נתונים להציג, מה רמת הגישה, האם יש צורך בקוד QR.
- עיצוב: יצירת המחלקה ותבנית האובייקט.
- יישום: יצירת JWT בצד השרת, אינטגרציה לאפליקציה הניידת.
- בדיקות: אימות במכשירים אמיתיים, בדיקת התראות.
- פריסה: פרסום עדכון אפליקציה, ניטור.
| שלב | משך |
|---|---|
| ניתוח דרישות | 0.5 יום |
| יצירת מחלקה ואובייקט | יום אחד |
| יצירת JWT | 0.5 יום |
| אינטגרציה לאפליקציה | 1–2 ימים |
| בדיקות | 0.5 יום |
| תיעוד והדרכה | 0.5 יום |
לוחות זמנים ועלות
לוחות הזמנים תלויים במורכבות:
- כרטיס בסיסי עם קוד QR והתראות — החל מ-3 ימים.
- אינטגרציה עם מערכות חיצוניות (AD, 1C) — החל מ-5 ימים.
- מחזור מלא עם הדרכה ותיעוד — עד 8 ימים.
העלות מחושבת באופן אישי. צרו קשר להערכת הפרויקט שלכם.
מה כלול
- ניתוח דרישות ועיצוב תכנית הכרטיס
- יצירת מחלקה ואובייקט ב-Google Wallet
- יצירת JWT בצד השרת
- אינטגרציה לאפליקציית Android (Kotlin/Java)
- הגדרת התראות על פקיעת תוקף
- תיעוד והדרכת צוות
- שבועיים של תמיכה לאחר המסירה
טעויות נפוצות
- שכחת יצירת המחלקה דרך API לפני ה-JWT הראשון — האובייקט לא יישמר.
- אי הגדרת
def create_generic_class(class_suffix: str) -> dict: issuer_id = "YOUR_ISSUER_ID" return { "id": f"{issuer_id}.{class_suffix}", "issuerName": "Your Company", "reviewStatus": "UNDER_REVIEW", "enableSmartTap": False, "multipleDevicesAndHoldersAllowedStatus": "ONE_USER_ONE_DEVICE" }כאשר משתמשים בקוראי NFC — הכרטיס לא יעבוד. - שימוש ב-MANY_DEVICES במקום ONE_USER_ONE_DEVICE — סיכון לדליפת כרטיס.
למה נחוץ class PassActivity : AppCompatActivity() { private val walletClient by lazy { Wallet.getWalletClient(this, WalletOptions.Builder() .setEnvironment(WalletConstants.ENVIRONMENT_PRODUCTION) .build()) } private val savePassLauncher = registerForActivityResult( ActivityResultContracts.StartIntentSenderForResult() ) { result -> when (result.resultCode) { RESULT_OK -> { analytics.track("wallet_pass_added") binding.addToWalletBtn.text = "Уже в Wallet" binding.addToWalletBtn.isEnabled = false } RESULT_CANCELED -> Unit } } fun onAddToWalletClicked() { viewModel.generatePassJwt().observe(this) { jwt -> walletClient.savePassesViaIntent( SavePassesRequest.newBuilder().setJwt(jwt).build() ) { result -> result.intentSender?.let { savePassLauncher.launch(IntentSenderRequest.Builder(it).build()) } ?: run { binding.addToWalletBtn.isEnabled = false } } } } } ?
enableSmartTap מאפשר אינטראקציית NFC. אם לכניסות יש קוראי NFC, ללא הגדרה זו הכרטיס לא יעבוד. ברירת המחדל היא False, לכן יש להפעיל זאת במפורש.
למה חשובה מגבלת enableSmartTap?
ללא זה, ניתן לשמור את הכרטיס במספר מכשירים של אותו חשבון. עבור כרטיסים ארגוניים, זו הפרת אבטחה. הפתרון שלנו משתמש ב-enableSmartTap: True.
אסימוני JWT מהירים פי 6 מקריאות REST ישירות: יצירה בצד השרת אורכת <1 אלפית שנייה, ומחזור הוספת הכרטיס המלא אורך פחות משנייה במכשיר.
המהנדסים שלנו מוסמכים על ידי Google ובעלי ניסיון של 5+ שנים בפיתוח מובייל. אנו מבטיחים אינטגרציה יציבה. קבעו פגישת ייעוץ — נבדוק את הפרויקט שלכם תוך יום אחד.
לעיון נוסף: Google Wallet API







