request->param(); if(isset($param['pay_notify_url'])){ session('pay_notify_url',$param['pay_notify_url']); } if(isset($param['order_no'])){ session('order_no',$param['order_no']); } if(!session('order_no')){ die('order_no is empty'); } $order_no = session('order_no'); $companyCode = $this->_validCompanyCode($param); WxPayConfig::$companyCode(); require_once(APP_PATH.'/index/service/wechat/WxPayPubHelper.php'); //使用jsapi接口 $jsApi = new JsApi_pub(); //通过code获得openid if (!isset($_GET['code'])) { $url = $jsApi->createOauthOpenidForCode("http://{$_SERVER['HTTP_HOST']}".WxPayConfig::$JS_API_CALL_URL, rand(100,1000)); header("Location: $url"); exit; } else { $code = $_GET['code']; $jsApi->setCode($code); $openInfo = $jsApi->getOpenidInfo(); if(!isset($openInfo['openid'])){ HelperService::addLog($openInfo); header("HTTP/1.1 301 Moved Permanently"); header("Location: http://".$_SERVER['HTTP_HOST']."/index/wechat/warmError.html?err_msg=支付调用失败(openid)&err_detail=重复支付;网络连接失败"); exit; } $openid = $openInfo['openid']; } $orderModel = new ProductOrderModel(); $order = $orderModel->getOne(['order_no'=>$order_no]); if(!$order){ HelperService::returnJson(['code'=>'400','msg'=>'order_no is error']); } $unifiedOrder = new UnifiedOrder_pub(); $money = intval($order['total_price']); if($money<=0){ $order['error_msg'] = "money is fail"; HelperService::addLog($order); header("HTTP/1.1 301 Moved Permanently"); header("Location: http://".$_SERVER['HTTP_HOST']."/index/wechat/warmError.html?err_msg=支付调用失败(money)&err_detail=重复支付;网络连接失败"); exit; } //设置统一支付接口参数 $unifiedOrder->setParameter("openid", "$openid"); //商品描述 $unifiedOrder->setParameter("body",WxPayConfig::$PAY_TIPS."[".date('Y-m-d H:i:s')."]"); //商品描述 //自定义订单号,此处仅作举例 $out_trade_no = substr($companyCode,0,6).'_'.$order_no."_".date('his'); $unifiedOrder->setParameter("out_trade_no", $out_trade_no); //商户订单号 $unifiedOrder->setParameter("total_fee", $money); //总金额 $unifiedOrder->setParameter("notify_url", "http://{$_SERVER['HTTP_HOST']}".WxPayConfig::$NOTIFY_URL); //通知地址 $unifiedOrder->setParameter("trade_type", "JSAPI"); //交易类型 $prepay_id = $unifiedOrder->getPrepayId($out_trade_no.'_'.time()); $jsApi->setPrepayId($prepay_id); $jsApiParameters = $jsApi->getParameters(); $notify_url = base64_decode(session('pay_notify_url')); $this->getProductInfoByOrderNo($order_no); require_once(APP_PATH.'/index/view/wechat/wxPay.php'); } /** * 平台版支付接口 */ public function PlatformWxPay(){ $param = $this->request->param(); HelperService::addLog($param); if(isset($param['pay_notify_url'])){ session('pay_notify_url',$param['pay_notify_url']); } if(isset($param['order_no']) && isset($param['total_price'])){ session('order_no',$param['order_no']); session('total_price',$param['total_price']); } if(isset($param['note'])){ session('note',$param['note']); } if(!session('order_no')){ die('order_no or total_price is empty'); } $order_no = session('order_no'); $companyCode = $this->_validCompanyCode($param); WxPayConfig::$companyCode(); $wxPayRecordModel = new WxPayRecordModel(); $wxPayRecord = $wxPayRecordModel->where(['order_no'=>$order_no,'out_trade_no'=>['like',"{$companyCode}_%"]])->find(); if(!empty($wxPayRecord)){ $notify_url = base64_decode(session('pay_notify_url')); header("HTTP/1.1 301 Moved Permanently"); header("Location: $notify_url"); exit; } require_once(APP_PATH.'/index/service/wechat/WxPayPubHelper.php'); //使用jsapi接口 $jsApi = new JsApi_pub(); //通过code获得openid if (!isset($_GET['code'])) { $url = $jsApi->createOauthOpenidForCode("http://{$_SERVER['HTTP_HOST']}".WxPayConfig::$platform_API_CALL_URL, rand(100,1000)); header("Location: $url"); exit; } else { $code = $_GET['code']; $jsApi->setCode($code); $openInfo = $jsApi->getOpenidInfo(); if(!isset($openInfo['openid'])){ HelperService::addLog($openInfo); $notify_url = base64_decode(session('pay_notify_url')); header("HTTP/1.1 301 Moved Permanently"); header("Location: $notify_url"); exit; } $openid = $openInfo['openid']; } $unifiedOrder = new UnifiedOrder_pub(); $money = intval(session('total_price')); if($money<=0){ $order['error_msg'] = "money is fail"; $order['money'] = session('total_price'); HelperService::addLog($order); header("HTTP/1.1 301 Moved Permanently"); header("Location: http://".$_SERVER['HTTP_HOST']."/index/wechat/warmError.html?err_msg=支付调用失败(total_price)&err_detail=重复支付;网络连接失败"); exit; } //设置统一支付接口参数 $unifiedOrder->setParameter("openid", "$openid"); //商品描述 $unifiedOrder->setParameter("body",WxPayConfig::$PAY_TIPS.session('note')."[". substr($order_no, -8)."]"); //商品描述 if(WxPayConfig::$PAY_TIPS.session('note')){ $unifiedOrder->setParameter("attach",WxPayConfig::$PAY_TIPS.session('note')); //附加信息 } //自定义订单号,此处仅作举例 $out_trade_no = substr($companyCode,0,6).'_'.$order_no."_".date('his'); $unifiedOrder->setParameter("out_trade_no", $out_trade_no); //商户订单号 $unifiedOrder->setParameter("total_fee", $money); //总金额 $unifiedOrder->setParameter("notify_url", "http://{$_SERVER['HTTP_HOST']}".WxPayConfig::$PLATFORM_NOTIFY_URL); //通知地址 $unifiedOrder->setParameter("trade_type", "JSAPI"); //交易类型 $prepay_id = $unifiedOrder->getPrepayId($out_trade_no.'_'.time()); $jsApi->setPrepayId($prepay_id); $jsApiParameters = $jsApi->getParameters(); $notify_url = base64_decode(session('pay_notify_url')); require_once(APP_PATH.'/index/view/wechat/wxPlatformPay.php'); } private function getInput(){ $params = file_get_contents("php://input"); return json_decode($params,true); } /** * 平台版退款接口 */ public function PlatformRefund(){ $params = $this->getInput(); $rule = [ 'out_trade_no'=>'require', //'out_refund_no'=>'require', 'total_fee'=>'require', 'refund_fee'=>'require', 'op_user_id'=>'require', 'companyCode'=>'require' ]; $companyCode = $this->_validCompanyCode($params); WxPayConfig::$companyCode(); $validate = new Validate($rule); if(!$validate->check($params)){ HelperService::returnJson(['code'=>400,'msg'=>$validate->getError()],$params); } require_once(APP_PATH.'/index/service/wechat/WxPayPubHelper.php'); $Refund = new Refund_pub(); $Refund->setParameter('out_trade_no',$params['out_trade_no']); $Refund->setParameter('out_refund_no',uniqid()); $Refund->setParameter('total_fee',$params['total_fee']); $Refund->setParameter('refund_fee',$params['refund_fee']); $Refund->setParameter('op_user_id',$params['op_user_id']); $data = $Refund->getResult(); $msg = isset($data['result_code'])?$data['result_code']:'fail'; HelperService::returnJson(['code'=>200,'msg'=>"{$msg}",'data'=>$data]); } /** * 微信退款异步通知 */ public function refundNotify(){ $param = file_get_contents("php://input"); $params = (array)simplexml_load_string($param, 'SimpleXMLElement', LIBXML_NOCDATA); $time = date('Y-m-d H:i:s'); file_put_contents('refundNotify.wx',"[$time]",FILE_APPEND); file_put_contents('refundNotify.wx',json_encode($params),FILE_APPEND); file_put_contents('refundNotify.wx',"\n",FILE_APPEND); die('success'); } /** * 微信刷卡支付 */ public function microPay(){ $params = $this->getInput(); $rule = [ 'order_no'=>'require|max:32', 'body'=>'require|max:120',//购买说明 'attach'=>'max:120',//购买附属说明 'total_fee'=>'require|number',//付款金额 'spbill_create_ip'=>'require|max:16', 'goods_tag'=>'max:32',//优惠详情 'limit_pay'=>'max:32', 'companyCode'=>'require', 'auth_code'=>'require|max:128', 'notify_url'=>'require' ]; $companyCode = $this->_validCompanyCode($params); WxPayConfig::$companyCode(); $validate = new Validate($rule); if(!$validate->check($params)){ HelperService::returnJson(['code'=>400,'msg'=>$validate->getError()],$params); } $out_trade_no = "{$params['companyCode']}_{$params['order_no']}_".rand(100,999); require_once(APP_PATH.'/index/service/wechat/WxPayPubHelper.php'); $Refund = new MicroPay_pub(); $Refund->setParameter('out_trade_no',$out_trade_no); $Refund->setParameter('body',$params['body']); isset($params['attach'])?$Refund->setParameter('attach',$params['attach']):''; $Refund->setParameter('total_fee',$params['total_fee']); $Refund->setParameter('spbill_create_ip',$params['spbill_create_ip']); isset($params['goods_tag'])?$Refund->setParameter('goods_tag',$params['goods_tag']):''; isset($params['limit_pay'])?$Refund->setParameter('limit_pay',$params['limit_pay']):''; $Refund->setParameter('auth_code',$params['auth_code']); $data = $Refund->getResult(); $msg = isset($data['result_code'])?$data['result_code']:'fail'; $WxPayRecordModel = new WxPayRecordModel(); $WxPayRecordModel->insert([ 'out_trade_no'=> $out_trade_no, 'order_no'=>"{$params['order_no']}", 'total_fee'=>"{$params['total_fee']}", 'pay_type'=>"MICRO", 'add_ts'=>time(), 'notify_url'=>"{$params['notify_url']}" ]); file_put_contents("cronOrderQuery.mp","\n sync1、".date('Y-m-d H:i:s'),FILE_APPEND); file_put_contents("cronOrderQuery.mp","\n sync2、".json_encode($data),FILE_APPEND); if(strtolower($msg) == 'success' && isset($data['trade_type']) && strtoupper($data['trade_type'])== 'MICROPAY' && isset($data['transaction_id'])){ $WxPayRecordModel = new WxPayRecordModel(); $WxPayRecordModel->where(['out_trade_no'=>"{$out_trade_no}"])->update(['wechat_msg'=>json_encode($data)]); $openid = isset($data['openid'])?$data['openid']:''; $total_fee = isset($data['total_fee'])?$data['total_fee']:''; HelperService::addLog("{$params['notify_url']}?order_no={$params['order_no']}&out_trade_no={$out_trade_no}&openid={$openid}&total_fee={$total_fee}&msg=success&transaction_id={$data['transaction_id']}&bank=".HelperService::BankList("{$data['bank_type']}")); $res = HelperService::httpPost("{$params['notify_url']}?order_no={$params['order_no']}&out_trade_no={$out_trade_no}&openid={$openid}&total_fee={$total_fee}&msg=success&transaction_id={$data['transaction_id']}&bank=".HelperService::BankList("{$data['bank_type']}")); file_put_contents("cronOrderQuery.mp","\n sync3、".date('Y-m-d H:i:s'),FILE_APPEND); file_put_contents("cronOrderQuery.mp","\n sync3-1、{$params['notify_url']}?order_no={$params['order_no']}&out_trade_no={$out_trade_no}&openid={$openid}&total_fee={$total_fee}&msg=success&transaction_id={$data['transaction_id']}&bank=".HelperService::BankList("{$data['bank_type']}"),FILE_APPEND); if($res === false){ file_put_contents("cronOrderQuery.mp","\n sync4、".HelperService::$_httpErr,FILE_APPEND); } file_put_contents("cronOrderQuery.mp","\n sync5、".json_encode($res),FILE_APPEND); } HelperService::returnJson(['code'=>200,'msg'=>"{$msg}",'data'=>$data]); } public function cronOrderQuery(){ while(true){ $WxPayRecordModel = new WxPayRecordModel(); $last_ts = time() - 7200; $WxPayRecordList = $WxPayRecordModel->where("pay_type='MICRO' and add_ts>{$last_ts} and wechat_msg is null")->select(); require_once(APP_PATH.'/index/service/wechat/WxPayPubHelper.php'); foreach($WxPayRecordList as $item){ $exOrder = explode('_',$item['out_trade_no']); $exOrder = current($exOrder); WxPayConfig::$exOrder(); $OrderQuery = new OrderQuery_pub(); $OrderQuery->setParameter('out_trade_no',$item['out_trade_no']); $data = $OrderQuery->getResult(); $msg = isset($data['result_code'])?$data['result_code']:'fail'; file_put_contents("cronOrderQuery.mp","\n notify1、{$item['out_trade_no']}-".date('Y-m-d H:i:s'),FILE_APPEND); file_put_contents("cronOrderQuery.mp","\n notify2、".json_encode($data),FILE_APPEND); if(strtolower($msg) == 'success' && isset($data['trade_type']) && strtoupper($data['trade_type'])== 'MICROPAY' && isset($data['transaction_id'])){ $WxPayRecordModel = new WxPayRecordModel(); $WxPayRecordModel->where(['out_trade_no'=>"{$item['out_trade_no']}"])->update(['wechat_msg'=>json_encode($data)]); $openid = isset($data['openid'])?$data['openid']:''; $total_fee = isset($data['total_fee'])?$data['total_fee']:''; HelperService::addLog("{$item['notify_url']}?order_no={$item['order_no']}&out_trade_no={$item['out_trade_no']}&openid={$openid}&total_fee={$total_fee}&msg=success&transaction_id={$data['transaction_id']}&bank=".HelperService::BankList("{$data['bank_type']}")); $res = HelperService::httpPost("{$item['notify_url']}?order_no={$item['order_no']}&out_trade_no={$item['out_trade_no']}&openid={$openid}&total_fee={$total_fee}&msg=success&transaction_id={$data['transaction_id']}&bank=".HelperService::BankList("{$data['bank_type']}")); file_put_contents("cronOrderQuery.mp","\n notify3、".date('Y-m-d H:i:s'),FILE_APPEND); if($res === false){ file_put_contents("cronOrderQuery.mp","\n notify4、".HelperService::$_httpErr,FILE_APPEND); } file_put_contents("cronOrderQuery.mp","\n notify5、success",FILE_APPEND); }elseif(strtolower($msg) == 'fail' || (isset($data['trade_state']) && strtoupper($data['trade_state']) != 'USERPAYING')){ $WxPayRecordModel = new WxPayRecordModel(); $WxPayRecordModel->where(['out_trade_no'=>"{$item['out_trade_no']}"])->update(['wechat_msg'=>json_encode($data)]); $openid = isset($data['openid'])?$data['openid']:''; $total_fee = isset($data['total_fee'])?$data['total_fee']:''; HelperService::addLog("{$item['notify_url']}?order_no={$item['order_no']}&out_trade_no={$item['out_trade_no']}&openid={$openid}&total_fee={$total_fee}&msg=fail"); $res = HelperService::httpPost("{$item['notify_url']}?order_no={$item['order_no']}&out_trade_no={$item['out_trade_no']}&openid={$openid}&total_fee={$total_fee}&msg=fail"); file_put_contents("cronOrderQuery.mp","\n notify3、".date('Y-m-d H:i:s'),FILE_APPEND); if($res === false){ file_put_contents("cronOrderQuery.mp","\n notify4、".HelperService::$_httpErr,FILE_APPEND); } file_put_contents("cronOrderQuery.mp","\n notify5、fail",FILE_APPEND); } } sleep(1); } } /** * 活动接口微信支付 * @return mixed */ public function ActivityWxPay(){ $param = $this->request->param(); if(isset($param['pay_notify_url'])){ session('pay_notify_url',$param['pay_notify_url']); } if(isset($param['order_no'])){ session('order_no',$param['order_no']); } if(!session('order_no')){ die('order_no is empty'); } $order_no = session('order_no'); $companyCode = $this->_validCompanyCode($param); WxPayConfig::$companyCode(); require_once(APP_PATH.'/index/service/wechat/WxPayPubHelper.php'); //使用jsapi接口 $jsApi = new JsApi_pub(); //通过code获得openid if (!isset($_GET['code'])) { $url = $jsApi->createOauthOpenidForCode("http://{$_SERVER['HTTP_HOST']}".WxPayConfig::$activity_API_CALL_URL, rand(100,1000)); header("Location: $url"); exit; } else { $code = $_GET['code']; $jsApi->setCode($code); $openInfo = $jsApi->getOpenidInfo(); if(!isset($openInfo['openid'])){ HelperService::addLog($openInfo); header("HTTP/1.1 301 Moved Permanently"); header("Location: http://".$_SERVER['HTTP_HOST']."/index/wechat/warmError.html?err_msg=支付调用失败(openid)&err_detail=重复支付;网络连接失败"); exit; } $openid = $openInfo['openid']; } $orderModel = new ActivityOrderModel(); $order = $orderModel->getOne(['activity_order_no'=>$order_no]); if(!$order){ HelperService::returnJson(['code'=>'400','msg'=>'order_no is error']); } $unifiedOrder = new UnifiedOrder_pub(); $money = intval($order['total_price']); if($money<=0){ $order['error_msg'] = "money is fail"; HelperService::addLog($order); header("HTTP/1.1 301 Moved Permanently"); header("Location: http://{$_SERVER['HTTP_HOST']}/index/wechat/warmError.html?err_msg=支付调用失败(money)&err_detail=重复支付;网络连接失败"); exit; } //设置统一支付接口参数 $unifiedOrder->setParameter("openid", "$openid"); //商品描述 $unifiedOrder->setParameter("body",WxPayConfig::$PAY_TIPS."[".date('Y-m-d H:i:s')."]"); //商品描述 //自定义订单号,此处仅作举例 $out_trade_no = substr($companyCode,0,6).'_'.$order_no."_".date('his'); $unifiedOrder->setParameter("out_trade_no", $out_trade_no); //商户订单号 $unifiedOrder->setParameter("total_fee", $money); //总金额 $unifiedOrder->setParameter("notify_url", "http://{$_SERVER['HTTP_HOST']}".WxPayConfig::$NOTIFY_ACTIVITY_URL); //通知地址 $unifiedOrder->setParameter("trade_type", "JSAPI"); //交易类型 $prepay_id = $unifiedOrder->getPrepayId($out_trade_no.'_'.time()); $jsApi->setPrepayId($prepay_id); $jsApiParameters = $jsApi->getParameters(); $notify_url = base64_decode(session('pay_notify_url')); require_once(APP_PATH.'/index/view/wechat/wxPay.php'); } /** * 酒店接口微信支付 * @return mixed */ public function HotelWxPay(){ $param = $this->request->param(); HelperService::addLog("param".json_encode($param)); if(isset($param['pay_notify_url'])){ session('pay_notify_url',$param['pay_notify_url']); } if(isset($param['order_no'])){ session('order_no',$param['order_no']); } if(!session('order_no')){ die('order_no is empty'); } $order_no = session('order_no'); $companyCode = $this->_validCompanyCode($param); WxPayConfig::$companyCode(); require_once(APP_PATH.'/index/service/wechat/WxPayPubHelper.php'); //使用jsapi接口 $jsApi = new JsApi_pub(); //通过code获得openid if (!isset($_GET['code'])) { $url = $jsApi->createOauthOpenidForCode("http://{$_SERVER['HTTP_HOST']}".WxPayConfig::$hotel_API_CALL_URL, rand(10000,99999)); HelperService::addLog("url:$url"); header("Location: $url"); exit; } else { $code = $_GET['code']; HelperService::addLog($code); $jsApi->setCode($code); $openInfo = $jsApi->getOpenidInfo(); HelperService::addLog('code here'); if(!isset($openInfo['openid'])){ HelperService::addLog($openInfo); header("HTTP/1.1 301 Moved Permanently"); header("Location: http://".$_SERVER['HTTP_HOST']."/index/wechat/warmError.html?err_msg=支付调用失败(openid)&err_detail=重复支付;网络连接失败"); exit; } $openid = $openInfo['openid']; } $orderModel = new OrderModel(); $order = $orderModel->getOne(['order_no'=>$order_no]); if(!$order){ HelperService::returnJson(['code'=>'400','msg'=>'order_no is error']); } $unifiedOrder = new UnifiedOrder_pub(); $money = intval($order['total_price']); if($money<=0){ $order['error_msg'] = "money is fail"; HelperService::addLog($order); header("HTTP/1.1 301 Moved Permanently"); header("Location: http://".$_SERVER['HTTP_HOST']."/index/wechat/warmError.html?err_msg=支付调用失败(money)&err_detail=重复支付;网络连接失败"); exit; } //设置统一支付接口参数 $unifiedOrder->setParameter("openid", "$openid"); //商品描述 $unifiedOrder->setParameter("body",WxPayConfig::$PAY_TIPS."[".date('Y-m-d H:i:s')."]"); //商品描述 //自定义订单号,此处仅作举例 $out_trade_no = substr($companyCode,0,6).'_'.$order_no."_".date('his'); $unifiedOrder->setParameter("out_trade_no", $out_trade_no); //商户订单号 $unifiedOrder->setParameter("total_fee", $money); //总金额 $unifiedOrder->setParameter("notify_url", "http://{$_SERVER['HTTP_HOST']}".WxPayConfig::$NOTIFY_HOTEL_URL); //通知地址 $unifiedOrder->setParameter("trade_type", "JSAPI"); //交易类型 $prepay_id = $unifiedOrder->getPrepayId($out_trade_no.'_'.time()); $jsApi->setPrepayId($prepay_id); $jsApiParameters = $jsApi->getParameters(); $notify_url = base64_decode(session('pay_notify_url')); $this->getRoomInfoByOrderNo($order_no); require_once(APP_PATH.'/index/view/wechat/wxPay.php'); exit; } /** * 商城微信支付异步调用 */ public function notifyUrl(){ $param = file_get_contents("php://input"); $params = (array)simplexml_load_string($param, 'SimpleXMLElement', LIBXML_NOCDATA); try { $arr = ['total_fee', 'out_trade_no']; foreach ($arr as $value) { if (!isset($params[$value])) { HelperService::returnJson(['code' => 400, 'msg' => "$value don't find"],$param); } } $tradeNoArr = explode('_', $params['out_trade_no']); $companyCode = $tradeNoArr[0]; $orderNo = isset($tradeNoArr[1]) ? $tradeNoArr[1] : 0; $companyCode = $this->_validCompanyCode(['companyCode' => $companyCode]); $orderModel = new ProductOrderModel(); $orderModel->startTrans(); $order = $orderModel->upInfo(['order_no' => $orderNo,'status'=>0], ['status' => 1,'pay_time'=>time(),'out_trade_no'=>$params['out_trade_no']]); if ($order === false) { HelperService::addLog('update orderModel error('.$orderModel->getLastSql().')',$params); die('update orderModel error'); } //查询当前订单中含有的商品信息 $orderDetailModel = new ProductOrderDetailModel(); $productModel = new ProductModel(); $orderDetail = $orderDetailModel->where(['order_no'=>$orderNo])->select(); foreach($orderDetail as $item_detail){ $product_id = $item_detail['product_id']; $num = $item_detail['num']; $productModel->upInfo(['product_id'=>$product_id],[ 'remain_num'=>['exp',"`remain_num`-$num"], 'sales_num'=>['exp',"`sales_num`+$num"], ]); } $orderModel->commit(); $data = [ 'order_no' => $orderNo, 'total_fee' => $params['total_fee'], 'out_trade_no' => $params['out_trade_no'], 'add_ts' => time(), ]; $wxPayRecordModel = new WxPayRecordModel(); $res = $wxPayRecordModel->insertGetId($data); if ($res === false) { HelperService::addLog('insert wx_pay_record fail('.$wxPayRecordModel->getLastSql().')',$params); die('insert wx_pay_record fail'); } HelperService::addLog('success',$params); if(session('SmsConfig')){ $url = session('SmsConfig')['reback_url']."?type=MALL&order_no=$orderNo"; $res = HelperService::httpPost($url); //file_put_contents('wxPayRecord.mp',"[".date('Y-m-d H:i:s')."]".json_encode($res)."[url:$url]"."\n\n",FILE_APPEND); } die('success'); }catch (\Exception $ex){ file_put_contents('wxPayRecord.mp',"[".date('Y-m-d H:i:s')."]".$ex->getMessage()."+".$ex->getFile()."+".$ex->getLine().json_encode($params)."\n\n",FILE_APPEND); } } /** * 商城微信支付异步调用 */ public function activityNotifyUrl(){ $param = file_get_contents("php://input"); $params = (array)simplexml_load_string($param, 'SimpleXMLElement', LIBXML_NOCDATA); try { $arr = ['total_fee', 'out_trade_no']; foreach ($arr as $value) { if (!isset($params[$value])) { HelperService::returnJson(['code' => 400, 'msg' => "$value don't find"],$param); } } $tradeNoArr = explode('_', $params['out_trade_no']); $companyCode = $tradeNoArr[0]; $orderNo = isset($tradeNoArr[1]) ? $tradeNoArr[1] : 0; $companyCode = $this->_validCompanyCode(['companyCode' => $companyCode]); $orderModel = new ActivityOrderModel(); $order = $orderModel->upInfo(['activity_order_no' => $orderNo,'status'=>0], ['status' => 1,'pay_time'=>time(),'out_trade_no'=>$params['out_trade_no']]); if ($order === false) { HelperService::addLog('update orderModel error('.$orderModel->getLastSql().')',$params); die('update orderModel error'); } $data = [ 'order_no' => $orderNo, 'total_fee' => $params['total_fee'], 'out_trade_no' => $params['out_trade_no'], 'add_ts' => time(), ]; $wxPayRecordModel = new \app\index\model\activity\WxPayRecordModel(); $res = $wxPayRecordModel->insertGetId($data); if ($res === false) { HelperService::addLog('insert wx_pay_record fail('.$wxPayRecordModel->getLastSql().')',$params); die('insert wx_pay_record fail'); } HelperService::addLog('success',$params); if(session('SmsConfig')){ $url = session('SmsConfig')['reback_url']."?type=MALL&order_no=$orderNo"; HelperService::httpPost($url); } die('success'); }catch (\Exception $ex){ file_put_contents('wxPayRecord.mp',"[".date('Y-m-d H:i:s')."]".$ex->getMessage().json_encode($params)."\n\n",FILE_APPEND); } } /** * 商城微信支付异步调用 */ public function platformNotifyUrl(){ $param = file_get_contents("php://input"); $params = (array)simplexml_load_string($param, 'SimpleXMLElement', LIBXML_NOCDATA); try { $arr = ['total_fee', 'out_trade_no']; foreach ($arr as $key=>$value) { if (!isset($params[$value])) { HelperService::returnJson(['code' => 400, 'msg' => "参数错误($key)"],$param); } } $tradeNoArr = explode('_', $params['out_trade_no']); if(count($tradeNoArr)<2){ HelperService::returnJson(['code' => 400, 'msg' => "参数错误(trade)"],$param); } $companyCode = $tradeNoArr[0]; $orderNo = isset($tradeNoArr[1]) ? $tradeNoArr[1] : 0; $companyCode = $this->_validCompanyCode(['companyCode' => $companyCode]); $data = [ 'order_no' => $orderNo, 'total_fee' => $params['total_fee'], 'out_trade_no' => $params['out_trade_no'], 'add_ts' => time(), 'wechat_msg'=>json_encode($params) ]; $wxPayRecordModel = new WxPayRecordModel(); $res = $wxPayRecordModel->insertGetId($data); if ($res === false) { HelperService::addLog('insert wx_pay_record fail('.$wxPayRecordModel->getLastSql().')',$params); die('insert wx_pay_record fail'); } HelperService::addLog('success',$params); if(session('SmsConfig')){ $url = session('SmsConfig')['reback_url']."?type=MALL&order_no=$orderNo&total_price={$params['total_fee']}&out_trade_no={$params['out_trade_no']}&bank=".HelperService::BankList("{$params['bank_type']}"); $is_ssl = false; if(strpos($url,'https://')===0){ $is_ssl = true; } $times = 3; while($times--){ $res1 = HelperService::httpPost($url,'',$is_ssl); \think\Log::record("推送记录url:".$url."=>data:". json_encode($res1)); if($res1 !== false){ break; } } HelperService::addLog($res1,['url'=>$url]); if(isset(session('SmsConfig')['reback_url2'])){ $is_ssl = false; if(strpos($url,'https://')===0){ $is_ssl = true; } $url = session('SmsConfig')['reback_url2']."?type=MALL&order_no=$orderNo&total_price={$params['total_fee']}&out_trade_no={$params['out_trade_no']}"; $res1 = HelperService::httpPost($url,'',$is_ssl); HelperService::addLog($res1,['url'=>$url]); } } die('success'); }catch (\Exception $ex){ file_put_contents('wxPayRecord.mp',"[".date('Y-m-d H:i:s')."]".$ex->getMessage().json_encode($params)."\n\n",FILE_APPEND); } } /** * 商城微信支付异步调用 */ public function hotelNotifyUrl(){ $param = file_get_contents("php://input"); $params = (array)simplexml_load_string($param, 'SimpleXMLElement', LIBXML_NOCDATA); //file_put_contents('wxPayRecord.mp',"[".date('Y-m-d H:i:s')."]".json_encode($params)."\n\n",FILE_APPEND); try { $arr = ['total_fee', 'out_trade_no']; foreach ($arr as $value) { if (!isset($params[$value])) { HelperService::returnJson(['code' => 400, 'msg' => "$value don't find"],$param); } } $tradeNoArr = explode('_', $params['out_trade_no']); $companyCode = $tradeNoArr[0]; $orderNo = isset($tradeNoArr[1]) ? $tradeNoArr[1] : 0; $companyCode = $this->_validCompanyCode(['companyCode' => $companyCode]); $orderModel = new OrderModel(); $order = $orderModel->upInfo(['order_no' => $orderNo,'status'=>0], ['status' => 1,'pay_time'=>time(),'out_trade_no'=>$params['out_trade_no']]); if ($order === false) { HelperService::addLog('update orderModel error('.$orderModel->getLastSql().')',$params); die('update orderModel error'); } $data = [ 'order_no' => $orderNo, 'total_fee' => $params['total_fee'], 'out_trade_no' => $params['out_trade_no'], 'add_ts' => time(), ]; $wxPayRecordModel = new \app\index\model\hotel\WxPayRecordModel(); $res = $wxPayRecordModel->insertGetId($data); if ($res === false) { HelperService::addLog('insert wx_pay_record fail('.$wxPayRecordModel->getLastSql().')',$params); die('insert wx_pay_record fail'); } HelperService::addLog('success',$params); if(session('SmsConfig')){ $url = session('SmsConfig')['reback_url']."?type=MALL&order_no=$orderNo"; HelperService::httpPost($url); } die('success'); }catch (\Exception $ex){ file_put_contents('wxPayRecord.mp',"[".date('Y-m-d H:i:s')."]".$ex->getMessage().json_encode($params)."\n\n",FILE_APPEND); } } public function warmError(){ $params = $this->request->param(); $err_msg = isset($params['err_msg'])?$params['err_msg']:''; $err_detail = isset($params['err_detail'])?$params['err_detail']:''; $this->assign('err_msg',$err_msg); if(!empty($err_detail)){ $str = '可能原因如下:
'; $err_detail_arr = explode(';',$err_detail); foreach($err_detail_arr as $key=>$detail){ $str .= ($key+1)."、{$detail}
"; } $this->assign('err_detail',$str); } return $this->fetch('common/error'); } /** * 微信授权 */ public function authorize(){ $param = $this->request->param(); if(isset($param['notify_url'])){ session('wx_authorize_notify',$param['notify_url']); } if(!session('wx_authorize_notify')){ die("I don't know wx_authorize_notify."); } $companyCode = $this->_validCompanyCode($param); require_once(APP_PATH.'/index/service/wechat/WxPayPubHelper.php'); $JsApi = new JsApi_pub(); WxPayConfig::$companyCode(); //第一步调用起授权拿到Code if(!isset($param['code'])){ //触发微信返回code码 $url = $JsApi->createOauthOpenidAndMoreUrlForCode("http://{$_SERVER['HTTP_HOST']}".WxPayConfig::$Authorize_URL, rand(100,1000)); header("HTTP/1.1 301 Moved Permanently"); header("Location: $url"); exit; } //第二步得到openid $code = $param['code']; $JsApi->setCode($code); $openInfo = $JsApi->getOpenidInfo(); //第三步授权 $access_token = isset($openInfo['access_token'])?$openInfo['access_token']:''; $openid = isset($openInfo['openid'])?$openInfo['openid']:''; $this->_attention($openid,$companyCode); $result = $JsApi->getOauthUserInfo($access_token,$openid); $url = base64_decode(session('wx_authorize_notify')); $params = @http_build_query($result); if(empty($result)){ HelperService::addLog($result,$param); header("HTTP/1.1 301 Moved Permanently"); header("Location: $url"); } header("Location: $url?$params"); exit; } public function _attention($openid,$companyCode){ $biz = WxPayConfig::$BIZ; \think\Log::record('WX_SUBSCRIBE:'. $biz); if(empty($biz)){ return true; } // 获取公众号的access_token,此access_token不是用户授权后的access_token $accessToken = $this->_getToken($companyCode); $subscribe_msg = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=".$accessToken."&openid=".$openid; $subscribe_info = HelperService::httpPost($subscribe_msg,'',true); $subscribe_info = json_decode($subscribe_info,true); \think\Log::record('WX_SUBSCRIBE:'. $subscribe_msg. "=>".json_encode($subscribe_info)); if(isset($subscribe_info['subscribe']) && $subscribe_info['subscribe']){ return true; }else{ die('长按关注公众号 '); } } private function _getToken($companyCode,$is_force=false){ WxPayConfig::$companyCode(); $token = Cache::get('access_token_'.$companyCode); if(!empty($token) && $is_force==false){ HelperService::returnJson([ 'code'=>200, 'msg'=>'cache', 'data'=>"$token" ]); } //判断有没有当前公司的access_token $request_token = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".WxPayConfig::$APPID."&secret=".WxPayConfig::$APPSECRET; $token_json = HelperService::httpPost($request_token,'',true); if($token_json === false){ HelperService::returnJson([ 'code'=>400, 'msg'=>'token is error', 'data'=>"$token_json" ]); } $tokenArr = json_decode($token_json,true); if(!isset($tokenArr['access_token'])){ HelperService::returnJson([ 'code'=>400, 'msg'=>'wechat return', 'data'=>"$token_json", 'url'=>$request_token ]); } $token = $tokenArr['access_token']; return $token; } private function _validCompanyCode($param){ if(isset($param['companyCode'])){ $AuthCompanyModel = new AuthCompanyModel(); $companyCode = $param['companyCode']; $company = $AuthCompanyModel->getInfo(['company_code'=>['like',"$companyCode%"]]); if(empty($company)){ die("I don't have this companyCode."); } session('company_db_json',$company['db_json']); session('SmsConfig',json_decode($company['sms_json'],true)); session('companyCode',$param['companyCode']); } if(!session('companyCode')){ die("I don't know companyCode."); } $companyCode = session('companyCode'); $this->_loadConfig(); return $companyCode; } private function _loadConfig(){ $db_json = session('company_db_json'); if(empty($db_json)){ return true; } $db_arr = json_decode($db_json,true); foreach($db_arr as $k=>$v){ $data = [ 'type' => 'mysql', 'hostname' => '127.0.0.1', 'database' => 'test', 'username' => 'root', 'password' => '', 'hostport' => '3306', 'params' => [], 'charset' => 'utf8', 'prefix' => '', ]; $data['type'] = $v['type']; $data['hostname'] = $v['hostname']; $data['database'] = $v['database']; $data['username'] = $v['username']; $data['password'] = $v['password']; Config::set($v['config_name'],$data); } } /** * 通过订单信息检查商品数量是否足够 * @param $order_no * @return bool */ private function getProductInfoByOrderNo($order_no){ $orderDetailModel = new ProductOrderDetailModel(); $productModel = new ProductModel(); $orderDetail = $orderDetailModel->where(['order_no'=>$order_no])->select(); foreach($orderDetail as $item_detail){ $product_id = $item_detail['product_id']; $num = $item_detail['num']; $res = $productModel->where(['product_id'=>$product_id,'remain_num'=>['egt',$num],'status'=>0])->find(); if(!$res){ HelperService::addLog(['msg'=>"getProductInfoByOrderNo($order_no)"]); header("HTTP/1.1 301 Moved Permanently"); header("Location: http://".$_SERVER['HTTP_HOST']."/index/wechat/warmError.html?err_msg=产品数量不足($order_no/$product_id/$num)&err_detail=请联系卖家"); exit; } } return true; } /** * 判断酒店的房间信息是否足够 * @param $order_no * @return bool */ private function getRoomInfoByOrderNo($order_no){ $orderModel = new OrderModel(); $order = $orderModel->where(['order_no'=>$order_no])->find(); $num = $order['total_room_num']; $start_date = strtotime($order['start_date']); $end_date = strtotime($order['end_date']); $room_id = $order['room_id']; $roomModel = new RoomModel(); $room = $roomModel->where(['room_id'=>$room_id])->find(); $room_num = $room['total_number']; for($date=$start_date;$date<$end_date;$date+=86400){ $current_num = $this->getRoomNumByDate($room_id,$date); if($room_num < $current_num + $num){ HelperService::addLog(['msg'=>"getRoomInfoByOrderNo($order_no)"]); header("HTTP/1.1 301 Moved Permanently"); header("Location: http://".$_SERVER['HTTP_HOST']."/index/wechat/warmError.html?err_msg=房间剩余数目不足&err_detail=请联系店家($order_no)"); exit; } } return true; } private function getRoomNumByDate($room_id,$date){ $OrderModel = new OrderModel(); $next_date = $date + 86400; $room_num = $OrderModel->where("room_id = $room_id and add_time >= $date and add_time < $next_date and (status =1 or status=6)")->sum('total_room_num'); return $room_num; } }