לפי מדריך המפתחים של Apple Wallet, קובץ ה-.pkpass חייב לכלול מניפסט וחתימה. פיתחת כרטיס נאמנות, אבל משתמשים מתלוננים שכשהם מנסים להוסיף אותו ל-Apple Wallet, הם מקבלים את השגיאה 'Invalid pass'. לרוב, הסיבה היא מבנה .pkpass שגוי: אי-התאמה ב-hash ב-manifest.json או תעודה שלא מקושרת ל-passTypeIdentifier. בואו נחקור כיצד להימנע מבעיות אלו ולהקים אינטגרציה סוהר. הניסיון שלנו: 5 שנים עם Apple Wallet ויותר מ-20 פרויקטים מוצלחים. במקרה אחד לאחרונה, הלקוח חסך שעתיים על כל בניית pass לאחר אוטומציה של החתימה, ושיעור השגיאות ירד ב-95%. האינטגרציה הסוהר שלנו עולה $1,500, וחוסכת לכם 40% בהשוואה לפיתוח פנימי.
PassKit הוא הפריימוורק שמנהל קבצי .pkpass במכשיר. כרטיס נאמנות של Apple Wallet הוא ארכיון JSON חתום עם תמונות, מטא-דאטה, ונתוני NFC אופציונליים. נקודת הכניסה הראשית בקוד היא PKAddPassesViewController. ללא ארכיון מעוצב וחתום כראוי, המשתמש מקבל את השגיאה 'Invalid pass' כשמנסים להוסיף את הכרטיס.
למה מתרחשת שגיאת 'Invalid pass'?
הסיבה הנפוצה ביותר היא אי-התאמה ב-hash ב-manifest.json. Apple Wallet בודק את ה-SHA1 של כל קובץ מול הרשומה במניפסט. אם אפילו בייט אחד שונה, החתימה נחשבת לא חוקית. ב-80% מהמקרים, הבעיה נפתרת על ידי יצירת מניפסט מחדש לאחר כל שינוי ב-pass.json. טעות נפוצה נוספת היא שרשרת תעודות שגויה: ה-Pass Type ID חייב להיות חתום על ידי WWDR Intermediate, אחרת חתימת PKCS#7 נכשלת באימות. הניסיון שלנו מראה ש-99% מהכרטיסים מתקבלים בניסיון הראשון כשעוקבים אחרי השיטות המומלצות.
מבנה של .pkpass וחתימה
הארכיון מכיל:
-
pass.json— סוג, צבעים, שדות כרטיס -
icon.png,logo.png,strip.png— משאבים גרפיים (נדרשת רזולוציה כפולה @2x) -
@2x— hashes SHA1 של כל הקבצים -
manifest.json— חתימת PKCS#7 של המניפסט באמצעות תעודת Pass Type ID
השגיאה הנפוצה ביותר בבנייה ידנית היא signature שגוי. ה-hash חייב להתאים לתוכן הקובץ בפועל בייט אחר בייט. תו אחד נוסף ב-manifest.json ו-Apple Wallet ידחה את החבילה ללא הודעה ברורה.
pass.json מינימלי לכרטיס נאמנות:
{ "formatVersion": 1,
"passTypeIdentifier": "pass.com.yourcompany.loyalty",
"serialNumber": "USER-12345",
"teamIdentifier": "ABCDE12345",
"organizationName": "YourCompany",
"description": "Карта лояльности YourCompany",
"logoText": "YourCompany",
"foregroundColor": "rgb(255,255,255)",
"backgroundColor": "rgb(30,90,200)",
"storeCard": {
"primaryFields": [
{
"key": "balance",
"label": "Баллы",
"value": "1 240"
}
],
"secondaryFields": [
{
"key": "tier",
"label": "Уровень",
"value": "Золотой"
}
],
"barcode": {
"message": "USER-12345",
"format": "PKBarcodeFormatQR",
"messageEncoding": "iso-8859-1"
}
}
}השדה pass.json הוא סוג הכרטיס לכרטיסי נאמנות. חלופות: { "formatVersion": 1, "passTypeIdentifier": "pass.com.yourcompany.loyalty", "serialNumber": "USER-12345", "teamIdentifier": "ABCDE12345", "organizationName": "YourCompany", "description": "Карта лояльности YourCompany", "logoText": "YourCompany", "foregroundColor": "rgb(255,255,255)", "backgroundColor": "rgb(30,90,200)", "storeCard": { "primaryFields": [ { "key": "balance", "label": "Баллы", "value": "1 240" } ], "secondaryFields": [ { "key": "tier", "label": "Уровень", "value": "Золотой" } ], "barcode": { "message": "USER-12345", "format": "PKBarcodeFormatQR", "messageEncoding": "iso-8859-1" } } } , storeCard, boardingPass, coupon. להלן השוואה בין הסוגים:
| סוג | מטרה | שדות חובה |
|---|---|---|
| storeCard | כרטיסי נאמנות | primaryFields, secondaryFields, barcode |
| boardingPass | כרטיסי עלייה למטוס | transitType, primaryFields, secondaryFields |
| coupon | קופונים | primaryFields, secondaryFields |
| eventTicket | כרטיסי אירועים | primaryFields, secondaryFields, locations |
| generic | סוג כללי | primaryFields, secondaryFields |
איך לחתום על Wallet Pass: שלב אחר שלב
- צור תעודת Pass Type ID בפורטל המפתחים של Apple.
- הורד את תעודת ה-WWDR Intermediate מ-Apple.
- צור מפתח פרטי וחתום על בקשת החתימה.
- הרכב את ארכיון ה-.pkpass: pass.json, תמונות, manifest.json.
- חתום על manifest.json באמצעות OpenSSL:
openssl smime -binary -sign \
-signer pass_certificate.pem \
-inkey pass_key.pem \
-certfile wwdr.pem \
-in manifest.json \
-out signature \
-outform DER -nodetachיצירה ידנית עם OpenSSL מהירה פי 2 מפתרון Node.js מותאם אישית, אבל דורשת הגדרה מדויקת של שרשרת התעודות. חלופה היא שימוש בספריות מוכנות: eventTicket ל-Node, generic ל-TypeScript, openssl smime -binary -sign \ -signer pass_certificate.pem \ -inkey pass_key.pem \ -certfile wwdr.pem \ -in manifest.json \ -out signature \ -outform DER -nodetach ל-PHP. אנו ממליצים על passbook — היא יוצרת את המניפסט אוטומטית ותומכת בכל סוגי הכרטיסים.
iOS: הוספת הכרטיס באפליקציה
import PassKit
func addLoyaltyCard(passData: Data) {
guard let pass = try? PKPass(data: passData) else {
showError("Не удалось прочитать пасс")
return
}
let passLibrary = PKPassLibrary()
if passLibrary.containsPass(pass) {
// Карта уже добавлена — предложить обновление
passLibrary.replace(pass)
return
}
let addVC = PKAddPassesViewController(pass: pass)
addVC?.delegate = self
present(addVC!, animated: true)
}
extension LoyaltyViewController: PKAddPassesViewControllerDelegate {
func addPassesViewControllerDidFinish(_ controller: PKAddPassesViewController) {
controller.dismiss(animated: true)
checkPassStatus()
}
}passkit-generator בודק לפי השילוב של wallet-php ו-passkit-generator. אם הכרטיס כבר קיים, import PassKit func addLoyaltyCard(passData: Data) { guard let pass = try? PKPass(data: passData) else { showError("Не удалось прочитать пасс") return } let passLibrary = PKPassLibrary() if passLibrary.containsPass(pass) { // Карта уже добавлена — предложить обновление passLibrary.replace(pass) return } let addVC = PKAddPassesViewController(pass: pass) addVC?.delegate = self present(addVC!, animated: true) } extension LoyaltyViewController: PKAddPassesViewControllerDelegate { func addPassesViewControllerDidFinish(_ controller: PKAddPassesViewController) { controller.dismiss(animated: true) checkPassStatus() } } מציג דיאלוג 'עדכון' במקום 'הוספה'.
איך להגדיר עדכוני שרת?
Apple Wallet תומך בעדכוני שרת באמצעות Web Service URL. ב-PKPassLibrary().containsPass(_:), הוסף:
"webServiceURL": "https://api.yourcompany.com/wallet",
"authenticationToken": "vxwxd7J8AlNNFPS8k0a0FfUFtq0ewzFdc"Wallet יבדוק מעת לעת את passTypeIdentifier, יקבל רשימה של serialNumber מעודכנים, ויוריד גרסאות חדשות של הכרטיס. אם הכרטיס לא מתעדכן, בדוק את שרשרת התעודות ואת ה-URL — ב-50% מהמקרים, הבעיה היא PKAddPassesViewController שגוי.
טעויות נפוצות בהגדרת עדכוני push
- authenticationToken שגוי: ה-token חייב להיות מחרוזת אקראית ולתאום בין השרת לכרטיס.
- חוסר תמיכה ב-TLS 1.2: Apple Wallet דורש HTTPS עם הצפנה מודרנית.
- URL שגוי: webServiceURL חייב להסתיים ללא קו נטוי בסוף ולהיות נגיש מהאינטרנט.
מה כלול באינטגרציה סוהר
- יצירה וחתימה של .pkpass על השרת שלך
- הטמעת בקר iOS להוספת הכרטיס
- הגדרת התראות push לעדכוני יתרה
- תיעוד API ותמיכה
- בדיקות על מכשירים עם גרסאות iOS שונות
למה לבחור בנו
אנחנו בפיתוח מובייל כבר למעלה מ-5 שנים. בתקופה זו, השלמנו 30+ פרויקטים עם אינטגרציה של Apple Wallet ו-Google Pay. המהנדסים שלנו מוסמכים על ידי Apple ויודעים את כל רזי PassKit. קבלו ייעוץ — צרו קשר כדי לדון בפרויקט שלכם. הזמינו אינטגרציה וקצרו את זמן ההשקה של כרטיס הנאמנות שלכם.
לוח זמנים ועלות
2–3 ימים ליצירת כרטיס וחתימה בצד השרת, הטמעת pass.json, והגדרת עדכוני push. העלות מחושבת באופן אישי.







