如何开发WordPress WooCommerce移动端获取配送方式的API接口
完善WooCommerce移动端配送方式查询API
咱们先梳理下你现有代码里的几个潜在问题,再一步步给出完善后的实现方案:
现有代码的隐患
- 参数获取不规范:直接读取
php://input没有利用WP REST API的原生参数处理机制,兼容性差(比如GET请求会直接失效),也没做参数校验,容易抛出Undefined index错误。 - 购物车无保护:直接清空购物车会覆盖用户当前的购物车内容,严重影响正常购物流程。
- 商品添加无错误处理:
add_to_cart的代码未完成,也没判断添加是否成功,遇到商品不存在、库存不足的情况会直接崩溃。 - 缺少配送地址设置:只清空购物车加商品,但没配置配送国家/州,WooCommerce无法正确计算配送方式。
- 无响应返回逻辑:函数最后没有返回符合REST规范的响应,客户端拿不到有效结果。
完善后的API实现
public function get_shipping(WP_REST_Request $request) { // 1. 用WP REST API原生方法获取参数,自动兼容GET/POST请求 $params = $request->get_params(); // 校验必填参数,缺失则返回明确错误 $required_fields = ['state', 'country', 'line_items']; foreach ($required_fields as $field) { if (empty($params[$field])) { return new WP_REST_Response( ['error' => "缺少必填参数: $field"], 400 ); } } // 安全过滤参数,避免注入风险 $state = sanitize_text_field($params['state']); $country = sanitize_text_field($params['country']); $line_items = $params['line_items']; global $woocommerce; // 临时保存用户原有购物车,操作完成后恢复,不影响用户正常购物 $original_cart = $woocommerce->cart->get_cart(); try { // 清空购物车准备计算配送方式 $woocommerce->cart->empty_cart(); // 2. 批量添加商品到购物车,带错误校验 foreach ($line_items as $item) { if (empty($item['id']) || empty($item['quantity'])) { throw new Exception("商品项必须包含id和quantity参数"); } $product_id = (int) $item['id']; $quantity = (int) $item['quantity']; $variation_id = isset($item['variation_id']) ? (int) $item['variation_id'] : 0; $variations = isset($item['variations']) ? $item['variations'] : []; // 添加商品并检查是否成功 $cart_item_key = $woocommerce->cart->add_to_cart( $product_id, $quantity, $variation_id, $variations ); if (!$cart_item_key) { throw new Exception("商品ID $product_id 添加到购物车失败,请检查商品是否存在/库存是否充足"); } } // 3. 设置配送地址,这是计算配送方式的核心前提 $woocommerce->customer->set_shipping_country($country); $woocommerce->customer->set_shipping_state($state); // 可选:如果需要更精准的计算,可以添加邮编、城市参数 // $woocommerce->customer->set_shipping_postcode($params['postcode']); // $woocommerce->customer->set_shipping_city($params['city']); // 4. 计算并格式化配送方式为前端易读结构 $packages = $woocommerce->cart->get_shipping_packages(); $shipping_methods = []; foreach ($packages as $package) { $rates = WC()->shipping()->calculate_shipping($package); foreach ($rates as $rate) { $shipping_methods[] = [ 'id' => $rate->id, 'method_name' => $rate->method_title, 'method_code' => $rate->method_id, 'display_label' => $rate->label, 'base_cost' => wc_format_decimal($rate->cost, 2), 'tax_amounts' => array_map(function($tax) { return wc_format_decimal($tax, 2); }, $rate->taxes), 'total_cost' => wc_format_decimal($rate->get_total(), 2) ]; } } // 5. 恢复用户原有购物车,完全不干扰用户正常购物流程 $woocommerce->cart->empty_cart(); foreach ($original_cart as $cart_item) { $woocommerce->cart->add_to_cart( $cart_item['product_id'], $cart_item['quantity'], $cart_item['variation_id'], $cart_item['variation'], $cart_item['cart_item_data'] ); } // 返回成功响应,前端可直接解析使用 return new WP_REST_Response([ 'success' => true, 'shipping_methods' => $shipping_methods ], 200); } catch (Exception $e) { // 出错时务必恢复原有购物车,避免用户数据丢失 $woocommerce->cart->empty_cart(); foreach ($original_cart as $cart_item) { $woocommerce->cart->add_to_cart( $cart_item['product_id'], $cart_item['quantity'], $cart_item['variation_id'], $cart_item['variation'], $cart_item['cart_item_data'] ); } return new WP_REST_Response([ 'error' => $e->getMessage() ], 500); } }
关键优化点说明
- 参数安全与兼容:用
$request->get_params()替代直接读取php流,自动适配不同请求方式,同时做了必填校验和安全过滤。 - 购物车状态保护:操作前后保存并恢复用户原有购物车,完全不影响用户的正常购物流程。
- 错误捕获机制:任何步骤出错都会抛出异常,返回清晰的错误信息,同时恢复购物车避免数据丢失。
- 配送地址完整设置:正确配置配送国家和州,确保WooCommerce能调用对应的配送插件计算费率。
- 响应格式化:把WooCommerce返回的复杂对象转成前端易解析的数组,包含所有前端需要的关键信息(名称、费用、ID等)。
额外注意事项
- 权限控制:注册这个API路由时,记得添加
permission_callback,比如限制只有登录用户能调用,或者根据业务需求调整权限。 - 库存校验:如果需要确保商品有库存才能计算配送,可以在添加购物车前调用
wc_get_product($product_id)->get_stock_quantity()做检查。 - 缓存策略:如果配送查询请求频繁,可以考虑用WordPress的缓存机制缓存结果,减少服务器压力。
内容的提问来源于stack exchange,提问作者stanly




