response->format = Response::FORMAT_RAW; \Yii::$app->response->formatters = []; $response = WechatService::getInstance()->payment->handlePaidNotify(function ($notify, $fail) { /** * {"appid":"wx36bbb299d88c6127","bank_type":"ZJRCUB_DEBIT","cash_fee":"1","fee_type":"CNY","is_subscribe":"N","mch_id":"1496340382","nonce_str":"637ed1617f5f3","openid":"o88xX5Z-mpVWWV-yw2X6MefDIUqE","out_trade_no":"PY20221124100521434224","result_code":"SUCCESS","return_code":"SUCCESS","sign":"FAB5D4E3AD785DBF7D6FB1FE0E1A897E","time_end":"20221124100606","total_fee":"1","trade_type":"JSAPI","transaction_id":"4200001675202211242752421487"} */ //记录回调信息 $callback = new Callback(); $callback->content = json_encode($notify); $callback->type = 'order'; $callback->save(); if($notify['return_code']=='SUCCESS' && $notify['result_code']=='SUCCESS'){ $t = \Yii::$app->db->beginTransaction(); try { $out_trade_no = $notify['out_trade_no']; $paymentProductOrder = PaymentProductOrder::find()->where([ 'pay_order_no' => $out_trade_no ])->one(); if($paymentProductOrder){ $data['order_no'] = $paymentProductOrder->order_no; $data['transaction_id'] = $notify['transaction_id']; $data['pay_type'] = 1; $productOrderPayForm = new ProductOrderSubmitForm(); $order = $productOrderPayForm->paid($data); $order_type=1; }else{ $PaymentRegister=PaymentRegister::find()->where([ 'pay_order_no' => $out_trade_no ])->one(); if (!$PaymentRegister){ throw new Exception('订单不存在'); } $data['order_no']= $PaymentRegister->order_no; $data['transaction_id'] = $notify['transaction_id']; $data['pay_type'] = 1; $RegisterSubmitForm = new RegisterSubmitForm(); $order = $RegisterSubmitForm->paid($data); $order_type=2; } // 增加流水记录 $fundWater = new FundWater(); $fundWater->store_id = $order->store_id; // 入账 $fundWater->type = 'enter'; // 入账 $fundWater->order_type = $order_type; $fundWater->order_id = $order->id; $fundWater->user_id = $order->user_id; $fundWater->service_user_id = $order_type==1?$order->su_id:$order->service_user_id; $fundWater->order_no = $order->order_no; $fundWater->price = $order_type==1 ? $order->total_pay_price : $order->price; $fundWater->pay_type = 1; //微信 $fundWater->saveOrFail(); //回调处理成功 $callback->status = 1; $callback->save(); $t->commit(); return true; }catch (\Exception $exception){ $t->rollBack(); $callback->message = $exception->getMessage(); $callback->save(); return $fail('通信失败,请稍后再通知我'); } } }); // $response = unserialize('O:41:"Symfony\\Component\\HttpFoundation\\Response":6:{s:7:"headers";O:50:"Symfony\\Component\\HttpFoundation\\ResponseHeaderBag":5:{s:23:"' . "\0" . '*' . "\0" . 'computedCacheControl";a:1:{s:8:"no-cache";b:1;}s:10:"' . "\0" . '*' . "\0" . 'cookies";a:0:{}s:14:"' . "\0" . '*' . "\0" . 'headerNames";a:2:{s:13:"cache-control";s:13:"Cache-Control";s:4:"date";s:4:"Date";}s:10:"' . "\0" . '*' . "\0" . 'headers";a:2:{s:13:"cache-control";a:1:{i:0;s:8:"no-cache";}s:4:"date";a:1:{i:0;s:29:"Wed, 09 Mar 2022 02:19:18 GMT";}}s:15:"' . "\0" . '*' . "\0" . 'cacheControl";a:0:{}}s:10:"' . "\0" . '*' . "\0" . 'content";s:96:"";s:10:"' . "\0" . '*' . "\0" . 'version";s:3:"1.0";s:13:"' . "\0" . '*' . "\0" . 'statusCode";i:200;s:13:"' . "\0" . '*' . "\0" . 'statusText";s:2:"OK";s:10:"' . "\0" . '*' . "\0" . 'charset";N;}'); return $response; } /** * 退款回调 */ public function actionRefundNotify() { \Yii::$app->response->format = Response::FORMAT_RAW; \Yii::$app->response->formatters = []; $response = WechatService::getInstance()->payment->handleRefundedNotify(function ($message, $reqInfo, $fail) { // 其中 $message['req_info'] 获取到的是加密信息 // $reqInfo 为 message['req_info'] 解密后的信息 // 你的业务逻辑... /** * {"cash_refund_fee":"1","out_refund_no":"RF20221124103051025400","out_trade_no":"PY20221124100521434224","refund_account":"REFUND_SOURCE_RECHARGE_FUNDS","refund_fee":"1","refund_id":"50300503882022112427569050043","refund_recv_accout":"\u6d59\u6c5f\u519c\u4fe1\u501f\u8bb0\u53617865","refund_request_source":"API","refund_status":"SUCCESS","settlement_refund_fee":"1","settlement_total_fee":"1","success_time":"2022-11-24 10:31:00","total_fee":"1","transaction_id":"4200001675202211242752421487"} */ //记录回调信息 $callback = new Callback(); $callback->content = json_encode($reqInfo); $callback->type = 'refund'; $callback->save(); $t = \Yii::$app->db->beginTransaction(); try { $transaction_id = $reqInfo['transaction_id']; $out_refund_no = $reqInfo['out_refund_no']; $paymentProductOrder = PaymentProductOrder::find()->where([ 'transaction_id' => $transaction_id, ])->one(); if ($paymentProductOrder){ if ($paymentProductOrder->is_pay!=1){ throw new Exception('支付订单不存在'); } $order = ProductOrder::find()->where([ 'order_no' => $paymentProductOrder->order_no, ])->with('prescription')->one(); if(!$order || $order->is_pay!=1){ throw new Exception('订单不存在'); } $order_type = 1; $refund = ProductOrderRefund::find()->where(['refund_no'=>$out_refund_no])->one();//退款订单 $payment_refund = PaymentProductRefund::find()->where(['refund_no'=>$out_refund_no])->one(); }else{ $PaymentRegister=PaymentRegister::find()->where([ 'transaction_id' => $transaction_id ])->one(); if (!$PaymentRegister || $PaymentRegister->is_pay!=1){ throw new \yii\db\Exception('支付订单不存在'); } $order = Register::find()->where([ 'order_no' => $PaymentRegister->order_no, ])->one(); if(!$order || $order->is_pay!=1){ throw new Exception('订单不存在'); } $order_type = 2; $refund= RegisterRefund::find()->where(['refund_no'=>$out_refund_no])->one();//退款订单 $payment_refund= PaymentRegisterRefund::find()->where(['refund_no'=>$out_refund_no])->one(); } if(!$refund || !$payment_refund){ throw new Exception('退款订单不存在'); } if($reqInfo['refund_status'] == 'SUCCESS'){ if ($order_type == 1){ $order->refund_status =3;//已退款 $order->status = ProductOrderEnum::REFUND;//已退款 $order->refund_time = time(); $order->save(); if($order->is_online){ //平台订单状态同步 \Yii::$app->queue->delay(0)->push(new ProductOrderSyncPlatformJob([ 'orderId' => $this->event->order->id, 'status' => 3 ])); } } $refund->is_refund = 1; $refund->refund_time = date('Y-m-d H:i:s',strtotime($reqInfo['success_time'])); $refund->save(); $payment_refund->is_pay = 1; $payment_refund->pay_type = 1; $payment_refund->save(); }else{ $refund->is_refund = -1; $refund->save(); $payment_refund->is_pay = -1; $payment_refund->save(); } // 增加流水记录 $fundWater = new FundWater();//出账 $fundWater->store_id = $order->store_id; $fundWater->order_type = $order_type; $fundWater->type = 'refund'; // 出账 $fundWater->order_id = $order->id; $fundWater->user_id = $order->user_id; $fundWater->service_user_id = $order_type==1?$order->su_id:$order->service_user_id; $fundWater->refund_no = $refund->refund_no; $fundWater->price = $order_type==1 ? $order->total_pay_price : $order->price; $fundWater->pay_type = 1; //微信 $fundWater->saveOrFail(); $callback->status = 1; $callback->save(); $t->commit(); return true; // 返回 true 告诉微信“我已处理完成” // 或返回错误原因 $fail('参数格式校验错误'); }catch (\Exception $exception){ $t->rollBack(); $callback->message = $exception->getMessage(); $callback->save(); $fail($exception->getMessage()); } }); return $response; } /** * 阿里oss直传回调 */ public function actionUploadNotify() { // 1.获取OSS的签名header和公钥url header $headers =\Yii::$app->request->getHeaders(); $authorizationBase64 = ""; $pubKeyUrlBase64 = ""; if(isset($headers['authorization'])) { $authorizationBase64 = $headers['authorization']; }else{ if (isset($_SERVER['HTTP_AUTHORIZATION'])) { $authorizationBase64 = $_SERVER['HTTP_AUTHORIZATION']; } } if(isset($headers['x-oss-pub-key-url'])){ $pubKeyUrlBase64 = $headers['x-oss-pub-key-url']; }else{ if (isset($_SERVER['HTTP_X_OSS_PUB_KEY_URL'])) { $pubKeyUrlBase64 = $_SERVER['HTTP_X_OSS_PUB_KEY_URL']; } } if ($authorizationBase64 == '' || $pubKeyUrlBase64 == '') { throw new Exception('参数异常'); } // 2.获取OSS的签名 $authorization = base64_decode($authorizationBase64); // 4.获取回调body $body = file_get_contents('php://input'); // 5.拼接待签名字符串 $authStr = ''; $path = $_SERVER['REQUEST_URI']; $pos = strpos($path, '?'); if ($pos === false) { $authStr = urldecode($path)."\n".$body; } else { $authStr = urldecode(substr($path, 0, $pos)).substr($path, $pos, strlen($path) - $pos)."\n".$body; } // 3.获取公钥 $pubKey = (new UploadService())->getPublicKey($pubKeyUrlBase64); if ($pubKey == "") { throw new Exception('公钥异常'); } // 6.验证签名 $ok = openssl_verify($authStr, $authorization, $pubKey, OPENSSL_ALGO_MD5); if(!$ok){ throw new Exception('签名异常'); } $data = (new UploadService())->getBody($body); return $data; } // 互医订单同步 public function actionPlatformNotify(){ \Yii::$app->response->format = Response::FORMAT_RAW; $content = file_get_contents('php://input'); $callback = new Callback(); $callback->content = $content; $callback->type = 'platform_notify'; $callback->save(); $t = \Yii::$app->db->beginTransaction(); try { $data = json_decode($content, true); $config = \Yii::$app->params; $sign = md5($data['order']['order_no'].$data['time'].$config['platform']['token'].$data['type']); if($sign != $data['sign']){ throw new Exception('sign不匹配'); } $isExist = ProductOrder::find()->where(['sync_order_no' => $data['order']['order_no'], 'is_online' => 1])->one(); switch ($data['type']) { case 'order_create'://订单创建 if($isExist){ throw new Exception('产品订单已存在'); } $userPatient = UserPatient::findOne([ 'user_id' => $data['order']['user_id'], 'id_card' => $data['order']['patient']['id_card'], 'is_delete' => 0 ]); $storeUser = StoreUser::find()->where([ 'user_id' => $data['order']['user_id'], 'is_online' => 1 ])->one(); $userAddress = Address::find()->select('id,name,mobile,province,region,detail_address')->where(['user_id' => $data['order']['user_id']])->orderBy('is_default DESC')->asArray()->all(); $productOrder = new ProductOrder(); $productOrder->store_id = $storeUser->store_id??11001; $productOrder->is_online = 1; $productOrder->dosage = isset($data['order']['dosage'])?$data['order']['dosage']:0; $productOrder->su_id = $data['order']['doctor_id']; $productOrder->user_id = $data['order']['user_id']; $productOrder->up_id = $userPatient->id??0; $productOrder->order_no = Carbon::now()->format('YmdHis') . rand(10000, 99999) . rand(10000, 99999); $productOrder->sync_order_no = $data['order']['order_no']; $productOrder->order_type = 2; //商城订单 $productOrder->prescription_type = $data['order']['prescription_type']; $productOrder->p_id = 0; $productOrder->status = 0; $productOrder->items_price = $data['order']['total_price']; $productOrder->trans_expenses = 0; $totalPayPrice = $data['order']['total_price']; if($userAddress){ $productOrder->address_id = $userAddress[0]['id']; $productOrder->address = Json::encode($userAddress[0]); $productOrder->express_name = $userAddress[0]['name']; $productOrder->express_mobile = $userAddress[0]['mobile']; $productOrder->express_region = $userAddress[0]['region']; $productOrder->express_address = $userAddress[0]['detail_address']; $region = Region::find()->where(['name' => $userAddress[0]['province']])->one(); $productOrder->trans_expenses = $region->express_fee; $totalPayPrice = $totalPayPrice + $region->express_fee; } $productOrder->total_pay_price = $totalPayPrice; $productOrder->saveOrFail(); foreach($data['order']['goods'] as $v){ $drug = Drug::find()->where(['id' => $v['id']])->one(); if(!$drug){ throw new Exception('药品不存在:'.$v['id']); } $item = new ProductOrderItems(); $item->product_order_id = $productOrder->id; if ($drug) { $item->drug_id = $drug->id; $item->drug_image = $drug->image; $item->number = $v['number']; $item->drug_no = $drug->drug_number; $item->price = $v['price']; $item->drug_name = $drug->drug_name; $item->small_info = $drug->small_info; $item->saveOrFail(); } } //触发订单创建事件 $event = new ProductOrderEvent(); $event->order = $productOrder; $event->sender = $this; \Yii::$app->trigger(ProductOrder::EVENT_CREATED, $event); break; case 'prescription_pass'://处方通过 if(!$isExist){ throw new Exception('产品订单不存在'); } $isExist->online_prescription_status = 1; $isExist->save(); break; case 'prescription_refuse'://处方拒绝 if(!$isExist){ throw new Exception('产品订单不存在'); } $isExist->online_prescription_status = 2; $isExist->save(); //TODO 未付款订单取消/已付款订单退款 break; default: throw new Exception('错误的回调类型'); break; } $callback->status = 1; $callback->save(); $t->commit(); return true; } catch (Exception $e) { $t->rollBack(); $callback->message = $e->getMessage(); $callback->save(); Yii::$app->response->setStatusCode('400'); return false; } } }