You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何开发WordPress WooCommerce移动端获取配送方式的API接口

完善WooCommerce移动端配送方式查询API

咱们先梳理下你现有代码里的几个潜在问题,再一步步给出完善后的实现方案:

现有代码的隐患

  1. 参数获取不规范:直接读取php://input没有利用WP REST API的原生参数处理机制,兼容性差(比如GET请求会直接失效),也没做参数校验,容易抛出Undefined index错误。
  2. 购物车无保护:直接清空购物车会覆盖用户当前的购物车内容,严重影响正常购物流程。
  3. 商品添加无错误处理add_to_cart的代码未完成,也没判断添加是否成功,遇到商品不存在、库存不足的情况会直接崩溃。
  4. 缺少配送地址设置:只清空购物车加商品,但没配置配送国家/州,WooCommerce无法正确计算配送方式。
  5. 无响应返回逻辑:函数最后没有返回符合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等)。

额外注意事项

  1. 权限控制:注册这个API路由时,记得添加permission_callback,比如限制只有登录用户能调用,或者根据业务需求调整权限。
  2. 库存校验:如果需要确保商品有库存才能计算配送,可以在添加购物车前调用wc_get_product($product_id)->get_stock_quantity()做检查。
  3. 缓存策略:如果配送查询请求频繁,可以考虑用WordPress的缓存机制缓存结果,减少服务器压力。

内容的提问来源于stack exchange,提问作者stanly

火山引擎 最新活动