Интеграция Apple Wallet (Wallet Pass) для карт лояльности в мобильном приложении
PassKit — фреймворк, который управляет .pkpass-файлами на устройстве. Карта лояльности в Apple Wallet — это подписанный JSON-архив с изображениями, метаданными и опциональными NFC-данными. Основная точка входа в коде — PKAddPassesViewController. Без правильно сформированного и подписанного архива пользователь получит ошибку «Недействительный пропуск» при попытке добавить карту.
Структура .pkpass и подпись
Архив содержит:
-
pass.json— тип, цвета, поля карты -
icon.png,logo.png,strip.png— графические ресурсы (обязательны двойная плотность@2x) -
manifest.json— SHA1-хэши всех файлов -
signature— PKCS#7 подпись манифеста через Pass Type ID certificate
Самая частая ошибка при самостоятельной сборке — неправильный manifest.json. Хэш должен совпадать байт в байт с реальным содержимым файлов в архиве. Один лишний символ в pass.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"
}
}
}
Поле storeCard — это тип пасса для карт лояльности. Альтернативы: boardingPass, coupon, eventTicket, generic.
Подписание на сервере
Для подписи нужны три сущности из Apple Developer Portal:
-
Pass Type ID certificate — выпускается под конкретный
passTypeIdentifier - WWDR Intermediate Certificate — загружается отдельно с сайта Apple
- Приватный ключ сертификата
Подпись генерируется через OpenSSL:
openssl smime -binary -sign \
-signer pass_certificate.pem \
-inkey pass_key.pem \
-certfile wwdr.pem \
-in manifest.json \
-out signature \
-outform DER -nodetach
На сервере (Node.js/PHP/Go) есть готовые библиотеки: passbook для Node, passkit-generator для TypeScript, wallet-php для PHP.
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()
}
}
PKPassLibrary().containsPass(_:) проверяет по связке passTypeIdentifier + serialNumber. Если пасс уже есть — PKAddPassesViewController покажет диалог «Обновить», а не «Добавить».
Обновление данных карты (push-уведомления)
Apple Wallet поддерживает серверные обновления через Web Service URL. В pass.json добавляете:
"webServiceURL": "https://api.yourcompany.com/wallet",
"authenticationToken": "vxwxd7J8AlNNFPS8k0a0FfUFtq0ewzFdc"
Wallet будет регулярно опрашивать GET /v1/devices/{deviceLibraryIdentifier}/registrations/{passTypeIdentifier}, получать список обновлённых serialNumber и загружать новые версии пасса.
Сроки
2–3 дня на серверную генерацию и подписание пассов, реализацию PKAddPassesViewController и настройку push-обновлений. Стоимость рассчитывается индивидуально.







