id)->first(); if(empty($store)){ return $this->error('450001','该店铺不能申请二级商户'); } $out_request_no=$store->out_request_no??date('ymdHis').mt_rand(10000,99999); $contact_name=$request->input('contact_name'); $contact_phone=$request->input('contact_phone'); $contact_id_card=$request->input('contact_id_card');//"412326199612220311" $store_name=$request->input('store_name')??$store->name; if(preg_match('/[^\x{4e00}-\x{9fa5}^0-9^A-Z^a-z]+/u',$store_name)){ return $this->error('450002','店铺名称中不能使用特殊符号,请前往公众号—代理个人中心—我的,点击“名片”,修改昵称。'); } if(mb_strlen($store_name)>10){ return $this->error('450002','店铺名称不能超过10个字符,请前往公众号—代理个人中心—我的,点击“名片”,修改昵称。'); } // $store_name=$this->filterEmoji($request->input('store_name'))??$this->filterEmoji($store->name); // $store_name=preg_replace("/[^\x{4e00}-\x{9fa5}^0-9^A-Z^a-z]+/u", '', $store_name);//^0-9^A-Z^a-z // $store_name=mb_substr($store_name,0,16); // if(mb_strlen(preg_replace("/[^\x{4e00}-\x{9fa5}^0-9^A-Z^a-z]+/u", '', $store_name))==0){ // return $this->error('450001','该店铺名称格式不符需重置'); // } $store_url=$request->input('store_url')??"http://api.app.jiuweiyun.cn/api/gzh"; $id_card_copy=$request->input('id_card_copy'); $id_card_national=$request->input('id_card_national'); $id_card_name=$request->input('id_card_name'); $id_card_number=$request->input('id_card_number'); $id_card_valid_time_begin=$request->input('id_card_valid_time_begin');//$request->input('id_card_valid_time');//"2027-09-07" $id_card_valid_time=$request->input('id_card_valid_time');//$request->input('id_card_valid_time');//"2027-09-07" $account_name=$request->input('account_name');//开户人姓名 $account_bank=$request->input('account_bank');//银行 $bank_address_code=str_pad($request->input('bank_address_code'),6,"0",STR_PAD_RIGHT);//开户城市编码 // $bank_branch_id=$request->input('sub_branch_id');//开户银行联行号 // $bank_name=$request->input('bank_name');//开户行(支行) $account_number=$request->input('account_number');//银行卡号 $url="https://api.mch.weixin.qq.com/v3/ecommerce/applyments/";//这个是微信的申请地址 $param=array( "out_request_no" => $out_request_no,//申请编号,用户自定义就可以 "organization_type" => "2401",//申请类型 2401代表申请的是小微商户(就是个人,没有营业执照的人),其它类型可参考微信v3文档 // "need_account_info" => false,//true,//是否填写结算银行账户,提现会提到这个账户上,设置true需要添加银行卡信息等。这里我就设置false了。因为绑定银行卡可以通过微信中的小程序“商家助手”自己去绑定。也可以通过微信的绑卡接口在写一个绑定银行卡的功能。 "account_info"=> [ "bank_account_type" => "75", "account_name"=> $this->getEncrypts($id_card_name),//开户名称 "account_bank"=> $account_bank,//开户银行 "bank_address_code"=> $bank_address_code,//"410100",//开户银行省市编码 // "bank_branch_id"=>$bank_branch_id,// "402713354941",//开户银行联行号 // "bank_name"=> $bank_name,//开户银行全称(含支行) "account_number"=> $this->getEncrypts($account_number),//银行账户'6214833787989683' ], "contact_info" => array(//填写一个店铺的管理员信息 "contact_type" => "65",//管理员类型 65是经营者/法人 其它类型看微信文档 "contact_name" => $this->getEncrypts($contact_name),//管理员姓名getEncrypts是加密字符串的方法,见下文。 "mobile_phone" => $this->getEncrypts($contact_phone),//管理员电话getEncrypts是加密字符串的方法 "contact_id_card_number"=> $this->getEncrypts($contact_id_card),//管理员身份证号码 ), "sales_scene_info" =>array(//店铺信息 "store_name" =>$store_name,//店铺全称 "store_url" =>$store_url //店铺的地址 ), "merchant_shortname" =>$store_name,//商户简称 "id_card_info" =>array(//经营者/法人的身份证信息 "id_card_copy" =>$this->uploadmedia($id_card_copy),//身份证人像面uploadmedia()是上传图片到微信的方法,见下文 "id_card_national" =>$this->uploadmedia($id_card_national),//身份证国徽面 "id_card_name" =>$this->getEncrypts($id_card_name),//身份证上的姓名 getEncrypts()字符串加密方法 见下文 "id_card_number" =>$this->getEncrypts($id_card_number),//身份证号,此身份证号可以和管理员是一个人 "id_card_valid_time_begin"=>$id_card_valid_time_begin, //身份证国徽面的开始日期 "id_card_valid_time"=>$id_card_valid_time //身份证国徽面的到期日期 ) ); Log::info('监测提交认证数据'); Log::info(json_encode($param,JSON_UNESCAPED_UNICODE)); $merchant_id = config('wechat.payment.default.mch_id'); //"1604585534"; //服务商的商户号 $serial_no = config('wechat.payment.default.serial_no'); //"73024BD5FA3E83F39DC1EE36D53FF206F6B82289";//商户证书的序列号,可在微信商户平台API安全 中获取 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp =time();//时间戳 $nonce =$this->nonce_str();//获取随机字符串 $sign =$this->sign($url,'POST',$timestamp,$nonce,json_encode($param),$mch_private_key,$merchant_id,$serial_no);//进行签名操作 $header =[//设置发送的头信息 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign,//签名 'Accept:application/json', 'User-Agent:' . $merchant_id,//服务商的商户号 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书的序列号,注意:是平台证书,不是上文的商户证书序列号 ]; $result=$this->curl($url,json_encode($param),$header);//curl方法见下文 $result=json_decode($result,true); if(isset($result['code']) && !empty($result['code'])){ return $this->error('450001',$result['message']??'未知错误'); } if(isset($result['applyment_id']) && isset($result['out_request_no'])){ DB::connection('mysql_w')->beginTransaction(); try{ Apply::create([ 'store_id'=>$store->id, 'contact_name'=>$contact_name, 'contact_phone'=>$contact_phone, 'contact_id_card'=>$contact_id_card, 'store_name'=>$store_name, 'store_url'=>$store_url, 'id_card_copy'=>$id_card_copy, 'id_card_national'=>$id_card_national, 'id_card_name'=> $id_card_name, 'id_card_number'=>$id_card_number, 'id_card_valid_time_begin'=>$id_card_valid_time_begin, 'id_card_valid_time'=>$id_card_valid_time, "account_name"=> $account_name,//开户名称 "account_bank"=> $account_bank,//开户银行 "bank_address_code"=> $bank_address_code,//"410100",//开户银行省市编码 // "bank_branch_id"=>$bank_branch_id,// "402713354941",//开户银行联行号 // "bank_name"=> $bank_name,//开户银行全称(含支行) "account_number"=> $account_number,//银行账户'6214833787989683' 'applyment_id'=>$result['applyment_id'], 'out_request_no'=>$result['out_request_no'], ]); Store::where('user_id',Auth::user()->id) ->update([ 'username'=>$id_card_name, 'idCard'=>$id_card_number, 'cardImg1'=>$id_card_copy, 'cardImg2'=>$id_card_national, 'applyment_id'=>$result['applyment_id'], 'out_request_no'=>$result['out_request_no'], 'is_apply'=>1,//1已申请待审核 2 审核通过,待签约,3 已签约,已完成 'province'=>$request->input('province'), 'city'=>$request->input('city'), 'area'=>$request->input('area'), 'address'=>$request->input('address'), 'account_number'=> $account_number, 'account_bank'=> $account_bank, ]); // AddressW::create([ // 'name'=>$contact_name, // 'phone'=>$contact_phone, // 'store_id'=>$store->id, // 'province'=>$request->input('province'), // 'city'=>$request->input('city'), // 'area'=>$request->input('area'), // 'address'=>$request->input('address'), // 'is_default'=>0 // ]); Log::info('applyment_id:'.$result['applyment_id'].',&&out_request_no:'.$result['out_request_no']); DB::connection('mysql_w')->commit(); return $this->success($result); }catch(\Exception $e){ DB::connection('mysql_w')->rollBack(); return $this->error('450001',$e->getMessage()); } }else{ return $this->error('450001','提交失败'); } } //过滤微信表情符 function filterEmoji($str) { $str = preg_replace_callback( '/./u', function (array $match) { return strlen($match[0]) >= 4 ? '' : $match[0]; }, $str); return $str; } //获取所有银行 public function getAllBank(){ return $this->success(Bank::whereNotNUll('bank_id')->where('status',1)->groupBy('bank_name')->pluck('bank_name','bank_id')); } //APP获取所有银行 public function getAppAllBank(){ return $this->success(['data'=>Bank::whereNotNUll('bank_id')->where('status',1)->groupBy('bank_name')->select('bank_name','bank_id')->get()]); } //获取省 public function getAllProvince(Request $request){ return $this->success(['list'=>Bank::where('status',1)->groupBy('province')->select('province','province_id')->get()]); } //获取省对应的市 public function getAllCity(Request $request){ return $this->success(['list'=>Bank::where('status',1)->where('province_id',$request->input('province_id'))->groupBy('city')->select('city','city_id')->get()]); } //获取支行 public function getBankBranch(Request $request){ $city_code=$request->input('city_code'); $bank_id=$request->input('bank_id'); // if($city_code=='1101' || $city_code=='1201' || $city_code=='3101' || $city_code=='5001'){ // $city_code-=$city_code; // } $city_code.='00'; Log::info($city_code.'//'.$bank_id); $bank=Bank::where('city_id',$city_code)->where('bank_id',$bank_id)->where('status',1)->get(); return $this->success($bank); } //查询进件状态 public function query(Request $request){ $store=Store::where('user_id',Auth::user()->id)->first(); $applyment_id=$store->applyment_id??$request->input('applyment_id');//'20200708093101909876';//申请编号 Log:info('iii---------iii'.$applyment_id); if(empty($applyment_id)){ return $this->error('450001',Auth::user()->id.'/当前申请认证,被驳回'); } $url='https://api.mch.weixin.qq.com/v3/ecommerce/applyments/'.$applyment_id;//查询地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); Log::info('------'.$result); $result=json_decode($result,true); $apply=Apply::where('store_id',$store->id)->where('applyment_id',$applyment_id)->OrderBy('id','desc')->first(); if($result['applyment_state']=="ACCOUNT_NEED_VERIFY"){ Apply::where('id',$apply->id)->update(['audit_detail'=>$result['legal_validation_url']]); } if($result['applyment_state']=="NEED_SIGN"){ Store::where('user_id',Auth::user()->id)->update(['sub_mchid'=>$result['sub_mchid'],'is_apply'=>2]); Apply::where('id',$apply->id)->update(['sub_mchid'=>$result['sub_mchid'], 'audit_detail'=>$result['sign_url']]); } if($result['applyment_state']=="FINISH"){ Log::info($applyment_id.'-----ooooo-----'.$result['sub_mchid']); Store::where('user_id',Auth::user()->id)->update(['sub_mchid'=>$result['sub_mchid'],'is_apply'=>3]); Apply::where('id',$apply->id)->update(['sub_mchid'=>$result['sub_mchid']]); } if($result['applyment_state']=="REJECTED"){//已驳回 Store::where('user_id',Auth::user()->id)->update(['is_apply'=>4]); Apply::where('id',$apply->id)->update(['audit_detail'=>$result['audit_detail'][0]['reject_reason']]); } if($result['applyment_state']=="FROZEN"){ Store::where('user_id',Auth::user()->id)->update(['is_apply'=>5]);//已冻结 Apply::where('id',$apply->id)->update(['audit_detail'=>$result['audit_detail'][0]['reject_reason']]); } Apply::where('id',$apply->id)->update(['applyment_state'=>$result['applyment_state'],'applyment_state_desc'=>$result['applyment_state_desc']]); return $this->success($result); // $result['applyment_state']=="FINISH"; //完成签约 其它状态:CHECKING:资料校验中 ACCOUNT_NEED_VERIFY:待账户验 AUDITING:审核中 REJECTED:已驳回 NEED_SIGN:待签约 FINISH:完成 FROZEN:已冻结 } //查询进件状态 public function query123(Request $request){ // $store=Store::where('user_id',Auth::user()->id)->first(); // if(Auth::user()->id==32531){ // $store=Store::where('user_id',9900)->first(); // } $applyment_id=$request->input('applyment_id');//'20200708093101909876';//申请编号$store->applyment_id?? Log:info('iii---------iii'.$applyment_id); if(empty($applyment_id)){ return $this->error('450001',Auth::user()->id.'/当前申请认证,被驳回'); } $url='https://api.mch.weixin.qq.com/v3/ecommerce/applyments/'.$applyment_id;//查询地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); Log::info('------'.$result); $result=json_decode($result,true); return $this->success($result); if($result['applyment_state']=="ACCOUNT_NEED_VERIFY"){ Apply::where('applyment_id',$applyment_id)->update(['audit_detail'=>$result['legal_validation_url']]); } if($result['applyment_state']=="NEED_SIGN"){ Store::where('user_id',Auth::user()->id)->update(['sub_mchid'=>$result['sub_mchid'],'is_apply'=>2]); Apply::where('applyment_id',$applyment_id)->update(['sub_mchid'=>$result['sub_mchid'], 'audit_detail'=>$result['sign_url']]); } if($result['applyment_state']=="FINISH"){ Log::info($applyment_id.'-----ooooo-----'.$result['sub_mchid']); Store::where('user_id',Auth::user()->id)->update(['sub_mchid'=>$result['sub_mchid'],'is_apply'=>3]); Apply::where('applyment_id',$applyment_id)->update(['sub_mchid'=>$result['sub_mchid']]); } // if($result['applyment_state']=="AUDITING"){ // Store::where('user_id',Auth::user()->id)->update(['sub_mchid'=>$result['sub_mchid'],'is_apply'=>3]); // Apply::where('applyment_id',$applyment_id)->update(['sub_mchid'=>$result['sub_mchid']]); // } if($result['applyment_state']=="REJECTED"){//已驳回 Store::where('user_id',Auth::user()->id)->update(['is_apply'=>4]); Apply::where('applyment_id',$applyment_id)->update(['audit_detail'=>$result['audit_detail'][0]['reject_reason']]); } if($result['applyment_state']=="FROZEN"){ Store::where('user_id',Auth::user()->id)->update(['is_apply'=>5]);//已冻结 Apply::where('applyment_id',$applyment_id)->update(['audit_detail'=>$result['audit_detail'][0]['reject_reason']]); } Apply::where('applyment_id',$applyment_id)->update(['applyment_state'=>$result['applyment_state'],'applyment_state_desc'=>$result['applyment_state_desc']]); return $this->success($result); // $result['applyment_state']=="FINISH"; //完成签约 其它状态:CHECKING:资料校验中 ACCOUNT_NEED_VERIFY:待账户验 AUDITING:审核中 REJECTED:已驳回 NEED_SIGN:待签约 FINISH:完成 FROZEN:已冻结 } //加密敏感字符串 public function getEncrypts($str="张三"){ // $public_key_path='D:\phpstudy_pro\WWW\weidian-api/cert/cert.pem';//获取的文件临时保存到服务器 $public_key_path=config('wechat.payment.default.cert_pem');//这是获取平台证书临时存起来的平台公钥,通过getzhengshu()方法获取,见下文。。。注意是平台证书,不是商户证书 $public_key=file_get_contents($public_key_path); $encrypted=''; if (openssl_public_encrypt($str,$encrypted,$public_key,OPENSSL_PKCS1_OAEP_PADDING)) { //base64编码 $sign = base64_encode($encrypted); } else { throw new Exception('encrypt failed'); } return $sign; // if(openssl_public_encrypt($str,$encrypted,$public_key,OPENSSL_PKCS1_OAEP_PADDING)){ // $sign=base64_encode($encrypted); // }else{ // echo "error";exit; // } // return $sign;//返回加密的敏感字符串 } //上传证件图片 public function uploadmedia($paths){//$path="uploads/header/z.jpg" Log::info($paths); if(substr($paths,0,5)=='/cert'){ $path='/www/wwwroot/test.woaidakele.cn/app-api/public'.$paths; }else{ $path='https://qny.d0w.cc'.$paths; } // $path='/www/wwwroot/api.app.jiuweiyun.cn/app-api/public'.$path; Log::info($path); $url="https://api.mch.weixin.qq.com/v3/merchant/media/upload";//微信的上传地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//商户证书序列号,注意是商户证书,不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 // $fi=new \finfo(FILEINFO_MIME_TYPE); // $mime_type=$fi->file($path); if(substr($paths,0,5)=='/cert'){ $fi=new \finfo(FILEINFO_MIME_TYPE); $mime_type=$fi->file($path); }else{ $info = pathinfo($path); if($info['extension']=='jpg'){ $info['extension']='jpeg'; } $mime_type='image/'.$info['extension']; } Log::info($mime_type); if(substr($paths,0,5)=='/cert'){ $pathss=$path; }else{ $pathss=$path; $res = @get_headers($url,true); if($res){ if(array_key_exists('Content-Length',$res) && $res['Content-Length'] > 1024*1024){ Log::info('-----七牛云压缩图片-----'); $pathss=$path.'?imageView2/0/w/500/q/80'; } } } $meta=[ 'filename'=>pathinfo($path,2), 'sha256'=>hash_file('sha256',$pathss) ]; $sign=$this->sign($url,'POST',$timestamp,$nonce,json_encode($meta),$mch_private_key,$merchant_id,$serial_no); $boundary=uniqid(); $header=[ 'Content-Type:multipart/form-data;boundary=' . $boundary, 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id ]; Log::info($path); Log::info($pathss); $body='--' . $boundary . "\r\n"; $body.='Content-Disposition:form-data; name="meta"' . "\r\n"; $body.='Content-Type:application/json' . "\r\n\r\n"; $body.=json_encode($meta)."\r\n"; $body.='--' . $boundary . "\r\n"; $body.='Content-Disposition:form-data;name="file";filename="' . $meta['filename'] . '"' . "\r\n"; $body.='Content-Type:' .$mime_type."\r\n\r\n"; $body.=file_get_contents($pathss)."\r\n"; $body.='--'.$boundary .'--'."\r\n"; $result=$this->curl($url,$body,$header); $result=json_decode($result,true); Log::info($result['media_id']); return $result['media_id'];//返回微信返回来的图片标识 } public function getImgToMediaId(Request $request) { $app = app('wechat.official_account'); $accessTokens = $app->access_token; $access_token = $accessTokens->getToken(); $token = $access_token['access_token']; $img = $request->input('img'); $url = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=" . $token . "&media_id=" . $img; return $url; } //读取商户api证书公钥 public function getPublicKey(){ return openssl_get_privatekey(file_get_contents(config('wechat.payment.default.key_path')));//商户平台API安全证书中下载,保存到服务器 } //生成随机字符串 public function nonce_str($length=32){ $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str =""; for ( $i = 0; $i < $length; $i++ ) { $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1); } return $str; } //签名 public function sign($url,$http_method,$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no){ $url_parts=parse_url($url); $canonical_url=($url_parts['path'].(!empty($url_parts['query'])?"?${url_parts['query']}":"")); $message= $http_method . "\n". $canonical_url . "\n". $timestamp . "\n". $nonce . "\n". $body . "\n"; openssl_sign($message,$raw_sign,$mch_private_key,'sha256WithRSAEncryption'); $sign=base64_encode($raw_sign); $schema='WECHATPAY2-SHA256-RSA2048'; $token=sprintf( 'mchid="%s",nonce_str="%s",signature="%s",timestamp="%d",serial_no="%s"', $merchant_id, $nonce, $sign, $timestamp, $serial_no ); return $token; } //curl提交 public function curl($url,$data=[],$header,$method='POST'){ $curl=curl_init(); curl_setopt($curl,CURLOPT_URL,$url); curl_setopt($curl,CURLOPT_HTTPHEADER,$header); // curl_setopt($curl,CURLINFO_HEADER_OUT,true); // curl_setopt($curl,CURLOPT_HEADER,true); curl_setopt($curl,CURLOPT_RETURNTRANSFER,1); curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,false); if($method=="POST"){ curl_setopt($curl,CURLOPT_POST,TRUE); curl_setopt($curl,CURLOPT_POSTFIELDS,$data); } $result=curl_exec($curl); // $headerStr=curl_getinfo($curl,CURLINFO_HEADER_OUT); // list($responseStr,$contentStr)=explode("\r\n\r\n",$result,2); // log::info("result:".$result); // log::info("request header:".$headerStr); // log::info('response header:'.$responseStr); // log::info('response content:'.$contentStr); curl_close($curl); return $result; } public function curls($url,$data=[],$header,$method='POST'){ $curl=curl_init(); curl_setopt($curl,CURLOPT_URL,$url); curl_setopt($curl,CURLOPT_HTTPHEADER,$header); curl_setopt($curl,CURLOPT_HEADER,false); curl_setopt($curl,CURLOPT_RETURNTRANSFER,1); curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,false); if($method=="POST"){ curl_setopt($curl,CURLOPT_POST,TRUE); curl_setopt($curl,CURLOPT_POSTFIELDS,$data); } $result=curl_exec($curl); $status=curl_getinfo($curl,CURLINFO_HTTP_CODE); curl_close($curl); return [$result,$status]; } //获取平台证书 public function getzhengshu(){ $url="https://api.mch.weixin.qq.com/v3/certificates";//获取地址 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//获取一个随机字符串 $body=""; $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//商户证书序列号 $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no); $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 '.$sign, 'Accept:application/json', 'User-Agent:'.$merchant_id ]; $result=$this->curl($url,'',$header,'GET'); $result=json_decode($result,true); $serial_no=$result['data'][0]['serial_no'];//获取的平台证书序列号 $encrypt_certificate=$result['data'][0]['encrypt_certificate']; $sign_key=config('wechat.payment.default.api_v3'); //APIv3密钥,商户平台API安全中获取 $result=$this->decryptToString($encrypt_certificate['associated_data'],$encrypt_certificate['nonce'],$encrypt_certificate['ciphertext'],$sign_key); // return null;//file_get_contents('/www/wwwroot/ceshi.api.woaidakele.cn/test-h5/cert/cert.pem'); // if(empty(file_get_contents('/www/wwwroot/ceshi.api.woaidakele.cn/test-h5/cert/cert.pem'))){ // file_get_contents('/www/wwwroot/ceshi.api.woaidakele.cn/test-h5/cert/cert.pem',$result); file_put_contents(config('wechat.payment.default.cert_pem'),$result);//获取的文件临时保存到服务器 // } return $serial_no;//返回平台证书序列号 } //解密加密密钥 public function getDecrypt($ciphertext, $associatedData, $nonceStr){ $mch_private_key= file_get_contents(config('wechat.payment.default.key_path')); // Log::info($mch_private_key); $str = base64_decode($ciphertext); openssl_private_decrypt($str,$encrypted,$mch_private_key,OPENSSL_PKCS1_OAEP_PADDING); return trim($encrypted); } //解密返回的信息 public function decryptToString($associatedData,$nonceStr,$ciphertext,$aesKey){ if (strlen($aesKey) != 32) { Log::info('1--'); throw new InvalidArgumentException('无效的ApiV3Key,长度应为32个字节'); } $ciphertext=\base64_decode($ciphertext); if (strlen($ciphertext) <= 16) { Log::info('2--'); return false; } if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') && \sodium_crypto_aead_aes256gcm_is_available()) { Log::info('3--'); return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $aesKey); } if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && \Sodium\crypto_aead_aes256gcm_is_available()) { Log::info('4--'); return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $aesKey); } if(PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())){ $ctext=substr($ciphertext,0,-16); $authTag=substr($ciphertext,-16); Log::info('5--'); return \openssl_decrypt( $ctext, 'aes-256-gcm', $aesKey, \OPENSSL_RAW_DATA, $nonceStr, $authTag, $associatedData ); } Log::info('6--'); throw new \RuntimeException('php7.1'); } //设置银行账户信息 public function setBankInfo(Request $request){ Log::error($request->all()); // if (Auth::user()->id==32531){ // $user_id='13878'; // }else{ // $user_id=Auth::user()->id; // } $sub_mchid=Store::withTrashed()->where('is_failure',0)->where('user_id',Auth::user()->id)->value('sub_mchid'); $url='https://api.mch.weixin.qq.com/v3/apply4sub/sub_merchants/'.$sub_mchid.'/modify-settlement';//地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $bank_address_code= $request->input('bank_address_code'); if($bank_address_code=='1101' || $bank_address_code=='1201' || $bank_address_code=='3101' || $bank_address_code=='5001'){ $bank_address_code=substr($bank_address_code,0,2).'00'; } Log::info('开户行所在城市代码:'.$bank_address_code); $data=[ 'account_type' =>'ACCOUNT_TYPE_PRIVATE',//ACCOUNT_TYPE_BUSINESS:对公银行账户 ACCOUNT_TYPE_PRIVATE:经营者个人银行卡 'account_bank' =>$request->input('account_bank'), 'bank_address_code'=>str_pad($bank_address_code,6,"0",STR_PAD_RIGHT), // 'bank_name'=>$request->input('bank_name'), // 'bank_branch_id'=>$request->input('bank_branch_id'), 'account_number'=>$this->getEncrypts($request->input('account_number')) ]; Log::info($data); $sign=$this->sign($url,'POST',$timestamp,$nonce,json_encode($data),$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, // 'Content-Type:multipart/form-data', 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curls($url,json_encode($data),$header); Log::error('修改结算账户返回结果。'.json_encode($result)); $http_status=$result[1]; $result=json_decode($result[0],true); if($http_status==204){ Log::error('结算账户绑定成功。商户id为:'.$sub_mchid.'---http状态码为:'.$http_status); Store::withTrashed()->where('is_failure',0)->where('user_id',Auth::user()->id) ->update(['account_number'=>$request->input('account_number'),'account_bank'=>$request->input('account_bank')]); return $this->success($result); }else{ Log::error('结算账户绑定失败。http状态吗为:'.$http_status.',错误信息为'.$result['message'].',商户id为:'.$sub_mchid); return $this->error('450001',$result['message']); } } //获取银行账户信息 public function getBankInfo(){ $sub_mchid=Store::withTrashed()->where('is_failure',0)->where('user_id',Auth::user()->id)->value('sub_mchid'); // if($sub_mchid=='1607429904'){ // $sub_mchid='1609015697'; // } // if($sub_mchid=='1607448291'){ // $sub_mchid='1609035479'; // } $url='https://api.mch.weixin.qq.com/v3/apply4sub/sub_merchants/'.$sub_mchid.'/settlement';//'https://api.mch.weixin.qq.com/v3/apply4sub/sub_merchants/'.$sub_mchid.'/modify-settlement';//查询地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); Log::error(Auth::user()->id.'//'.$result); $result=json_decode($result,true); return $this->success($result); } public function uploadImg(Request $request) { $path_url = 'public/wechat/' . date("ymd"); $path = $request->file('img')->store($path_url); if ($path) { $url = Storage::url($path); return $this->success($url); } else { return $this->error(); } } //获取账户实时余额 public function getAccountInfo(){ $sub_mchid=Store::withTrashed()->where('is_failure',0)->where('user_id',Auth::user()->id)->value('sub_mchid'); $result=$this->getAccount($sub_mchid); if($result['sub_mchid']){ Store::withTrashed()->where('is_failure',0)->where('sub_mchid',$result['sub_mchid']) ->update([ 'available_amount'=>round($result['available_amount']/100,2), 'pending_amount'=>round($result['pending_amount']/100,2) ]); } return $this->success($result,$sub_mchid); } //获取账户信息 public function getAccount($sub_mchid){ $url='https://api.mch.weixin.qq.com/v3/ecommerce/fund/balance/'.$sub_mchid;//查询地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); Log::info($result); $result=json_decode($result,true); Log::info($result); return $result; } //二级商户提现 public function withdrawal(Request $request){ $sub_mchid=Store::withTrashed()->where('is_failure',0)->where('user_id',Auth::user()->id)->value('sub_mchid'); Log::info('提现金额:'.$request->input('amount')); $withdrawal_amount=str_replace( ',', '',$request->input('amount')); if(!is_numeric($withdrawal_amount)){ return $this->error('450001','提现金额为非数值'); } $amount=floor($withdrawal_amount * 100); if($amount < 1){ return $this->error('450001','提现金额有误请重新输入'); } $result=$this->getAccount($sub_mchid); if(!$result['sub_mchid']){ return $this->error('450001','结算账户信息有误,暂不能提现'); } // $phone=[]; // $agent_phone=Store::where('user_id',Auth::user()->id)->value('phone'); // if(!in_array($agent_phone,$phone)){ // if(!$result['sub_mchid']){ // return $this->error('450001','可提现金额小于200元,暂不能提现'); // } // if($result['available_amount'] < 20000){ // return $this->error('450001','可提现金额小于200元,暂不能提现'); // } // } $url='https://api.mch.weixin.qq.com/v3/ecommerce/fund/withdraw';//查询地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $out_request_no='TX'.date('ymdHis') . substr(microtime(), 2, 6).mt_rand(10000,99999); $data=[ 'sub_mchid'=>$sub_mchid, 'out_request_no'=> $out_request_no, 'amount'=> (int) $amount, 'remark'=> '二级商户提现', 'bank_memo'=> '微信二级商户提现' ]; // Log::error(json_encode($data)); $sign=$this->sign($url,'POST',$timestamp,$nonce,json_encode($data),$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,json_encode($data),$header,'POST'); $result=json_decode($result,true); if(isset($result['withdraw_id']) && !empty($result['withdraw_id'])){ $store=Store::withTrashed()->where('is_failure',0)->where('user_id',Auth::user()->id)->first(); Amount::create([ 'transaction_id'=>$result['withdraw_id'], 'order_no'=>$result['out_request_no'], 'store_id'=>$store->id, 'money'=>$amount/100, 'type'=>3,//提现 'status'=>0, 'status_code'=>'CREATE_SUCCESS', 'service_fee'=>0, 'remark'=>'提现', 'remark_amount'=>$store->account_bank.'-'.$store->account_number, ]); }else{ return $this->error('450001',$result['message']); } return $this->success($result); } //商户提现状态查询 public function getWithdrawalStates(Request $request){ $withdraw_id=$request->input('withdraw_id'); $store_id=$request->input('user_id'); // $user_id='32531'; // $index=$request->input('index'); // $size=$request->input('size'); // $refunds=Amount::where('type',3)->orderBy('id')->skip($index)->take($size)->get(); //// return $refunds; // foreach($refunds as $key=>$val){ $sub_mchid=Store::where('id',$store_id)->value('sub_mchid'); // $withdraw_id=$val->order_no; $url='https://api.mch.weixin.qq.com/v3/ecommerce/fund/withdraw/out-request-no/'.$withdraw_id.'?sub_mchid='.$sub_mchid;//查询地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); $result=json_decode($result,true); // if($val->status_code<>$result['status']){ // Log::info('提现状态有误:'.$val->store_id.'---'.$val->order_no.'---'.$result['status']); // } // Amount::where('id',$val->id)->update([ // 'transaction_id'=>$result['withdraw_id'], // ]); // } // $sub_mchid=Store::where('user_id',$user_id)->value('sub_mchid'); return $result; // if($result['status']=='FAIL' ||$result['status']=='REFUND' ||$result['status']=='CLOSE'){ // $reason=$result['reason']; // }else{ // $reason=null; // } // Amount::where('withdraw_id',$withdraw_id) // ->update([ // 'status'=>0, // 'status_code'=>$result['status'], // 'reason'=>$reason, // ]); // return $this->success($result); } //商户提现状态查询 public function getWithdrawalState(Request $request){ $withdraw_id=$request->input('withdraw_id'); $sub_mchid=Store::withTrashed()->where('is_failure',0)->where('user_id',Auth::user()->id)->value('sub_mchid'); $url='https://api.mch.weixin.qq.com/v3/ecommerce/fund/withdraw/'.$withdraw_id.'?sub_mchid='.$sub_mchid;//查询地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); $result=json_decode($result,true); if($result['status']=='FAIL' ||$result['status']=='REFUND' ||$result['status']=='CLOSE'){ $reason=$result['reason']; }else{ $reason=null; } Amount::where('withdraw_id',$withdraw_id) ->update([ 'status'=>0, 'status_code'=>$result['status'], 'reason'=>$reason, ]); return $this->success($result); } //获取收款记录 public function getAccountDetail(Request $request){ $type=$request->input('type'); $cycle=$request->input('cycle'); $page_size=$request->input('page_size'); $page_index=$request->input('page_index'); $startime=$request->input('startime'); $endtime=$request->input('endtime'); $num=$page_size*($page_index-1); $store=Store::where('user_id',Auth::user()->id)->first(); $data= Amount::where('store_id',$store->id); if($type!='all'){ $data->where('type',$type); } if($startime && $endtime){ $data->whereBetween('created_at',[date("Y-m-d 00:00:00",strtotime($startime)),date("Y-m-d 23:59:59",strtotime($endtime))]); } $cc=clone $data; $count=$data->groupBy('order_no','transaction_id','type')->get()->count(); if($type==3){ $ll['account']=$cc->where('status_code','SUCCESS')->sum('money'); }else{ $ll['account']=$cc->sum('money'); } if($type==4){ $data->with('refund_money:refund_no,order_no'); } $data->groupBy('order_no','transaction_id','type'); if($type=='all'){ $data->OrderBy('id'); }else{ $data->OrderByDesc('id'); } $list=$data->skip($num)->take($page_size)->get(); if($type==1){ foreach($list as $key=>$val){ $order_no=$val->order_no; $refund_no='TK'.substr($order_no,2); $amount=Amount::where('store_id',$store->id)->where('order_no',$refund_no)->where('type',4)->first(); if($amount){ $list[$key]->refund_no=$refund_no; $list[$key]->is_refund=1; }else{ $list[$key]->refund_no=''; $list[$key]->is_refund=0; } if($val->type==4){ } } } $ll['list']=$list; return $this->success_list($ll,'',$count); } //获取按日下载提现异常文件 public function getDownWithdraw(Request $request){ $bill_type=$request->input('bill_type'); $bill_date=$request->input('bill_date'); $tar_type=$request->input('tar_type'); $url='https://api.mch.weixin.qq.com/v3/bill/tradebill?bill_date='.$bill_date;// .'&bill_type='.$bill_type.'&tar_type='.$tar_type $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); $res=json_decode($result,true); $con= $this->down($res['download_url'],'withdraw'); return $this->success($con); } //获取资金账单 public function getfundflowbill(Request $request){ $bill_date=$request->input('bill_date'); $account_type=$request->input('account_type'); $tar_type=$request->input('tar_type'); $url='https://api.mch.weixin.qq.com/v3/bill/fundflowbill?bill_date='.$bill_date;// .'&account_type='.$bill_type.'&tar_type='.$tar_type $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); return $this->success($result); $res=json_decode($result,true); $this->down($res['download_url']); return $this->success($res); } //获取分账结算账单 public function getprofitsharing(Request $request){ $bill_date=$request->input('bill_date'); $sub_mchid=$request->input('sub_mchid'); $tar_type=$request->input('tar_type'); $url='https://api.mch.weixin.qq.com/v3/profitsharing/bills?bill_date='.$bill_date;// .'&account_type='.$bill_type.'&tar_type='.$tar_type $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); $res=json_decode($result,true); $con= $this->down($res['download_url'],'sharing'); return $this->success($con); } //获取二级商户资金账单 public function getecommercebill(Request $request){ $bill_date=$request->input('bill_date'); $account_type=$request->input('account_type'); $algorithm=$request->input('algorithm'); $url='https://api.mch.weixin.qq.com/v3/ecommerce/bill/fundflowbill?bill_date='.$bill_date.'&account_type='.$account_type.'&algorithm='.$algorithm; $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); $res=json_decode($result,true); if(!array_key_exists('download_bill_list',$res)){ Log::info($res); return $this->success($res); } Log::info($bill_date.'下载资金账单,页数为'.count($res['download_bill_list'])); foreach($res['download_bill_list'] as $key=>$val){ $ciphertext= $this->down($val['download_url']); $key=$this->getDecrypt($val['encrypt_key'],'',$val['nonce']); $result_str=$this->decryptToString('',$val['nonce'],base64_encode($ciphertext),$key); $res_arr=$this->deal_ecommerce_bill($result_str); $bill_day = $res_arr['bill'][0]['bill_date']; $trade_info = EcommerceBillW::where('bill_date',$bill_day)->first(); if(!$trade_info){ if(count($res_arr['bill']) > 1000){ $arr = array_chunk($res_arr['bill'],1000); foreach($arr as $k=>$v){ EcommerceBillW::insert($v); } }else{ EcommerceBillW::insert($res_arr['bill']); } } } // $ciphertext= $this->down($res['download_bill_list'][0]['download_url']); // $key=$this->getDecrypt($res['download_bill_list'][0]['encrypt_key'],'',$res['download_bill_list'][0]['nonce']); // $result=$this->decryptToString('',$res['download_bill_list'][0]['nonce'],base64_encode($ciphertext),$key); // $res=$this->deal_ecommerce_bill($result); // $bill_date = $res['bill'][0]['bill_date']; // $trade_info = EcommerceBillW::where('bill_date',$bill_date)->first(); // if(!$trade_info){ // if(count($res['bill']) > 1000){ // $arr = array_chunk($res['bill'],1000); // foreach($arr as $key=>$val){ // EcommerceBillW::insert($val); // } // }else{ // EcommerceBillW::insert($res['bill']); // } // } return $this->success($res); } public function down($url){ // $url=$request->input('url'); $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json;charset=utf-8', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); return $result; if($t == 'withdraw'){ $res = $this->deal_WeChat_response($result); $trade_date = $res['bill'][0]['trade_date']; $trade_info = TradeBillW::where('trade_date',$trade_date)->first(); if(!$trade_info){ if(count($res['bill']) > 1000){ $arr = array_chunk($res['bill'],1000); foreach($arr as $key=>$val){ TradeBillW::insert($val); } }else{ TradeBillW::insert($res['bill']); } } }elseif($t == 'sharing'){ $res = $this->deal_profit_sharing($result); $sharing_date = $res['sharing'][0]['sharing_date']; $sharing_info = ProfitSharingW::where('sharing_date',$sharing_date)->first(); if(!$sharing_info){ if(count($res['sharing']) > 1000){ $arr = array_chunk($res['sharing'],1000); foreach($arr as $key=>$val){ ProfitSharingW::insert($val); } }else{ ProfitSharingW::insert($res['sharing']); } } } return $res; } public function deal_WeChat_response($response){ $result = array(); $response = str_replace(","," ",$response); $response = explode(PHP_EOL, $response); foreach ($response as $key=>$val){ if(strpos($val, '`') !== false){ $data = explode('`', $val); array_shift($data); // 删除第一个元素并下标从0开始 if(count($data) == 27){ // 处理账单数据 $result['bill'][] = array( 'pay_time' => $data[0], // 支付时间 'app_id' => $data[1], // app_id 'mch_id' => $data[2], // 商户id 'sub_mch_id' => $data[3], // 特约商户id 'imei' => $data[4], // 设备号 'order_sn_wx' => $data[5], // 微信订单号 'order_sn_sh' => $data[6], // 商户订单号 'user_tag' => $data[7], // 用户标识 'pay_type' => $data[8], // 交易类型 'pay_status' => $data[9], // 交易状态 'bank' => $data[10], // 付款银行 'money_type' => $data[11], // 货币种类 'total_amount' => $data[12], // 应结订单金额 'coupon_amount' => $data[13], // 代金券金额 'refund_number_wx' => $data[14], // 微信退款单号 'refund_number_sh' => $data[15], // 商户退款单号 'refund_amount' => $data[16], // 退款金额 'coupon_refund_amount' => $data[17], // 充值券退款退款金额 'refund_type' => $data[18], // 退款类型 'refund_status' => $data[19], // 退款状态 'goods_name' => $data[20], // 商品名称 'goods_data_bag' => $data[21], // 商户数据包 'service_charge' => $data[22], // 手续费 'rate' => $data[23], // 费率 'order_account' => $data[24], // 订单金额 'apply_refund_account' => $data[25], // 申请退款金额 'rate_remark' => $data[26], // 费率备注 'trade_date' => date("Y-m-d", strtotime($data[0])) ); } if(count($data) == 7){ // 统计数据 $result['summary'] = array( 'order_num' => $data[0], // 总交易单数 'turnover' => $data[1], // 应结订单总金额 'refund_turnover' => $data[2], // 退款总金额 'coupon_turnover' => $data[3], // 充值券退款总金额 'rate_turnover' => $data[4], // 手续费总金额 'order_turnover' => $data[5], // 订单总金额 'apply_refund_turnover' => $data[6], // 申请退款总金额 ); } } } return $result; } public function deal_profit_sharing($response) { $result = array(); $response = str_replace(",", " ", $response); $response = explode(PHP_EOL, $response); foreach ($response as $key => $val) { if (strpos($val, '`') !== false) { $data = explode('`', $val); array_shift($data); // 删除第一个元素并下标从0开始 if (count($data) == 9) { // 处理账单数据 $result['sharing'][] = array( 'sharing_time' => $data[0], // 分账时间 'sharing_originator' => $data[1], // 分账发起方 'sharing_user' => $data[2], // 分账方 'wx_order_no' => $data[3], // 微信订单号 'wx_refund_no' => $data[4], // 微信分账方/回退单号 'sharing_detail_no' => $data[5], // 分账明细单号 'mch_refund_no' => $data[6], // 商户分账/回退单号 'order_amount' => $data[7], // 订单金额 'sharing_recipient' => explode(' ',$data[8])[0], // 分账接收方 'amount' => explode(' ',$data[8])[1], // 金额 'sharing_type' => explode(' ',$data[8])[2], // 业务类型 'sharing_status' => explode(' ',$data[8])[3], // 处理状态 'sharing_desc' => explode(' ',$data[8])[4], // 分账描述 'remark' => explode(' ',$data[8])[5], // 备注 'sharing_date' => date("Y-m-d", strtotime($data[0])), // 分账日期 ); } if(count($data) == 5){ // 统计数据 $result['summary'] = array( 'sharing_num' => $data[0], // 总条数 'sharing_success_amount' => $data[1], // 分账成功出资金 'sharing_fail_turnover' => $data[2], // 分账失败已转回分账方 'thaw_funds_amount' => $data[3], // 解冻资金给分账方 'refund_amount' => $data[4], // 分账回退资金 ); } } } return $result; } public function deal_ecommerce_bill($response){ $result = array(); $response = str_replace(","," ",$response); $response = explode(PHP_EOL, $response); foreach ($response as $key=>$val){ if(strpos($val, '`') !== false){ $data = explode('`', $val); array_shift($data); // 删除第一个元素并下标从0开始 if(count($data) == 13){ // 处理账单数据 $result['bill'][] = array( 'bill_time' => $data[0], // 记账时间 'wx_order_no' => $data[1], // 微信支付业务单号 'fee_order_no' => $data[2], // 资金流水单号 'bill_name' => $data[3], // 业务名称 'bill_type' => $data[4], // 业务类型 'fee_type' => $data[5], // 收支类型 'amount' => $data[6], // 收支金额(元) 'account_fee' => $data[7], // 账户结余(元) 'apply_name' => $data[8], // 资金变更提交申请人 'remark' => $data[9], // 备注 'bill_cre_no' => $data[10], // 业务凭证号 'sub_mch_id' => $data[11], // 电商二级商户号 'account_type' => $data[12], // 账户类型 'bill_date' => date("Y-m-d", strtotime($data[0])) ); } if(count($data) == 1){ // 统计数据 $result['summary'] = array( 'order_num' => $data[0], // 资金流水总笔数 ); } } } return $result; } //开启点金计划 public function dianjin(Request $request){ $sub_mchid=Store::where('user_id',Auth::user()->id)->value('sub_mchid'); $url='https://api.mch.weixin.qq.com/v3/goldplan/merchants/changegoldplanstatus';//查询地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $data=[ 'sub_mchid'=>$sub_mchid, 'operation_type'=>'OPEN' ]; $sign=$this->sign($url,'POST',$timestamp,$nonce,json_encode($data),$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,json_encode($data),$header,'POST'); $result=json_decode($result,true); if(isset($result['sub_mchid']) && !empty($result['sub_mchid'])){ Store::where('sub_mchid',$sub_mchid)->update(['is_dianjin'=>1]); return $this->success($result); }else{ return $this->error('450001',$result['message']); } } //开启商家小票 public function businessTips(){ $sub_mchid=Store::where('user_id',Auth::user()->id)->value('sub_mchid'); $url='https://api.mch.weixin.qq.com/v3/goldplan/merchants/changecustompagestatus';//点金地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $data=[ 'sub_mchid'=>$sub_mchid, 'operation_type'=> 'OPEN' ]; $sign=$this->sign($url,'POST',$timestamp,$nonce,json_encode($data),$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,json_encode($data),$header,'POST'); $result=json_decode($result,true); if(isset($result['sub_mchid']) && !empty($result['sub_mchid'])){ Store::where('sub_mchid',$sub_mchid)->update(['is_business'=>1]); return $this->success($result); }else{ return $this->error('450001',$result['message']); } } //关闭广告 public function adverting(Request $request){ $sub_mchid=Store::where('user_id',Auth::user()->id)->value('sub_mchid'); $url='https://api.mch.weixin.qq.com/v3/goldplan/merchants/close-advertising-show';//查询地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $data=[ 'sub_mchid'=>$sub_mchid ]; $sign=$this->sign($url,'POST',$timestamp,$nonce,json_encode($data),$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,json_encode($data),$header,'POST'); $result=json_decode($result,true); if(empty($result)){ Store::where('sub_mchid',$sub_mchid)->update(['is_adverting'=>1]); return $this->success($result); }else{ // Log::info(Auth::user()->nickname.'关闭广告失败:'.json_encode($result)); return $this->error('450001',$result['message']); } } //手动退款 public function refundAmountManual(Request $request){ $order_no=$request->input('order_no'); $order=OrderW::where('order_no',$order_no)->first(); $sub_mchid=Store::where('id',$order->store_id)->value('sub_mchid'); if(empty($sub_mchid)){ return $this->error('450001','店铺信息有误,暂不能退款'); } if(in_array($order->status,[1,2,3]) && $order->is_pay==1){ $amount=["refund"=> (int) ($order->pay_money*100),"total"=> (int)($order->pay_money*100),"currency"=> "CNY"]; }else{ return $this->error('450001','订单状态有误,暂不能退款'); } // $pay_money=$request->input('pay_money'); // $sub_mchid = $request->input('sub_mchid'); $wechat_pay_no = $order->wechat_pay_no; // $out_refund_no = $request->input('out_refund_no'); $url='https://api.mch.weixin.qq.com/v3/ecommerce/refunds/apply';//查询地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $data=[ 'sub_mchid'=>$sub_mchid, 'sp_appid'=>config('wechat.payment.default.app_id'), 'transaction_id'=>$wechat_pay_no, // 'out_trade_no'=> $order_no, 'out_refund_no'=> 'TK'.substr($order_no,2), 'amount'=> $amount, ]; // return $this->success($data); $sign=$this->sign($url,'POST',$timestamp,$nonce,json_encode($data),$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,json_encode($data),$header,'POST'); $result=json_decode($result,true); return $this->success($result); if(isset($result['refund_id']) && !empty($result['refund_id'])){ return $this->success($result); } return $this->error(); } //退款 public function refundAmount(Request $request){ $order_no=$request->input('order_no'); $order=OrderW::where('order_no',$order_no)->first(); $sub_mchid=Store::where('id',$order->store_id)->value('sub_mchid'); if(empty($sub_mchid)){ return $this->error('450001','店铺信息有误,暂不能退款'); } if(in_array($order->status,[1,2,3]) && $order->is_pay==1){ $amount=["refund"=> (int) ($order->pay_money*100),"total"=> (int)($order->pay_money*100),"currency"=> "CNY"]; }else{ return $this->error('450001','订单状态有误,暂不能退款'); } $url='https://api.mch.weixin.qq.com/v3/ecommerce/refunds/apply';//查询地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $data=[ 'sub_mchid'=>$sub_mchid, 'sp_appid'=>config('wechat.payment.default.app_id'), 'transaction_id'=>$order->wechat_pay_no, // 'out_trade_no'=> $order_no, 'out_refund_no'=> 'TK'.substr($order_no,2), 'amount'=> $amount, 'notify_url'=>url('api/miniSub/refund_notify') ]; $sign=$this->sign($url,'POST',$timestamp,$nonce,json_encode($data),$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,json_encode($data),$header,'POST'); $result=json_decode($result,true); if(isset($result['refund_id']) && !empty($result['refund_id'])){ // OrderW::where('order_no',$order_no) // ->update(['refund_status'=>'START','refund_no'=>$result['refund_id'],'refund_time'=>$result['create_time']]); OrderRefundMoneyW::create([ 'order_no'=>$order_no, 'refund_status'=>'START', 'refund_time'=>$result['create_time'], 'refund_no'=>$result['refund_id'], 'refund_account'=>null, 'refund_amount'=>null ]); return $this->success($result); }else{ return $this->error('450001',$result['message']); } } //退款状态查询 public function getRefundState(Request $request){ $out_refund_no=$request->input('out_refund_no'); $sub_mchid=$request->input('sub_mchid'); $url='https://api.mch.weixin.qq.com/v3/ecommerce/refunds/out-refund-no/'.$out_refund_no.'?sub_mchid='.$sub_mchid; $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); $result=json_decode($result,true); return $result; // if($result['status']=='FAIL' ||$result['status']=='REFUND' ||$result['status']=='CLOSE'){ // $reason=$result['reason']; // }else{ // $reason=null; // } // Amount::where('withdraw_id',$withdraw_id) // ->update([ // 'status'=>0, // 'status_code'=>$result['status'], // 'reason'=>$reason, // ]); // return $this->success($result); } //微信支付状态查询 public function getPayState(Request $request){ $out_refund_no=$request->input('out_refund_no'); $sub_mchid=$request->input('sub_mchid'); $sp_mchid=config('wechat.payment.default.mch_id'); // $url='https://api.mch.weixin.qq.com/v3/pay/partner/transactions/out-trade-no/'.$out_refund_no.'?sp_mchid='.$sp_mchid.'&sub_mchid='.$sub_mchid; $url=' https://api.mch.weixin.qq.com/v3/pay/partner/transactions/id/'.$out_refund_no.'?sp_mchid='.$sp_mchid.'&sub_mchid='.$sub_mchid; $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); $result=json_decode($result,true); return $result; // if($result['status']=='FAIL' ||$result['status']=='REFUND' ||$result['status']=='CLOSE'){ // $reason=$result['reason']; // }else{ // $reason=null; // } // Amount::where('withdraw_id',$withdraw_id) // ->update([ // 'status'=>0, // 'status_code'=>$result['status'], // 'reason'=>$reason, // ]); // return $this->success($result); } //退款通知 public function refundNotify(){ Log::info('开始退款通知'); defined('BASE_PATH') || define('BASE_PATH', getenv('BASE_PATH') ?: realpath(dirname(__FILE__) . '/../..')); //接收微信返回的数据数据,返回的xml格式 $xmlData = file_get_contents('php://input'); //将xml格式转换为数组 $xmlData=json_decode($xmlData,true); $data=$xmlData['resource']; $sign_key=config('wechat.payment.default.api_v3'); //APIv3密钥,商户平台API安全中获取 $result=$this->decryptToString($data['associated_data'],$data['nonce'],$data['ciphertext'],$sign_key); $result=json_decode($result,true); log::info(json_encode($result)); if($result['refund_status']=='SUCCESS'){ if(strpos($result['out_trade_no'],'_')){ $result['out_trade_no']=explode('_',$result['out_trade_no'])['1']; } $order=OrderW::withTrashed()->where('order_no',$result['out_trade_no'])->first(); // $order->refund_status =$result['refund_status']; // $order->refund_time =$result['success_time']; // $order->refund_no =$result['refund_id']; // $order->refund_account =$result['user_received_account']; // $order->refund_amount =json_encode($result['amount']); // $order->save(); DB::connection('mysql_w')->transaction(function()use($order,$result) { OrderRefundMoneyW::where('order_no', $result['out_trade_no'])->where('refund_no', $result['refund_id']) ->update([ 'refund_status' => $result['refund_status'], 'refund_time' => $result['success_time'], 'refund_account' => $result['user_received_account'], 'refund_amount' => json_encode($result['amount']), ]); //学分变更 // $integral = $order->total * 2; $integral = 0; $inte = IntegralW::where('order_no', $order->order_no)->where('store_id', $order->store_id)->where('type', 2)->first(); if (empty($inte)) { $inte_add = IntegralW::where('order_no', $order->order_no)->where('store_id', $order->store_id)->where('type', 1)->first(); if($inte_add){ // $integral_double= $inte_add->integral_double; $integral= $inte_add->integral; $integral_double= $inte_add->integral_double; $is_zbs = $inte_add->is_zbs; }else{ $integral_double= $integral; $is_zbs = 0; } IntegralW::create([ 'store_id' => $order->store_id, 'order_no' => $order->order_no, 'num' => 0 - $order->total, 'integral' => 0 - $integral, 'integral_double' => 0 - $integral_double, 'type' => 2, 'remark' => '取消订单', 'is_zbs' => $is_zbs, ]); } //店铺信息q $total_fee = round($result['amount']['refund'] / 100, 2); $store = Store::where('id', $order->store_id)->lockForUpdate()->first(); $start_money = $store->pending_amount; $store->pending_amount -= $total_fee; $store->integral -= $integral; $store->cycle_inte -= $integral; $store->total -= $order->total; $store->save(); //退款日志 Amount::create([ 'user_id' => $order->user_id, 'store_id' => $order->store_id, 'order_no' => $result['out_refund_no'], 'transaction_id' => $result['refund_id'], 'money' => $total_fee, 'type' => 4, //退款 'status' => 1, //成功 'service_fee' => 0, 'start_money' => $start_money,//支付前冻结金额 'end_money' => $store->pending_amount,//支付后冻结金额 'start_amount' => $store->available_amount,//支付前可用金额 'end_amount' => $store->available_amount,//支付后可用金额 'remark' => '退款', ]); },5); Log::info('完成退款通知'); return response()->json(["code"=>"SUCCESS","message"=> "ERROR_DESCRIPTION",],200); }else{ OrderW::where('order_no',$result['out_trade_no'])->update([ 'refund_status'=> $result['refund_status'], 'refund_no'=> $result['refund_id'], ]); Log::info('退款通知失败'); return response()->json(["code"=>"SUCCESS","message"=> "ERROR_DESCRIPTION",],200); } //为了防止假数据,验证签名是否和返回的一样。 //记录一下,返回回来的签名,生成签名的时候,必须剔除sign字段。 // $sign = $data['sign']; // unset($data['sign']); // if($sign == self::getSign($data,config('wechat.payment.default.app_v3'))){ // //签名验证成功后,判断返回微信返回的 // if ($data['result_code'] == 'SUCCESS') { // //根据返回的订单号做业务逻辑 // Log::info(json_encode($data)); // }else{//支付失败,输出错误信息 // fwrite($file,date("Y-m-d H:i:s")."错误信息:支付失败,".json_encode($data).PHP_EOL); // } // }else{ // fwrite($file,date("Y-m-d H:i:s")."错误信息:签名验证失败,".json_encode($data).PHP_EOL); // } } //查询分账 public function fenzhang() { $sub_mchid = '1608091453'; $transaction_id = '4200000933202104068603011660'; $out_order_no = 'WJ21040615412878976147481'; $url = 'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/orders?sub_mchid=' . $sub_mchid . '&transaction_id=' . $transaction_id . '&out_order_no=' . $out_order_no;//查询地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key = $this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp = time();//时间戳 $nonce = $this->nonce_str();//随机字符串 $body = ""; $sign = $this->sign($url, 'GET', $timestamp, $nonce, $body, $mch_private_key, $merchant_id, $serial_no);//签名 $header = [ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result = $this->curl($url, '', $header, 'GET'); $result = json_decode($result, true); return $this->success($result); } //查询分账 public function searchFenzhang(Request $request) { $sub_mchid = $request->input('sub_mchid'); $transaction_id = $request->input('transaction_id'); $out_order_no = $request->input('out_order_no'); $url = 'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/orders?sub_mchid=' . $sub_mchid . '&transaction_id=' . $transaction_id . '&out_order_no=' . $out_order_no;//查询地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key = $this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp = time();//时间戳 $nonce = $this->nonce_str();//随机字符串 $body = ""; $sign = $this->sign($url, 'GET', $timestamp, $nonce, $body, $mch_private_key, $merchant_id, $serial_no);//签名 $header = [ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result = $this->curl($url, '', $header, 'GET'); $result = json_decode($result, true); return $this->success($result); } //完结分账信息 public function finish(Request $request) { $order_no=$request->input('order_no'); event(new FinishAccount($order_no)); return $this->success('完结结束'); } //只完结不记录数据 public function simpleFinish(Request $request) { $wechat_pay_no= '4200001141202110183876870599'; $sub_mchid = '1609518357'; $order_no='6530_DX21101815293983868465657'; $url = 'https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/finish-order';//地址 $merchant_id = config('wechat.payment.default.mch_id');//商户号 $serial_no = config('wechat.payment.default.serial_no');//不是平台证书序列号 $handler = new SignHandler(); $mch_private_key = $handler->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp = time();//时间戳 $nonce = $handler->nonce_str();//随机字符串 $data = [ 'sub_mchid' => $sub_mchid, 'transaction_id' => $wechat_pay_no,//微信支付单号 'out_order_no' => 'WJ' . $order_no,//订单号 'description' => '分账完结', ]; $sign = $handler->sign($url, 'POST', $timestamp, $nonce, json_encode($data), $mch_private_key, $merchant_id, $serial_no);//签名 $header = [ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $handler->getzhengshu()//获取平台证书序列号 ]; $result = $handler->curl($url, json_encode($data), $header); Log::info($result); $result = json_decode($result, true); return $result; } public function setBankInfodemo(Request $request){ $id=Auth::user()->id; $sub_mchid=Store::where('user_id',$id)->value('sub_mchid'); $url='https://api.mch.weixin.qq.com/v3/apply4sub/sub_merchants/'.$sub_mchid.'/modify-settlement';//地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $bank_address_code= $request->input('bank_address_code'); if($bank_address_code=='1101' || $bank_address_code=='1201' || $bank_address_code=='3101' || $bank_address_code=='5001'){ $bank_address_code=substr($bank_address_code,0,2).'00'; } $data=[ 'account_type' =>'ACCOUNT_TYPE_PRIVATE',//ACCOUNT_TYPE_BUSINESS:对公银行账户 ACCOUNT_TYPE_PRIVATE:经营者个人银行卡 'account_bank' =>$request->input('account_bank'), 'bank_address_code'=>str_pad($bank_address_code,6,"0",STR_PAD_RIGHT), 'bank_name'=>$request->input('bank_name'), 'bank_branch_id'=>$request->input('bank_branch_id'), 'account_number'=>$this->getEncrypts($request->input('account_number')) ]; $sign=$this->sign($url,'POST',$timestamp,$nonce,json_encode($data),$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curls($url,json_encode($data),$header); $http_status=$result[1]; $result=json_decode($result[0],true); return $result; if($http_status==204){ Log::error('结算账户绑定成功。商户id为:'.$sub_mchid.'---http状态码为:'.$http_status); Store::where('user_id',$id) ->update(['account_number'=>$request->input('account_number'),'account_bank'=>$request->input('account_bank')]); return $this->success($result); }else{ Log::error('结算账户绑定失败。http状态吗为:'.$http_status.',错误信息为'.$result['message'].'商户id为:'.$sub_mchid); return $this->error('450001',$result['message']); } } public function searchAccount(){ $user=User::find(13878); $token = Auth::guard('api')->fromUser($user); dd($token); } public function getBankInfodemo(Request $request){ $sub_mchid=Store::where('user_id',$request->id)->value('sub_mchid'); $url='https://api.mch.weixin.qq.com/v3/apply4sub/sub_merchants/'.$sub_mchid.'/settlement';//'https://api.mch.weixin.qq.com/v3/apply4sub/sub_merchants/'.$sub_mchid.'/modify-settlement';//查询地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); dd($result); $result=json_decode($result,true); return $this->success($result); } //获取支持个人业务的银行列表 public function getPersonBankList(){ $offset=0; $limit=100; $url='https://api.mch.weixin.qq.com/v3/capital/capitallhh/banks/personal-banking?offset='.$offset.'&limit='.$limit; $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); $result=json_decode($result,true); return $this->success($result); } //获取省份列表 public function getProvinceList(){ $url='https://api.mch.weixin.qq.com/v3/capital/capitallhh/areas/provinces'; $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); $result=json_decode($result,true); return $this->success($result); } //获取对应城市列表 public function getCityList(Request $request){ $province_code=$request->input('province_code'); $url='https://api.mch.weixin.qq.com/v3/capital/capitallhh/areas/provinces/'.$province_code.'/cities'; $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); $result=json_decode($result,true); foreach($result['data'] as $key=>$val){ CityW::where('city',$val['city_name'])->update(['link_code'=>$val['city_code']]); } return $this->success($result); } //获取对应支行列表 public function getBankBranchList(Request $request){ $bank_alias_code=$request->input('bank_alias_code'); $city_code=$request->input('city_code'); $offset=$request->input('offset'); $limit=$request->input('limit'); $url='https://api.mch.weixin.qq.com/v3/capital/capitallhh/banks/'.$bank_alias_code.'/branches?city_code='.$city_code.'&offset='.$offset.'&limit='.$limit; $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $body=""; $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curl($url,'',$header,'GET'); $result=json_decode($result,true); return $this->success($result); } //修改银行账户信息 public function setBankInfoTest(Request $request){ Log::error($request->all()); // if (Auth::user()->id==32531){ // $user_id='13878'; // }else{ // $user_id=Auth::user()->id; // } $sub_mchid=Store::withTrashed()->where('is_failure',0)->where('user_id',Auth::user()->id)->value('sub_mchid'); $url='https://api.mch.weixin.qq.com/v3/apply4sub/sub_merchants/'.$sub_mchid.'/modify-settlement';//地址 $merchant_id=config('wechat.payment.default.mch_id');//商户号 $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 $timestamp=time();//时间戳 $nonce=$this->nonce_str();//随机字符串 $bank_address_code= $request->input('bank_address_code'); if($bank_address_code=='1101' || $bank_address_code=='1201' || $bank_address_code=='3101' || $bank_address_code=='5001'){ $bank_address_code=substr($bank_address_code,0,2).'00'; } Log::info($bank_address_code); $data=[ 'account_type' =>'ACCOUNT_TYPE_PRIVATE',//ACCOUNT_TYPE_BUSINESS:对公银行账户 ACCOUNT_TYPE_PRIVATE:经营者个人银行卡 'account_bank' =>$request->input('account_bank'), 'bank_address_code'=>str_pad($bank_address_code,6,"0",STR_PAD_RIGHT), // 'bank_name'=>$request->input('bank_name'), // 'bank_branch_id'=>$request->input('bank_branch_id'), 'account_number'=>$this->getEncrypts($request->input('account_number')) ]; return $data; Log::info($data); $sign=$this->sign($url,'POST',$timestamp,$nonce,json_encode($data),$mch_private_key,$merchant_id,$serial_no);//签名 $header=[ 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign, 'Accept:application/json', 'User-Agent:' . $merchant_id, // 'Content-Type:multipart/form-data', 'Content-Type:application/json', 'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书序列号 ]; $result=$this->curls($url,json_encode($data),$header); Log::error('修改结算账户返回结果。'.json_encode($result)); $http_status=$result[1]; $result=json_decode($result[0],true); if($http_status==204){ Log::error('结算账户绑定成功。商户id为:'.$sub_mchid.'---http状态码为:'.$http_status); Store::withTrashed()->where('is_failure',0)->where('user_id',Auth::user()->id) ->update(['account_number'=>$request->input('account_number'),'account_bank'=>$request->input('account_bank')]); return $this->success($result); }else{ Log::error('结算账户绑定失败。http状态吗为:'.$http_status.',错误信息为'.$result['message'].',商户id为:'.$sub_mchid); return $this->error('450001',$result['message']); } } // public function pay(Request $request){ // $order_no=$request->input('order_no'); // $order=OrderW::where('order_no',$order_no)->first(); // $store=Store::where('id',$order->store_id)->first(); // $openid=User::where('id',Auth::user()->id)->value('openid'); // $info=array(//订单信息 // "sp_mchid" => config('wechat.payment.test.mch_id'),//服务商的商户号 // "sp_appid" => config('wechat.payment.test.app_id'),//服务商的appid // "sub_mchid" => $store->sub_mchid,//二级商户的商户号 // "description" => "测试JSAPI下单API接口",// // "out_trade_no" => $order_no,//商户订单号 // "amount" => array(//支付信息 // "total" =>1,//支付金额 单位为分 int类型 // "currency" =>"CNY"//币种 CNY人民币 // ), // "payer" =>array(//支付用户的信息 // "sp_openid"=>$openid //用户在服务商appid下的唯一标识 // ), // "notify_url" => url('api/payment/notifyUrl') //支付回调地址 支付成功后 微信通知你服务器的地址 // ); // Log::info($info); // $json=json_encode($info); // $url="https://api.mch.weixin.qq.com/v3/pay/partner/transactions/jsapi"; // // $appid=config('wechat.payment.test.app_id'); // $merchant_id=config('wechat.payment.default.mch_id');//商户号 // $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号 // $mch_private_key=$this->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文 // $timestamp=time();//时间戳 // $nonce=$this->nonce_str();//随机字符串 // // $sign=$this->sign($url,'POST',$timestamp,$nonce,$json,$mch_private_key,$merchant_id,$serial_no);//签名 // $header=[ // 'Authorization:WECHATPAY2-SHA256-RSA2048 '.$sign, // 'Accept:application/json', // 'User-Agent:'.$merchant_id, // 'Content-Type:application/json', // ]; // $result=$this->curl($url,$json,$header,'POST'); // $result=json_decode($result,true); // Log::info($result); // $prepayID="prepay_id=".$result['prepay_id'];//字符串拼接 // $key="微信证书v3 32位密钥字符串"; //微信证书v3密钥 在微信商户平台 API安全中设置的 // $qianming=$this->signJS($appid,$timestamp,$nonce,$prepayID,$mch_private_key);//二次签名 // //一下几个参数需要传到前端 js中使用 // $data['timestamp'] = $timestamp;//上文生成的时间戳 // $data['nonceStr'] = $nonce;//上文生成的随机字符串 // $data['package'] = $prepayID;//微信返回的预支付订单标识 // $data['signType'] = "RSA";//签名方式 // $data['paySign'] = $qianming;//二次签名 // $data['appId'] = $appid;//商户的appid // Log::info($data); // return response()->json([ // 'error_code'=>200, // 'code'=>200, // 'msg'=>'成功', // 'data'=>$data // ]); // } // 二次签名 // public function signJS($wxid,$timeStamp,$nonce,$package,$mch_private_key){ // $message= // $wxid . "\n". // $timeStamp . "\n". // $nonce . "\n". // $package . "\n"; // openssl_sign($message,$raw_sign,$mch_private_key,'sha256'); // $sign=base64_encode($raw_sign); // return $sign; // } //回调地址 public function notifyUrl(){ $header = $this->getHeaders();//读取http头信息 见下文 $body = file_get_contents('php://input');//读取微信传过来的信息,是一个json字符串 Log::info($header); Log::info($body); if (empty($header)|| empty($body)) { throw new Exception('通知参数为空', 2001); } $timestamp = $header['WECHATPAY-TIMESTAMP']; $nonce = $header['WECHATPAY-NONCE']; $signature = $header['WECHATPAY-SIGNATURE']; $serialNo = $header['WECHATPAY-SERIAL']; if (empty($timestamp) || empty($nonce) || empty($signature) || empty($serialNo)) { Log::info('通知头参数为空'); return ; } $cert = $this->getzhengshu(); if($cert!=$serialNo){ Log::info('验签失败'); return ; } $decodeBody = json_decode($body,true); if (empty($decodeBody) || !isset($decodeBody['resource'])) { Log::info('通知参数内容为空'); return ; } $sign_key=config('wechat.payment.default.api_v3'); //APIv3密钥,商户平台API安全中获取 $decodeBodyResource = $decodeBody['resource']; $decodeData = $this->decryptToString($decodeBodyResource['associated_data'], $decodeBodyResource['nonce'],$decodeBodyResource['ciphertext'], $sign_key);//解密resource $decodeData = json_decode($decodeData, true); Log::info($decodeData); $arr=array("code"=>"SUCCESS","message"=>""); return json_encode($arr); } //获取微信回调http头信息 public function getHeaders(){ $headers = array(); foreach ($_SERVER as $key => $value) { if ('HTTP_' == substr($key, 0, 5)) { $headers[str_replace('_', '-', substr($key, 5))] = $value; } if (isset($_SERVER['PHP_AUTH_DIGEST'])) { $header['AUTHORIZATION'] = $_SERVER['PHP_AUTH_DIGEST']; } elseif (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) { $header['AUTHORIZATION'] = base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $_SERVER['PHP_AUTH_PW']); } if (isset($_SERVER['CONTENT_LENGTH'])) { $header['CONTENT-LENGTH'] = $_SERVER['CONTENT_LENGTH']; } if (isset($_SERVER['CONTENT_TYPE'])) { $header['CONTENT-TYPE'] = $_SERVER['CONTENT_TYPE']; } } return $headers; } public function uploadAgentCard(Request $request) { //上传文件 if (!$request->hasFile('file')) { return $this->error('450001','请上传文件'); } //设置文件后缀白名单 $allowExt = ["jpg","png","jpeg"]; //获取文件 $file = $request->file('file'); // 获取七牛云配置信息 $config = config('filesystems.disks.qiniu'); // 构建鉴权对象 $auth = new Auths($config['access_key'], $config['secret_key']); // 生成上传 Token $token = $auth->uploadToken($config['bucket']); //获取文件的绝对路径,但是获取到的在本地不能打开 $filePath = $file->getRealPath(); //获取文件的扩展名 $ext = $file->getClientOriginalExtension(); //获取上传文件的名称 $ext_name = $file->getClientOriginalName(); Log::info('上传文件的名称->'.$ext_name); //判断是否是Excel if (empty($ext) || !in_array(strtolower($ext), $allowExt)) { return $this->error('450001','不允许的文件类型'); } // 新文件名 $filename =date('ymdHis') . uniqid(mt_rand('100','999')) .'.'. $ext; $dirname=$config['dirname']; // 初始化 UploadManager 对象并进行文件的上传。 $uploadMgr = new UploadManager(); // 调用 UploadManager 的 putFile 方法进行文件的上传。 $uploadMgr->putFile($token, $dirname.'/'.$filename, $filePath); // 获取文件完整路径 $filePath = $config['domain'].'/'.$dirname.'/'.$filename; // 返回上传到云存储的文件名 return $this->success($filePath); } }