Skip to content
intermediate Phase 42 · Product Types

Virtual and Downloadable Products

Virtual and downloadable products including digital goods, links, samples, and license management

45m
0 problems
Topic Progress 0%

Virtual Products

Virtual Product Overview

Virtual products are non-physical items without shipping:

Examples:
  - Insurance
  - Warranty
  - Service contract
  - Membership
  - Gift card

Virtual Product Structure

-- Virtual product
SELECT entity_id, sku, type_id
FROM catalog_product_entity
WHERE entity_id = 400;
+-----------+----------+--------+
| entity_id | sku      | type_id|
+-----------+----------+--------+
|       400 | WARRANTY | virtual|
+-----------+----------+--------+

Creating Virtual Product

// Create virtual product
$virtualProduct = $objectManager->get(
    \Magento\Catalog\Model\ProductFactory::class
)->create();

$virtualProduct->setName('Extended Warranty')
    ->setSku('WARRANTY')
    ->setPrice(49.99)
    ->setStatus(1)
    ->setVisibility(4)
    ->setAttributeSetId(4)
    ->setTypeId('virtual')
    ->setStockData([
        'qty' => 999999,
        'is_in_stock' => 1,
        'manage_stock' => 0,
        'use_config_manage_stock' => 0,
    ])
    ->save();

Virtual vs Simple

Feature Simple Virtual
Physical item Yes No
Shipping Required Not required
Stock management Tracked Not tracked
Weight Required Not required
Tax Based on location Based on location
Use case T-shirt, phone Insurance, warranty

Downloadable Products

Downloadable Product Overview

Downloadable products provide files or links for download:

Examples:
  - eBooks
  - Software
  - Music
  - Video
  - Templates
  - Stock photos

Downloadable Product Structure

-- Downloadable product
SELECT entity_id, sku, type_id
FROM catalog_product_entity
WHERE entity_id = 500;
+-----------+----------+-------------+
| entity_id | sku      | type_id     |
+-----------+----------+-------------+
|       500 | EBOOK    | downloadable |
+-----------+----------+-------------+

-- Links table
SELECT * FROM downloadable_link WHERE product_id = 500;
+----------+------------+-----------+--------+--------+
| link_id  | product_id | title     | price  | sort_order|
+----------+------------+-----------+--------+--------+
|       1  |        500 | PDF       |  0.0000|        1|
|       2  |        500 | EPUB      |  0.0000|        2|
|       3  |        500 | MOBI      |  0.0000|        3|
+----------+------------+-----------+--------+--------+

-- Samples table
SELECT * FROM downloadable_sample WHERE product_id = 500;
+----------+------------+-----------+--------+
| sample_id| product_id | title     | sort_order|
+----------+------------+-----------+--------+
|       1  |        500 | Chapter 1 |        1|
+----------+------------+-----------+--------+

Creating Downloadable Product

// Create downloadable product
$downloadableProduct = $objectManager->get(
    \Magento\Catalog\Model\ProductFactory::class
)->create();

$downloadableProduct->setName('Complete Guide to PHP')
    ->setSku('EBOOK-PHP')
    ->setPrice(29.99)
    ->setStatus(1)
    ->setVisibility(4)
    ->setAttributeSetId(4)
    ->setTypeId('downloadable')
    ->setLinksPurchasedSeparately(0) // 0=bundle, 1=separate
    ->setStockData([
        'qty' => 999999,
        'is_in_stock' => 1,
        'manage_stock' => 0,
    ])
    ->save();

// Add downloadable links
$links = [
    [
        'title' => 'PDF Version',
        'price' => 0,
        'file' => '/path/to/file.pdf',
        'sample' => '/path/to/sample.pdf',
        'sort_order' => 1,
        'is_shareable' => 1, // 1=shareable, 0=not
        'max_downloads' => 0, // 0=unlimited
    ],
    [
        'title' => 'EPUB Version',
        'price' => 0,
        'file' => '/path/to/file.epub',
        'sample' => '/path/to/sample.epub',
        'sort_order' => 2,
        'is_shareable' => 0,
        'max_downloads' => 5,
    ],
];

$downloadableProduct->setLinks($links);

// Add samples
$samples = [
    [
        'title' => 'Chapter 1 Preview',
        'file' => '/path/to/chapter1.pdf',
        'sort_order' => 1,
    ],
];

$downloadableProduct->setSamples($samples);
$downloadableProduct->save();

Downloadable Link Configuration

Link Properties

$linkData = [
    'title' => 'Link Title',
    'price' => 0,           // Price (0 if included)
    'file' => '/path/file', // File path
    'sample' => '/path/sample', // Sample file
    'sort_order' => 1,
    'is_shareable' => 1,    // 1=can share, 0=per customer
    'max_downloads' => 0,    // 0=unlimited
    'link_url' => '',        // External URL (alternative)
    'sample_url' => '',      // Sample URL
];

Link Types

Property Description Values
price Additional price 0 = included
is_shareable Can be shared 1=yes, 0=no
max_downloads Download limit 0=unlimited, N=limit
link_url External URL URL or file path
sample_url Sample URL URL or file path

Download Tracking

-- Track downloads
SELECT * FROM downloadable_link_price_configuration WHERE product_id = 500;

-- Download links per customer
SELECT * FROM downloadable_link purchased WHERE product_id = 500;
+----------+------------+-----------+--------+--------+
| link_id  | product_id | order_id  | customer_id | downloads|
+----------+------------+-----------+--------+--------+
|       1  |        500 |     10001 |      123 |       3 |
|       2  |        500 |     10001 |      123 |       1 |
+----------+------------+-----------+--------+--------+

Download Limits

// Check download count
$downloadInfo = $objectManager->get(
    \Magento\Downloadable\Model\Link\Purchased\Factory::class
)->create();

// Limit reached? If max_downloads=5 and downloads=5, no more allowed
// Unlimited? If max_downloads=0, always allowed

Inventory and Pricing

Inventory for Digital Products

// Virtual product inventory
$virtualProduct->setStockData([
    'qty' => 999999,
    'is_in_stock' => 1,
    'manage_stock' => 0,  // Don't track
    'use_config_manage_stock' => 0,
    'use_config_notify_stock_qty' => 0,
    'notify_stock_qty' => 0,
    'is_decimal_divided' => 0,
]);

// Downloadable product inventory
$downloadableProduct->setStockData([
    'qty' => 999999,
    'is_in_stock' => 1,
    'manage_stock' => 0,
    'use_config_manage_stock' => 0,
]);

Pricing

// Base price
$downloadableProduct->setPrice(29.99);

// Link price (additional)
$links = [
    ['title' => 'Basic', 'price' => 0],     // Included
    ['title' => 'Premium', 'price' => 10.00], // +$10
];

// Links purchased separately
$downloadableProduct->setLinksPurchasedSeparately(1);
// Customer can buy links individually

// Links not purchased separately
$downloadableProduct->setLinksPurchasedSeparately(0);
// All links included in base price

Tax Configuration

// Digital products may have different tax rules
$downloadableProduct->setTaxClassId(2); // Taxable goods

// Some regions tax digital goods differently
// Configure in Stores > Tax Rules

Best Practices

Virtual Products:
  - Use for services, warranties, memberships
  - Set high stock qty (unlimited)
  - Don't track stock
  - No weight needed

Downloadable Products:
  - Use for digital goods
  - Provide samples for preview
  - Set appropriate download limits
  - Consider shareability settings
  - Use CDN for large files
  - Monitor download logs
  - Set reasonable prices per link

Quiz

1. What is a virtual product?

Question 1 options

2. What does links_purchased_separately control?

Question 2 options

3. What does max_downloads=0 mean?

Question 3 options

Flashcards

Question

What is a virtual product?

Answer

Non-physical item (warranty, service, membership) without shipping

Question

What is a downloadable product?

Answer

Digital product with files/links for download (ebook, software)

Question

What does links_purchased_separately do?

Answer

1=links sold individually, 0=all included in base price

Question

What is max_downloads?

Answer

Download limit per customer (0=unlimited)

Question

How is inventory managed?

Answer

Not tracked - set high qty, manage_stock=0

Revision Notes

Key Takeaways

  • 1. Virtual products: non-physical items without shipping (warranties, services)
  • 2. Downloadable products: digital goods with links/samples for download
  • 3. links_purchased_separately: 1=sold individually, 0=bundled
  • 4. max_downloads: 0=unlimited, N=limit per customer
  • 5. Both types: manage_stock=0, high qty, no tracking

Interview Tips

  • Explain the difference between virtual and downloadable products
  • Discuss downloadable link configuration and limits
  • Describe inventory management for digital products

Cheat Sheet

Virtual Product:
  type_id = 'virtual'
  Non-physical, no shipping
  manage_stock = 0
  Examples: warranty, insurance, membership

Downloadable Product:
  type_id = 'downloadable'
  Digital files/links
  links_purchased_separately (0/1)
  max_downloads (0=unlimited)
  is_shareable (0/1)
  Samples for preview

Inventory:
  qty = 999999
  manage_stock = 0
  is_in_stock = 1