Skip to main content
Adding Passes Directly from Your App

How to Add PassKit Passes to Apple and Google Wallet Directly from Your App

Danny Allen avatar
Written by Danny Allen
Updated today

Introduction

This article is for developers who want to integrate passes (loyalty cards, tickets, coupons, etc.) into their iOS or Android apps. It explains PassKit Pass URLs, their purpose, and how to use them to deliver a seamless end-user experience. Whether you want to allow users to install passes directly from your app, debug pass contents, or programmatically remove passes from Apple Wallet, this guide has you covered.


Who Is This Article For?

This article is for you if:

  • You want to understand PassKit Pass URLs, their purpose, and how they determine the end-user experience.

  • You have an iOS or Android app and want to let users install or access their passes directly from within your app.

  • You want to download and analyze the Apple Pass Bundle (.pkpass file) for debugging or educational purposes.


Prerequisites:

Before proceeding, ensure the following:

  1. Pass Record: You have created a pass record using the PassKit Web Portal or API and have obtained the Pass ID.

  2. Valid Pass: The pass record is valid and not expired. (Note: Passes in test projects automatically expire within 48 hours.)

Tip: You can find the Pass ID in the Members or Coupons view within the PassKit Web Portal.


Understanding PassKit Pass URLs

PassKit Pass URLs (also called Pass Landing Pages) are public pages that allow users to download and install their passes. These URLs are unique for each pass record and contain a 22-character PassKit ID, which is an alphanumeric representation of a 128-bit UUID. This ensures sufficient entropy to protect against random guessing.

Key Features of Pass URLs

No Authentication Required

Users only need the Pass URL to download their pass. They cannot guess another user’s pass by manipulating the URL.

Device Detection

The proprietary PassKit service behind the Pass URL detects the user’s device and operating system, delivering the most appropriate experience:

  • Apple Wallet: Prompts iOS users or macOS Safari/Chrome users to add the pass to Apple Wallet.

  • Google Wallet: Presents the Google Pay experience for Android users (if Google Pay is the default wallet for the PassKit project).

  • Third-Party Android Wallets: Presents the WalletPasses or PassWallet experience for Android users in regions where Google Pay is unsupported.

  • Desktop: Displays instructions and a QR code for users to open the Pass URL on their mobile device.

Default Pass URL Format

  • Date Region Europe: https://pub1.pskt.io/{{PassKit ID}}

  • Data Region USA: https://pub2.pskt.io/{{PassKit ID}}

Pass URL benefits

The Pass URL is ideal when distributing links via email, SMS, or other channels where the user's operating system or device is unknown. However, if you want users to install a pass directly from within your iOS or Android app—and you already know their device type—you can configure the Pass URLs for a more controlled experience. This allows you to directly link to the correct pass asset for their specific device.


Installing a Pass into Apple Wallet from Within an iOS App

If you already know the user’s device (e.g., within your iOS app), you can configure the Pass URL for a more controlled experience.

Steps to Install a Pass

1. Append .pkpass to the Pass URL

  • Format: https://pub1.pskt.io/{{PassKit ID}}.pkpass or https://pub2.pskt.io/{{PassKit ID}}.pkpass

2. Call the Endpoint:

  • Use a client capable of processing .pkpass files (e.g., NSURL in iOS).

  • Handling Unsupported User Agents:
    If you receive HTML instead of the binary data for the .pkpass bundle, it’s likely due to an unsupported user agent. For example, this can happen when using a UIWebView component in an iOS app.
    Solution: Include PassKit in the user agent string when making the request. This ensures the endpoint recognizes the request and returns the correct binary data.

3. Load the Pass Bundle:

Sample cURL Request

curl -I https://pub1.pskt.io/26M0JjuCpGHBqPYvnlE4RF.pkpass

Expected Response

HTTP/2 200 
server: nginx/1.19.0
date: Tue, 02 Feb 2021 18:04:30 GMT
content-type: application/vnd.apple.pkpass
content-length: 322897
access-control-allow-methods: OPTIONS, GET
access-control-allow-origin: *
access-control-expose-headers: Cache-Control, Content-Disposition, Content-Language, Content-Length, Content-Transfer-Encoding, Expires, Content-Type, ETag, Last-Modified, X-PassKit-PID
cache-control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
content-disposition: attachment; filename="26M0JjuCpGHBqPYvnlE4RF.pkpass"
content-transfer-encoding: binary
etag: 900c55c45f5cfdd0df2387fb8dbb2633
last-modified: Tue, 02 Feb 2021 18:04:30 UTC
x-passkit-pid: 26M0JjuCpGHBqPYvnlE4RF
strict-transport-security: max-age=15724800; includeSubDomains


Installing a Pass into Google Wallet from Within an Android App

For Android users, you can direct them to install the pass into Google Wallet.

Steps to Install a Pass

1. Append .gpay to the Pass URL

  • Format: https://pub1.pskt.io/{{PassKit ID}}.gpay or https://pub2.pskt.io/{{PassKit ID}}.gpay

2. Redirect the User

Redirect the user to the URL. Google will handle the rest:

  • If Google Pay is installed, they will be directed to the Google Pay app which will then load in the pass.

  • If Google Pay is not installed, they will complete the process via the browser, then be presented a link to install Google Pay and load in the pass.

  • If Google Pay is unsupported in the user’s region, they can only view the pass through the Google Pay web experience.

Note: There is no .pkpass bundle or other file based process like with Apple Wallet.


Downloading and Analysing the .pkpass Bundle

If you need to debug or analyze the contents of a .pkpass bundle, you can download it directly for inspection. This is useful for troubleshooting or educational purposes.

Download the Bundle

You can download the pass bundle using a browser or cURL.

Append .wallet to the Pass URL

  • Format: https://pub1.pskt.io/{{PassKit ID}}.wallet or https://pub2.pskt.io/{{PassKit ID}}.wallet

  • Important: Open the URL in a browser other than Safari (e.g., Chrome or Firefox). Safari will attempt to add the pass to Apple Wallet instead of allowing you to download it.

Use cURL

Alternatively, use cURL to download the bundle directly:

curl https://pub1.pskt.io/26M0JjuCpGHBqPYvnlE4RF.pkpass --output pass.pkpass

Inspect the Bundle

Once downloaded, you can inspect the contents of the .pkpass bundle.

  1. Rename the .pkpass file to .zip.

  2. Extract the .zip file to view its contents, which include:

    • JSON files: Contain pass configuration and data.

    • Images: Icons, logos, and other visual assets.

    • Signatures: Ensure the pass is valid and signed correctly.

Why Analyze the Bundle?

Inspecting the .pkpass bundle can help you:

  • Debug issues with pass content or formatting.

  • Understand how passes are structured.

  • Verify that all required assets and data are included.

Bonus: Programmatically Removing a Pass from Apple Wallet

Apple provides functionality to programmatically remove passes from Apple Wallet directly within your app. This eliminates the need for users to manually tap "Remove Pass" on the back of the pass in Apple Wallet.

Key Considerations

Before implementing this feature, it’s crucial to understand Apple’s guidelines and prerequisites:

User Consent:

  • Passes belong to the user, not your app. Always obtain explicit user consent before removing a pass.

  • Never remove a pass without the user’s direct action, even if the pass has expired or is outdated.

Ownership:

  • You must be the owner of the pass to remove it programmatically. This means:

    • The pass must be signed with your Apple Certificate.

    • The certificate must belong to the same Apple Developer Team as your app certificate (the Team Identifiers must match).

Live Projects Only:

  • This functionality is only available for "Live" projects. Test projects use a PassKit demo certificate and do not support programmatic pass removal.

Why This Matters

Programmatically removing passes can enhance user experience by allowing them to manage their passes directly within your app. However, always prioritize user consent and adhere to Apple’s guidelines to ensure compliance.


Conclusion

By leveraging PassKit Pass URLs, you can deliver a seamless pass installation experience for both Apple Wallet and Google Wallet users. Whether you’re integrating passes into your app, debugging pass contents, or programmatically managing passes, this guide provides all the necessary details to get started.

Did this answer your question?