verifySignature($data)) { Yii::error('达达回调签名验证失败: ' . json_encode($data, JSON_UNESCAPED_UNICODE), 'dada-callback'); return false; } // 处理订单状态变更 return $this->processOrderCallback($data); } catch (\Exception $e) { Yii::error('达达回调处理异常: ' . $e->getMessage() . ' | ' . $e->getTraceAsString(), 'dada-callback'); return false; } } /** * 处理订单回调 */ private function processOrderCallback($data) { $orderSn = $data['order_id']; // 对应 orderSn $dadaStatus = $data['order_status']; $clientId = isset($data['client_id']) ? $data['client_id'] : ''; //达达物流订单号 // 查找主订单 $order = OrderClass::getByCondition(['orderSn' => $orderSn], true); $isGhs = true; if (!$order) { $order = HdOrderClass::getByCondition(['orderSn' => $orderSn], true); $isGhs = false; } if (!$order) { Yii::error('达达回调未找到对应订单: ' . $orderSn, 'dada-callback'); return false; } // 查找配送订单 $deliveryOrder = $this->getDeliveryOrder($order, $isGhs); if (!$deliveryOrder) { Yii::error('达达配送订单不存在: orderSn=' . $orderSn . ' ghsOrderId=' . $order->id, 'dada-callback'); return false; } // 更新 client_id (达达物流订单号) if (!empty($clientId) && empty($deliveryOrder->orderId)) { // $deliveryOrder->orderId = $clientId; } $sendStatus = $this->convertOrderSendStatus($dadaStatus); $orderStatus = $this->convertOrderStatus($dadaStatus); if ($sendStatus === null) { return true; } // 更新配送订单状态 $deliveryOrder->orderStatus = $sendStatus; $deliveryOrder->save(); // 更新主订单 if ($isGhs) { util::checkRepeatCommit('ghs_pt_' . $order->id . '_' . $dadaStatus, 2); //$order = OrderClass::getById($order->id, true, 'id,sendType,sendStatus,deliveryId,purchaseId,customId,status'); $cg = PurchaseClass::getById($order->purchaseId, true, 'id,status,sendStatus'); if ($order) { // 已送达 if ($sendStatus == 5) { if($cg->status == 3){ OrderClass::confirmReach($order, ['staffId' => 0, 'staffName' => '']); }else{ Yii::warning('进行确认送达时,采购单状态不为3,无法进行确认送达。orderId='.$order->id); noticeUtil::push('进行确认送达时,采购单状态不为3,无法进行确认送达。orderId='.$order->id.', purchaseId='.$cg->id); } } // 取消/异常 (且当前状态未取消) if (!in_array($order->sendStatus, [-2, -1]) && in_array($sendStatus, [-1, -2])) { OrderClass::cancelOrderSend($order, ['staffId' => 0, 'staffName' => '']); $event = $this->cancelFrom($sendStatus, $data['cancel_from'], $dadaStatus); GhsNotifyClass::ptErrorNotify($order->id, $event); } if ($cg) { $cg->sendStatus = $sendStatus; $cg->save(); } $order->sendStatus = $sendStatus; if ($orderStatus !== null) { $order->status = $orderStatus; } $order->save(); } } else { // 零售订单处理 util::checkRepeatCommit('hd_pt_' . $order->id . '_' . $dadaStatus, 2); //$order = HdOrderClass::getById($order->id, true, 'id,sendType,sendStatus,deliveryId,customId,status'); // 取消/异常 (且当前状态未取消) if (!in_array($order->sendStatus, [-2, -1]) && in_array($sendStatus, [-1, -2])) { $event = $this->cancelFrom($sendStatus, $data['cancel_from'], $dadaStatus); HdNotifyClass::ptErrorNotify($order->id, $event); } if ($order) { $order->sendStatus = $sendStatus; if ($orderStatus !== null) { $order->status = $orderStatus; } $order->save(); } } return true; } /** * 验证签名 */ private function verifySignature($data) { if (!isset($data['signature'])) { return false; } // client_id, order_id, update_time // 值为 null 时转为空字符串 $clientId = isset($data['client_id']) ? $data['client_id'] : ''; $orderId = isset($data['order_id']) ? $data['order_id'] : ''; $updateTime = isset($data['update_time']) ? $data['update_time'] : ''; $list = [$clientId, $orderId, $updateTime]; sort($list, SORT_STRING); $str = implode('', $list); $sign = md5($str); return $sign === $data['signature']; } private function getDeliveryOrder($order, $isGhs) { if ($isGhs) { $gdos = GhsDeliveryOrderClass::getAllByCondition([ 'deliveryId' => 'dada', 'ghsOrderId' => $order->id, 'orderStatus' => ['not in', [-1, -2]], ], 'id DESC', '*', null, true); if(count($gdos)>=2){ noticeUtil::push("xhGhsDeliveryOrder ghsOrderId={$order->id} 有两笔以上是在配送中"); $gdo = $gdos[0]; }elseif(count($gdos)==1){ $gdo = $gdos[0]; }else{ $gdo = null; } return $gdo; } else { $hdos = HdDeliveryOrderClass::getAllByCondition([ 'deliveryId' => 'dada', 'hdOrderId' => $order->id, 'orderStatus' => ['not in', [-1, -2]], ], 'id DESC', '*', null, true); if(count($hdos)>=2){ noticeUtil::push("xhHdDeliveryOrder hdOrderId={$order->id} 有两笔以上是在配送中"); $hdo = $hdos[0]; }elseif(count($hdos)==1){ $hdo = $hdos[0]; }else{ $hdo = null; } return $hdo; } } private function convertOrderSendStatus($dadaStatus) { $map = [ 1 => 2, // 待接单 -> 派单中 2 => 20, // 待取货 -> 已分配骑手 3 => 4, // 配送中 -> 配送中 4 => 5, // 已完成 -> 已送达 5 => -1, // 已取消 -> 已取消 8 => 2, // 已追加待接单 -> 派单中 9 => -2, // 妥投异常之物品返回中=9 -> 异常 10 => -2, // 妥投异常之物品返回完成=10 -> 异常 100 => 30,// 骑士到店 -> 骑手已到店 1000 => -2,// 创建失败 -> 异常 ]; return $map[$dadaStatus] ?? null; } private function convertOrderStatus($dadaStatus) { $map = [ 1 => 3, // 待接单 -> 配送中 2 => 3, // 待取货 -> 配送中 3 => 3, // 配送中 -> 配送中 4 => 4, // 已完成 -> 已完成 100 => 3, // 到店 -> 配送中 ]; return $map[$dadaStatus] ?? null; } private function cancelFrom($sendStatus, $from, $dadaStatus) { if($sendStatus == -1){ switch($from){ case 1: $which = '达达配送员取消'; break; case 2: $which = '门店主动取消'; break; case 3: $which = '系统或客服取消'; break; default: $which = '未知'; } return $which; } if($sendStatus == -2){ $reasons = [ 9 => '妥投异常之物品返回中', 10 => '妥投异常之物品返回完成', 1000 => '创建达达运单失败', ]; return $reasons[$dadaStatus] ?? '未知'; } } }