authInitialize(); $this->setChannel('outpatient'); $this->his_client = app('HisHttpService'); $this->order_model = new Order(); } /** * 支付 * @param string $patient_id * @param string $serial_no * @param string $prescription_ids * @param string $reg_id * @return array * @throws GeneralException */ public function payment(string $patient_id, string $serial_no, string $prescription_ids, string $reg_id): array { // 基础信息 $patient_info = $this->getPatientInfo($patient_id, $this->open_id); $pending_info = $this->getPendingPrescriptionDetails($patient_id, $serial_no, $prescription_ids, $reg_id); // 创建订单 $order_type = Type::OUTPATIENT_PAYMENT; $pay_type = PayType::WECHAT_PAY; $order_id = $this->order_model->getOrderId($pay_type, 'M'); $total_fee = (float)(string) array_sum(array_column($pending_info['prescription_lists'], 'ZFJE')); $order = $this->createOrder($order_id, $pay_type, $total_fee, $order_type, $patient_info, $pending_info); // 申请支付 $pay_data = $this->applyPayment($order_type, $order_id, $total_fee, $patient_info['PATIENTID'], $patient_info['NAME']); // 去除无用数据 unset($pay_data['merchantId'], $pay_data['merchantName'], $pay_data['channelId'], $pay_data['channelName']); return $pay_data; } /** * 获取患者信息 * @param string $patient_id * @param string $open_id * @return mixed * @throws GeneralException */ protected function getPatientInfo(string $patient_id, string $open_id): mixed { $info = $this->patient_model->getBindPatientInfo($open_id, $patient_id); if (empty($info)) { throw new GeneralException('找不到患者信息,请重新再试!', Response::HTTP_BAD_REQUEST); } $patient_info = $this->his_client->getPatientInfo($info['patient_id'], CardType::OUTPATIENT_NO, $info['name']); if (!isset($patient_info['RESULTCODE']) || $patient_info['RESULTCODE'] !== '0') { throw new GeneralException($patient_info['ERRORMSG'] ?? '找不到患者信息,请重新再试!', Response::HTTP_SERVICE_UNAVAILABLE); } // 添加Patient 表ID $patient_info['id'] = $info['id']; $this->info('缴费患者信息', $info); return $info; } /** * 获取缴费处方详情 * @param string $patient_id * @param string $serial_no * @param string $prescription_ids * @param string $reg_id * @return array * @ * @throws GeneralException */ protected function getPendingPrescriptionDetails(string $patient_id, string $serial_no, string $prescription_ids, string $reg_id): array { $response = $this->his_client->getPendingLists($patient_id); if (!isset($response['RESULTCODE']) || $response['RESULTCODE'] !== '0') { throw new GeneralException($response['ERRORMSG'] ?? '暂无相关缴费记录!', Response::HTTP_SERVICE_UNAVAILABLE); } // 获取具体的缴费详情 $response = xmlArrayToListByKey($response, 'ITEM'); foreach ($response['ITEM'] as $v) { if ($v['JZXH'] === $serial_no) { $info = $v; break; } } if (empty($info)) { throw new GeneralException('查询不到待缴费处方,请重新再试!', Response::HTTP_SERVICE_UNAVAILABLE); } $response = $this->his_client->getPendingDetails($prescription_ids, $serial_no, $reg_id); if (!isset($response['RESULTCODE']) || $response['RESULTCODE'] !== '0') { throw new GeneralException($response['ERRORMSG'] ?? '暂无相关缴费记录!', Response::HTTP_SERVICE_UNAVAILABLE); } // 获取具体的缴费详情 $response = xmlArrayToListByKey($response, 'ITEM'); foreach ($response['ITEM'] as $v) { if (strpos($prescription_ids, $v['CFID'])) { $info['prescription_lists'][] = $v; break; } } if (empty($info['prescription_lists'])) { throw new GeneralException('查询不到待缴费处方详情,请重新再试!', Response::HTTP_SERVICE_UNAVAILABLE); } $info['prescription_ids'] = $prescription_ids; return $info; } /** * 创建订单表 * @param string $order_id * @param PayType $pay_type * @param float $total_fee * @param Type $order_type * @param array $patient_info * @param array $pending_info * @return mixed * @throws GeneralException */ protected function createOrder(string $order_id, PayType $pay_type, float $total_fee, Type $order_type, array $patient_info, array $pending_info): mixed { // 挂号记录表 $pay_record_data = [ 'relate_patient_id' => $patient_info['id'], 'dept_id' => $pending_info['BQDM'], 'dept_name' => $pending_info['BQMC'], 'doctor_id' => $pending_info['YSGH'], 'doctor_name' => $pending_info['YSMC'], 'visit_date' => date('Y-m-d', strtotime($pending_info['JZRQ'])), 'total_amount' => $total_fee, 'pre_settle_status' => 0, 'extra_info' => json_encode($pending_info, JSON_UNESCAPED_UNICODE), ]; $order = $this->order_model->createOrder( $order_id, $pay_type, $total_fee * 100, $this->open_id, $patient_info['PATIENTID'], $patient_info['NAME'], $order_type, SourceId::MINI_PROGRAM, $pay_record_data ); if (empty($order)) { throw new GeneralException('创建缴费单失败,请重新再试!'); } $this->info('创建订单,ID:'. $order_id->id); return $order; } /** * 申请支付 * @param Type $order_type * @param string $order_id * @param float $reg_fee * @param string $patient_id * @param string $patient_name * @return array * @throws GeneralException */ protected function applyPayment(Type $order_type, string $order_id, float $reg_fee, string $patient_id, string $patient_name): array { try { $order_obj = new CreateOrder( $order_type->label(), $order_id, (string) $reg_fee, '1', $patient_id. '|'. $patient_name, 'A', $this->open_id, url('/Api/Notify', [], true) ); $response = Unify::pay(env('unify'))->mini->jsapi($order_obj); $this->info('jsapi 支付参数', $response); if (!$response['success'] || empty($response['response'])) { throw new GeneralException('申请支付失败,请重新再试!', Response::HTTP_SERVICE_UNAVAILABLE); } return $response['response']; } catch (InvalidConfigException|RuntimeException|ReflectionException $e) { throw new GeneralException('申请支付失败,请重新再试!', Response::HTTP_INTERNAL_SERVER_ERROR); } } }