Commit b5e27abaf10 for woocommerce
commit b5e27abaf10685fc73b791000536aa71ac519764
Author: Noruzzaman <noruzzamanrubel@gmail.com>
Date: Wed Nov 11 16:36:21 2026 +0600
Revoke downloadable permissions when refunding a product variation line item (#70276)
* Revoke downloadable permissions when refunding a product variation line item
* Fix variation refund item type handling
---------
Co-authored-by: Thomas Roberts <5656702+opr@users.noreply.github.com>
diff --git a/plugins/woocommerce/changelog/fix-69452-refund-variation-download-permissions b/plugins/woocommerce/changelog/fix-69452-refund-variation-download-permissions
new file mode 100644
index 00000000000..e621d672dde
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-69452-refund-variation-download-permissions
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Revoke downloadable product permissions when a product variation line item is refunded.
diff --git a/plugins/woocommerce/includes/wc-order-functions.php b/plugins/woocommerce/includes/wc-order-functions.php
index 6da2d728f75..8c3679e9f54 100644
--- a/plugins/woocommerce/includes/wc-order-functions.php
+++ b/plugins/woocommerce/includes/wc-order-functions.php
@@ -640,9 +640,13 @@ function wc_create_refund( $args = array() ) {
// later to be used for revoking download permission.
// checking if the item is a product, as we only need to revoke download permission for products.
if ( $item->is_type( 'line_item' ) ) {
+ $product_id = $item->get_product_id();
+ if ( $item instanceof WC_Order_Item_Product && $item->get_variation_id() ) {
+ $product_id = $item->get_variation_id();
+ }
$refunded_order_and_products[ $item_id ] = array(
'order_id' => $order->get_id(),
- 'product_id' => $item->get_product_id(),
+ 'product_id' => $product_id,
);
}
diff --git a/plugins/woocommerce/tests/legacy/unit-tests/order/class-wc-tests-order-functions.php b/plugins/woocommerce/tests/legacy/unit-tests/order/class-wc-tests-order-functions.php
index 11e9a4f787a..07f68d61ed7 100644
--- a/plugins/woocommerce/tests/legacy/unit-tests/order/class-wc-tests-order-functions.php
+++ b/plugins/woocommerce/tests/legacy/unit-tests/order/class-wc-tests-order-functions.php
@@ -1804,6 +1804,75 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
);
}
+ /**
+ * @testdox Refunding a product variation revokes its customer download permissions.
+ * @see https://github.com/woocommerce/woocommerce/issues/69452
+ */
+ public function test_wc_create_refund_revokes_variation_download_permissions() {
+ $variable_product = WC_Helper_Product::create_variation_product();
+ $variation_ids = $variable_product->get_children();
+ $variation_id = $variation_ids[0];
+ $variation = wc_get_product( $variation_id );
+ $variation->set_downloadable( true );
+ $variation->save();
+
+ $order = new WC_Order();
+ $item = new WC_Order_Item_Product();
+ $item->set_product( $variation );
+ $item->set_quantity( 1 );
+ $item->set_subtotal( 10 );
+ $item->set_total( 10 );
+ $order->add_item( $item );
+ $order->calculate_totals();
+ $order->save();
+
+ // Add customer download permission for the variation.
+ $download = new WC_Customer_Download();
+ $download->set_user_id( 1 );
+ $download->set_order_id( $order->get_id() );
+ $download->set_product_id( $variation->get_id() );
+ $download->set_download_id( wp_generate_uuid4() );
+ $download->save();
+
+ $download_data_store = WC_Data_Store::load( 'customer-download' );
+ $initial_downloads = $download_data_store->get_downloads(
+ array(
+ 'order_id' => $order->get_id(),
+ 'product_id' => $variation->get_id(),
+ )
+ );
+ $this->assertCount( 1, $initial_downloads, 'Download permission should exist prior to refund.' );
+
+ $item_id = $item->get_id();
+
+ $refund = wc_create_refund(
+ array(
+ 'amount' => 10,
+ 'order_id' => $order->get_id(),
+ 'line_items' => array(
+ $item_id => array(
+ 'qty' => 1,
+ 'refund_total' => 10,
+ 'refund_tax' => array( 1 => 0 ),
+ ),
+ ),
+ )
+ );
+
+ $this->assertNotWPError( $refund, 'Refund should be created successfully.' );
+
+ $remaining_downloads = $download_data_store->get_downloads(
+ array(
+ 'order_id' => $order->get_id(),
+ 'product_id' => $variation->get_id(),
+ )
+ );
+ $this->assertEmpty(
+ $remaining_downloads,
+ 'Download permissions for a refunded variation must be revoked.'
+ );
+ }
+
/**
* Test wc_sanitize_order_id().
*/