Type something to search...
How to Sell Digital Downloads with WordPress?

How to Sell Digital Downloads with WordPress?

Selling ebooks, software, templates, or courses from WordPress needs different plumbing than selling a physical product that has to ship somewhere. You don't need shipping zones or package weights, but you do need secure file delivery, download limits that stop a single purchase from being shared with everyone, and licensing if you're selling software. WordPress has two well-established paths for this: WooCommerce's built-in downloadable product type, and Easy Digital Downloads, a plugin built specifically around digital-only sales.

This guide covers both approaches, when to pick one over the other, securing your download links so files can't be accessed by anyone with a direct URL, and a real code example for hooking into a completed purchase to handle fulfillment logic beyond what either plugin does automatically.

Option 1: WooCommerce Downloadable Products

If you already have WooCommerce set up, or plan to sell both physical and digital products from the same store, its built-in downloadable product type is the simpler path, no second plugin required.

On any product, under Product data → General, check Downloadable, then switch to the new Downloadable section:

  • File — upload directly to the Media Library, or link to a file hosted elsewhere (an external CDN, for instance, if the file is large).
  • Download limit — how many times a customer can download the file before the link expires; leave blank for unlimited.
  • Download expiry — number of days after purchase before the download link stops working.

Also check Virtual on the General tab, which tells WooCommerce this product needs no shipping calculation at all.

By default, WooCommerce serves downloads through a redirect that includes a unique, hard-to-guess token per order, not the file's real path, which is the setting to confirm under WooCommerce → Settings → Products → Downloadable products → File download method. The Redirect only and Force downloads (recommended) options both avoid exposing your Media Library's real file URL, but "Force downloads" adds an extra layer by streaming the file through PHP rather than redirecting the browser directly to it.

Option 2: Easy Digital Downloads

If your store sells digital products exclusively, Easy Digital Downloads (EDD) is purpose-built for it and tends to have a cleaner admin experience for digital-only catalogs: simpler checkout (no shipping fields to hide), built-in file access logs, and an ecosystem of extensions specifically for licensing and software updates.

Install and activate Easy Digital Downloads from Plugins → Add New, then go to Downloads → New Download. Add your title and description, and under Download Files, upload one or more files, a single purchase can bundle multiple files (for example, a PDF plus its source templates). Set a price under Pricing, or enable Variable Pricing to offer multiple tiers of the same download (e.g., "Standard License" vs. "Extended License") at different price points.

EDD serves files through its own secure download system automatically, generating a unique, time-limited URL per purchase rather than a permanent public link, so there's no equivalent "force downloads" setting to configure separately.

Choosing Between WooCommerce and Easy Digital Downloads

  • Pick WooCommerce if you're already running it for physical products, or plan to eventually add physical products to the same catalog.
  • Pick Easy Digital Downloads if the store is, and will stay, entirely digital, especially if you're selling software that needs license key generation and update delivery, which EDD's official extensions handle more directly than WooCommerce's more general-purpose downloadable product type.

Step: Handle Fulfillment Logic with a Real Purchase Hook

Both a delivered file and an order confirmation email are handled automatically by either plugin, but many digital products need something extra on purchase: issuing a license key, granting access to a private area, or notifying an external system. Easy Digital Downloads fires a real, documented action once a purchase is marked complete: edd_complete_purchase. Add this to a site-specific plugin:

add_action( 'edd_complete_purchase', function ( $payment_id ) {
    $payment = edd_get_payment( $payment_id );

    if ( ! $payment ) {
        return;
    }

    $email = $payment->email;

    foreach ( $payment->cart_details as $item ) {
        // Only run custom fulfillment for a specific download by its post ID.
        if ( (int) $item['id'] !== 42 ) {
            continue;
        }

        $license_key = wp_generate_password( 20, false, false );

        update_post_meta( $payment_id, '_custom_license_key', sanitize_text_field( $license_key ) );

        wp_mail(
            sanitize_email( $email ),
            __( 'Your license key', 'textdomain' ),
            sprintf( __( 'Thanks for your purchase! Your license key is: %s', 'textdomain' ), $license_key )
        );
    }
}, 10, 1 );

If you're building the same kind of post-purchase fulfillment on WooCommerce instead (for a downloadable product rather than an EDD download), the equivalent real hook is woocommerce_order_status_completed, which fires once an order's status changes to Completed:

add_action( 'woocommerce_order_status_completed', function ( $order_id ) {
    $order = wc_get_order( $order_id );

    if ( ! $order ) {
        return;
    }

    foreach ( $order->get_items() as $item ) {
        if ( 'Software License' !== $item->get_name() ) {
            continue;
        }

        $license_key = wp_generate_password( 20, false, false );

        $order->update_meta_data( '_custom_license_key', sanitize_text_field( $license_key ) );
        $order->save();
    }
}, 10, 1 );

A few things worth understanding across both examples:

  • Fire fulfillment logic on the "completed" event, not "add to cart" or "checkout started." Both hooks used here only run once payment is actually confirmed, which matters for anything irreversible like generating and emailing a license key.
  • Always match on something stable, a product ID or a consistent item name, rather than assuming a cart only ever contains the one product you're expecting.
  • wp_generate_password() is a convenient built-in WordPress function for generating a random string; it's fine for a simple license key, but a real licensing system usually needs a dedicated extension (like EDD's own Software Licensing add-on) that also handles activation limits and revocation.

Preventing Common Digital Download Problems

A handful of issues come up repeatedly once a digital-goods store is live, and it's worth checking for each before you launch rather than after a customer reports one:

  • Files served from the wrong location. Confirm downloads actually route through the plugin's tokenized delivery system rather than a direct, guessable Media Library URL; this is the "File download method" setting in WooCommerce, and it's on by default in Easy Digital Downloads.
  • Download links that never expire. An unlimited download limit and no expiry might feel generous, but it also means a purchased file can circulate indefinitely with no way to trace or limit further redistribution. A limit of a handful of downloads over 30-60 days is generally plenty for a legitimate customer re-downloading a lost file.
  • Large files timing out or exceeding your host's upload limit. Video courses, large software installers, or high-resolution asset packs often exceed a typical hosting plan's PHP upload limits; hosting the file on an external CDN or storage service and linking to it from the product avoids this entirely.
  • No confirmation that the file actually downloads correctly. Before announcing a new digital product, complete a real test purchase (using your gateway's sandbox mode) and confirm the delivered file opens correctly, not just that an email arrived.

Frequently Asked Questions (FAQ) About Selling Digital Downloads

It depends on your download limit and expiry settings. Both WooCommerce and Easy Digital Downloads generate a unique, tokenized URL per order rather than a permanent public link to the file itself, and you control how many times and for how long that specific link works.

Yes, easily in WooCommerce, since a single order can mix Virtual/Downloadable products with normal shippable ones, and WooCommerce calculates shipping only for the physical items. This mixed use case is one of the main reasons to choose WooCommerce over Easy Digital Downloads.

The core plugin is free, similar to WooCommerce's model, with paid extensions available for features like Software Licensing, Recurring Payments, and various payment gateway integrations beyond the free defaults.

Neither plugin can prevent a customer from personally sharing a file they've legitimately downloaded, but setting a reasonable download limit and expiry window limits how long or how many times any single generated link works, which is the standard mitigation both plugins are built around.

Yes, but this typically needs a dedicated extension, WooCommerce Subscriptions for WooCommerce, or Recurring Payments for Easy Digital Downloads, since neither plugin's core handles recurring billing on its own.

Yes, and this applies regardless of which plugin you use; any store processing payments needs HTTPS both for basic customer trust and because most payment gateways require it as a condition of integration.

Both plugins can serve essentially any file type WordPress allows to be uploaded (PDFs, zip archives, audio, video, images), though very large files are often better hosted externally and linked rather than uploaded directly to your WordPress Media Library, to avoid straining your hosting's storage and bandwidth.

Conclusion

Selling digital downloads through WordPress comes down to choosing the right plugin for your catalog, WooCommerce if you're mixed or already using it, Easy Digital Downloads if you're digital-only, and then configuring secure delivery through download limits and expiry windows rather than relying on a plain, permanent file URL. Both plugins handle the core mechanics (payment, delivery, and confirmation emails) without any code required.

Where custom fulfillment logic comes in, issuing a license key, granting private access, or notifying an external system, edd_complete_purchase and woocommerce_order_status_completed are the real, documented hooks to build on, and both follow the same underlying pattern: wait for a confirmed purchase, match against the specific product you care about, and keep any generated data (like a license key) tied to that order.

If digital products are just one part of a broader store, it's worth reviewing what WordPress plugins actually are and how they work to understand how EDD, WooCommerce, and any extensions you add all cooperate on the same WordPress install.

Tags :
Share :

Related Posts

Effortlessly Crafting Compelling WordPress Pages

Effortlessly Crafting Compelling WordPress Pages

As a website owner or content creator, having the ability to seamlessly add new pages to your WordPress site is crucial. Whether you're introducing a

Continue Reading
High Traffic Tips for WordPress Mastery 🚥

High Traffic Tips for WordPress Mastery 🚥

In our digital age, where online visibility is paramount, ensuring your WordPress site can handle surging traffic is crucial. Just like a finely-tune

Continue Reading
How Do I Change the WordPress Login URL?

How Do I Change the WordPress Login URL?

By default, every WordPress site's login page lives at the same predictable address: yoursite.com/wp-login.php (which also happens to redirect from

Continue Reading