Build a loyalty extension
This tutorial will teach you how to create a loyalty extension on the Customer Details screen that allows merchants to award loyalty points and redeem them for order discounts on POS.
This tutorial uses the Shopify Admin API to calculate the loyalty points to be awarded to a customer. If you plan to include order, customer or any other Shopify admin data, you'll need additional access scopes.
Anchor to What you will achieve:What you will achieve:
- Create a POS extension that calculates available points, and allows a customer to redeem discounts by using their points.
- Leverage Direct API Access to query the Admin graphQL API directly from the POS extension.
Requirements
Scaffold an app, and make sure you add the read_customers
and write_customers
access scopes to the app.toml
file.
Generate a POS UI Extension using the Shopify CLI.
Project
Anchor to Create an extensionCreate an extension
You'll need to generate a new extension in your app.
Anchor to Create the extensionCreate the extension
-
Navigate to your app directory.
-
Run the following command to create a new extension:
shopify app generate extension
-
Select
POS UI Extension
as the extension type, and then provide a name for your extension. -
Select a language for your extension.
Configure your extension using the TOML file to render your extension at the correct target.
Make sure that the following package versions in your package.json
match the api_version
you have set in the extension TOML file:
@shopify/ui-extensions
@shopify/ui-extensions-react
Version mismatches can cause build errors or unexpected behavior at runtime.
Anchor to Fetch the points balance using Direct APIFetch the points balance using Direct API
Fetch the points available to the customer by querying the Customer metafield, using a Direct API graphQL request. Then, store the available discounts in a stateful hook.
Define the different discount tiers for your loyalty program.
Implement a Direct API fetch to get the point balance stored on a customer metafield. Note that you may have to create your own metafield definition to store the point balance. However, the code for the mutation will automatically create the metafield definition for you, if one doesn't exist.
Implement a hook that invokes the Direct API fetch method, updating its internal state with the latest point balance and available discounts.
Anchor to Build the UIBuild the UI
To build the UI of the extension, you'll need to build the UI of your extension using the POS UI extension component library.
Extend the pos.customer-details.block.render
target.
Implement the CustomerDetailsBlock
component.
Initialize the POS API.
Subscribe to the useFetchLoyaltyPoints
hook to obtain the points balance and available discounts.
Implement the applyDiscount
function to apply the discount to the cart. The discount title will also contain the number of points available after the transaction is complete.
Implement the main UI block by rendering a button for each available discount. Each button should invoke the applyDiscount
function we previously defined.
Handle the loading and error states.
Anchor to Implement point reward and redemption mechanismImplement point reward and redemption mechanism
To reliably redeem or reward points at the end of a transaction, we can leverage the pos.transaction-complete.event.observe
target to see which discounts were used when the transaction is complete. We can also read the subtotal of the transaction and use this to reward points when no rewards are used.
Implement the pos.transaction-complete.event.observe
target.
Implement a Direct API query to mutate the customer's custom.loyalty_direct_points
metafield to contain the updated point balance.
Look for any loyalty discounts that were applied to the transaction, and deduct the points from the customer's point balance.
If no loyalty discounts were applied, reward the customer with points based on the subtotal (one point per dollar) of the transaction.
Anchor to Test the extensionTest the extension
Congratulations! You've built a loyalty extension that awards and redeems loyalty points.
To test the extension, you'll need to run your app locally and test the extension in the POS.
-
Navigate to your app directory and start your development server:
-
Press
p
to open the developer console. -
In the developer console, click on the view mobile button to preview your extension.
Anchor to Next stepsNext steps
Keep on building your extension! Now that you have implemented a customer details block extension, you can leverage other targets to create incredible merchant experiences.
Add a new pos.purchase.post.block.render
target implementation to provide a block that presents the number of points available to the customer at the end of a transaction.
Implement the pos.home.tile.render
and pos.home.modal.render
to allow rewards to be applied from the smart grid.
Anchor to Troubleshooting common challengesTroubleshooting common challenges
Learn more about troubleshooting your extension.
Use your browser's developer tools to monitor network requests and check for any CORS or authentication issues.
For more information, see Debugging your extension.
Anchor to GraphQL errorsGraph QL errors
If you encounter a GraphQL error, check the following:
- Check that your access scopes include the necessary permissions.
- Check that your query is correctly formatted.