# How to issue a wallet pass on geozone entry

Issue an Apple or Google Wallet pass when a shopper enters a store geozone, then push the install link. This guide builds that journey with the [Issue Wallet Pass](/product/customer-journey/journey-elements/channels/issue-wallet-pass/) element.

<Aside type="note" title="Prerequisites">

* Connect the [iOS platform](/developer/first-steps/connect-messaging-services/ios-configuration/) and complete [Apple Wallet pass setup](/developer/first-steps/connect-messaging-services/ios-configuration/ios-wallet-pass-configuration/), and/or configure [Google Wallet for Android](/developer/first-steps/connect-messaging-services/android-configuration/android-google-wallet-configuration/), for the platforms you support.
* Geo campaigns need location permission on the device and location tracking enabled in the app. See [Understanding geo campaigns](/product/messaging-channels/push-notifications/geo-campaigns/).

</Aside>

## Create a Wallet Pass Campaign

The [Issue Wallet Pass](/product/customer-journey/journey-elements/channels/issue-wallet-pass/) element can only issue passes from an existing campaign, so create one first. A campaign's **Platform** is permanent, so if you support both Apple Wallet and Google Wallet, repeat this section once per platform.

1. Go to **Campaigns → Wallet Passes → Campaigns** and click **Create campaign**.
2. Choose **Apple Wallet** or **Google Wallet** as the **Platform**, enter a **Name** for your own reference, for example `Store loyalty` (this labels the campaign in Pushwoosh, it doesn't appear on the pass), and pick a pass style, for example **Store Card** (Apple) or **Loyalty card** (Google).

<img src="/wallet-pass-campaigns-2.webp" alt="New campaign creation form showing Name and Description fields, and a Pass Style picker"/>

3. Under **Basic Information**, set **Pass Name** to what shows on the pass itself, for example `Store Loyalty Card`.

<img src="/apple-wallet-passes-pass-builder-2.webp" alt="Basic information section with Pass Name, Description, and Logo Text fields"/>

4. Design the rest of the pass, then preview and create the campaign.

Full field-by-field walkthrough: [Create Wallet Pass Campaigns](/product/messaging-channels/wallet-passes/wallet-pass-campaigns/).

## Create the store's geozone

The journey needs a live geozone to trigger from, so create one before building the journey.

1. Go to **Campaigns → Geo campaigns** and click **Create geozone**.

<img src="/push-notifications-geo-based-push-1.webp" alt="Geo campaigns Get Started screen with map view and Create geozone action in the Pushwoosh control panel"/>

2. Enter a **Campaign name**, for example `Downtown store`.

<img src="/push-notifications-geo-based-push-2.webp" alt="Geozone form section with Campaign name and Aggregated statistics fields"/>

3. Under **Set the trigger location**, choose **Circle**, search for the store's address, and set the **Range**.

<img src="/push-notifications-geo-based-push-5.webp" alt="Trigger location set to Circle mode with an address search result and a range circle drawn on the map"/>

4. Under **Entry actions**, turn on [**Fire event**](/product/messaging-channels/push-notifications/geo-campaigns/create-geozone/#fire-event). Leave **Event name** empty so the default `PW_GeozoneEntered` is used.
5. Turn [**Send push**](/product/messaging-channels/push-notifications/geo-campaigns/create-geozone/#send-push) off if you only want the journey to message the shopper, not a separate geozone push on the same entry.
6. Set **Cooldown** (**Standalone** with a short duration is enough to start) and **Campaign schedule** (**Always active** unless you need set hours), then click **Save**. The event is available in **Trigger-based entry** as soon as you save.

<img src="/push-notifications-geo-based-push-6.webp" alt="Cooldown mode dropdown set to Standalone with a 2-day 1-hour duration"/>

Full field-by-field walkthrough: [Create a geozone](/product/messaging-channels/push-notifications/geo-campaigns/create-geozone/).

<Aside type="note">
`PW_GeozoneEntered` fires when a device enters and the geozone's entry actions are allowed to run (campaign schedule active, [cooldown](/product/messaging-channels/push-notifications/geo-campaigns/create-geozone/#choose-a-cluster-and-cooldown) allows delivery, and the user granted location permission).
</Aside>

## Build the journey

Go to **Campaigns → Customer Journey Builder**, click **Create campaign**, and build everything below on one canvas.

### Set the entry

1. Add a [Trigger-based entry](/product/customer-journey/journey-elements/entry-elements/trigger-based-entry/) element to the canvas.
2. Select `PW_GeozoneEntered` as the **Event**.

<Aside type="note" title="Limit to one store">
This guide uses the default event name. Every geozone that leaves **Event name** empty fires the same `PW_GeozoneEntered`, so shoppers from all those stores enter this journey. To limit it to one store, set a unique **Event name** on that geozone and select that name here, or keep the default and click **+ Add condition** to filter by `geozone_code` (or `geozone_name`) for that store.
</Aside>

### Issue the wallet pass

1. Add **Issue Wallet Pass** right after the entry.
2. Name it `Store pass`.

<img src="/how-to-issue-a-wallet-pass-on-geozone-entry-1.webp" alt="Geozone Entry trigger node connected to a Store pass Issue Wallet Pass node on the journey canvas"/>

3. In **Apple Wallet campaign**, select the campaign you created for Apple. In **Google Wallet campaign**, select the campaign you created for Google. Each dropdown only lists campaigns for its own platform. The element issues a pass for each platform you select.

<img src="/journey-elements-issue-wallet-pass-1.webp" alt="Issue Wallet Pass settings with Apple Wallet campaign and Google Wallet campaign as two separate dropdowns, Google Wallet campaign set to Loyalty rewards"/>

### Branch by platform and send the push

<Aside type="note">
You could also branch on the **Platform** [tag](/product/audience-data-and-segmentation/user-data-tags/tags/) with a [Condition split](/product/customer-journey/journey-elements/flow-controls/segment-split/), but a stored tag value doesn't confirm the device can currently receive a push. Use **Reachability check** instead: it confirms the device is registered and **Push Alerts Enabled** is on, checking only the device that entered when you set that scope.
</Aside>

1. After **Issue Wallet Pass**, add a [Reachability check](/product/customer-journey/journey-elements/flow-controls/reachability-check/) element and name it, for example, `iOS Device?`.
2. Under **Push Notifications**, keep only **iOS** selected (remove the other platform chips).
3. Under **Which devices to check**, select **Only the device that entered**, so the check matches the device that triggered the geozone entry, not every device the shopper owns.
4. On the **Push: iOS** branch, add a [Send Push](/product/customer-journey/journey-elements/channels/push/) element.
5. In the message body, insert `{apple_install_link|regular|}`.
6. Turn on **Personalise message with event attributes**, check **Overwrite placeholder**, set **Source event** to `Store pass`, and set **Dynamic attribute** to `apple_install_link`.

<img src="/journey-elements-issue-wallet-pass-11.webp" alt="Overwrite placeholder checked with apple_install_link, Source event and Dynamic attribute dropdowns next to it"/>

7. After you edit the push, reselect the preset so the mapping picks up the new placeholder. Full click path: [Deliver the pass to the user](/product/customer-journey/journey-elements/channels/issue-wallet-pass/#deliver-the-pass-to-the-user).
8. On **All others**, add a second **Reachability check** named `Android Device?`, with **Push Notifications** narrowed to **Android** and the same **Only the device that entered** setting.
9. On its **Push: Android** branch, add **Send Push**. Insert `{google_save_link|regular|}` and map **Dynamic attribute** `google_save_link` the same way as on the iOS branch.
10. Leave the remaining **All others** branch unconnected, unless you have another channel for those users. A branch with no outgoing connection ends the journey there on its own, so it doesn't need an **Exit** element.

A shopper reaches **All others** when their device isn't registered on the platform you're checking, or when their **Push Alerts Enabled** tag isn't `true` for that device (push permission off).

When `PW_GeozoneEntered` fires, the shopper enters the journey, **Issue Wallet Pass** issues their pass, and the matching **Send Push** delivers the install link for their platform.

<Aside type="note" title="Later visits">
If the same shopper reaches **Issue Wallet Pass** again on a later visit, Pushwoosh returns the pass already issued for that campaign instead of creating a new one, and **Send Push** still fires from that new run. Two things gate the later visit: the geozone's [cooldown](/product/messaging-channels/push-notifications/geo-campaigns/create-geozone/#choose-a-cluster-and-cooldown) must have elapsed for `PW_GeozoneEntered` to fire again at all, and the entry's [re-entry setting](/product/customer-journey/journey-elements/entry-elements/trigger-based-entry/#control-whether-users-can-re-enter-the-campaign) only blocks a repeat trigger while the shopper's previous session is still active. That session finishes right after the first visit's push, because neither branch connects to a further step, and a branch with no outgoing connection ends on its own without needing an **Exit** element. So the default **Do not allow re-entry** doesn't stop a later visit. See [Repeat entries and drop conditions](/product/customer-journey/journey-elements/channels/issue-wallet-pass/#repeat-entries-and-drop-conditions) for the pass-issuance side.
</Aside>

### Launch and check

1. Launch the journey when the canvas is ready.
2. After a test entry, check entries and drop-offs on **Issue Wallet Pass** and the stats on each **Send Push**.

<img src="/how-to-issue-a-wallet-pass-on-geozone-entry-3.webp" alt="Assembled journey with Geozone Entry, Store pass, two Reachability checks, and Send Push on each branch"/>