Multi-Website Configuration

Overview

Manage different customer prices across multiple websites within your Magento installation. Set region-specific pricing, handle multi-currency scenarios, and maintain separate price lists for different storefronts.

How It Works

The website_id field determines which website(s) a price applies to:

  • website_id = 0: Price applies to all websites (global)
  • website_id = 1, 2, 3, etc.: Price applies only to that specific website

When resolving prices, the system:

  1. Checks for prices with matching website_id
  2. Falls back to website_id = 0 if no website-specific price exists
  3. Applies standard catalog price if no customer price matches

Website ID Reference

Finding Website IDs

Admin Method:

Navigate to: Stores >All Stores

View your website structure:

Main Website (ID: 1) └─ Main Store └─ English Store View └─ German Store View EU Website (ID: 2) └─ EU Store └─ EU English View └─ EU German View US Website (ID: 3) └─ US Store └─ US English View

Database Query:

SELECT website_id, code, name FROM store_website;

Example output:

| website_id | code | name | |------------|--------|--------------| | 0 | admin | Admin | | 1 | base | Main Website | | 2 | eu | EU Website | | 3 | us | US Website |

Use Cases

Regional Pricing Strategy

Scenario: Different prices for US and EU customers

US Website (website_id=3): Customer: ACME Corp Product: Widget ABC Quantity: 1 Price: $100.00 Website: US Website EU Website (website_id=2): Customer: ACME Corp (same customer) Product: Widget ABC Quantity: 1 Price: €90.00 Website: EU Website

Same customer sees different prices based on which website they're browsing.

Multi-Currency Handling

Example: Product with different currency pricing

Main Website (USD): - Price: $100.00 - Website ID: 1 UK Website (GBP): - Price: £75.00 - Website ID: 4 EU Website (EUR): - Price: €85.00 - Website ID: 2

Global Price with Regional Overrides

Scenario: Default price everywhere, but cheaper in specific region

Global Default: - Customer: Beta Ltd - Product: Widget ABC - Quantity: 1 - Price: $100.00 - Website: All Websites (0) EU Override: - Customer: Beta Ltd - Product: Widget ABC - Quantity: 1 - Price: €80.00 - Website: EU Website (2)

Browsing EU website: €80.00 Browsing any other website: $100.00

Admin Setup

Step 1: Create Website-Specific Price

Navigate to: Catalog >Customer Prices > Add New

Step 2: Fill Basic Information

Customer: Select customer Product: Select product Quantity: 1 Price: 100.00

Step 3: Select Website

Website Dropdown Options:

  • All Websites (ID: 0)
  • Main Website (ID: 1)
  • EU Website (ID: 2)
  • US Website (ID: 3)

Select the specific website this price should apply to.

Step 4: Save

Click Save to create the website-specific price.

Advanced Scenarios

Per-Website Quantity Tiers

Example: Different tier structure by region

US Website (website_id=3): qty=1, price=$100, website_id=3 qty=50, price=$95, website_id=3 qty=100, price=$90, website_id=3 EU Website (website_id=2): qty=1, price=€85, website_id=2 qty=25, price=€80, website_id=2 qty=75, price=€75, website_id=2

Same customer, same product, but different tier breakpoints and currency per region.

Time-Based Regional Campaigns

Example: Seasonal promotion only in EU

EU Q1 Campaign (website_id=2): - qty=1 - price=€70 - from_date=2025-01-01 - to_date=2025-03-31 - website_id=2 US Standard (website_id=3): - qty=1 - price=$95 - from_date=NULL - to_date=NULL - website_id=3

EU customers see promotional price Jan-Mar, US customers see standard price year-round.

Shared Customers Across Websites

Important: If a customer can access multiple websites, they can have different prices on each:

Customer ID: 456 (Global B2B Customer) On US Website: - Sees $100.00 (website_id=3 price) On EU Website: - Sees €85.00 (website_id=2 price) On APAC Website: - Sees $110.00 (website_id=4 price)

Database Structure

Schema

CREATE TABLE pricesystem_customerprice ( id INT PRIMARY KEY AUTO_INCREMENT, entity_id INT NOT NULL, customer_id INT NOT NULL, qty DECIMAL(12,4) NOT NULL, value DECIMAL(12,4) NOT NULL, from_date DATE NULL, to_date DATE NULL, website_id INT NOT NULL DEFAULT 0, CONSTRAINT fk_website FOREIGN KEY (website_id) REFERENCES store_website(website_id) ON DELETE CASCADE, CONSTRAINT UNIQUE (entity_id, customer_id, qty, from_date, to_date, website_id) );

Unique Constraint

You can have:

  • Same customer/product/qty with different website_id
  • Same customer/product/website with different qty
  • Exact duplicate including website_id (avoid)

Foreign Key Constraint

The foreign key ensures:

  • You can only use valid website IDs
  • If a website is deleted, associated prices are automatically removed
  • Data integrity is maintained

Price Resolution Logic

Resolution Order

When a customer views a product, the system:

  1. Find all customer prices for entity_id + customer_id
  2. Filter by website:
    • Include prices where website_id = current website
    • Include prices where website_id = 0 (global)
  3. Filter by date (if from_date/to_date set)
  4. Filter by quantity (qty <= cart quantity)
  5. Select best price:
    • Website-specific price (if exists)
    • Global price (website_id=0) as fallback
    • Highest qty tier that matches

Example Resolution

Setup:

Customer: 456 Product: 123 Current Website: 2 (EU) Cart Quantity: 15 Price Entries: Entry A: qty=1, price=$100, website_id=0 (global) Entry B: qty=10, price=$95, website_id=0 (global) Entry C: qty=1, price=€85, website_id=2 (EU) Entry D: qty=10, price=€80, website_id=2 (EU)

Resolution:

  1. Filter by website: Keep Entry A, B, C, D (all match website 2 or 0)
  2. Filter by quantity: Keep Entry A, C, D (qty 10 ≤ 15)
  3. Select best price:
    • Website-specific: Entry D (qty=10, €80, website_id=2)
    • Entry D wins (website-specific + highest matching qty)

Result: €80.00 applied

Frontend Display

Product Page

Shows website-specific pricing:

Product: Widget ABC Your Price: €85.00 (Viewing EU Website)

Cart

Displays active website price:

Widget ABC Website: EU Website Quantity: 1 Unit Price: €85.00

Customer Account

"Download My Prices" CSV includes website info:

Product,SKU,Quantity,Price,Currency,Website Widget ABC,WGT-ABC,1,85.00,EUR,EU Website Widget ABC,WGT-ABC,1,100.00,USD,US Website Widget ABC,WGT-ABC,1,95.00,USD,All Websites

Best Practices

Website Configuration

Do:

  • Use website_id=0 for default/fallback pricing
  • Set website-specific prices only when needed
  • Document which websites use which currencies
  • Test customer experience on each website
  • Consider tax implications per region

Don't:

  • Create prices for non-existent website IDs
  • Forget to set global fallback prices
  • Mix currencies on the same website
  • Create unnecessary website-specific entries

Regional Strategy

Centralized Pricing

All pricing at website_id=0 (global)

Good for: Single-currency stores, simple setups

Hybrid Approach

Global defaults + regional overrides

Good for: Most multi-website scenarios

Fully Separated

Every website has its own price entries

Good for: Complex multi-currency, independent regions

Troubleshooting

Wrong Price on Website

Check:

  1. Current website ID matches price entry
  2. Global fallback (website_id=0) exists
  3. Customer is logged in
  4. Website filter in admin grid
  5. Cache cleared after changes

Debug Query:

SELECT * FROM pricesystem_customerprice WHERE entity_id = 123 AND customer_id = 456 AND (website_id = 2 OR website_id = 0) ORDER BY website_id DESC, qty DESC;

Price Not Found on Website

Verify:

  1. Price entry exists with correct website_id
  2. Foreign key constraint hasn't deleted it
  3. Website ID is valid in store_website table
  4. Customer has access to that website

Duplicate Entry Error

Error Message:

Duplicate entry '123-456-1-NULL-NULL-2' for key 'UNIQUE'

Cause: Trying to create duplicate entry for same:

  • entity_id + customer_id + qty + dates + website_id

Solution:

  • Edit existing entry, or
  • Change website_id, or
  • Change qty, or
  • Change date range

Combining Features

Full Feature Combination Example

Multi-Website + Quantity Tiers + Time-Based: US Website Q1 Campaign: qty=1, price=$90, from=2025-01-01, to=2025-03-31, website_id=3 qty=50, price=$85, from=2025-01-01, to=2025-03-31, website_id=3 qty=100, price=$80, from=2025-01-01, to=2025-03-31, website_id=3 EU Website Q1 Campaign: qty=1, price=€80, from=2025-01-01, to=2025-03-31, website_id=2 qty=25, price=€75, from=2025-01-01, to=2025-03-31, website_id=2 qty=75, price=€70, from=2025-01-01, to=2025-03-31, website_id=2 Global Fallback (Year-Round): qty=1, price=$100, from=NULL, to=NULL, website_id=0 qty=50, price=$95, from=NULL, to=NULL, website_id=0

Reporting

Prices by Website Query

SELECT w.name as website, c.email as customer, p.sku, cp.qty, cp.value FROM pricesystem_customerprice cp JOIN store_website w ON cp.website_id = w.website_id JOIN customer_entity c ON cp.customer_id = c.entity_id JOIN catalog_product_entity p ON cp.entity_id = p.entity_id WHERE cp.website_id = 2 ORDER BY c.email, p.sku;

Global vs Website-Specific Count

SELECT CASE WHEN website_id = 0 THEN 'Global' ELSE 'Website-Specific' END as type, COUNT(*) as count FROM pricesystem_customerprice GROUP BY website_id = 0;

Coverage Analysis

-- Products with website-specific pricing SELECT p.sku, GROUP_CONCAT(DISTINCT w.name) as websites FROM pricesystem_customerprice cp JOIN catalog_product_entity p ON cp.entity_id = p.entity_id JOIN store_website w ON cp.website_id = w.website_id WHERE cp.website_id >0 GROUP BY p.sku;

Migration Scenarios

Converting Global to Website-Specific

Step 1: Export existing global prices

SELECT * FROM pricesystem_customerprice WHERE website_id = 0;

Step 2: Create website-specific copies

INSERT INTO pricesystem_customerprice (entity_id, customer_id, qty, value, from_date, to_date, website_id) SELECT entity_id, customer_id, qty, value, from_date, to_date, 2 as website_id FROM pricesystem_customerprice WHERE website_id = 0;

Step 3: Adjust website-specific values as needed

Step 4: Optionally remove global entries

Next Steps

Found an issue with this documentation? Let us know