Summary
Walletify does not require an account or login. Card designs you save in the app stay on your
device. When you generate a pass for Apple Wallet, the app sends pass fields to Walletify's
server so a signed .pkpass can be created. The server also stores a per-device pass
count and subscription entitlement data needed to enforce the free allowance and paid access.
Data stored on your device
The following stay on your iPhone or iPad unless you choose to generate a pass:
- Card designs (store/loyalty cards, boarding passes, Wi-Fi passes), including text fields, colors, barcode values, and optional relevant locations, stored locally with SwiftData.
- Photos or files you use only to detect a barcode. Detection runs on-device; the image is not uploaded for signing.
- Local caches of pass-count and entitlement status (for example in UserDefaults), and App Attest key material in Keychain when App Attest is available.
Device identifier
The app uses Apple's Identifier for Vendor (IDFV) via DeviceManager as a stable
device identifier for API calls. On Simulator, or if IDFV is unavailable, the app generates a
fallback UUID and stores it in UserDefaults. This identifier is used to associate pass-generation
counts, App Attest state, and subscription linkage for that device. It is not used for advertising.
Devices, App Attest, and abuse prevention
Pass-generation requests include an hourly app secret (x-app-secret) used to verify
that requests come from the genuine app client. Where supported, Walletify also uses Apple App
Attest / DeviceCheck to attest the device and attach assertion headers. Challenge and
attestation state for a device may be stored in Google Cloud Firestore. These mechanisms exist
for fraud prevention and abuse prevention (for example limiting free pass generations and
reducing automated misuse), not for advertising profiling.
Pass content sent to the server
To produce a signed Apple Wallet pass, the app sends a JSON request to
POST /api/v1/generate-pass. Based on the current client and server code, that
payload can include:
- Your device identifier.
- Pass text fields and metadata (for example description, logo text, store name, cardholder, Wi-Fi SSID/password/auth fields, boarding details, barcode message/format, colors, serial number, grouping identifier, transit type, relevant date, and optional location coordinates).
- Flags such as whether to generate a background image from the chosen colors, or whether to link the pass back to the Walletify app.
The server uses that content to assemble and cryptographically sign a .pkpass
file and returns the signed pass to your device. Template artwork used in the pass package
comes from server-side pass models. The current app does not upload custom logo or photo binary
attachments for signing; barcode images used for scanning remain on-device, and only the
resulting barcode payload string is sent.
Pass content must reach the server to create a valid signed pass. Do not put secrets in pass fields that you are unwilling to transmit for signing.
Pass generation count
For each device identifier, the server stores a passesGenerated count in Firestore
and enforces a free allowance of 3 successful pass generations per device
unless an active subscription or lifetime purchase applies. Related temporary fields (for
example a pending generation confirmation id) may also be stored during the generate/confirm
flow.
Subscriptions and StoreKit data
Purchases use Apple StoreKit. When the app validates or restores a purchase, it can send your
device identifier and Apple-signed transaction JWS strings to
/subscription/validate or /subscription/restore. The server verifies
those transactions with Apple and may store entitlement records such as product id, original
transaction id, status, expiration date (when applicable), environment, and linked device ids.
Apple may also send App Store Server Notifications to update subscription status. Billing
details (payment card, Apple ID email, etc.) are handled by Apple, not by Walletify.
Third parties
- Apple - App Store distribution, StoreKit purchases, PassKit / Apple Wallet, and App Attest / DeviceCheck.
- Google Cloud - Cloud Functions hosts the Walletify API; Firestore stores device, attestation-challenge, and subscription records described above.
The current iOS app and API codebases do not integrate separate analytics, advertising, or crash-reporting SDKs. This marketing website may receive basic hosting/CDN request logs from Cloudflare.
Logs
The API uses structured logging (Pino). Logs can include operational details such as device identifiers, subscription product ids, pass-limit outcomes, and error messages needed to run and debug the service. Logs are not an analytics product and are retained according to the hosting provider's log retention for the deployment environment. There is no separate automatic long-term analytics warehouse implemented in the application code.
Retention and deletion
The application code does not implement an automatic timed deletion window for device records, subscription records, or pass-generation counts. Records remain while needed to enforce limits, honor purchases, and operate the service, unless removed through a deletion request or routine operational cleanup.
App Attest challenges are short-lived (on the order of minutes) and are deleted after use or expiry.
To request deletion of server-side data associated with your device identifier or purchases, email alex@apvl.dev with enough detail to locate the record (for example the device identifier if you have it, approximate purchase date, or other purchase evidence). Local card data can be removed by deleting cards in the app or deleting the app. Uninstalling the app does not by itself erase server-side device or subscription records.
Children
Walletify is not directed at children under 13, and we do not knowingly collect personal information from children under 13.
International processing
Server infrastructure is operated on Google Cloud and may process data in the regions configured for that project. By using pass generation or purchase validation features, you understand that the data described above is transmitted to those processors.
Changes
We may update this policy as the product changes. The "Last updated" date at the top will change when we do. Material changes will be reflected on this page.
Contact
Privacy and deletion requests: alex@apvl.dev. Also see Terms of Use and Support.