---
title: "Worked Example: Build a Shared-Hosting Product"
description: "This is a worked example that takes an empty catalogue and ends with a shared-hosting plan a customer can buy, configure and have provisioned automatically. It touches every screen in this category in the order you actually need them. Follow…"
url: "https://rackhelm.com/documentation/build-a-shared-hosting-product/"
updated: "2026-09-24"
category: "Products & Catalogue"
---

# Worked Example: Build a Shared-Hosting Product

This is a worked example that takes an empty catalogue and ends with a shared-hosting plan a customer can buy, configure and have provisioned automatically. It touches every screen in this category in the order you actually need them. Follow it once and the pattern will carry over to VPS, game servers and domains. This article is for operators.

## Before you start

- Sign in as a **Super Admin**. Several catalogue screens check capabilities that are not seeded to any other role, so a lesser staff account will hit a 403 partway through.
- If you want automatic provisioning, connect and enable your control panel first, so it appears in the product's **Integration Type** list. You can complete every other step without it and add the integration later.

The plan we are going to build:

| Item | Value |
| --- | --- |
| Group | Web Hosting (Product Grid layout) |
| Product | Starter Hosting |
| Terms | Monthly £4.99, Annually £49.99, with a £10.00 setup fee on monthly only |
| Asks the customer for | A primary domain name |
| Optional extra | Extra Disk — 10 GB or 25 GB |
| Launch offer | 25% off the first invoice, code `LAUNCH25`, first 100 customers |

## Step 1 — Create the billing cycles

Nothing can be priced until cycles exist, and a new install has none.

1. Open **Catalogue → Billing Cycles**.
2. Click **New Billing Cycle**. Label `Monthly`, Months `1`, Sort Order `0`, Active on. Save.
3. Repeat for label `Annually`, Months `12`, Sort Order `1`.

Both should now show as **Active** with "Unused" in the **Used By** column. See [Billing Cycles](/docs/billing-cycles/).

## Step 2 — Create the custom field the plan needs

Shared hosting needs a domain to attach the account to.

1. Open **Catalogue → Custom Fields → New Field**.
2. **Display Name**: `Primary Domain`.
3. **System Key**: `DomainName` — match whatever key your panel integration expects, not the friendly label.
4. **Field Type**: **Text Input**.
5. **Description**: something like "The domain this hosting account will serve, without www." It doubles as the placeholder.
6. Leave **Required Field** on. Save.

See [Custom Fields](/docs/custom-fields/).

## Step 3 — Create the product group

1. Open **Catalogue → Catalogue & Groups** and click **New Group**.
2. On **General**: **Group Name** `Web Hosting`, a short description, **Page Layout** **Product Grid**.
3. On **Display & SEO**: **Group Sort Order** `0`, leave **Include in Store** and **Allow Direct Link** on, and switch **Show Cycle Savings** on so the annual term advertises its saving.
4. On **Configurable Options**: tick **Primary Domain** and leave all three switches on — every plan in this group will need it.
5. Click **Create Group**.

> **Tip:** Assigning the field to the *group* rather than to each product means every future hosting plan inherits it automatically. See [Configurable Options](/docs/configurable-options/).

## Step 4 — Create the add-on

1. Open **Catalogue → Product Addons → New Addon**.
2. **Addon Name** `Extra Disk`, **Category** `Resources`, a one-line description.
3. Leave **Linked Custom Field** as "— None —" unless you have a disk-quota field your panel reads; if you do, pick it here.
4. Leave **Needs provisioning** and **Include in store** on, **Manual (staff setup)** off.
5. Click **Create & Configure Options**.
6. On the configuration screen click **Add Option** twice and fill in:
   - Label `+10 GB`, Value `10240` — Monthly price `2.00`, Annually price `20.00`.
   - Label `+25 GB`, Value `25600` — Monthly price `4.50`, Annually price `45.00`.
7. Click **Save Configuration**.

> **Warning:** Leave a cycle's cell blank if the option is not sold on that term. Typing `0` does not make it free — a zero price with a zero setup fee is treated as unpriceable and the customer is stopped at checkout. See [Product Add-ons](/docs/product-addons/).

## Step 5 — Create the product

Back on **Catalogue → Catalogue & Groups**, open the **Web Hosting** group's **⋯** menu and choose **Add Product** — the group will be pre-selected for you.

### General tab

- **Product Name**: `Starter Hosting`.
- **Group**: already set to **Web Hosting**.
- **Product Description**: the feature list customers read on the store card.
- **Available Upgrades / Downgrades**: empty for now — it only populates once the product is saved into a group.

### Pricing tab

- Leave **One-Time Price (Base)** and **One-Time Setup Fee** blank — this product is priced by cycle.
- In the billing cycles table set **Monthly** Price `4.99`, Setup Fee `10.00`.
- Set **Annually** Price `49.99`, Setup Fee blank.

The counter above the table should read "2 of 2 cycles priced".

### Provisioning tab

- Choose your panel from **Integration Type**.
- Pick the **Panel** this product provisions on.
- Enter the **Package / Plan ID** exactly as the panel names it.
- Optionally set **AutoSSL**, **Suspend after (days past due)** and **Terminate after (days after suspend)**.

Choose **None / Manual Processing** if you are not automating yet — orders wait for staff instead.

### Store & SEO tab

- **Product Sort Order** `0`.
- Leave **Include in Store** and **Allow Direct Link** on.
- Switch **Highlight Product** on if this is the plan you want badged "Most Popular".
- Fill in **SEO Title** and **SEO Description**.

Click **Create Product**. See [Creating and Editing a Product](/docs/creating-and-editing-products/) for the full field reference.

## Step 6 — Attach the add-on

The add-on column only exists on an existing product, so reopen **Starter Hosting**:

1. Go to the **Options & Add-ons** tab.
2. Under **Available Add-ons**, tick **Extra Disk**.
3. Leave the left column alone. **Primary Domain** is assigned on the group, and that picker only shows this product's own assignments, so the field appears unticked here and still reaches the order page. Tick it only if this product needs different switches from the rest of the group.
4. **Save Changes**.

## Step 7 — Create the launch coupon

1. Open **Billing → Coupons → Create Coupon**.
2. **Name** `Launch offer`, **Code** `LAUNCH25`.
3. **Discount Type** **Percentage (%)**, **Discount Value** `25`.
4. **Quantity Limit** `100`. Set an **Expiration Date** if the offer is time-boxed.
5. Leave **Apply to ALL Products & Addons (Global)** off, and under **Restrict to Groups** pick **Web Hosting**.
6. Leave **Apply discount to Setup Fees** and **Apply discount to Addons** on so the whole first invoice is reduced.
7. Click **Create Coupon**.

> **Note:** The discount applies to the checkout it is used on, once. Recurring and duration are stored but not applied to renewal invoices. See [Coupons and Discounts](/docs/coupons-and-discounts/).

## Step 8 — Test it as a customer

1. From the product row's **⋯** menu choose **View in Store**, or copy the **Direct Link to Product** from the **Store & SEO** tab.
2. On `/store`, confirm the **Web Hosting** card is listed.
3. Open the group page and confirm the pricing card shows £4.99 with the "Most Popular" badge if you set it.
4. Open the product. You should see a **Configuration** section with **Primary Domain** marked required, a billing-cycle selector showing both terms with the annual saving, and an **Extra Disk** dropdown defaulting to "None".
5. Add it to the basket, apply `LAUNCH25` in the **Promo Code** box on the checkout page and check the total falls by 25%.

![The customer-facing store page showing the Web Hosting group with the Starter Hosting pricing card](/wp-content/uploads/rackhelm-docs/catalogue-worked-example-store.png)
The end result: the group renders as a pricing grid, with the highlighted plan badged and the annual saving shown.

## If something is missing

| Symptom | Cause and fix |
| --- | --- |
| The group does not appear on `/store`. | **Include in Store** is off on the group, or every product inside it is inactive or hidden. |
| The product page returns 404. | The product is inactive. Activate it from the row's **⋯** menu — **Include in Store** and **Allow Direct Link** are ignored while it is inactive. |
| Saving the product asks for a One-Time Price. | No cycle carries a price. Fill in at least one, or set the base price to `0.01` or more. |
| No **Configuration** section on the order page. | The field is assigned but **Show on Order Page** or **User Changeable** is off, or it was assigned to a different group. |
| **Extra Disk** is missing from the order page. | It is not ticked on the product (and not attached to the group), it is not marked **Include in store**, or it has no price for the cycle being viewed. |
| The coupon is accepted but nothing changes. | The restriction did not match. For this example the restriction must be the **Web Hosting** group; a cycle restriction would also exclude any line with no cycle chosen. |
| Checkout reports a pricing problem. | Something resolved to zero. Check for a cycle or add-on cell containing `0.00` and blank it instead. |
| An order is placed but nothing is created on the panel. | The **Provisioning** tab is set to **None / Manual Processing**, or the **Package / Plan ID** does not exist on the panel. Check the pending-provisioning queue in the admin area. |
