executeParam2( self::NAMESPACE, 'alibaba.createOrder.preview', 1, $businessParams ); if ($result === false) { Log::channel('alibaba')->error('[预下单] API请求失败', $businessParams); return false; } Log::channel('alibaba')->info('[预下单] API请求成功', ['result' => json_encode($result)]); return $this->formatPreviewResult($result); } /** * 格式化预下单返回结果 * * 实际返回结构: * { * "orderPreviewResuslt": [{ * "tradeModeNameList": ["assureTrade"], * "status": true, * "sumPayment": 370, // 总支付金额(单位:分) * "sumCarriage": 300, // 总运费(单位:分) * "sumPaymentNoCarriage": 70, // 商品总金额(不含运费,单位:分) * "flowFlag": "fenxiaonew", * "cargoList": [{ // 商品列表 * "amount": 0.7, * "finalUnitPrice": 0.7, * "specId": "...", * "skuId": 6148579878582, * "offerId": 678279922176, * "openOfferId": "...", * "cargoPromotionList": [] * }], * "tradeModelList": [{"name":"担保交易","tradeType":"assureTrade","opSupport":true}], * "payChannelInfos": [{"name":"alipay"}], * "orderGroup": "79d4f82d...", * "canUseOfficialSolution": false * }], * "success": true, * "unsupportedCrossBorderPayOfferList": [] * } * * @param array $result API原始返回数据 * @return array */ protected function formatPreviewResult(array $result): array { $success = $result['success'] ?? false; $previewList = $result['orderPreviewResuslt'] ?? []; if (empty($previewList) || !is_array($previewList)) { return [ 'success' => $success, 'preview' => null, 'list' => [], ]; } $formattedList = []; foreach ($previewList as $item) { $formattedList[] = [ 'sumPayment' => $item['sumPayment'] ?? 0, 'sumCarriage' => $item['sumCarriage'] ?? 0, 'sumPaymentNoCarriage' => $item['sumPaymentNoCarriage'] ?? 0, 'flowFlag' => $item['flowFlag'] ?? '', // 'orderGroup' => $item['orderGroup'] ?? '', // 'status' => $item['status'] ?? false, // 'cargoList' => $item['cargoList'] ?? [], // 'tradeModeNameList' => $item['tradeModeNameList'] ?? [], // 'tradeModelList' => $item['tradeModelList'] ?? [], // 'payChannelInfos' => $item['payChannelInfos'] ?? [], // 'shopPromotionList' => $item['shopPromotionList'] ?? [], // 'tradeServiceList' => $item['tradeServiceList'] ?? [], // 'taoSampleSinglePromotion' => $item['taoSampleSinglePromotion'] ?? false, // 'canUseOfficialSolution' => $item['canUseOfficialSolution'] ?? false, ]; } return [ // 'success' => $success, 'preview' => $formattedList[0] ?? null, // 'list' => $formattedList, // 'unsupportedCrossBorderPayOfferList' => $result['unsupportedCrossBorderPayOfferList'] ?? [], ]; } /** * 快速创建订单 * * API: com.alibaba.trade:alibaba.trade.fastCreateOrder-1 * * 接口文档: https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.trade%3Aalibaba.trade.fastCreateOrder-1 * * 请求参数: * - flow: 流程标识(saleproxy=分销采购, general=普通下单) * - cargoParamList: 商品列表JSON数组(alibaba.trade.fast.cargo[]),每个商品包含 offerId, quantity, specId * - addressParam: 地址参数JSON对象,包含 fullName, mobile, provinceText, cityText, areaText, address * - totalAmount: 总金额(单位:分,可选) * - message: 买家留言(可选) * - orderGroup: 订单分组标识(从预下单返回的 orderGroup 字段获取,可选) * * @param array $params 创建订单参数 * @return array|false */ public function fastCreateOrder(array $params = []) { $businessParams = []; // --- flow(流程标识) --- $businessParams['flow'] = $params['flow'] ?? 'general'; // --- cargoParamList(商品列表,JSON字符串) --- if (!empty($params['cargoParamList'])) { $businessParams['cargoParamList'] = is_array($params['cargoParamList']) ? json_encode($params['cargoParamList'], JSON_UNESCAPED_UNICODE) : $params['cargoParamList']; } // --- addressParam(地址参数,JSON字符串) --- if (!empty($params['addressParam'])) { $businessParams['addressParam'] = is_array($params['addressParam']) ? json_encode($params['addressParam'], JSON_UNESCAPED_UNICODE) : $params['addressParam']; } // --- 调用API --- $result = $this->executeParam2( self::NAMESPACE, 'alibaba.trade.fastCreateOrder', 1, $businessParams ); if ($result === false) { Log::channel('alibaba')->error('[创建订单] API请求失败', $businessParams); return false; } Log::channel('alibaba')->info('[创建订单] API请求成功', ['result' => json_encode($result)]); return $this->formatCreateOrderResult($result); } /** * @param StoreOrderEntity[] $storeOrderEntityList * @return bool * @author 史晨 * @date 2026/4/30 09:44 * 支付成功通知1688 */ public function paySuccess(array $storeOrderEntityList): bool { foreach ($storeOrderEntityList as $storeOrderEntity) { $alibabaOrderId = $storeOrderEntity->getAlibabaOrderId(); if (empty($alibabaOrderId)) { Log::channel('alibaba')->error($storeOrderEntity->getOrderSn() . '不是1688订单,不需要调取1688支付成功接口'); continue; } $res = $this->prepareProtocolPay(['orderId' => $alibabaOrderId]); if ($res['success'] === false) { return false; } } return true; } /** * 免密支付准备 * * API: com.alibaba.trade:alibaba.trade.pay.protocolPay.preparePay-1 * * 接口文档: https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.trade%3Aalibaba.trade.pay.protocolPay.preparePay-1 * * 请求参数说明(接口文档定义): * - tradeWithholdPreparePayParam: 必填,类型 message:alibaba.trade.pay.withhold.preparePayParam * preparePayParam 结构: * - orderId: 订单ID(Long,必填) * * 调用示例: * $orderService->prepareProtocolPay([ * 'orderId' => 123456789, * ]); * * @param array $params 免密支付参数(orderId) * @return array|false */ public function prepareProtocolPay(array $params = []) { // --- 参数校验 --- if (empty($params['orderId'])) { Log::channel('alibaba')->error('[免密支付] orderId不能为空'); return false; } // --- 构建 tradeWithholdPreparePayParam(message类型需序列化为JSON字符串) --- $businessParams = [ 'tradeWithholdPreparePayParam' => json_encode([ 'orderId' => (int)$params['orderId'], ], JSON_UNESCAPED_UNICODE), ]; // --- 调用API --- $result = $this->executeParam2( self::NAMESPACE, 'alibaba.trade.pay.protocolPay.preparePay', 1, $businessParams ); if ($result === false) { Log::channel('alibaba')->error('[免密支付] API请求失败', $businessParams); return false; } Log::channel('alibaba')->info('[免密支付] API请求成功', ['result' => json_encode($result)]); return $this->formatProtocolPayResult($result); } /** * 格式化免密支付准备返回结果 * * @param array $result API原始返回数据 * @return array */ protected function formatProtocolPayResult(array $result): array { // 返回结构: { "result": { ... }, "success": true } $data = $result['result'] ?? $result; $success = $result['success'] ?? false; Log::channel('alibaba')->info('[免密支付] 返回结果', [ 'success' => $success, 'data' => $data, ]); return [ 'success' => $success, 'data' => $data, 'rawData' => $result, ]; } /** * 格式化创建订单返回结果 * * @param array $result API原始返回数据 * @return array */ protected function formatCreateOrderResult(array $result): array { // 创建订单成功返回: { "result": { "orderId": "123456", "totalAmount": 370 }, "success": true } $data = $result['result'] ?? $result; $success = $result['success'] ?? false; return [ 'success' => $success, 'orderId' => $data['orderId'] ?? 0, 'totalAmount' => $data['totalAmount'] ?? 0, 'rawData' => $data, ]; } /** * 构建商品列表参数(便捷方法) * * @param array $items 商品列表 [['offerId' => 123, 'quantity' => 2, 'skuId' => 456], ...] * @return array */ public function buildProductList(array $items): array { $productList = []; foreach ($items as $item) { $product = [ 'offerId' => (int)($item['offerId'] ?? $item['productId'] ?? 0), 'quantity' => (int)($item['quantity'] ?? 1), ]; if (!empty($item['skuId'])) { $product['skuId'] = (int)$item['skuId']; } if (!empty($item['price'])) { $product['price'] = (int)$item['price']; // 单位:分 } if (!empty($item['productUnit'])) { $product['productUnit'] = $item['productUnit']; } $productList[] = $product; } return $productList; } /** * 构建地址参数(便捷方法) * * @param int $addressId 地址ID * @return array */ public function buildAddressParam(int $addressId): array { return [ 'addressId' => $addressId, ]; } /** * 构建完整地址参数(使用系统地址数据格式) * * 适配系统 user_address 表字段: * address_id, real_name, phone, province, city, district, detail, post_code, code_list * * @param array $address 地址信息(系统user_address表数据) * @return array */ public function buildFullAddressParam(array $address): array { // 解析地区编码列表: "1,67449,35,493" $codeList = $address['code_list'] ?? ''; $codes = explode(',', $codeList); $districtCode = $codes[1] ?? $codes[0] ?? ''; return [ 'fullName' => $address['real_name'] ?? $address['fullName'] ?? '', 'mobile' => $address['phone'] ?? $address['mobile'] ?? '', 'phone' => $address['phone'] ?? $address['phone'] ?? '', 'postCode' => $address['post_code'] ?? $address['postCode'] ?? '', 'cityText' => $address['city'] ?? $address['cityText'] ?? '', 'provinceText' => $address['province'] ?? $address['provinceText'] ?? '', 'areaText' => $address['district'] ?? $address['areaText'] ?? '', 'townText' => $address['village'] ?? $address['townText'] ?? '', 'address' => $address['detail'] ?? $address['address'] ?? '', 'districtCode' => $districtCode, ]; } /** * 获取交易订单的物流信息(买家视角) * * API: com.alibaba.trade:alibaba.trade.get.logisticsInfos.buyerView-1 * * 接口文档: https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.trade%3Aalibaba.trade.get.logisticsInfos.buyerView-1 * * 请求参数: * - orderId: 1688订单ID(必填) * - webSite: 1688站点(可选,默认"1688") * * 返回示例: * { * "result": { * "logisticsItems": [{ * "logisticsId": "LP001", * "logisticsCode": "SF1234567890", // 物流单号 * "logisticsName": "顺丰速运", // 物流公司名称 * "logisticsCompany": "shunfeng", // 物流公司编码 * "status": "accept", // 物流状态 * "gmtCreate": "2018-05-30 19:34:27" * }] * }, * "success": true * } * * @param array $params 请求参数(orderId 必填) * @return array|false */ public function getLogisticsInfosBuyerView(array $params = []) { // --- 参数校验 --- if (empty($params['orderId'])) { Log::channel('alibaba')->error('[获取物流信息] orderId不能为空'); return false; } $businessParams = [ 'orderId' => (string)$params['orderId'], 'webSite' => $params['webSite'] ?? '1688', ]; // --- 调用API --- $result = $this->executeParam2( self::LOGISTICS_NAMESPACE, 'alibaba.trade.getLogisticsInfos.buyerView', 1, $businessParams ); if ($result === false) { Log::channel('alibaba')->error('[获取物流信息] API请求失败, params:' . json_encode($businessParams, JSON_UNESCAPED_UNICODE)); return false; } Log::channel('alibaba')->info('[获取物流信息] API请求成功, result:' . json_encode($result, JSON_UNESCAPED_UNICODE)); return $this->formatLogisticsInfosResult($result); } /** * 格式化物流信息返回结果 * * @param array $result API原始返回数据 * @return array */ protected function formatLogisticsInfosResult(array $result): array { $success = $result['success'] ?? false; $logisticsItems = []; if (isset($result['result']['logisticsItems']) && is_array($result['result']['logisticsItems'])) { foreach ($result['result']['logisticsItems'] as $item) { $logisticsItems[] = [ 'logisticsId' => $item['logisticsId'] ?? '', 'logisticsCode' => $item['logisticsCode'] ?? '', // 物流单号 'logisticsName' => $item['logisticsName'] ?? '', // 物流公司名称 'logisticsCompany' => $item['logisticsCompany'] ?? '', // 物流公司编码 'status' => $item['status'] ?? '', 'gmtCreate' => $item['gmtCreate'] ?? '', ]; } } return [ 'success' => $success, 'logisticsItems' => $logisticsItems, 'rawData' => $result, ]; } }