Skip to main content

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.

Note

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.

Learn more about 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

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

Generate a POS UI Extension using the Shopify CLI.

Project

You'll need to generate a new extension in your app.

Anchor to Create the extensionCreate the extension

  1. Navigate to your app directory.

  2. Run the following command to create a new extension:

    shopify app generate extension

  3. Select POS UI Extension as the extension type, and then provide a name for your extension.

  4. Select a language for your extension.

Configure your extension using the TOML file to render your extension at the correct target.

API version

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.

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.

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.

  1. Navigate to your app directory and start your development server:

  2. Press p to open the developer console.

  3. In the developer console, click on the view mobile button to preview your extension.

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.

Note

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.

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.
Was this page helpful?