This article will go over how you can build your own pass landing page. The demo will use HTML and JavaScript to build a simplified example page that serves a customer the correct pass URL based on their user agent.
To start, I'll create a simple HTML page with a header and two images.
The images are the official button SVG element from Apple Wallet and Google Wallet. You can download their assets here: Apple / Google
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<title>Custom Landing Page</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<h2>Custom Landing Page</h4>
<div id="assets">
<img id="ios" height="60" src="images/US- UK_Add_to_Apple_Wallet_RGB_101421.svg" />
<img id="google" height="60" src="images/Save to Google Pay - English (Dark).svg" />
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="scripts.js"></script>
</body>
</html>
JavaScript
$(document).ready(function () {
console.log("Running");
});
CSS
img {
cursor: pointer;
}
#assets {
display: flex;
flex-direction: column;
align-items: flex-start;
}
With this in place, my page should look like this
Next, I need to show or hide each button element depending on the browser viewing the page.
Inside my scripts.js file, I'll check for the browser and hide the correct button.
$(document).ready(function () {
if (getBrowser("chrome")) {
$("#ios").css("display", "none"); }
else if (getBrowser("safari")) {
$("#google").css("display", "none");
}});
function getBrowser(browserString) {
return navigator.userAgent.toLowerCase().indexOf(browserString) > -1;
}
*** NOTE ***
This check is overly simplistic for the purposes of demonstration only. This should not be used for production pages.
Now when I visit my page on Chrome, the Apple Wallet button is hidden and when I visit the page on Safari, the Google Pay button is hidden.
The next thing to do is retrieve the PassKit Pass Id from the URL. The PassKit Pass Id is the only piece of dynamic content you need to make your custom landing page work.
If you aren't sure what the PassKit Pass Id is, you can find it in the PassKit portal or in the existing PassKit Pass landing page URL.
PassKit Portal
PassKit Landing Page
For this example page, the PassKit Pass Id is passed into the URL via query parameters. Your own implementation may differ, but this should give you an idea of what to do when you have it.
I'll add logic to grab the PassKit Pass Id from the URL and combine it with the URL prefix https://pub1.pskt.io/.
Example URL: www.custom-landing-page?id=12345
$(document).ready(function () {
var urlParams = new URLSearchParams(window.location.search);
var id = urlParams.get("id");
var baseURL = "https://pub1.pskt.io/" + id;
if (getBrowser("chrome")) {
$("#ios").css("display", "none"); }
else if (getBrowser("safari")) {
$("#google").css("display", "none");
}});
function getBrowser(browserString) {
return navigator.userAgent.toLowerCase().indexOf(browserString) > -1;
}
Now that we have the base URL and the Id, the last thing to do is trigger a call to PassKit to get the Pass Bundle for each wallet.
To do that I'll create two onclick events for the images we have. Each event will take the base URL we created earlier and append it with the respective prefix needed to deliver the Pas Bundle directly to the browser. For iOS passes we use .pkpass for Google we use .gpay .
$(document).ready(function () {
var urlParams = new URLSearchParams(window.location.search);
var id = urlParams.get("id");
var baseURL = "https://pub1.pskt.io/" + id;
$("#ios").click(function () {
window.location.href = `${baseURL}.pkpass`;
});
$("#google").click(function () {
window.location.href = `${baseURL}.gpay`;
});
if (getBrowser("chrome")) {
$("#ios").css("display", "none"); }
else if (getBrowser("safari")) {
$("#google").css("display", "none");
}});
function getBrowser(browserString) {
return navigator.userAgent.toLowerCase().indexOf(browserString) > -1;
}
With this in place, when I click on the button in the browser, I should be given the correct user journey for each wallet.


