Build your WordPress website with Elementor.Discover Elementor Affiliate link
Français

Site appearance

WooCommerce store and checkout flow · Intermediate

Older WooCommerce purchases lose a download after a file change

Does a WooCommerce file disappear from older purchases? Compare product rows and permissions, then test access on two dummy orders.

Source published: · Source updated: · Editorial policy

Read the French edition

Recognize a download disappearing after a file change

Someone already purchased a digital product. After the file is replaced, their download no longer appears under My Account > Downloads, while recent orders can access it. This is the symptom described on the WooCommerce forum. The thread distinguished two operations that look similar in the product editor. You can edit the name or address in an existing file row. You can also delete that row or use the button adding a new one. WooCommerce documentation says the first operation updates past orders' access with their expiry and remaining download count. A new row does not automatically grant previous orders permission.

In WooCommerce, the order and product page answer different questions. The product lists files currently associated with the product or variation. Order permissions specify files that order can access. Two distinct rows may share a visible name. Restoring the same label in a fresh row therefore does not restore the original row's permissions. Conversely, changing the file in an existing row may work with a different address. The on-disk filename is not the only element to examine.

Establish whether the link is missing or visible but returning an error. A link missing for old purchases but present for new ones calls for comparing permissions. A link visible to everyone but producing rejection, an empty file or storage error also requires checking the file actually served and permission to open it. Verify the order, account used and exact variation before concluding. A variable product may carry different files on each variation.

  1. Record when the change was saved. Identify an affected previous order and, if available, a comparable recent order.
  2. Ask the customer to open My Account > Downloads with the account associated with the order. For a guest purchase, check the intended route through the link received in the order or email. Do not forward a customer link into a shared ticket.
  3. If the link appears but downloading fails, record the message and expected filename without publishing the full address. Links may contain order keys or identifying parameters.

Prepare a comparison separating file, order and account

In WooCommerce staging, prepare a dummy product and small file whose contents identify its version, such as a document containing “TÉMOIN V1”. For a variable product, choose one variation and record its ID in the order. Create a first test order with a dummy customer. Put it in the state granting download permission under staging policy. Some stores allow downloads after payment, others after completion. Use a test method or authorized dummy order and capture the copy's notifications.

Open WooCommerce > Orders, select the order and find Downloadable product permissions. Record visible files, expiry and remaining count. Then open a separate test session to view My Account > Downloads and verify that the file contains the first-version marker. Clicking may consume a use if the store counts downloads. On a real order, do not download on the customer's behalf to inspect a file without planning for that effect. For the control, allow enough uses for comparisons.

Prepare a second document marked “TÉMOIN V2” and keep the first version outside any folder that might be overwritten. Compare two situations on the copy. First, edit the V1 row. Second, restore the starting state or use another dummy product, then create a new row. A recent order then checks whether that row is available after purchase. Test with staging addresses and documents, recording link presence, received file and counter separately.

  1. Record order status, product or variation and visible permissions before changing anything.
  2. Verify working customer access to V1. Record the count after this download to establish the next check's baseline.
  3. Prepare a second test order for post-change comparison. Both orders must target the same product or variation.

Replace the file while preserving the original row

If V2 should replace V1 for all already-authorized buyers, open Products > All Products and edit the product. For a simple downloadable product, open Product data and locate Downloadable files. For a variable product, open Variations, expand the purchased variation and find that variation's list. Labels may differ in a custom product editor. Check that the identified row matches the control order's file.

In that row, change the address field or use the same row's file-selection button. Save the product or variation with the interface's designated button. Keep V1 during checking so its address can be restored. If WooCommerce reports the new file is in an unapproved directory, use the location intended by your store and check approved-directory settings. Do not make a storage address public for a quick test. Checking must use the order link and intended delivery mode.

  1. Save V2 in the existing row, then reopen the product to confirm the change was retained.
  2. On the previous order, check permission, expiry and remaining count before downloading again. With the dummy account, open the link and check the V2 marker.
  3. If the new document is incorrect or inaccessible, restore the V1 address in the same row in staging, then verify receipt of V1. If the original row was already deleted, check permission recovery separately.

Grant a new file to a targeted order

If V2 is an additional file and V1 must remain available, keep two separate rows. Then confirm which orders should receive the new version under the product's sales terms. Under WooCommerce > Orders, open one comparable dummy order and find Downloadable product permissions. Depending on version, it allows product search and access granting. Some interfaces grant product access and calculate associated files. Check all permissions displayed after the action. Do not use the command if it grants extra files the customer should not receive.

An order's regenerate-permissions action has broader scope. It may recreate permissions from the product's current state and replace permissions adjusted for that order. Check version and behavior in staging before using it. Record counters, expiry dates and manually granted permissions. If these must be preserved and the interface offers no sufficiently precise correction, stop testing on that order and give the comparison to the store owner. Changing a real order's status to retry access may trigger other processing. Retain the status matching the order and delivery policy.

If the original row was deleted, restoring the document at the same address may leave old orders without permission. In staging, check whether the row and associated permissions can be restored from a targeted backup. For an isolated purchase, explicit granting may be simpler. A full database restore can erase recent orders. Use a separate copy to compare states before selecting the repair.

  1. Record the dummy order's permission list before granting access, including limits and dates. Make one addition for the intended product.
  2. Check new access and compare other permissions with baseline. Open the staging customer session and confirm the version actually delivered.
  3. If an extra permission was granted mistakenly, remove only that permission if the interface permits. In staging, return to its snapshot if the initial state cannot be recovered precisely.

Compare stored permissions from a terminal

With authorized WP-CLI access, place the script below outside the web root as verifier-droits-telechargement.php. Run wp --path="/chemin/recette" --url="https://boutique.recette.example.test" eval-file "/chemin/prive/verifier-droits-telechargement.php" 123 456. The two dummy IDs represent the order and purchased product. Use the variation ID if the order concerns a variation. The probe uses WooCommerce's order API and download-permission storage. It counts IDs without showing private URLs, emails or order keys. Keep plugins loaded and verify site context before running it.

A row reading fichiers=2 autorises=1 sans_permission=1 permissions_sans_fichier=0 indicates two product files and an order permission matching only one. A permission without a file indicates a reference no longer matching current rows. These numbers measure ID correspondence. They check neither order status, expiry, count nor server ability to deliver the document. Compare both orders and continue in the interface if figures match but access fails.

<?php
if (!function_exists('wc_get_order') || !class_exists('WC_Data_Store')) {
    WP_CLI::error('WooCommerce doit être chargé sur cette recette.');
}
$commande_id = filter_var($args[0] ?? null, FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);
$produit_id = filter_var($args[1] ?? null, FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);
if (count($args) !== 2 || $commande_id === false || $produit_id === false) {
    WP_CLI::error('Indiquez un ID de commande et un ID de produit ou de variation.');
}
$commande = wc_get_order($commande_id);
$produit = wc_get_product($produit_id);
if (!$commande instanceof WC_Order || !$produit) {
    WP_CLI::error('Commande ou produit introuvable sur la cible.');
}
$achete = false;
foreach ($commande->get_items('line_item') as $article) {
    $id = $article->get_variation_id() ?: $article->get_product_id();
    if ((int) $id === $produit_id) {
        $achete = true;
        break;
    }
}
if (!$achete) {
    WP_CLI::error('Ce produit ou cette variation ne figure pas dans la commande.');
}
$actifs = array_map('strval', array_keys($produit->get_downloads('edit')));
$droits = WC_Data_Store::load('customer-download')->get_downloads([
    'order_id' => $commande_id,
    'product_id' => $produit_id,
    'return' => 'download_id',
]);
$identifiants = array_unique(array_column($droits, 'download_id'));
WP_CLI::log(sprintf(
    'fichiers=%d autorises=%d sans_permission=%d permissions_sans_fichier=%d',
    count($actifs),
    count(array_intersect($actifs, $identifiants)),
    count(array_diff($actifs, $identifiants)),
    count(array_diff($identifiants, $actifs))
));

Distinguish an existing permission from usable access

When IDs match but access remains missing, open the order under WooCommerce > Orders. Compare its associated account with the one opening My Account, then inspect status, expiry and downloads remaining. A zero counter can explain a missing file despite a permission row. Under WooCommerce > Settings > Products > Downloadable products, check when access is granted and whether login is required. These settings interpret the flow. Changing them to make one test pass may alter access for other orders.

For an old purchase, also check that the product and variation still exist. Replacing a product or recreating a variation may change the purchased ID even with identical title and options. In that case, the probe refuses to compare the new variation with the old order. Return to the order item and ask which product should continue providing access. A new display name does not link both identities.

If the file is visible but will not download, use the route intended by the configured delivery mode. Under WooCommerce > Settings > Products, check approved download directories when this feature is active. Compare V2's location with V1's. A file hosted at another address may require a store-designated access rule. Ask the storage owner to check the file response in the authorized context. Comparing received content distinguishes WooCommerce permission issues from an error page or missing provider file.

Verify the customer flow and retain targeted rollback

To close diagnosis, compare an older and recent order under each one's intended conditions. If V2 replaces V1, the same permission should lead an eligible old purchase to V2. If V2 is an addition, check that the old purchase receives it only after the decided grant. Check status, account and counters before opening the file. A staging account without a purchase must not receive access. For protected files, verify delivery through the intended route instead of copying the link into another session.

If the link is present but fails, check the file path, approved directory and store download method. A correct document name and download of a few bytes may represent an error page. Open the received dummy file and find the marker. Then check counter changes and other files' presence. If a regression follows a row edit, restore the previous address. If it follows a permission addition, remove or restore only affected permissions in staging. Restoring a file does not automatically restore an already-consumed count.

Record the expected version, variation, result for each order and counter state in the tracking record. For a real correction, have the customer confirm through the designated channel that the received document is correct. A positive server response or visible administration row does not replace this check.

Do not regenerate permissions for a simple replacement

WooCommerce documentation states that regeneration deletes existing permissions and their download logs before creating new ones. Previous counters and logs are lost. It is therefore not a harmless refresh button for checking whether V2 appears.

For normal replacement, start with the existing product row and check an eligible order. Free WooCommerce core suffices: neither a subscription plugin nor file-management plugin is necessary. A subscription becomes a separate functional choice when the sale promises access to future files added as new rows.

Before any permission repair, record the staging order's file, remaining count, expiry and any manual additions. After the targeted change, compare these four elements and the document actually received. If you regenerated during the exercise, use the staging snapshot to recover counters and logs too: merely restoring the old product URL does not reconstruct them. On an active store, prepare targeted repair instead of a general restore overwriting recent orders.

Sources and references

Use these references to check the features, requirements and limitations described. Reading documentation is not a practical test.

View 7 references

English translation of the reviewed French edition. Code examples retain their original identifiers, comments and output strings for reproducibility. Linked exercise files and original screenshots may contain French. No new practical tests or price checks are implied by translation.

Continue reading in English