createApp(); $server = $app->getServer(); $message = $server->getRequestMessage(); if (empty($message)) { return $this->response->withStatus(500)->withBody(new SwooleStream(strval(json_encode(['code' => 'ERROR', 'message' => "问诊微信支付回调数据为空"], JSON_UNESCAPED_UNICODE)))); } // 验证推送消息签名 $app->getValidator()->validate($app->getRequest()); Log::getInstance()->info("问诊微信支付回调数据:" . json_encode($message->toArray(), JSON_UNESCAPED_UNICODE)); if (empty($message['out_trade_no'])) { Log::getInstance()->info("问诊微信支付回调数据处理失败,缺少外部订单号"); return $server->serve(); } // 查询订单 $params = array(); $params['inquiry_no'] = $message['out_trade_no']; $order_inquiry = OrderInquiry::getOne($params); if (empty($order_inquiry)) { Log::getInstance()->info("问诊微信支付回调数据处理失败,无订单数据"); return $server->serve(); } // 获取病例数据 $params = array(); $params['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; $order_inquiry_case = OrderInquiryCase::getOne($params); if (empty($order_inquiry_case)){ Log::getInstance()->info("问诊微信支付回调数据处理失败,患者病例错误"); return $server->serve(); } // 验证订单状态 if ($order_inquiry['inquiry_status'] != 1) { // 问诊订单状态(1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消) Log::getInstance()->info("问诊微信支付回调数据处理失败,订单状态当前为" . $order_inquiry['inquiry_status']); return $server->serve(); } // 支付状态无需验证,如第一次支付失败,会修改支付状态,再次支付时,会出现验证不通过的情况 // 修改支付状态 $data = array(); if ($message['trade_state'] == "SUCCESS") { // 支付成功 $data['inquiry_pay_status'] = 2; $data['pay_time'] = date('Y-m-d H:i:s', strtotime($message['success_time']));// 支付时间 if ($order_inquiry['inquiry_type'] == 1 || $order_inquiry['inquiry_type'] == 3) { // 专家-公益 $data['inquiry_status'] = 3;// 3:待接诊 } elseif ($order_inquiry['inquiry_type'] == 2 || $order_inquiry['inquiry_type'] == 4) { // 快速-购药 $data['inquiry_status'] = 2;// 2:待分配 } } elseif ($message['trade_state'] == "CLOSED") { // 已关闭 $data['inquiry_pay_status'] = 6; } elseif ($message['trade_state'] == "REVOKED") { // 已撤销(付款码支付) $data['inquiry_pay_status'] = 7; } elseif ($message['trade_state'] == "USERPAYING") { // 用户支付中(付款码支付) $data['inquiry_pay_status'] = 3; } elseif ($message['trade_state'] == "PAYERROR") { // 支付失败(其他原因,如银行返回失败) $data['inquiry_pay_status'] = 4; } $data['escrow_trade_no'] = $message['transaction_id']; $data['updated_at'] = date('Y-m-d H:i:s', time()); $params = array(); $params['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; OrderInquiry::edit($params, $data); } catch (\Exception $e) { // 验证失败 Log::getInstance()->error("问诊微信支付回调数据处理失败:" . $e->getMessage()); return $this->wxPayErrorReturn($e->getMessage()); } Log::getInstance()->info("问诊微信支付回调数据处理成功"); Log::getInstance()->info("问诊微信支付回调数据处理成功,开始分配医生/发送问诊消息"); try { if ($message['trade_state'] == "SUCCESS") { if ($order_inquiry['inquiry_type'] == 2 || $order_inquiry['inquiry_type'] == 4) { Log::getInstance()->info("加入分配医生队列"); // 快速-购药 // 加入分配医生队列 $data = array(); $data['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; $message = new AssignDoctorDelayDirectProducer($data); $message->setDelayMs(1000 * 5); $producer = $this->container->get(Producer::class); $res = $producer->produce($message); if (!$res) { Log::getInstance()->info("加入分配医生队列失败"); return $server->serve(); } Log::getInstance()->info("加入分配医生队列成功"); } elseif ($order_inquiry['inquiry_type'] == 1 || $order_inquiry['inquiry_type'] == 3) { // 专家-公益,发送im消息 Log::getInstance()->info("开始发送im消息"); // 获取订单医生数据 $params = array(); $params['doctor_id'] = $order_inquiry['doctor_id']; $user_doctor = UserDoctor::getOne($params); if (empty($user_doctor)) { Log::getInstance()->info("医生数据错误"); return $server->serve(); } // 发送im消息 $imService = new ImService(); // 患者病例 $imService->patientCase($order_inquiry,$user_doctor['user_id'],$order_inquiry_case['disease_desc']); // 等待医生接诊 $imService->waitDoctorInquiry($order_inquiry, $user_doctor['user_id'], $order_inquiry['user_id']); // 发送站内、订阅失败发送短信消息-医生有新问诊 $MessagePush = new MessagePush($user_doctor['user_id'], $order_inquiry['order_inquiry_id']); $MessagePush->doctorHaveNewInquiry(); Log::getInstance()->info("发送im消息成功"); } } } catch (\Exception $e) { // 验证失败 Log::getInstance()->error("问诊微信支付回调数据处理成功,分配医生/发送问诊消息失败:" . $e->getMessage()); return $server->serve(); } Log::getInstance()->info("问诊微信支付回调处理成功"); return $server->serve(); } /** * 微信问诊退款回调 * @return ResponseInterface * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface * @throws \Throwable */ public function wxPayInquiryRefundCallBack(): ResponseInterface { Db::beginTransaction(); try { // 处理支付结果事件 $WechatPay = new WechatPay(1, 1); $app = $WechatPay->createApp(); $server = $app->getServer(); $message = $server->getRequestMessage(); if (empty($message)) { Db::rollBack(); return $this->response->withStatus(500)->withBody(new SwooleStream(strval(json_encode(['code' => 'ERROR', 'message' => "回调数据为空"], JSON_UNESCAPED_UNICODE)))); } // 验证推送消息签名 $app->getValidator()->validate($app->getRequest()); Log::getInstance()->info("微信退款回调数据:" . json_encode($message->toArray(), JSON_UNESCAPED_UNICODE)); if (empty($message['out_trade_no'])) { Log::getInstance()->info("微信退款回调数据错误"); return $server->serve(); } // 验证订单数据 $params = array(); $params['inquiry_no'] = $message['out_trade_no']; $order_inquiry = OrderInquiry::getOne($params); if (empty($order_inquiry)) { Log::getInstance()->info("非法订单"); return $server->serve(); } // 验证订单状态 if ($order_inquiry['inquiry_status'] == 1) { // 问诊订单状态(1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消) Log::getInstance()->info("订单状态错误:当前为" . $order_inquiry['inquiry_status']); return $server->serve(); } // 验证订单退款状态 if ($order_inquiry['inquiry_refund_status'] == 3) { // 问诊订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭) Log::getInstance()->info("订单退款状态错误:当前为" . $order_inquiry['inquiry_refund_status']); return $server->serve(); } // 验证订单支付状态 if (in_array($order_inquiry['inquiry_pay_status'], [1, 3, 4, 5, 6, 7])) { // 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款) Log::getInstance()->info("订单支付状态错误:当前为" . $order_inquiry['inquiry_pay_status']); return $server->serve(); } // 退款状态 if ($message['refund_status'] == "SUCCESS") { // 退款成功 $inquiry_refund_status = 3; } elseif ($message['refund_status'] == "CLOSED") { // 退款关闭 $inquiry_refund_status = 5; } elseif ($message['refund_status'] == "ABNORMAL") { // 退款异常 $inquiry_refund_status = 6; } if (empty($inquiry_refund_status)) { // 错误,无退款状态 Log::getInstance()->info("订单支付状态错误:未接收到退款状态"); return $this->wxPayErrorReturn("退款状态错误"); } // 修改订单 $data = array(); $data['inquiry_refund_status'] = $inquiry_refund_status; $params = array(); $params['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; OrderInquiry::edit($params, $data); // 修改退款订单 $data = array(); $data['inquiry_refund_status'] = $inquiry_refund_status; $data['success_time'] = $message['success_time']; $params = array(); $params['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; OrderInquiryRefund::edit($params, $data); // 恢复优惠卷 if ($inquiry_refund_status == 3) { if (!empty($order_inquiry['coupon_amount_total']) && $order_inquiry['coupon_amount_total'] > 0) { $InquiryService = new InquiryService(); $InquiryService->returnInquiryCoupon($order_inquiry['order_inquiry_id'], $order_inquiry['user_id']); } } Db::commit(); } catch (\Exception $e) { // 验证失败 Db::rollBack(); Log::getInstance()->error("微信支付回调数据验证失败:" . $e->getMessage()); return $this->wxPayErrorReturn($e->getMessage()); } Log::getInstance()->info("微信退款回调处理成功,推送消息"); // 发送推送消息 if ($inquiry_refund_status == 3) { try { // 发送站内、订阅、短信消息-问诊服务退款成功 $MessagePush = new MessagePush($order_inquiry['user_id'], $order_inquiry['order_inquiry_id']); // 取消订单原因(1:医生未接诊 2:主动取消 3:无可分配医生 4:客服取消 5:支付超时) $MessagePush->refundInquirySuccess($order_inquiry['cancel_reason']); if (!empty($order_inquiry['coupon_amount_total']) && $order_inquiry['coupon_amount_total'] > 0) { // 获取用户优惠卷信息 $params = array(); $params['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; $order_inquiry_coupon = OrderInquiryCoupon::getOne($params); if (!empty($order_inquiry_coupon)){ // 发送站内消息-优惠卷退还 $MessagePush = new MessagePush($order_inquiry['user_id'], $order_inquiry['order_inquiry_id']); $MessagePush->patientRefundCoupon($order_inquiry_coupon['coupon_name']); } } } catch (\Exception $e) { // 验证失败 Log::getInstance()->error("微信退款回调处理成功,推送消息失败:" . $e->getMessage()); return $server->serve(); } } return $server->serve(); } /** * 患者端药品微信支付回调 * @return ResponseInterface * @throws \Throwable */ public function wxPayProductSuccessCallBack(): ResponseInterface { try { // 处理支付结果事件 $WechatPay = new WechatPay(1, 2); $app = $WechatPay->createApp(); $server = $app->getServer(); $message = $server->getRequestMessage(); if (empty($message)) { return $this->response->withStatus(500)->withBody(new SwooleStream(strval(json_encode(['code' => 'ERROR', 'message' => "药品微信支付回调数据为空"], JSON_UNESCAPED_UNICODE)))); } // 验证推送消息签名 $app->getValidator()->validate($app->getRequest()); Log::getInstance()->info("药品微信支付回调数据:" . json_encode($message->toArray(), JSON_UNESCAPED_UNICODE)); if (empty($message['out_trade_no'])) { Log::getInstance()->info("药品微信支付回调数据处理失败,缺少外部订单号"); return $server->serve(); } } catch (\Exception $e) { // 验证失败 Log::getInstance()->error("药品微信支付回调数据处理失败:" . $e->getMessage()); return $this->wxPayErrorReturn($e->getMessage()); } Log::getInstance()->info("药品微信支付回调数据验证成功,执行数据库操作"); Db::beginTransaction(); try { // 查询药品订单 $params = array(); $params['order_product_no'] = $message['out_trade_no']; $order_product = OrderProduct::getOne($params); if (empty($order_product)) { Db::rollBack(); Log::getInstance()->info("药品微信支付回调数据处理失败,无订单数据"); return $server->serve(); } // 验证订单状态 if ($order_product['order_product_status'] != 1) { Db::rollBack(); // 订单状态(1:待支付 2:待发货 3:已发货 4:已签收 5:已取消) Log::getInstance()->info("药品微信支付回调数据处理失败,订单状态当前为" . $order_product['order_product_status']); return $server->serve(); } // 支付状态无需验证,如第一次支付失败,会修改支付状态,再次支付时,会出现验证不通过的情况 // 修改支付状态 $data = array(); if ($message['trade_state'] == "SUCCESS") { // 支付成功 $data['order_product_status'] = 2; $data['pay_status'] = 2;// 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款) $data['pay_time'] = date('Y-m-d H:i:s', strtotime($message['success_time']));// 支付时间 } elseif ($message['trade_state'] == "CLOSED") { // 已关闭 $data['pay_status'] = 6; } elseif ($message['trade_state'] == "REVOKED") { // 已撤销(付款码支付) $data['pay_status'] = 7; } elseif ($message['trade_state'] == "USERPAYING") { // 用户支付中(付款码支付) $data['pay_status'] = 3; } elseif ($message['trade_state'] == "PAYERROR") { // 支付失败(其他原因,如银行返回失败) $data['pay_status'] = 4; } $data['escrow_trade_no'] = $message['transaction_id']; $data['updated_at'] = date('Y-m-d H:i:s', time()); $params = array(); $params['order_product_id'] = $order_product['order_product_id']; OrderProduct::edit($params, $data); // 获取订单商品订单列表 $params = array(); $params['order_product_id'] = $order_product['order_product_id']; $order_product_item = OrderProductItem::getList($params); if (empty($order_product_item)) { Db::rollBack(); Log::getInstance()->info("药品微信支付回调数据处理失败,未查询到对应订单商品订单列表"); return $server->serve(); } Db::commit(); } catch (\Exception $e) { Db::rollBack(); Log::getInstance()->error("药品微信支付回调数据处理失败:" . $e->getMessage()); return $this->wxPayErrorReturn($e->getMessage()); } Log::getInstance()->error("药品微信支付回调数据处理成功"); return $server->serve(); } /** * 微信药品退款回调 * @return ResponseInterface * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface * @throws \Throwable */ public function wxPayProductRefundCallBack(): ResponseInterface { Db::beginTransaction(); try { // 处理支付结果事件 $WechatPay = new WechatPay(1, 1); $app = $WechatPay->createApp(); $server = $app->getServer(); $message = $server->getRequestMessage(); if (empty($message)) { Db::rollBack(); return $this->response->withStatus(500)->withBody(new SwooleStream(strval(json_encode(['code' => 'ERROR', 'message' => "回调数据为空"], JSON_UNESCAPED_UNICODE)))); } // 验证推送消息签名 $app->getValidator()->validate($app->getRequest()); Log::getInstance()->info("微信退款回调数据:" . json_encode($message->toArray(), JSON_UNESCAPED_UNICODE)); if (empty($message['out_trade_no'])) { Log::getInstance()->info("药品微信退款回调数据处理失败,缺少外部订单号"); return $server->serve(); } // 查询药品订单 $params = array(); $params['order_product_no'] = $message['out_trade_no']; $order_product = OrderProduct::getOne($params); if (empty($order_product)) { Db::rollBack(); Log::getInstance()->info("药品微信退款回调数据处理失败,无订单数据"); return $server->serve(); } // 验证订单状态 if ($order_product['order_product_status'] == 1) { // 订单状态(1:待支付 2:待发货 3:已发货 4:已签收 5:已取消) Log::getInstance()->info("药品微信退款回调数据处理失败,订单状态错误:当前为" . $order_product['order_product_status']); return $server->serve(); } // 验证订单退款状态 if ($order_product['refund_status'] == 3) { // 商品订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭) Log::getInstance()->info("药品微信退款回调数据处理失败,订单退款状态为" . $order_product['refund_status']); return $server->serve(); } // 验证订单支付状态 if (in_array($order_product['pay_status'], [1, 3, 4, 5, 6, 7])) { // 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款) Log::getInstance()->error("药品微信退款回调数据处理失败:订单未支付"); return $server->serve(); } // 退款状态 if ($message['refund_status'] == "SUCCESS") { // 退款成功 $refund_status = 3; } elseif ($message['refund_status'] == "CLOSED") { // 退款关闭 $refund_status = 5; } elseif ($message['refund_status'] == "ABNORMAL") { // 退款异常 $refund_status = 6; } if (empty($refund_status)) { // 错误,无退款状态 Log::getInstance()->error("药品微信退款回调数据处理失败:订单未支付"); return $this->wxPayErrorReturn("退款状态错误"); } // 修改订单 $data = array(); $data['refund_status'] = $refund_status; $params = array(); $params['order_product_id'] = $order_product['order_product_id']; OrderProduct::edit($params, $data); // 修改退款订单 $data = array(); $data['product_refund_status'] = $refund_status; $data['success_time'] = $message['success_time']; $params = array(); $params['order_product_id'] = $order_product['order_product_id']; OrderProductRefund::edit($params, $data); Db::commit(); } catch (\Exception $e) { // 验证失败 Db::rollBack(); Log::getInstance()->error("药品微信退款回调数据处理失败:" . $e->getMessage()); return $this->wxPayErrorReturn($e->getMessage()); } Log::getInstance()->info("药品微信退款回调数据处理成功"); // 发送推送消息 try { // 获取患者数据 $params = array(); $params['patient_id'] = $order_product['patient_id']; $user_patient = UserPatient::getOne($params); if (!empty($user_patient)) { // 发送站内、订阅、短信消息-药品订单退款成功 $MessagePush = new MessagePush($user_patient['user_id']); $MessagePush->refundProductSuccess($order_product['order_product_id']); } } catch (\Exception $e) { // 验证失败 Log::getInstance()->error("微信退款回调处理成功,推送消息失败:" . $e->getMessage()); return $server->serve(); } // 告知处方平台 return $server->serve(); } /** * 微信支付返回错误响应 * @param string $message * @return ResponseInterface */ protected function wxPayErrorReturn(string $message): ResponseInterface { return $this->response ->withStatus(500) ->withBody( new SwooleStream( strval( json_encode(['code' => 'ERROR', 'message' => $message], JSON_UNESCAPED_UNICODE) ) ) ); } /** * im回调 * @return ResponseInterface * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ public function imCallBack(): ResponseInterface { $request_params = $this->request->all(); try { Log::getInstance()->info("Im回调数据:" . json_encode($request_params, JSON_UNESCAPED_UNICODE)); if (empty($request_params['RequestTime']) || empty($request_params['Sign'])) { Log::getInstance()->error("Im回调数据处理失败:缺少时间时间戳/签名字段"); return $this->ImErrorReturn("缺少时间时间戳/签名字段"); } // 鉴定回调签名 $imService = new ImService(); $result = $imService->validateSign($request_params['RequestTime'], $request_params['Sign']); if (!$result) { Log::getInstance()->error("Im回调数据处理失败:回调签名不匹配"); return $this->ImErrorReturn("回调签名不匹配"); } // 验证消息内容 if (empty($request_params['MsgBody'])) { Log::getInstance()->error("Im回调数据处理失败:消息内容错误"); return $this->ImErrorReturn("消息内容错误,缺少MsgBody"); } // 验证消息内容类型 if (empty($request_params['MsgBody'][0]['MsgType'])) { Log::getInstance()->error("Im回调数据处理失败:缺少MsgType"); return $this->ImErrorReturn("消息内容错误,缺少MsgType"); } // 验证消息内容详情 if (empty($request_params['MsgBody'][0]['MsgContent'])) { Log::getInstance()->error("Im回调数据处理失败:缺少MsgContent"); return $this->ImErrorReturn("消息内容错误,缺少MsgContent"); } // 验证接收方user_id if (empty($request_params['To_Account'])) { Log::getInstance()->error("Im回调数据处理失败:接收用户错误"); return $this->ImErrorReturn("消息内容错误,接收用户错误"); } // 验证消息唯一id if (empty($request_params['MsgKey'])) { Log::getInstance()->error("Im回调数据处理失败:消息唯一标识错误"); return $this->ImErrorReturn("消息内容错误,消息唯一标识错误"); } // 验证消息重复性 $params = array(); $params['message_key'] = $request_params['MsgKey']; $message = MessageIm::getExists($params); if ($message) { // 消息重复 Log::getInstance()->info("Im回调数据处理失败:消息重复"); return $this->ImSuccessReturn(); } // 处理发送结果 if ($request_params['SendMsgResult'] == 0) { // im中0表示成功 $message_send_result = 1; } // 验证自定义消息内容 $is_system = 0;// 是否系统操作发送(0:否 1:是) if (!empty($request_params['CloudCustomData'])) { $cloud_custom_data = json_decode($request_params['CloudCustomData'], true); if (!empty($cloud_custom_data['order_inquiry_id'])) { // 获取订单数据 $params = array(); $params['order_inquiry_id'] = $cloud_custom_data['order_inquiry_id']; $order_inquiry = OrderInquiry::getOne($params); if (empty($order_inquiry)) { Log::getInstance()->error("Im回调数据处理失败:非法订单"); return $this->ImErrorReturn("消息内容错误,非法订单"); } $order_inquiry_id = $cloud_custom_data['order_inquiry_id']; } if (!empty($cloud_custom_data['is_system'])) { if ($cloud_custom_data['is_system'] == 1) { // 系统发送 $is_system = 1; } } } // 入库 $data = array(); if (!empty($request_params['From_Account'])) { // 系统发送时不带参数 $data['from_user_id'] = $request_params['From_Account']; } $data['to_user_id'] = $request_params['To_Account']; $data['message_key'] = $request_params['MsgKey']; $data['message_send_time'] = $request_params['RequestTime']; $data['message_seq'] = $request_params['MsgSeq']; $data['message_send_result'] = $message_send_result ?? 0; $data['send_error_info'] = $request_params['ErrorInfo']; $data['message_type'] = $request_params['MsgBody'][0]['MsgType']; $data['is_system'] = $is_system; if (!empty($order_inquiry_id)) { $data['order_inquiry_id'] = $order_inquiry_id; } $message_content = $request_params['MsgBody'][0]['MsgContent']; $data['message_content'] = json_encode($message_content, JSON_UNESCAPED_UNICODE); $data['message_custom_content'] = $request_params['CloudCustomData'] ?? ""; $message = MessageIm::addMessage($data); if (empty($message)) { Log::getInstance()->error("Im回调数据处理失败:存储数据库失败"); return $this->wxPayErrorReturn("存储数据库失败"); } } catch (\Exception $e) { // 验证失败 Log::getInstance()->error("Im回调数据处理失败:" . $e->getMessage()); return $this->wxPayErrorReturn($e->getMessage()); } Log::getInstance()->info("Im回调数据处理成功"); return $this->ImSuccessReturn(); } /** * im返回错误响应 * @param string $message * @return ResponseInterface */ protected function ImErrorReturn(string $message): ResponseInterface { return $this->response ->withStatus(200) ->withBody( new SwooleStream( strval( json_encode([ 'ActionStatus' => 'FAIL', 'ErrorCode' => 1, 'ErrorInfo' => $message, ], JSON_UNESCAPED_UNICODE) ) ) ); } /** * im返回正确响应 * @return ResponseInterface */ protected function ImSuccessReturn(): ResponseInterface { return $this->response ->withStatus(200) ->withBody( new SwooleStream( strval( json_encode([ 'ActionStatus' => 'OK', 'ErrorCode' => 0, 'ErrorInfo' => "", ], JSON_UNESCAPED_UNICODE) ) ) ); } // 处方平台物流回调 public function platformLogisticsCallBack(): ResponseInterface { $request_params = $this->request->all(); try { Log::getInstance()->info("处方平台物流回调数据:" . json_encode($request_params, JSON_UNESCAPED_UNICODE)); if (!isset($request_params['sign'])) { Log::getInstance()->error("处方平台物流回调数据处理失败:缺少签名结果"); return $this->platformLogisticsErrorReturn("缺少签名结果"); } if (!isset($request_params['nonce'])) { Log::getInstance()->error("处方平台物流回调数据处理失败:缺少随机数"); return $this->platformLogisticsErrorReturn("缺少随机数"); } if (!isset($request_params['timestamp'])) { Log::getInstance()->error("处方平台物流回调数据处理失败:缺少签名时间戳"); return $this->platformLogisticsErrorReturn("缺少签名时间戳"); } if (!isset($request_params['paramJsonStr'])) { Log::getInstance()->error("处方平台物流回调数据处理失败:缺少数据体"); return $this->platformLogisticsErrorReturn("缺少数据体"); } // 验证签名 $sign_params = array(); $sign_params['clientId'] = config('prescription_platform.client_id'); $sign_params['paramJsonStr'] = $request_params['paramJsonStr']; $sign_params['timestamp'] = $request_params['timestamp']; $sign_params['nonce'] = $request_params['nonce']; $sign_params['clientSecret'] = config('prescription_platform.client_secret'); $sign = md5(http_build_query($sign_params, '', '&')); if ($sign != $request_params['sign']) { Log::getInstance()->error("处方平台物流回调数据处理失败:签名错误"); Log::getInstance()->error("系统签名:" . $sign); Log::getInstance()->error("处方平台签名:" . $sign); Log::getInstance()->error("处方平台签名:" . $request_params['sign']); return $this->platformLogisticsErrorReturn("签名错误"); } $param_json_str = json_decode($request_params['paramJsonStr'], true); if (empty($param_json_str)) { // 数据体为空,直接返回成功,不进行验证签名 Log::getInstance()->info("处方平台物流回调数据处理成功:数据体解析为空"); return $this->platformLogisticsSuccessReturn(); } } catch (\Exception $e) { // 验证失败 Log::getInstance()->error("处方平台物流回调数据处理失败:" . $e->getMessage()); return $this->platformLogisticsErrorReturn($e->getMessage()); } Log::getInstance()->info("处方平台物流回调数据处理成功"); return $this->platformLogisticsSuccessReturn(); } /** * 处方平台物流返回错误响应 * @param string $message * @return ResponseInterface */ protected function platformLogisticsErrorReturn(string $message): ResponseInterface { return $this->response ->withStatus(200) ->withBody( new SwooleStream( strval( json_encode([ 'resultCode' => '0', 'resultDesc' => $message, ], JSON_UNESCAPED_UNICODE) ) ) ); } /** * 处方平台物流返回正确响应 * @return ResponseInterface */ protected function platformLogisticsSuccessReturn(): ResponseInterface { return $this->response ->withStatus(200) ->withBody( new SwooleStream( strval( json_encode([ 'resultCode' => "1000", 'resultDesc' => "成功", ], JSON_UNESCAPED_UNICODE) ) ) ); } /** * 快递100订阅回调 * @return ResponseInterface * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ public function LogisticsCallBack(): ResponseInterface { $request_params = $this->request->all(); try { Log::getInstance()->info("快递100订阅回调数据:" . json_encode($request_params, JSON_UNESCAPED_UNICODE)); // 检测回调数据 if (!isset($request_params['sign']) || !isset($request_params['param'])) { return $this->LogisticsFailReturn("缺少推送参数:sign/param"); } // 检测签名 $sign = strtoupper(md5( $request_params['param'] . config('kuaidi100.salt') )); if ($sign != $request_params['sign']){ return $this->LogisticsFailReturn("签名验证错误"); } // 转换编码 $request_params['param'] = json_decode($request_params['param'],true); if (empty($request_params['param'])){ return $this->LogisticsFailReturn("转换json失败"); } // 检测消息体 if (!isset($request_params['param']['lastResult'])){ return $this->LogisticsFailReturn("缺少推送参数:lastResult"); } // 检测订单号 if (!isset($request_params['param']['lastResult']['nu'])){ return $this->LogisticsFailReturn("缺少推送参数:nu"); } // 检测快递公司编码 if (!isset($request_params['param']['lastResult']['com'])){ return $this->LogisticsFailReturn("缺少推送参数:com"); } // 检测内容 if (!isset($request_params['param']['lastResult']['data'])){ return $this->LogisticsFailReturn("缺少推送参数:data"); } // 检测状态 if (!isset($request_params['param']['lastResult']['state'])){ return $this->LogisticsFailReturn("缺少推送参数:state"); } // 运单签收状态(0在途 1揽收 2疑难 3签收 4退签 5派件 8清关 14拒签) $logistics_status = [0,1,2,3,4,5,8,14]; if (!in_array($request_params['param']['lastResult']['state'],$logistics_status)){ return $this->LogisticsSuccessReturn("非可执行状态"); } Db::beginTransaction(); try { // 获取药品订单数据 $params = array(); $params['logistics_no'] = $request_params['param']['lastResult']['nu']; $params['logistics_company_code'] = $request_params['param']['lastResult']['com']; $order_product = OrderProduct::getOne($params); if (empty($order_product)){ Db::rollBack(); return $this->LogisticsFailReturn("药品订单数据错误"); } // 检测药品订单数据 if (in_array($order_product['order_product_status'],[1,4,5])){ // 订单状态(1:待支付 2:待发货 3:已发货 4:已签收 5:已取消) Db::rollBack(); return $this->LogisticsSuccessReturn("无需处理"); } // 获取快递公司数据 $params = array(); $params['company_code'] = $request_params['param']['lastResult']['com']; $params['company_type'] = 1; $basic_logistics_company = BasicLogisticsCompany::getOne($params); if (empty($basic_logistics_company)){ Db::rollBack(); return $this->LogisticsFailReturn("快递公司编码错误"); } // 获取商品订单-物流数据 $params = array(); $params['logistics_no'] = $request_params['param']['lastResult']['nu']; $params['company_code'] = $request_params['param']['lastResult']['com']; $order_product_logistics = OrderProductLogistic::getOne($params); if (empty($order_product_logistics)){ // 不存在物流数据 $data = array(); $data['order_product_id'] = $order_product['order_product_id']; $data['logistics_status'] = $request_params['param']['lastResult']['state']; $data['logistics_no'] = $request_params['param']['lastResult']['nu']; $data['company_name'] = $basic_logistics_company['company_name']; $data['company_code'] = $request_params['param']['lastResult']['com']; $data['logistics_content'] = json_encode($request_params['param']['lastResult']['data'],JSON_UNESCAPED_UNICODE); $order_product_logistics = OrderProductLogistic::addOrderProductLogistic($data); if (empty($order_product_logistics)){ Db::rollBack(); return $this->LogisticsFailReturn("添加物流数据错误"); } }else{ $params = array(); $params['logistics_id'] = $order_product_logistics['logistics_id']; $data = array(); if ($order_product_logistics['logistics_status'] != $request_params['param']['lastResult']['state']){ $data['logistics_status'] = $request_params['param']['lastResult']['state']; } $data['logistics_content'] = json_encode($request_params['param']['lastResult']['data'],JSON_UNESCAPED_UNICODE); OrderProductLogistic::edit($params,$data); } // 运单签收状态(0在途 1揽收 2疑难 3签收 4退签 5派件 8清关 14拒签) if ($request_params['param']['lastResult']['state'] == 3){ // 修改药品订单数据为已签收 $params = array(); $params['order_product_id'] = $order_product['order_product_id']; $data = array(); $data['order_product_status'] = 4; OrderProduct::edit($params,$data); // 新增药品用药记录 } Db::commit(); } catch (\Exception $e) { Db::rollBack(); return $this->LogisticsFailReturn($e->getMessage()); } // 推送消息 try { // 获取患者数据 $params = array(); $params['patient_id'] = $order_product['patient_id']; $user_patient = UserPatient::getOne($params); if (empty($user_patient)){ return $this->LogisticsSuccessReturn("推送消息错误:用户数据错误"); } // 检测是否推送过 $redis = $this->container->get(Redis::class); $redis_key = "logistics_" . $request_params['param']['lastResult']['nu'] . $request_params['param']['lastResult']['state']; $redis_value = $redis->get($redis_key); if (empty($redis_value)){ // 未推送过 $status = ""; if ($request_params['param']['lastResult']['state'] == 1){ // 1揽收 $status = "已揽收"; }elseif ($request_params['param']['lastResult']['state'] == 0){ // 0在途 $status = "已发货"; }elseif ($request_params['param']['lastResult']['state'] == 3){ // 3签收 $status = "已签收"; } if (!empty($status)){ // 患者-物流信息-站内 $MessagePush = new MessagePush($user_patient['user_id']); $MessagePush->logistics($status,$order_product['order_product_id']); $redis->set($redis_key, 1, 60 * 10); } } }catch (\Exception $e){ return $this->LogisticsSuccessReturn("推送消息错误:" . $e->getMessage()); } return $this->LogisticsSuccessReturn(); } catch (\Exception $e) { return $this->LogisticsFailReturn("异常:" . $e->getMessage()); } } /** * 快递100订阅回调失败 * @param string $message * @return ResponseInterface */ protected function LogisticsFailReturn(string $message): ResponseInterface { return $this->response ->withStatus(200) ->withBody( new SwooleStream( strval( json_encode([ 'result' => false, 'returnCode' => "500", 'message' => $message, ], JSON_UNESCAPED_UNICODE) ) ) ); } /** * 快递100订阅回调成功 * @param string $message * @return ResponseInterface */ protected function LogisticsSuccessReturn(string $message = ""): ResponseInterface { return $this->response ->withStatus(200) ->withBody( new SwooleStream( strval( json_encode([ 'result' => true, 'returnCode' => "200", 'message' => $message, ], JSON_UNESCAPED_UNICODE) ) ) ); } /** * 患者端检测支付回调 * @return ResponseInterface * @throws \Throwable */ public function wxPayDetectionSuccessCallBack(): ResponseInterface { try { // 处理支付结果事件 $WechatPay = new WechatPay(1, 3); $app = $WechatPay->createApp(); $server = $app->getServer(); $message = $server->getRequestMessage(); if (empty($message)) { return $this->response->withStatus(500)->withBody(new SwooleStream(strval(json_encode(['code' => 'ERROR', 'message' => "问诊微信支付回调数据为空"], JSON_UNESCAPED_UNICODE)))); } // 验证推送消息签名 $app->getValidator()->validate($app->getRequest()); Log::getInstance()->info("检测微信支付回调数据:" . json_encode($message->toArray(), JSON_UNESCAPED_UNICODE)); if (empty($message['out_trade_no'])) { Log::getInstance()->info("检测微信支付回调数据处理失败,缺少外部订单号"); return $server->serve(); } // 查询订单 $params = array(); $params['detection_no'] = $message['out_trade_no']; $order_detection = OrderDetection::getOne($params); if (empty($order_detection)) { Log::getInstance()->info("检测微信支付回调数据处理失败,无订单数据"); return $server->serve(); } // 验证订单状态 if ($order_detection['detection_status'] != 1) { // 检测订单状态(1:待支付 2:待绑定 3:检测中 4:检测完成 5:已取消) Log::getInstance()->info("检测微信支付回调数据处理失败,订单状态当前为" . $order_detection['detection_status']); return $server->serve(); } // 支付状态无需验证,如第一次支付失败,会修改支付状态,再次支付时,会出现验证不通过的情况 // 修改支付状态 $data = array(); if ($message['trade_state'] == "SUCCESS") { // 支付成功 $data['detection_pay_status'] = 2; $data['pay_time'] = date('Y-m-d H:i:s', strtotime($message['success_time']));// 支付时间 $data['detection_status'] = 2;// 2:待绑定 if (empty($message['amount'])){ Log::getInstance()->error("检测微信支付回调数据处理失败:无支付金额"); return $this->wxPayErrorReturn("检测微信支付回调数据处理失败:无支付金额"); } } elseif ($message['trade_state'] == "CLOSED") { // 已关闭 $data['detection_pay_status'] = 6; } elseif ($message['trade_state'] == "REVOKED") { // 已撤销(付款码支付) $data['detection_pay_status'] = 7; } elseif ($message['trade_state'] == "USERPAYING") { // 用户支付中(付款码支付) $data['detection_pay_status'] = 3; } elseif ($message['trade_state'] == "PAYERROR") { // 支付失败(其他原因,如银行返回失败) $data['detection_pay_status'] = 4; } $data['escrow_trade_no'] = $message['transaction_id']; $data['updated_at'] = date('Y-m-d H:i:s', time()); $params = array(); $params['order_detection_id'] = $order_detection['order_detection_id']; OrderDetection::editOrderDetection($params, $data); } catch (\Exception $e) { // 验证失败 Log::getInstance()->error("问诊微信支付回调数据处理失败:" . $e->getMessage()); return $this->wxPayErrorReturn($e->getMessage()); } Log::getInstance()->info("检测微信支付回调处理成功"); return $server->serve(); } /** * 微信检测退款回调 * @return ResponseInterface * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface * @throws \Throwable */ public function wxPayDetectionRefundCallBack(): ResponseInterface { Db::beginTransaction(); try { // 处理支付结果事件 $WechatPay = new WechatPay(1, 1); $app = $WechatPay->createApp(); $server = $app->getServer(); $message = $server->getRequestMessage(); if (empty($message)) { Db::rollBack(); return $this->response->withStatus(500)->withBody(new SwooleStream(strval(json_encode(['code' => 'ERROR', 'message' => "回调数据为空"], JSON_UNESCAPED_UNICODE)))); } // 验证推送消息签名 $app->getValidator()->validate($app->getRequest()); Log::getInstance()->info("微信退款回调数据:" . json_encode($message->toArray(), JSON_UNESCAPED_UNICODE)); if (empty($message['out_trade_no'])) { Log::getInstance()->info("微信退款回调数据错误"); return $server->serve(); } // 验证订单数据 $params = array(); $params['detection_no'] = $message['out_trade_no']; $order_detection = OrderDetection::getOne($params); if (empty($order_detection)) { Log::getInstance()->info("非法订单"); return $server->serve(); } // 验证订单状态 if ($order_detection['detection_status'] == 1) { // 检测订单状态(1:待支付 2:待绑定 3:检测中 4:检测完成 5:已取消) Log::getInstance()->info("订单状态错误:当前为" . $order_detection['detection_status']); return $server->serve(); } // 验证订单退款状态 if ($order_detection['detection_refund_status'] == 3) { // 检测订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常) Log::getInstance()->info("订单退款状态错误:当前为" . $order_detection['detection_refund_status']); return $server->serve(); } // 验证订单支付状态 if (in_array($order_detection['detection_pay_status'], [1, 3, 4, 5, 6, 7])) { // 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款) Log::getInstance()->info("订单支付状态错误:当前为" . $order_detection['detection_pay_status']); return $server->serve(); } // 退款状态 if ($message['refund_status'] == "SUCCESS") { // 退款成功 $detection_refund_status = 3; } elseif ($message['refund_status'] == "CLOSED") { // 退款关闭 $detection_refund_status = 5; } elseif ($message['refund_status'] == "ABNORMAL") { // 退款异常 $detection_refund_status = 6; } if (empty($detection_refund_status)) { // 错误,无退款状态 Log::getInstance()->error("队列执行失败原因:订单未支付"); return $this->wxPayErrorReturn("退款状态错误"); } // 修改订单 $data = array(); $data['detection_refund_status'] = $detection_refund_status; $params = array(); $params['order_detection_id'] = $order_detection['order_detection_id']; OrderDetection::editOrderDetection($params, $data); // 修改退款订单 $data = array(); $data['detection_refund_status'] = $detection_refund_status; $data['success_time'] = $message['success_time']; $params = array(); $params['order_detection_id'] = $order_detection['order_detection_id']; OrderDetectionRefund::edit($params, $data); Db::commit(); } catch (\Exception $e) { // 验证失败 Db::rollBack(); Log::getInstance()->error("微信支付回调数据验证失败:" . $e->getMessage()); return $this->wxPayErrorReturn($e->getMessage()); } Log::getInstance()->info("微信退款回调处理成功"); return $server->serve(); } /** * 检测所结果回调 * @return ResponseInterface */ public function DetectionResultCallBack(): ResponseInterface { $request_params = $this->request->all(); try { Log::getInstance("detectionResult")->info(json_encode($request_params, JSON_UNESCAPED_UNICODE)); // 获取检测订单数据 $params = array(); $params['detection_no'] = "D548076621233111040"; $order_detection = OrderDetection::getOne($params); if (empty($order_detection)){ return $this->detectionResultFailReturn("非法订单"); } // 检测订单状态 if ($order_detection['detection_status'] != 3){ return $this->detectionResultFailReturn("订单状态错误,无法处理"); } // 获取医生数据 $params = array(); $params['doctor_id'] = $order_detection['doctor_id']; $user_doctor = UserDoctor::getOne($params); if (empty($user_doctor)){ return $this->detectionResultFailReturn("订单数据错误"); } // 获取检测病例数据 $params = array(); $params['order_detection_id'] = $order_detection['order_detection_id']; $order_detection_case = OrderDetectionCase::getOne($params); if (empty($order_detection_case)){ return $this->detectionResultFailReturn("订单数据错误"); } // 获取检测项目数据 $params = array(); $params['detection_project_id'] = $order_detection['detection_project_id']; $detection_project = DetectionProject::getOne($params); if (empty($detection_project)){ return $this->detectionResultFailReturn("订单数据错误"); } // 检测家庭成员是否存在 $params = array(); $params['family_id'] = $order_detection['family_id']; $params['patient_id'] = $order_detection['patient_id']; $patient_family = PatientFamily::getOne($params); if (empty($patient_family)) { return $this->detectionResultFailReturn("患者信息错误"); } Db::beginTransaction(); try { $generator = $this->container->get(IdGeneratorInterface::class); // 创建问诊订单 $data = array(); $data['user_id'] = $order_detection['user_id']; $data['patient_id'] = $order_detection['patient_id']; $data['doctor_id'] = $order_detection['doctor_id']; $data['family_id'] = $order_detection['family_id']; $data['inquiry_type'] = 5; // 订单类型(1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药 5:检测) $data['inquiry_mode'] = 1; // 订单问诊方式(1:图文 2:视频 3:语音 4:电话 5:会员) $data['inquiry_status'] = 4; // 问诊订单状态(1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消) $data['inquiry_pay_channel'] = 3; // 支付渠道(1:小程序支付 2:微信扫码支付 3:模拟支付) $data['inquiry_pay_status'] = 2; // 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款) $data['inquiry_no'] = $generator->generate();// 订单编号 $data['escrow_trade_no'] = "GD" . $generator->generate(); // 第三方支付流水号 $data['amount_total'] = 0;// 订单金额 $data['coupon_amount_total'] = 0;// 优惠卷总金额 $data['payment_amount_total'] = 0;// 实际付款金额 $data['pay_time'] = date('Y-m-d H:i:s', time());// 支付时间 $data['reception_time'] = date('Y-m-d H:i:s', time());// 接诊时间 $data['patient_name'] = $patient_family['card_name'];// 患者姓名-就诊人 $data['patient_name_mask'] = $patient_family['card_name_mask'];// 患者姓名-就诊人(掩码) $data['patient_sex'] = $patient_family['sex'];// 患者性别-就诊人(0:未知 1:男 2:女) $data['patient_age'] = $patient_family['age'];// 患者年龄-就诊人 $order_inquiry = OrderInquiry::addOrderInquiry($data); if (empty($order_inquiry)) { Db::rollBack(); return $this->detectionResultFailReturn("问诊订单创建失败"); } // 回填问诊订单id $order_detection['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; // 增加患者问诊病例 $data = array(); $data['user_id'] = $order_detection['user_id']; $data['patient_id'] = $order_detection['patient_id']; $data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];// 订单-问诊id $data['family_id'] = $patient_family['family_id']; // 家庭成员id $data['relation'] = $patient_family['relation']; // 与患者关系(1:本人 2:父母 3:爱人 4:子女 5:亲戚 6:其他 ) $data['name'] = $patient_family['card_name']; // 患者名称 $data['sex'] = $patient_family['sex'] ?? 0; // 患者性别(0:未知 1:男 2:女) $data['age'] = $patient_family['age'] ?? null; // 患者年龄 $data['height'] = $patient_family['height'] ?: null; // 身高(cm) $data['weight'] = $patient_family['weight'] ?: null;; // 体重(kg) $order_inquiry_case = OrderInquiryCase::addOrderInquiryCase($data); if (empty($order_inquiry_case)) { Db::rollBack(); return $this->detectionResultFailReturn("问诊订单病例创建失败"); } // 修改检测状态 $data = array(); $data['detection_status'] = 4; $data['detection_time'] = date('Y-m-d H:i:s',time()); $data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];// 订单-问诊id $params = array(); $params['order_detection_id'] = $order_detection['order_detection_id']; OrderDetection::editOrderDetection($params,$data); // 添加自动完成队列 $time = 1000 * 60 * 60 * 24 * 3; $data = array(); $data['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; $message = new AutoCompleteInquiryDelayDirectProducer($data); $message->setDelayMs($time); $producer = $this->container->get(Producer::class); $res = $producer->produce($message); if (!$res) { Db::rollBack(); return $this->detectionResultFailReturn("添加自动完成队列失败"); } // 发送IM消息-检测报告结果 $imService = new ImService(); $imService->detectionTestReport( $order_detection, $user_doctor['user_id'], $order_detection['user_id'], $order_detection_case['detection_disease_class_names'], $detection_project['detection_project_name'] ); Db::commit(); } catch (\Throwable $e) { Db::rollBack(); return $this->detectionResultFailReturn($e->getMessage()); } try { // 发送IM消息-检测报告结果-文字 $imService->detectionTestReportStr( $order_detection, $user_doctor['user_name'], $detection_project['detection_project_name'], $user_doctor['user_id'], $order_detection['user_id'] ); // 患者-新报告生成通知 $MessagePush = new MessagePush($order_detection['user_id']); $MessagePush->patientDetectionResultNotice($order_detection['order_detection_id']); // 医生-发送检测报告短信 }catch (\Throwable $e){ Log::getInstance("detectionResult")->error($e->getMessage()); } return $this->detectionResultSuccessReturn(); } catch (\Throwable $e) { return $this->detectionResultFailReturn("异常:" . $e->getMessage()); } } /** * 检测所结果回调失败 * @param string $message * @return ResponseInterface */ protected function detectionResultFailReturn(string $message): ResponseInterface { return $this->response ->withStatus(200) ->withBody( new SwooleStream( strval( json_encode([ 'result' => false, 'returnCode' => "500", 'message' => $message, ], JSON_UNESCAPED_UNICODE) ) ) ); } /** * 检测所结果回调成功 * @param string $message * @return ResponseInterface */ protected function detectionResultSuccessReturn(string $message = ""): ResponseInterface { return $this->response ->withStatus(200) ->withBody( new SwooleStream( strval( json_encode([ 'result' => true, 'returnCode' => "200", 'message' => $message, ], JSON_UNESCAPED_UNICODE) ) ) ); } }