You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce REST API删优惠券返回错误但实际成功问题求助

WooCommerce REST API 删除优惠券返回500错误但实际操作成功的解决方案

问题描述

  • 创建新优惠券(或使用现有优惠券ID)
  • 调用WooCommerce REST API的DELETE /wp-json/wc/v3/coupons/<id>接口删除优惠券,返回500错误响应:
{
  "code": "woocommerce_rest_cannot_delete",
  "message": "The shop_coupon cannot be deleted.",
  "data": {
    "status": 500
  }
}
  • 实际查询数据库或后台,发现优惠券已被移入回收站,删除操作实际成功。

原因分析

问题出在WooCommerce的核心代码逻辑中:

  1. 在class-wc-rest-crud-controller.php的delete_item方法里,调用$object->delete()后,会检查当前对象的状态是否为trash:
$object->delete();
$result = 'trash' === $object->get_status();
if ( ! $result ) {
    return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) );
}
  1. 但WC_Coupon的delete()方法仅通过全局函数wp_trash_post()修改数据库中的优惠券状态,并未更新当前$object实例的属性:
wp_trash_post( $id );
do_action( 'woocommerce_trash_coupon', $id );

这导致$object->get_status()仍然返回原来的状态,触发错误响应。

解决方案

方案1:修复REST API错误响应判断(无需修改核心文件)

通过过滤器拦截错误响应,手动验证优惠券实际状态,若已移入回收站则返回成功响应:

add_filter( 'woocommerce_rest_api_error_response', 'fix_coupon_delete_rest_error', 10, 3 );
function fix_coupon_delete_rest_error( $error_data, $error, $request ) {
    // 仅处理优惠券删除的特定错误
    if ( 'woocommerce_rest_cannot_delete' === $error->get_error_code() && isset( $error->get_error_data()['post_type'] ) && 'shop_coupon' === $error->get_error_data()['post_type'] ) {
        $coupon_id = $request['id'];
        // 检查数据库中优惠券的实际状态
        $actual_status = get_post_status( $coupon_id );
        
        if ( 'trash' === $actual_status ) {
            // 重新准备成功响应
            $coupon = wc_get_coupon( $coupon_id );
            $controller = new WC_REST_Coupons_Controller();
            $success_response = $controller->prepare_item_for_response( $coupon, $request );
            return rest_ensure_response( $success_response )->get_data();
        }
    }
    return $error_data;
}

方案2:修复WC_Coupon的delete方法(更新对象实例状态)

通过重写WC_Coupon类,让delete()方法在修改数据库后同步更新当前对象的状态:

class Fixed_WC_Coupon extends WC_Coupon {
    public function delete( $force = false ) {
        if ( $force ) {
            // 硬删除逻辑沿用父类
            parent::delete( $force );
        } else {
            $id = $this->get_id();
            wp_trash_post( $id );
            do_action( 'woocommerce_trash_coupon', $id );
            // 同步更新当前对象的状态
            $this->set_status( 'trash' );
        }
    }
}

// 替换默认的WC_Coupon类
add_filter( 'woocommerce_coupon_class', function() {
    return 'Fixed_WC_Coupon';
} );

两种方案均无需修改WooCommerce核心文件,可添加到主题的functions.php或自定义插件中使用。

内容的提问来源于stack exchange,提问作者Meyer Auslander - Tst

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 06:32:37