xmlToArray($xmlData); // 验证签名 if (!$this->verifyWechatSign($data, $wechatConfig['api_key'])) { return $this->xmlResponse('FAIL', '签名验证失败'); } // 验证金额 $order = Order::where('order_no', $data['out_trade_no'])->find(); if (!$order) { return $this->xmlResponse('FAIL', '订单不存在'); } if ((int)$data['total_fee'] != (int)($order->amount * 100)) { return $this->xmlResponse('FAIL', '金额不匹配'); } // 验证交易状态 if ($data['result_code'] == 'SUCCESS') { // 更新订单状态 if ($order->status == 1) { // 只有待支付的订单才能更新 $order->status = 2; // 已支付 $order->payment_method = 'wechat'; $order->payment_time = date('Y-m-d H:i:s'); $order->trade_no = $data['transaction_id']; $order->save(); } } return $this->xmlResponse('SUCCESS', '支付成功'); } catch (\Exception $e) { return $this->xmlResponse('FAIL', $e->getMessage()); } } /** * @notes 验证微信签名 * @param array $data * @param string $apiKey * @return bool */ private function verifyWechatSign(array $data, string $apiKey): bool { try { // 获取签名 $sign = $data['sign'] ?? ''; unset($data['sign']); // 按键排序 ksort($data); // 构建签名字符串 $signStr = ''; foreach ($data as $key => $value) { if ($value !== '' && $value !== null) { $signStr .= $key . '=' . $value . '&'; } } $signStr .= 'key=' . $apiKey; // MD5签名 $computedSign = strtoupper(md5($signStr)); return $computedSign === $sign; } catch (\Exception $e) { return false; } } /** * @notes XML转数组 * @param string $xml * @return array */ private function xmlToArray(string $xml): array { try { $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return is_array($data) ? $data : []; } catch (\Exception $e) { return []; } } /** * @notes 返回XML响应 * @param string $returnCode * @param string $returnMsg * @return Xml */ private function xmlResponse(string $returnCode, string $returnMsg): Xml { $xml = ''; $xml .= ''; $xml .= ''; $xml .= ''; return response($xml, 200, ['Content-Type' => 'application/xml']); } }