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的核心代码逻辑中:
- 在
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 ) ); }
- 但
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
相关产品推荐
相关产品推荐

