PassKit

PassKit enables you to extend your mobile reach by integrating Apple Wallet and Google Pay passes into your customer’s experience. Easily create, manage, distribute, and analyze the performance of digital coupons, loyalty cards, membership cards, tickets, and much more; without your customers needing another app.

Deliver seamless, connected online to offline customer experiences with Braze and PassKit. Increase and measure the engagement of your online campaigns by instantly delivering Apple Wallet and Google Pay passes. Analyze usage and make real-time adjustments to increase in-store traffic by triggering location-based messages and personalized, dynamic updates to your customer’s mobile wallet.

Prerequisites

Requirement Origin Description
PassKit Account PassKit You will need to have a PassKit account and a PassKit account manager.
userDefinedID Client To appropriately update custom events and custom attributes to your users between PassKit and Braze, you will need to set the Braze external ID as the userDefinedID. This userDefinedID will be used when making API calls to the PassKit Endpoints.
Braze API Key Braze You will need to create a new API Key.

This can be created in the Developer Console -> API Settings -> Create New API Key with users.track permissions.
Braze REST Endpoint Braze Your REST Endpoint URL. Your endpoint will depend on the Braze URL for your instance.

API Integration

To further enrich your customers’ mobile wallet experiences, from within your PassKit dashboard you can opt to pass data into Braze through Braze’s Users Track Endpoint.

Examples of data to share from PassKit includes:

  • Pass Created: when a customer clicks on a pass link and is first shown a pass.
  • Pass Installs: when the customer adds/saves the pass to their wallet app.
  • Pass Updates: when a pass is updated.
  • Pass Delete: when a customer deletes the pass from their wallet app.

Once the data is passed into Braze, you can build audiences, personalize content via Liquid, and trigger campaigns or Cavanses once these actions have been performed.

Connect PassKit to Braze

To pass data from PassKit, please ensure that you have set your Braze external ID as PassKit’s externalId.

  1. Within Settings, under Integrations within your PassKit Pass Project or Program click Connect under the Braze Tab.
    Settings Button
  2. Fill out your Braze API Key, Endpoint URL, and provide a name for your connector.
  3. Toggle Enable Integration, and whichever events you want in Braze to trigger or personalize your messages with.
    Connect to Braze

Within Braze, you can setup a SmartPass Link to generate a unique URL for your customers to install their pass on either Android or iOS.

Prerequisites

Requirement Origin Description Example
PassKit URL PassKit Your PassKit URL is a unique URL for your passkit program.

Each program has a unique URL, and you can find it under the Distribution tab of your PassKit Program/Project.
https://pub1.pskt.io/c/ww0jir
PassKit Secret PassKit Along with the URL, you will need to have the PassKit Key for this program handy.

This can be found on the same page as your PassKit URL.
5AuNonZoFHejGXmHNATz4l
Program (or Project) ID PassKit Your PassKit Program ID will be required to create the SmartPass URL.

You can find it under the Settings tab of your project or program.
1x3j9vWjSGx2UwUblYlcue

PassKit Integrations

For more information on creating encrypted SmartPass Links, check out this PassKit Article.

To begin creating a SmartPass URL, you should create this encryption within a Braze Content Block. Creating it this way will allow you to re-use the block for future passes and coupons.

Step 1: Define your Pass Data Payload

First, you must define the coupon or member payload.

There are many different components you can include in your payload, but here as two important ones to note:

Component Required Type Description
person.externalId​ Required String Set as the Braze External ID, this is crucial for the callbacks from PassKit back to Braze to work, allowing Braze users to have coupons for multiple offers in one campaign. Not enforced as unique.
members.member.externalId​ Optional String Set as the Braze External ID, you may use your External ID to update the membership pass. Setting this field enforces the user as unique within the membership program.

For a full list of available fields, their types, and helpful descriptions have a look at the PassKit Github Documentation.

Example Payload

1
2
3
4
5
6
7
8
{
  "members.member.externalId": "{{${user_id}}}",
  "members.member.points": "100",
  "members.tier.name": "current_customer",
  "person.displayName": "{{${first_name}}} {{${last_name}}}",
  "person.externalId": "{{${user_id}}}",
  "universal.expiryDate": "{{ "now" | date: "%s" | plus: 31622400 | date: "%FT%TZ" }}"
}

Step 2: Create and Encode an Undefined Payload Variable

First, create and name a new content block by navigating to Templates & Media within the Braze Dashboard. Here you can find the Content Block Library tab, select Create Content Block to get started.

Next, you must define your Content Block Liquid Tag. After saving this content block, this Liquid tag can now be referenced when composing messages. In this example, we have assigned the Liquid tag as {{content_blocks.${passKit_SmartPass_url}}}.

Within this content block, we will not directly include the payload written above, but reference it in a {{passData}} variable. The first code snippet you must add to your content block captures a Base64 encoding of the {{passData}} variable.

1
{% capture base64JsonPayload %}{{passdata|base64_encode}}{% endcapture %}

Step 3: Create Your Encryption Signature using a SHA1 HMAC Hash

Next, you will be creating your encryption signature using a SHA1 HMAC hash of the project URL and the payload.

The second code snippet you must add to your content block captures the URL to be used for hashing.

1
{% capture url %}{{projectUrl}}?data={{base64JsonPayload}}{% endcapture %}

Next, you must generate a signature using this hash and your Project Secret. This can be done by including a third code snippet, shown below.

1
{% capture sig %}{{url | hmac_sha1: "Project_Secret"}}{% endcapture %}

Finally, append the signature to the full URL using the fifth code snippet, shown below.

1
{% capture longUrl %}{{projectUrl}}?data={{base64JsonPayload}}&sig={{sig}}{% endcapture %}

Step 4: Print Your URL

Lastly, make sure you call your final URL so that it prints your SmartPass URL within your message.

1
{{longURL}}

At this point you will have created a content block that looks something like this:

1
2
3
4
5
6
7
8
9
{% capture base64JsonPayload %}{{passdata|base64_encode}}{% endcapture %}

{% capture url %}{{projectUrl}}?data={{base64JsonPayload}}{% endcapture %}

{% capture sig %}{{url | hmac_sha1: "Project_Secret"}}{% endcapture %}

{% capture longUrl %}{{projectUrl}}?data={{base64JsonPayload}}&sig={{sig}}&utm_source=braze&utm_campaign={{campaign.${name}}}{% endcapture %}{% capture longUrl %}{{longUrl | url_encode}}{% endcapture %}

{{longURL}}

In this example, UTM parameters have been added to track the source of these installs back to Braze and this campaign.

Step 5: Putting it All Together

Once this content block has been made it can be reused again in the future.

You may notice there are two variables left undefined in the above content block.
{{passData}} - Your JSON pass data payload defined in step 1
{{projectUrl}} - Your project or program’s URL which you find on the distribution tab of your Passkit project.

This decision was purposeful and ensures the reusability of the content block. Because these variables are only referenced, not created within the content block, it allows for these variables to change without remaking the content block.

For example, maybe you want to change the introductory offer to include more initial points in your loyalty program, or perhaps you want to create a secondary member card or coupon. These scenarios would require different Passkit projectURLs or different pass payload which you would define per campaign in Braze.

Composing the Message Body

In your message body, you’ll want to capture both of these variables and then call your content block. Capture your minified JSON payload from step 1 above:

1. Assign the Project URL

1
{% assign projectUrl = "https://pub1.pskt.io/c/ww0jir" %}

2. Capture the JSON created in Step 1.

1
{% capture passData %}{"members.member.externalId": "{{${user_id}}}","members.member.points": "100","members.tier.name": "current_customer","person.displayName": "{{${first_name}}} {{${last_name}}}","person.externalId": "{{${user_id}}}","universal.expiryDate": "{{ "now" | date: "%s" | plus: 31622400 | date: "%FT%TZ" }}"}{% endcapture %}

3. Reference the content block you just made.

1
{{content_block.${passkit_SmartPass_url}}}

Your Message Body should look something like this: Message Body

The output URL for the sample above is: Output URL

That looks long doesn’t it? The reason for this is due to it containing all the pass data in addition to incorporating best in class security to ensure data integrity and no tempering via URL modification. If using SMS to distribute this URL, you may want to run it through a link shortening process such as bit.ly. This can be done through a Connected Content call to a bit.ly endpoint!

Update Pass Using the PassKit Webhook

Within Braze, you can setup a webhook campaign or a webhook within a Canvas to update an existing pass based on your user’s behavior. Check out the links below for information on useful PassKit Endpoints.

Prerequisites

Before you get started, here are the common JSON Payload Parameters that you can include within your Create and Update webhooks to PassKit.

Data Type Description
externalId String This allows a unique Id to be added to the pass record that can provide compatibility with an existing system using unique customer identifiers (e.g. membership numbers). You can retrieve pass data by using this endpoint via userDefinedId and campaignName instead of pass ID. This value must be unique within a campaign, and once this value is set, it cannot be changed.

For the Braze integration, we would recommend using the Braze external ID: {{${user_id}}}
campaignId (coupon)

programId (membership)
String This is the ID for the campaign/program template you created in PassKit. To find this, head to the Settings tab in your PassKit pass project.
expiryDate IO8601 DateTime This is the pass expiry date. After the expiry date, the pass is automatically voided (see isVoided). This value will override the template and campaign end date value.
status String This is the current status of a coupon, such as “REDEEMED” or “UNREDEEMED”.

Webhook Integration

Step 1: Create a Webhook Template in Braze

You can create this from the Templates & Media section, or create a new webhook campaign or Canvas in Braze. Next, select the PassKit - Update Pass webhook template, you should see the following in the composer:

Webhook URL (Compose Tab): https://api-pub1.passkit.io/coupon/singleUse/coupon
Request Body (Compose Tab): application/json
HTTP Method (Settings Tab): PUT

Step 2: Fill Out Your Template

To set up the webhook, fill out the details of the new event within the Request Body:

1
2
3
4
5
{
  “externalId”: “{{${user_id}}}”,
  “campaignId”: “ 2xa1lRy8dBz4eEElBfmIz8”,
  “expiryDate”: “2020-05-10T00:00:00Z”
}

Step 3: Fill Out Your Request Headers

HTTP Header Definition
Authorization Bearer [INSERT_YOUR_LONG_LIVED_TOKEN]
Content-Type application/json

Ensure that your HTTP Method is set to PUT.

Retrieve Your PassKit Long Lived Token
To retrieve your token, navigate to your PassKit Project/Program within the PassKit Admit Account. From here, go to Integrations within Settings, and select “Love Lived Integration Token” from the left-hand sidebar. Here, you find your long lived token.

Step 4: Preview Your Request

You will see that your raw text automatically highlights if it is an applicable Braze tag.

You can preview your request in the left-hand panel or navigate to the Test tab, where you can select a random user, an existing user, or customize your own to test your webhook.

Retrieve Pass Details via Connected Content

In addition to creating and updating passes, you can also retrieve your users’ pass metadata via Braze’s Connected Content in order to incorporate personalized pass details within your messaging campaigns. For more information on how to run Connected Content calls, check out our documentation.

PassKit Connected Content Call

1
2
3
{% connected_content  https://api-pub1.passkit.io/coupon/singleUse/coupon/externalId/{{${user_id}}} :headers {"Authorization": "Bearer [INSERT_YOUR_LONG_LIVED_TOKEN]","Content-Type": "application/json"} :save passes %}

{{passes.status}} 

Liquid Example Responses:

1
2
3
4
5
6
7
8
9
10
11
{
    "redemptionDate": null,
    "redemptionCode": "",
    "lat": 0,
    "lon": 0,
    "alt": 0,
    "redemptionSource": "",
    "redemptionReference": "",
    "transactionReference": "",
    "transactionAmount": 0
}
1
UNREDEEMED 
WAS THIS PAGE HELPFUL?
New Stuff!