Africa Conglomerate ← All Guides

💰 Pricing Setup

⏱ 12 min read 📋 7 steps 🎯 Beginner 👥 B2B Sellers & Admins

Learn how to configure prices for your products correctly — including setting retail and wholesale tiers, handling multiple currencies, using quantity-break discounts, and understanding why a product might appear to have a price but still fail to add to cart.

Before you begin
  • At least one product must exist in your catalog (see Catalog Management)
  • You must have a B2B account with Seller or Admin role
  • Know your selling currency — this is set on your Company profile and used as the default for all prices

Part 1 — How Pricing Works

Each product can have multiple Price records. The platform picks the best matching price at checkout using a 5-step resolution process. Understanding this prevents the most common setup mistakes.

💡 Key concept: a price record has five dimensions
FieldWhat it controlsCommon mistake
currency Which currency this price is expressed in (e.g. UGX, USD, KES) Setting currency to USD but your company's default is UGX — the price is found but the label shows the wrong currency
customer_tier retail (B2C buyers), wholesale (B2B buyers), or vip Only setting a wholesale price — B2C buyers can't add to cart
min_quantity Minimum order quantity for this price to apply Setting min_quantity=10 on the only price — adding 1 unit fails because no price applies
valid_from / valid_until Date window when this price is active (leave blank = always active) Setting valid_until in the past — the price appears in admin but is invisible to buyers
is_active Master on/off switch for the price record Accidentally deactivating the only price for a product

How the platform finds a price at checkout

When a buyer adds a product to cart, the platform tries these steps in order and stops at the first match:

1

Exact match — buyer's currency + buyer's tier

e.g. a UGX retail price for a retail buyer. Best case — always aim for this.

2

Same currency, retail tier (tier downgrade)

A B2B wholesale buyer gets the retail price when no wholesale price exists in their currency.

3

Any currency + buyer's tier

A US buyer (USD context) can still purchase a UGX-priced product. The price is shown in UGX with an automatic conversion displayed for reference.

4

Any currency + retail (last sensible fallback)

Wholesale buyer, wrong currency — still finds a retail price to fall back on.

5

Absolute last resort — any active price at all

VIP-only prices, exotic currencies — if anything active exists, it is used.

⚠️ When all 5 steps fail
If no valid active price is found for the requested quantity, the platform raises a "has no price configured" error at add-to-cart. See Part 5 — Diagnosing Price Problems for how to fix this.

Part 2 — Adding Your First Price

Every product needs at least one active retail price before buyers can add it to cart.

1

Open the product and go to the Pricing tab

Navigate to Catalog → Products, click your product, then select the Pricing tab.

📸 Screenshot: Product Pricing Tab Shows the product edit page with the Pricing tab highlighted and an empty prices table. /static/guides/images/pricing/01-pricing-tab.png Screenshot: Product Pricing Tab
2

Click + Add Price

Fill in the form with these values for a standard single retail price:

FieldValueNotes
CurrencyUGX (or your local currency)Must match your company's default currency for step-1 resolution
Customer TierretailRequired so B2C buyers can purchase. Add a separate wholesale row later for B2B pricing.
Unit Pricee.g. 45000The price per single unit
Min Quantity1⚠️ Must be 1 for a standard price. Higher values mean the price only activates for bulk orders.
Valid From(leave blank)Blank = active immediately
Valid Until(leave blank)Blank = never expires
Active✓ tickedMust be ticked or the price is invisible to buyers

Click Save Price.

📸 Screenshot: Add Price Form Shows the price creation modal with Currency=UGX, Tier=retail, Unit Price=45000, Min Quantity=1, Active checked. /static/guides/images/pricing/02-add-price-form.png Screenshot: Add Price Form
3

Verify the price is live

Open your product in the shop (Shop → Browse Catalog) and confirm the price is displayed. Try adding 1 unit to cart to confirm end-to-end.

Part 3 — Adding Wholesale (B2B) Pricing

B2B buyers are automatically assigned the wholesale tier. Add a separate price row to give them a discounted rate. If no wholesale price exists, the platform falls back to the retail price — B2B buyers can always purchase.

1

Add a second price row with tier = wholesale

Click + Add Price again on the same product and set:

FieldValue
CurrencySame as your retail price (e.g. UGX)
Customer Tierwholesale
Unit PriceYour discounted B2B rate, e.g. 38000
Min Quantity1 (or higher if the discount only applies for bulk)
Active✓ ticked
💡 Result with both rows configured
  • B2C buyer adds 1 unit → pays UGX 45,000 (retail)
  • B2B buyer adds 1 unit → pays UGX 38,000 (wholesale)

Part 4 — Quantity Break Discounts

Use multiple price rows with different min_quantity values to automatically apply bulk discounts. The platform always selects the row with the highest min_quantity that still fits the buyer's order quantity.

📋 Example: 3-tier bulk pricing for a retail buyer
RowTierMin QtyUnit PriceWhen applied
1retail1UGX 45,000Orders of 1–9 units
2retail10UGX 40,000Orders of 10–49 units
3retail50UGX 35,000Orders of 50+ units

⚠️ Always include a row with min_quantity=1. If your smallest row has min_quantity=10, a buyer adding 5 units will get a "no price configured" error even though prices clearly exist in the admin.

Part 5 — Diagnosing "No Price Configured" Errors

You see a price listed on the product page but the buyer gets an error when adding to cart. This happens when the price record exists but fails all five resolution steps. Here are the common causes and fixes:

Symptom Root cause Fix
Error on add-to-cart for qty=1, price visible in admin min_quantity is set to something greater than 1 on all price rows Add a new price row with min_quantity = 1
Price visible in admin but not in shop is_active = False on the price record Open the price record, tick Active, save
Price worked last week, fails now valid_until date has passed Update valid_until to a future date, or clear it (no expiry)
Price set up but not activating yet valid_from is in the future Clear valid_from or backdate it to today
B2C buyer gets error, B2B buyer is fine Only a wholesale tier price exists — no retail row Add a separate price row with customer_tier = retail
Price shows correctly in shop but Order Summary shows wrong currency Product price currency does not match company default currency Check your Company profile currency matches the currency code on your price records
🛠️ Run the built-in price diagnostics tool
Platform administrators can scan all products for price configuration issues from the Render shell:
python manage.py check_product_prices

To check a single product:

python manage.py check_product_prices --product-id 42

To automatically reactivate prices that are inactive but otherwise valid:

python manage.py check_product_prices --fix-inactive
The tool reports BLOCKING problems (will fail add-to-cart), warnings (prices expiring soon), and an OK summary for healthy products.

Part 6 — Multi-Currency & International Buyers

As a seller you set prices in your local currency (e.g. UGX). International buyers automatically see a converted price for reference alongside your original price. You do not need to create separate price records for each currency.

💡 How it works
  • Exchange rates are refreshed daily from Open Exchange Rates.
  • On the shop listing: UGX 45,000 with ≈ USD 12.20 shown below in smaller text.
  • On the product detail page: an "Approx." line below the headline price with the buyer's currency and a conversion badge (e.g. UGX → USD).
  • In the cart Order Summary: an indicative total in the buyer's currency with the note "actual charge in UGX".
  • The actual transaction is always processed in the seller's currency. The conversion is informational only.
  • If no FX rate is available for a pair (e.g. an obscure currency), the converted line is simply hidden — no error is shown.
⚠️ Setting your company currency correctly matters
Go to Settings → Company Profile → Default Currency and set it to the currency your prices are denominated in (e.g. UGX for Uganda, KES for Kenya, USD for USD-denominated businesses). This currency is used as the cart total label and the FX conversion base. Mismatched settings cause the Order Summary to show the wrong currency code on the correct number.

Part 7 — Promotional & Time-Limited Prices

Use valid_from and valid_until to schedule promotional pricing without touching your standard price row.

1

Keep your standard price row intact

Never edit the dates on your permanent price row. Instead, create a second price row with the promotional rate.

2

Add a promotional price row

FieldValue
CurrencySame as standard price
Customer Tierretail (or wholesale)
Unit PriceYour promotional rate, e.g. 35,000
Min Quantity1
Valid FromPromotion start date/time
Valid UntilPromotion end date/time
Active✓ ticked
3

How the platform handles the overlap

During the promotional window, both rows are valid. The platform selects the row with the highest min_quantity that still applies — so if both have min_quantity=1, the lower-priced row wins (it's ordered by -min_quantity, then the query returns whichever comes first). To guarantee the promo wins, set it to a slightly higher min_quantity (e.g. 1 for promo vs. 0 is not possible, so use an explicit valid_until instead — the standard row should have no dates).

Simplest reliable approach: deactivate the standard price row during the promo window, then reactivate it after. Use the is_active toggle rather than editing dates.

Quick Reference — Price Setup Checklist