How to create Shopify wholesale accounts without an app

John

Written by John

2022
ShareShare on TwitterShare on FacebookShare with Email

Whatever your ecommerce business needs, you can bet that Shopify has an app for it. But when it comes to adding wholesale functionality to a site, we found that the third-party apps out there - to put it politely - could be a whole lot better. Here’s why:

  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. Some discounts worked, some didn’t

So instead of continuing to subscribe to something that simply doesn’t work, we set about figuring out what Shopify's discount code feature had to offer. From here, we utilised this feature with our own custom code to provide a better solution.

Read on to discover how we hacked it and learn how to create a Shopify whole account without a third-party app, too.

Create 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 segment” 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.

Set up the discount code

To set up a unique discount for our “Trade Customers” 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 customer segment” and then select your customer group, eg: “Trade Customers”.

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 or the Shopify CLI to push your changes.

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


Set up 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 customer.tags contains 'trade' %}
  <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.

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 is outside of the scope of this post.

Apply the discounted price to the product

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

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 customer.tags contains 'trade' %}
  {% 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 qty = qty | default: 1 %}
{% 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 customer.tags contains 'trade' and is_discounted %}
  {% assign discount = 100.0 | minus: percentage_off | divided_by: 100.0 %}
  {% assign product_price = product.price | times: discount %}
{% endif %}

{{ product_price | times: qty | money }}

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).

The qty variable will make more sense a litter later.

Now head back to the product.liquid template/section and 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 snippet:

{% render 'calc-product-price', product: product %}

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

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 %}

Apply price change to the collection

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

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 to render the trade price.

In the product-item.liquid snippet find where the price is getting output (eg: {{ product.price | money }}), and replace this with our calculation snippet:

{% render 'calc-product-price', product: 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:

{% render 'calc-product-price', product: prod %}

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

Apply the updated price to 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.

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 %}

Once you find the price, replace it with our calculation snippet, ensuring that we pass in the line item’s associated product, e.g:

{%- render 'calc-product-price', product: item.product -%}

Remember the qty variable I mentioned earlier? Before showing the trade price this time, we need to multiply it by the quantity of the item:

{%- render 'calc-product-price', product: item.product, qty: item.quantity -%}

Our last step is to calculate the cart total price:

{% assign cart_total_price = 0 %}

{% for item in cart.items %}
  {% assign percentage_off = 20.0 %}
  {% assign discounted_collections = 'collection-one|collection-two|collection-three' | split: '|' %}

  {% assign is_discounted = false %}

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

  {% if customer.tags contains 'trade' and is_discounted %}
    {% assign discount = 100.0 | minus: percentage_off | divided_by: 100.0 %}
  {% else %} 
    {% assign discount = 1.0 %}
  {% endif %}
  
  {% assign product_total = item.final_price | times: discount | times: item.quantity %}

  {% assign cart_total_price = cart_total_price | plus: product_total %}
{% endfor %}

Next, 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.

Add a trade label to 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:

{% if customer.tags contains 'trade' %}Trade Account{% endif %}

And there you have it - wholesale functionality without the bugs, or the cost, of a Shopify app.

Let us take you further than you’ve ever been