Best way to create a "kit" of items, want to sell a 3 pack of single item at discount, track inventory correctly

Hi, so we are planning to sell an item. We want to sell:

  • item ($10)
  • 3 pack of item ($25)
  • 5 pack of item ($40)

I’m trying to figure out best way to do this where if we have a quantity of 100 item, it would say we have 20 x 5 pack available, and 100 x 1 item. And if we sell a 5 pack, we now have 95 quantity available.

I see the variation, stock, options on the item creation screen, but essentially we want to sell a new sku, which the fulfillment is made up of other skus, like a kit of other items.

What is the correct way to do this?


With items created in the Catalog each variation will have it’s own sku. If you’d like to sell that item in packs like you’ve described you’ll want to track the inventory in multiple units. :slightly_smiling_face:

Ok… this does require a subscription upgrade though correct?

We’re definitely not a retail establishment… e-commerce only

Yes, that will require Retail if you want to manage inventory that way. Otherwise you can have a function that updates the inventory each time a pack is sold. For example when a pack of 5 is sold inventory is reduced by 5. Here’s a Ruby example of this:

require 'square'
require 'dotenv/load'

# Load your Square access token and location ID from a .env file

# Set your Square access token
access_token = ENV['SQUARE_ACCESS_TOKEN']

# Initialize the Square client
Square.configure do |config|
  config.access_token = access_token

# Define the item ID for the 5-pack item
five_pack_item_id = 'your_5_pack_item_id'

# Function to reduce inventory by 5 when a 5-pack is sold as a single item
def reduce_inventory_by_5
  # Initialize a Square client
  square_client =

  # Retrieve the current inventory level of the 5-pack item
  response = square_client.inventory.retrieve_inventory_count(
    catalog_object_id: five_pack_item_id

  if response.success?
    # Calculate the new inventory count after selling a 5-pack as a single item
    current_inventory =
    new_inventory = current_inventory - 5

    if new_inventory >= 0
      # Update the inventory count
      response = square_client.inventory.update_inventory_count(
        catalog_object_id: five_pack_item_id,
        inventory_count: {
          quantity_on_hand: new_inventory

      if response.success?
        puts "Inventory updated. New count: #{new_inventory}"
        puts "Error updating inventory: #{response.errors.join(', ')}"
      puts "Insufficient inventory to sell as a single item."
    puts "Error retrieving inventory: #{response.errors.join(', ')}"

# Call the function to reduce inventory by 5


Interesting… ok. Is there a spot in Square that supports these types of after-purchase functions or is this something that would be completely external?

This would be something completely external. :slightly_smiling_face:

Ok thanks, I think I can work with that. Sounds like we could do an hourly lambda to keep inventory in sync without too much issue.