Create the gated discount function
In this tutorial, you'll use Shopify Functions to apply the discount specified in the GateConfiguration
. The server-side validation that's implemented in this tutorial prevents users from receiving applicable gated discounts without passing the gate.
This is the last part of a tutorial series to build a tokengating app. Complete the previous tutorials before starting this tutorial:
What you'll learn
Anchor link to section titled "What you'll learn"- How to build a Shopify Function to apply the discount specified in the
GateConfiguration
- Read and validate the HMAC signature stored as a cart attribute to verify your app's evaluation has not been tampered with. This will ensure your exclusive discount only goes to those who have met your gate requirements, as deemed by your app's evaluation.
Requirements
Anchor link to section titled "Requirements"You've installed Rust.
On Windows, Rust requires the Microsoft C++ Build Tools. Make sure to select the Desktop development with C++ workload when installing the tools.
You've installed cargo-wasi:
Step 1: Initialize a product discount extension
Anchor link to section titled "Step 1: Initialize a product discount extension"To automatically apply exclusive discounts for buyers at checkout, add a product discount function as an extension to your app.
- Navigate to your app directory.
Run the following command to create a new product discount extension:
Choose the
Rust
language option.Navigate to
extensions/tokengating-function
Replace your
Cargo.toml
file with the following:Build the function's Wasm module.
If you encounter any errors, ensure that you've installed Rust and cargo-wasi.
Step 2: Write the function logic
Anchor link to section titled "Step 2: Write the function logic"The function logic uses the input from the metafield that was defined when you created the GateConfiguration
. The following _shopify_gate_context
cart attribute key is the gate context that was created in the previous tutorial. This gate context is added here so that the function can determine whether the tokengated discount should be applied.
Input Query
Anchor link to section titled "Input Query"Copy the following code into extensions/tokengating-function/input.graphql
.
This file defines the input for the function. Replace tokengating-example-app
with the namespace that you used when creating your GateConfiguration
.
Function Logic
Anchor link to section titled "Function Logic"Your main discounting logic is located in extensions/tokengating-function/src/main.rs
directory and written in Rust. By the time the code in this file executes, the input query above will have resolved and we have everything we need to accomplish our tasks within the function which are:
- Check that the automatic discount is relevant by reading its metafield for the
GateConfiguration
and only evaluating further if it matches the line item'sGateConfiguration
- Verify the attached HMAC value, which is your app's attestation that this buyer has met the requirements to unlock the gate.
- If the above HMAC is verified, apply the discount by adding the corresponding discount object and returning it as the function's output. Otherwise, the function will not apply the discount.
The following code will set up the function logic to determine if the gate is unlocked. Replace the code in src/main.rs
with the following:
The code checks that your automatic discount is relevant to the cart's line items, and that your app has attested that the buyer has unlocked the gate. You can review the culmination of this logic by looking at the definition of gate_unlocked
.
Step 3: Deploy your function
Anchor link to section titled "Step 3: Deploy your function"Before deploying, ensure that the
api_version
in yourextensions/tokengating-function/shopify.extension.toml
is set tounstable
. In the end, it should look like the following:Because the
api_version
isunstable
, you need to update theschema.graphql
file. Navigate to theextensions/tokengating-function/
directory and run the following code:Deploy your app along with the function.
Step 4: Preview the function on a development store
Anchor link to section titled "Step 4: Preview the function on a development store"To test your function, you need to make it available to your development store.
If you're developing a function in a language other than JavaScript or TypeScript, ensure you have configured
build.watch
in your function extension configuration.Navigate back to your app root:
Use the Shopify CLI
dev
command to start app preview:You can keep the preview running as you work on your function. When you make changes to a watched file, Shopify CLI rebuilds your function and updates the function extension's drafts, so you can immediately test your changes.
Follow the CLI prompts to preview your app, and install it on your development store.
Step 5: Test the function
Anchor link to section titled "Step 5: Test the function"- Install the Shopify GraphiQL app on your store.
In the GraphiQL app, in the API Version field, select the unstable version.
Find the ID of your function by executing the following query:
The result contains a node with your function's ID:
Copy the ID and navigate to
/web/api/create-discount.js
to replace theYOUR_FUNCTION_ID
.
You've now:
- built an admin app for merchants to configure gates and the corresponding discount
- deployed a theme app extension to display those gate requirements to buyers along with a wallet connection experience
- used Shopify Functions to apply the discount when gated products are added to the cart
To see the function in action:
- Navigate to your gated product's detail page and unlock the product.
- Add the product to your cart.
- View your cart and check that the exclusive discount is applied. Note that the discount should be visibile in the cart, even before initiating the checkout process.
Developer tools and resources
Anchor link to section titled "Developer tools and resources"To view all of the code used for the tokengating example app, you can download the source code.