修复PHP调用WordPress WooCommerce REST API创建订单的问题
问题详情
我通过USSD系统调用WordPress站点的WooCommerce REST API创建订单,使用Postman测试默认创建订单接口时请求成功,但自行编写的PHP代码无法生成订单,返回参数类型错误:billing[first_name]、shipping[first_name]不是字符串类型,shipping_lines[0][total]不是字符串类型。
我的PHP代码
<?php function createOrder($selectedGame_id, $quantityToBuy, $totalPrice, $msisdn) { $consumer_key = ''; // 故意移除 $consumer_secret = ''; // 故意移除 $order_url = 'https://www.afrolottogh.com/wp-json/wc/v3/orders'; $auth = base64_encode($consumer_key . ":" . $consumer_secret); $customerExists = checkAndCreateCustomer($msisdn); // 根据拨打USSD码的手机号检查客户是否存在的函数 $customer_data = $customerExists ? $customerExists : null; // 如果客户存在则使用其信息创建订单 if ($customerExists) { $order_data = array( 'payment_method' => 'bacs', 'payment_method_title' => 'Afro Lotto Checkout', 'set_paid' => true, 'billing' => array( 'first_name' => $customer_data['first_name'], 'last_name' => $customer_data['last_name'], 'address_1' => $customer_data['billing']['address_1'], 'address_2' => $customer_data['billing']['address_2'], 'city' => $customer_data['billing']['city'], 'state' => $customer_data['billing']['state'], 'postcode' => $customer_data['billing']['postcode'], 'country' => $customer_data['billing']['country'], 'email' => $customer_data['email'], 'phone' => $customer_data['billing']['phone'] ), 'shipping' => array( 'first_name' => $customer_data['shipping']['first_name'], 'last_name' => $customer_data['shipping']['last_name'], 'address_1' => $customer_data['shipping']['address_1'], 'address_2' => $customer_data['shipping']['address_2'], 'city' => $customer_data['shipping']['city'], 'state' => $customer_data['shipping']['state'], 'postcode' => $customer_data['shipping']['postcode'], 'country' => $customer_data['shipping']['country'] ), 'line_items' => array( array( 'product_id' => $selectedGame_id, 'quantity' => $quantityToBuy ) ), 'shipping_lines' => array( array( 'method_id' => 'flat_rate', 'method_title' => 'Flat Rate', 'total' => $totalPrice ) ) ); } else { $order_data = array( 'payment_method' => 'bacs', 'payment_method_title' => 'Afro Lotto Checkout', 'set_paid' => true, 'billing' => array( 'first_name' => $msisdn, 'last_name' => 'USSD', 'address_1' => 'USSD', 'address_2' => '', 'city' => 'USSD', 'state' => 'AH', 'postcode' => '', 'country' => 'GH', 'email' => $msisdn . '@gmail.com', 'phone' => $msisdn ), 'shipping' => array( 'first_name' => $msisdn, 'last_name' => 'USSD', 'address_1' => 'USSD', 'address_2' => '', 'city' => 'USSD', 'state' => 'AH', 'postcode' => '', 'country' => 'GH' ), 'line_items' => array( array( 'product_id' => $selectedGame_id, 'quantity' => $quantityToBuy ) ), 'shipping_lines' => array( array( 'method_id' => 'flat_rate', 'method_title' => 'Flat Rate', 'total' => $totalPrice ) ) ); } // 发送创建订单请求 $ch = curl_init($order_url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($order_data)); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Authorization: Basic ' . $auth)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); // 处理响应 $order_response = json_decode($response, true); // 检查订单是否创建成功 if (isset($order_response['id'])) { return "订单创建成功。订单ID: " . $order_response['id']; } else { return "创建订单失败。错误信息: " . $order_response['message']; } } ?>
Postman测试请求示例
{ "payment_method": "bacs", "payment_method_title": "Afro Lotto Checkout", "set_paid": true, "billing": { "first_name": "John", "last_name": "Doe", "address_1": "123 Main St", "city": "Anytown", "state": "CA", "postcode": "12345", "country": "US", "email": "customer@example.com", "phone": "123456789" }, "shipping": { "first_name": "John", "last_name": "Doe", "address_1": "123 Main St", "city": "Anytown", "state": "CA", "postcode": "12345", "country": "US" }, "line_items": [ { "product_id": 41660, "quantity": 1 } ], "shipping_lines": [ { "method_id": "flat_rate", "method_title": "Flat Rate", "total": "5.00" } ] }
错误响应信息
{ "code":"rest_invalid_param", "message":"Invalid parameter(s): billing, shipping, shipping_lines", "data":{ "status":400, "params":{ "billing":"billing[first_name] is not of type string.", "shipping":"shipping[first_name] is not of type string.", "shipping_lines":"shipping_lines[0][total] is not of type string." }, "details":{ "billing":{ "code":"rest_invalid_type", "message":"billing[first_name] is not of type string.", "data":{ "param":"billing[first_name]" } }, "shipping":{ "code":"rest_invalid_type", "message":"shipping[first_name] is not of type string.", "data":{ "param":"shipping[first_name]" } }, "shipping_lines":{ "code":"rest_invalid_type", "message":"shipping_lines[0][total] is not of type string.", "data":{ "param":"shipping_lines[0][total]" } } } } }
解决方案
对比Postman请求和错误信息,问题核心是参数类型不匹配,针对性修复如下:
修复
first_name类型问题- 当客户存在时,
$customer_data中的first_name可能不是字符串类型;当客户不存在时,$msisdn可能是数字类型。 - 强制转换为字符串:使用
(string)或strval()函数处理相关字段。
- 当客户存在时,
修复
shipping_lines.total类型问题- Postman中该字段是字符串格式(如
"5.00"),但代码中$totalPrice大概率是数字类型。 - 转换为带两位小数的字符串:使用
number_format($totalPrice, 2)确保格式符合要求。
- Postman中该字段是字符串格式(如
修改后的关键代码片段:
// 客户存在时的字段处理 'billing' => array( 'first_name' => (string)$customer_data['first_name'], // 其余billing字段同理,确保为字符串类型 ), 'shipping' => array( 'first_name' => (string)$customer_data['shipping']['first_name'], // 其余shipping字段同理 ), 'shipping_lines' => array( array( 'method_id' => 'flat_rate', 'method_title' => 'Flat Rate', 'total' => number_format($totalPrice, 2) ) ) // 客户不存在时的字段处理 'billing' => array( 'first_name' => (string)$msisdn, // 其余billing字段同理 ), 'shipping' => array( 'first_name' => (string)$msisdn, // 其余shipping字段同理 ), 'shipping_lines' => array( array( 'method_id' => 'flat_rate', 'method_title' => 'Flat Rate', 'total' => number_format($totalPrice, 2) ) )
建议在调用json_encode前,显式确保所有需要字符串类型的参数都完成类型转换,避免PHP自动转换导致的格式问题。
内容的提问来源于stack exchange,提问作者Anthony Sackey
相关产品推荐
相关产品推荐

