🛍
Picket Shopify App - Merchant Documentation
Token gated commerce with a few simple clicks from your Shopify dashboard
Token gated products and discounts are common use cases of the Picket API. The Picket app on Shopify allows you to set up token gated discounts and token gated products from Shopify admin without the need for custom code.

Token Gated Discounts:
Enabling token gated discounts allows you to set discounts that can only be applied by users who hold the NFT or other token that you specify. You can do this on a product by product basis. You also can choose to require NFTs or tokens on any of the chains that Picket supports.
Token Gated Exclusive Products
Enabling token gated exclusive products allows you to set products as exclusives that can only be purchased by users who hold the NFT or other token that you specify. You can do this on a product by product basis. You also can choose to require NFTs or tokens on any of the chains that Picket supports.
The Shopify app is currently in beta. For private beta access, sign up here: https://forms.gle/uumfAnnzwFPtGoyeA
Before you begin, make sure that you have the Picket app for Shopify installed and open in Shopify admin.
- 1.Add your Picket API Key to Shopify Admin
Copy your publishable key and paste it in the corresponding field in Shopify admin.
2. Select the tokens you would like to use for your token gate
For Ethereum and other EVM chains, this is done by putting the contract address of the tokens you'd like to use for your token gate into the contract address field.

If you don't know the contract address of the tokens you'd like to use for your token gate, you can find it for Ethereum and other EVM based chains by searching for your desired NFTs or other tokens here.
3. Select how many tokens you want to require users to have
For NFT token gates this is most commonly set to 1. However, this is up to you.

4. Set the discount rate you'd like to give to users who have the token you require

5. Select any products that you'd like the discount to apply to for users who hold your chosen token.

Follow the same steps above for setting token gated discounts. However, instead of selecting products at the end as discount products within the "Token Gate Configuration by Product Section" within Shopify Admin. Select products as exclusives with the checkboxes shown below:

Once you've configured your token gated exclusive and discounted products, you need to make it visible within your Shopify Shop theme. Like many other Shopify apps, this requires modifying the theme code, creating and rendering snippets, and adding
data-picket
attributes to existing elements. We'll walk you through each step in the process below, but if you get stuck or run into issue, don't hesitate to reach out to [email protected].
To get started, we need to modify your Shop's theme code.
- 1.From your Shopify admin, go to Online Store > Themes.
- 2.Click Actions > Edit code.
The code editor shows a directory of theme files on the left, and a space to view and edit the files on the right.
Once you've opened up the Shop theme code editor, you'll see a directory called Snippets. Open the directory to reveal an Add a new snippet button.

We are going to use this button to create five snippets for different token gating functionality
- picket.liquid
- picket-product.liquid
- picket-exclusive-badge.liquid
- picket-discount-product.liquid
- picket-cart-footer.liquid
Create each of these snippets and copy-paste their contents from below:
picket.liquid
picket-product.liquid
picket-exclusive-badge.liquid
picket-discount-price.liquid
picket-cart-footer.liquid
picket.liquid
{% comment %}
This snippet must be named: picket.liquid
{% endcomment %}
<script src="https://cdn.jsdelivr.net/npm/@picketapi/picket-js/dist/global.js"></script>
<style>
:root {
--picket-purple: #5469d4;
}
.picketPurpleColor {
color: var(--picket-purple);
}
.picketButton {
background-color: var(--picket-purple);
color: #fff;
border: none;
font-family: Assistant, sans-serif;
width: 100%;
margin: 1rem 0;
padding-top: 15px;
padding-bottom: 15px;
text-align: center;
}
.cartMessage {
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
@media screen and (min-width: 750px) {
.cartMessage {
text-align: right;
justify-content: flex-end;
align-items: ce;
}
}
</style>
<script src="https://picket-shopify.fly.dev/store.js" ></script>
picket-product.liquid
{% comment %}
This snippet must be named: picket-product.liquid
{% endcomment %}
{%- if product.tags contains "picket_discount" or product.tags contains "picket_exclusive" -%}
<div style="margin: 8px 0; display: none; align-items: center;" data-picket="success-container">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="20" height="20" class="picketPurpleColor">
<path fill-rule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm13.36-1.814a.75.75 0 10-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 00-1.06 1.06l2.25 2.25a.75.75 0 001.14-.094l3.75-5.25z" clip-rule="evenodd" />
</svg>
<span style="margin-left: 8px; line-height: normal;" data-picket="success-message">
You're saving {{ shop.metafields.picket.discount_rate | metafield_tag }}% as a token holder
</span>
{%- if product.tags contains "picket_discount" -%}
<span style="display: none;" data-picket="product-discount"></span>
{%- endif -%}
{%- if product.tags contains "picket_exclusive" -%}
<span style="display: none;" data-picket="product-exclusive"></span>
{%- endif -%}
</div>
<button type="button" class="button picketButton" disabled="true" data-picket="login" >
Verify Token Ownership
</button>
{%- endif -%}
picket-exclusive-badge.liquid
{% comment %}
This snippet must be named: picket-exclusive-badge.liquid
{% endcomment %}
{%- if product.tags contains "picket_exclusive" -%}
<span class="badge" style="margin: 0 1rem; color:white; background-color: var(--picket-purple); border: none;">
Token Exclusive
</span>
{%- endif -%}
picket-discount-price.liquid
{% comment %}
This snippet must be named: picket-discount-price.liquid
{% endcomment %}
{%- if product.tags contains "picket_discount" -%}
<span style="margin: 4px 0; display: flex; align-items: center;" data-picket="price-discount-container">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 27 27" fill="currentColor" style="color: var(--picket-purple);">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.0883789 13.5C0.0883789 25.401 12.1676 31.4412 19.095 23.0923C23.5363 17.763 23.5363 9.23694 19.095 3.90849C12.1679 -4.44045 0.0883789 1.59978 0.0883789 13.5008V13.5ZM24.4243 22.3816H20.8722C19.4515 24.336 17.6743 25.9337 15.5429 27C19.2732 27 22.1158 25.4011 24.4246 22.3816H24.4243ZM26.733 16.6979H23.0027C22.6473 18.4739 22.1146 20.0729 21.4038 21.3162H24.9559C25.844 20.0727 26.3766 18.4739 26.732 16.6979H26.733ZM20.871 4.61859H24.4232C22.1144 1.59891 19.2721 0.000244141 15.5415 0.000244141C17.673 1.06653 19.4492 2.66439 20.8708 4.61859H20.871ZM23.0026 10.3024H26.7329C26.3774 8.52628 25.8448 6.92736 24.9568 5.50662H21.4047C22.1155 6.92728 22.6481 8.5263 23.0036 10.3024H23.0026ZM23.1797 11.1904V15.8088H26.9101V11.1904H23.1797Z" fill="currentFill"/>
</svg>
<span style="padding-left:8px;" class="price-item price-item--regular" data-picket="price-discount-amount">
{{ 100 | minus: shop.metafields.picket.discount_rate | divided_by: 100 | times: price | money_with_currency }}
</span>
</span>
{%- endif -%}
picket-cart-footer.liquid
{% comment %}
This snippet must be named: picket-cart-footer.liquid
{% endcomment %}
<div class="cartMessage" data-picket="cart-message-container" style="display: none">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 27 27" fill="currentColor" style="color: var(--picket-purple);">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.0883789 13.5C0.0883789 25.401 12.1676 31.4412 19.095 23.0923C23.5363 17.763 23.5363 9.23694 19.095 3.90849C12.1679 -4.44045 0.0883789 1.59978 0.0883789 13.5008V13.5ZM24.4243 22.3816H20.8722C19.4515 24.336 17.6743 25.9337 15.5429 27C19.2732 27 22.1158 25.4011 24.4246 22.3816H24.4243ZM26.733 16.6979H23.0027C22.6473 18.4739 22.1146 20.0729 21.4038 21.3162H24.9559C25.844 20.0727 26.3766 18.4739 26.732 16.6979H26.733ZM20.871 4.61859H24.4232C22.1144 1.59891 19.2721 0.000244141 15.5415 0.000244141C17.673 1.06653 19.4492 2.66439 20.8708 4.61859H20.871ZM23.0026 10.3024H26.7329C26.3774 8.52628 25.8448 6.92736 24.9568 5.50662H21.4047C22.1155 6.92728 22.6481 8.5263 23.0036 10.3024H23.0026ZM23.1797 11.1904V15.8088H26.9101V11.1904H23.1797Z" fill="currentFill"/>
</svg>
<small style="margin-left: 8px; line-height: normal;" >{{ shop.metafields.picket.discount_rate | metafield_tag }}% discount will be applied to token discounted products at checkout</small>
</div>
Well done! Now we can start modifying the theme's existing code to enable token gating.
The first step in enabling token gating is to allow users to verify token ownership. This is done via the
picket-product
snippet. Place this snippet on product pages above payment buttons like "Add to Cart", "Buy Now", etc.
In the Dawn theme, this snippet should be place in sections/main-product.liquid right above the submission form
{% comment %}
This snippet display the "Verify Token Ownership" button
and a success message for token holders.
Place it above the payment buttons, like "Add to Cart", "Buy Now", etc
{% endcomment %}
{% render 'picket-product', product: product %}
Now users are able to verify token ownership! If you are looking at a token exclusive or discounted product, you should see a button like this

Next, we need to prevent users who don't hold the required tokens from adding token holder exclusive products to their cart.
To prevent users from purchasing exclusive products, we remove the payment buttons until the user has verified that they hold the necessary tokens. We do this by conditionally adding
style="display: none;"
and data-picket="payment-buttons-container"
if the product is a token holder exclusive. In the Dawn theme, this snippet should be place in sections/main-product.liquid at the outer most
<div>
in the submission form{% comment %}
This is an example of conditionally adding the field to a div element
{% endcomment %}
<div
{%- if product.tags contains "picket_exclusive" -%}
data-picket="payment-buttons-container"
style="display: none;"
{%- endif -%}
>
Depending on your shop theme, you may have to add this logic to multiple places. In the Dawn theme, you only need to add it one place. For token holder exclusive products, the payment buttons should be hidden, so you only see the verify token ownership button, like this

We now have token gated products! Next let's improve the user experience by showing which products are token gated and/or eligible for token holder discounts.
We want to indicate to users which products are exclusive to token holders. Similar to how we indicate which items are on sale, we are going to show a badge next to the price of products that are exclusive to token holders.
Add the following
render
snippet to wherever your theme displays badges next to the product price. In the Dawn theme, this snippet should be place at the bottom of snippets/price.liquid before the closing
</div>
{% comment %}
Remember to pass the product object as an argument to the render function
{% endcomment %}
{% render 'picket-exclusive-badge', product: product %}
Once inserted, you'll see a badge next to the price of token holder exclusive products, like this

Next, we'll show the discounted price for products that are discounted for token holders.
There are a few steps to showing the discounted product price for token holders. First, we are going to find the
<div>
s that contain the price displayed in our shop. Second, we will render
the discounted price for token holders. And finally, we'll add mark the regular price with a data attribute, so we can cross it out for users who hold the necessary tokens.Find the container around the price displayed in your shop. In all relevant containers, add
data-picket="price-container"
to the container elementIn the Dawn theme, the price container
<div>
lives in snippets/price.liquid with the class name "price__container"{% comment %}
Add data-picket="price-container" to the existing element
{% endcomment %}
<div data-picket="price-container">
Within the price container, we are going to
render
the discounted price that token holders payIn the Dawn theme, this snippet should be placed in snippets/price.liquid between the regular price and the sale price
{% comment %}
Remember to pass the product object and the numeric price
as arguments to the render function
{% endcomment %}
{% render 'picket-discount-price', product: product, price: price %}
Once this snippet is inserted, we should see the discounted price displayed below or next to the original price

Lastly, we are going to mark the regular price with a
data-picket="price-regular-amount"
. This allows us to strikethrough the regular price once a user has verified token ownership.In the Dawn theme, this snippet will be in snippets/price.liquid where the class name is "price-item--regular"
{% comment %}
An example of how to modify the regular price element
{% endcomment %}
<span data-picket="price-regular-amount">
{{ money_price }}
</span>
Amazing! Once a user verifies token ownership, they will automatically have the discount code applied at checkout to the relevant products and will see the new prices like this

Finally, we want to show users that have successfully verified ownership that they will have a discount applied at checkout to any eligible products.
Due to limitations of Shopify, we can't show the token holder discount applied when the user views the cart. Instead, we display a message to inform users that they will have discounts automatically applied at checkout.
To add the cart message, find the code that displays the checkout button on the cart page
In the Dawn theme, this snippet will be at the bottom of sections/main-cart-footer.liquid right after the cart tax notes
{% render 'picket-cart-footer' %}
And that's it! For users that have verified token ownership, they'll see a message like this

Cart Message for Token Holders
And that's it! You are all done. You have enabled token gated products with an awesome user experience all controllable from an admin panel.
Need help setting up your token gated products and discounts? If you have any trouble with these instructions or just have a few questions, we're here to help. Email us at [email protected] or find some time for a zoom call with a member of our engineering team for more hands on realtime help.
Last modified 9mo ago