How to Create Shopify Wholesale Accounts without an App

Back to all journal posts

It was after five days of painful back and forth with multiple 3rd party apps for wholesale functionality and sleepless nights trying to figure out why and how these apps are charging money for something that simply doesn't work. The problems we faced were as follows:

  1. We had to wait for the app developer to manually install the app on our store
  2. Random generated discount codes were being generated
  3. Discounts randomly worked

To solve the issue, we set out to figure what Shopify's discount code feature had to offer and how we could utilise this with customers and some custom code. Check out our process of how we did this below.

The Customer Group

The easiest way to assign a discount code to many customers is by creating a customer group. The discount will also automatically apply to any future customers who are later added to the group.

To get started, simply add a tag to your customers, for example: “trade”.

Next, on the customers listing page, perform a search by filtering by the tag you added in the previous step.

Once you add the filter, a custom search will be performed and a list of your tagged customers will be shown. Whilst in this custom search view, click “Save search” to create a new group.

You’ll be prompted for a name; this can be anything you like and will only be shown in the Admin panel.

You should now see a new, easy to access tab at the top of the customers panel.

The Discount Code

To setup a unique discount for our “Trade Accounts” group, head over to the Discounts section in Shopify’s Admin and create a new discount code.

You can name this code anything you like, just note that this will be shown to customers at checkout and on their orders.

Next, fill out the discount as per your own needs. You can use any discount type (percentage, fixed amount, etc), add minimum orders — whatever your needs are for this customer group. Do note that this post will be referring to the percentage discount type with no minimum order, therefore certain code snippets might require significant tweaking to meet your discount rules.

The only requirement is that under Customer eligibility, you select “Specific groups of customers” and then select your customer group, eg: “Trade Accounts”.

You can check the discount summary at the top right of the page. If you’re happy with the discount rules, click save (note: you can come back and change these details at any time!)

Time to dig into some code!

You are free to edit your theme’s code via the Shopify Admin, or using a code editor and using a tool like Themekit to push your changes.

Please note that since in our example we’ve been using “Trade Accounts”, we’ll continue to do so in the code snippets below, feel free the rename any files and variables as you need — just make sure to stay consistent throughout this section.

The Check

Create a new snippet called trade-account-check.liquid and paste in the following code:

{% assign is_trade_account = false %}

{% if customer.tags contains 'trade' %}
  {% assign is_trade_account = true %}
{% endif %}

This snippet will ensure that we can easily check if the currently logged in user has a Trade Account.

The Cart

Head over to the cart.liquid template/section. Here we’ll need to do a few things, firstly we’ll automatically apply the discount code if a user has a trade account, using the following snippet. Make sure to paste it between the opening and closing <form> tags, since it is a hidden input the user won’t see it on the page.

{% if is_trade_account %}
  <input type="hidden" name="discount" value="TRADE_DISCOUNT"/>
{% endif %}

Note that if you named your discount code something other than “TRADE_DISCOUNT”, please update the value.

So at this point the discount will automatically be applied if a Trade Account user is logged in and submits the Cart form, they will see the discounted prices on the Checkout page.

This is great, however it would be much better if the product prices throughout the site, including the Cart page itself, reflected the discounted prices when a Trade Account user is logged in.

Let’s continue with some more code snippets which will calculate the product prices based on a few editable discount rules.

Please note that the following example doesn’t take minimum requirements into consideration (min. quantity of items, or purchase amount). While it is technically still possible to implement this Trade Accounts technique using minimum requirements, it requires much more custom code which are outside of the scope of this post.

The Product

The easiest place to start applying the conditional discount is the Product page since we only have 1 product price to worry about.

We’ll begin by adding our trade-account-check.liquid snippet to the top of the product.liquid template/section:

{% include 'trade-account-check' %}

This gives us access to the required is_trade_account variable needed to check whether we should apply a discount or not.

Next we’ll be creating the snippet in charge of calculating product prices; this snippet will likely need some editing to suit your use case, so read the snippet titles carefully and make any changes necessary to follow the rules of your discount code.

Create a new snippet called calc-product-price.liquid and paste the code snippet that most closely resembles your discount code rules:

1) If the discount applies to the entire store and is a percentage type discount:

{% assign percentage_off = 20.0 %}
{% assign product_price = product.price %}

{% if is_trade_account %}
  {% assign discount = 100.0 | minus: percentage_off | divided_by: 100.0 %}
  {% assign product_price = product.price | times: discount %}
{% endif %}

Edit the first line as needed, the above example is for a 20% discount.

2) If the discount applies only to a particular (or multiple) collections and is a percentage type discount:

{% assign percentage_off = 20.0 %}
{% assign discounted_collections = 'collection-one|collection-two|collection-three' %}

{% assign is_discounted = false %}
{% assign product_price = product.price %}
{% assign discounted_collections = discounted_collections | split: '|' %}

{% for collection in product.collections %}
  {% if discounted_collections contains collection.handle %}
    {% assign is_discounted = true %}
    {% break %}
  {% endif %}
{% endfor %}

{% if is_trade_account and is_discounted %}
  {% assign discount = 100.0 | minus: percentage_off | divided_by: 100.0 %}
  {% assign product_price = product.price | times: discount %}
{% endif %}

Edit the first and second line as needed, the above example is for a 20% discount applied only to the collections within the pipe-delimited list (make sure to use collection handles).

Now head back to the product.liquid template/section and include the snippet:

{% include 'calc-product-price' with product %}

Notice we pass in the product as a variable, this will become useful when the product object isn’t available on other pages.

Finally, we can update the product price! In the template/section find where the price is getting output eg {{ product.price }}, and replace this with our new product_price variable from our calculation snippet:

{{ product_price | money }}

Remember, this variable will automatically fall back to the regular price if the current logged in user isn’t a Trade Account or if the product isn’t in a discounted collection, so no need for an if statement.

If you’d like to conditionally show the original price, perhaps with a strikethrough, to indicate that the discount is being applied, add the following:

{% unless product_price == product.price %}
  {{ product.price | money }}
{% endunless %}

The Collection

Most of the hard work was done in The Product section, so we can reuse the snippets that were created earlier.

We’ll begin by adding our trade-account-check.liquid snippet to the top of the collection.liquid template/section:

{% include 'trade-account-check' %}

This gives us access to the required is_trade_account variable needed to check whether we should apply a discount or not.

Next we’ll need to find where the collection products are getting looped, we need to make sure to include the snippet inside the loop so that the price can be recalculated each time. In most themes the actual product info will be included to keep collection template clean — this will look a little different per theme, so check for something that looks like this:

{% for product in collection.products %}
  {% include 'product-item' %}
{% endif %}

In the above example, we need to look for a snippet called product-item.liquid. Inside the product item snippet, we can include our calculation snippet at the top of the file:

{% include 'calc-product-price' with product %}

Please note that the variable used is still product which allows us to use this shorthand syntax, if the collection products loop used a different variable name like prod, we’d have to update the snippet like so:

{% include 'calc-product-price' with product: prod %}

Finally, we can update the product price again! In the product-item.liquid snippet find where the price is getting output (eg: {{ product.price | money }}), and replace this with our product_price variable from our calculation snippet:

{{ product_price | money }}

Once again, you can include the earlier snippet to show the original price here too.

The Cart (Again)

Now that the Product and Collection pages have been updated, it’s time to come back to the Cart page and apply the discounted prices and totals here.

As always, we’ll begin by adding the trade-account-check.liquid snippet to the top of the cart.liquid template/section:

{% include 'trade-account-check' %}

Next we’ll need to apply the discount to each line item in the cart, keeping the quantity in mind too. Find the line that starts looping over the items in the cart, it should look something like:

{% for item in cart.items %}

Directly after this line, include our calculation snippet, ensuring that we pass in the item’s associated product:

{%- include 'calc-product-price' with product: item.product -%}

Once again, we have access to a product_price variable. The only difference before applying it this time is that we need to multiply it by the quantity of the item:

{{ product_price | times: item.quantity | money }}

Our last step is to calculate the cart total price, let’s create one last snippet called calc-cart-total-price.liquid and paste the following code:

{% assign cart_total_price = 0 %}

{% for item in cart.items %}
  {% include 'calc-product-price' with product: item.product %}

  {% assign product_total = product_price | times: item.quantity %}
  {% assign cart_total_price = cart_total_price | plus: product_total %}
{% endfor %}

Next we’ll need to include this snippet in our cart.liquid template/section, the top of the file is a good place for it, just make sure it comes after the Trade Account check:

{% include 'trade-account-check' %}
{% include 'calc-cart-total-price' %}

This snippet gives us access to a cart_total_price variable which adds all our cart items together keeping discounts and quantities in mind.

In the cart.liquid template/section find where the cart total price is getting output (eg: {{ cart.total_price | money }}), and replace this with our new variable:

{{ cart_total_price | money }}

The Cart page should now reflect all the discounts that are offered to the Trade Account users, while regular users will continue to see the normal prices.

The Account

It may be useful for customers to know or be able to double check whether they have been given a Trade account. Using our trade-account-check.liquid snippet, we can output an extra line on the Account page:

{% include 'trade-account-check' %}

{% if is_trade_account %}Trade Account{% endif %}

As mentioned earlier, it is recommended to simply include the trade-account-check.liquid snippet at the top of the template and then use the is_trade_account wherever needed.