$config['appId'], 'secret' => $config['appSecret'], 'token' => 'easywechat', 'response_type' => 'array', 'log' => [ 'level' => 'warning', 'file' =>__DIR__.'/wechat.log', ], ]; $app = Factory::officialAccount($options); return $app; } //公众号自动回复 public static function reply($uniacid,$content){ $app = self::getWechatConfig($uniacid); $server = $app->server; $user = $app->user; $server->push(function($message) use ($content) { // $fromUser = $user->get($message['FromUserName']); //return "{$fromUser->nickname} 您好!欢迎关注 overtrue!"; return $content; }); $response = $app->server->serve(); $response->send(); return $response; } //获取微信公众号用户信息 public static function getUserInfo($uniacid,$openId,$type=1){ $app =self::getWechatConfig($uniacid); if($type==1){ if(is_array($openId)){ //获取多个 $user = $app->user->select($openId); }else{ $user = $app->user->get($openId); } }else{ //获取微信公众号用户列表 $user = $app->user->list(); } return $user; } //小程序参数 public static function getMiniConfig($uniacid){ $config=Config::getSystemSet('miniConfig',$uniacid); return [ 'app_id' => $config['appId'], 'secret' => $config['appSecret'], 'response_type' => 'array', 'log' => [ 'level' => 'warning', 'file' => __DIR__.'/wechat.log', ], ]; } //退款查询 public static function refundSerach($uniacid,$outTradeNumber){ $app = Factory::miniProgram(self::getMerchantConfigure($uniacid)); $result=$app->queryByOutTradeNumber($outTradeNumber); return $result; } //小程序参数 public static function getMerchantConfigure($uniacid=0){ $config=Config::getSystemSet('merchantConfig',$uniacid); return [ 'app_id' => $config['miniAppId'], 'secret' => $config['miniSecret'], 'response_type' => 'array', 'log' => [ 'level' => 'warning', 'file' => __DIR__.'/wechat.log', ], ]; } //小程序登录 public static function merchantLogin($uniacid,$code){ $app = Factory::miniProgram(self::getMerchantConfigure($uniacid)); return $app->auth->session($code); } //公众号模板消息参数 public static function getWeChatTemplateConfig($uniacid){ $config=Config::getSystemSet('storeTemplates',$uniacid); if(!$config){ echo json_encode(['code'=>2,'msg'=>'请在管理后台配置商家端小程序配置']);die; } return [ 'app_id' => $config['appId'], 'secret' => $config['appSecret'], 'response_type' => 'array' ]; } /** 支付参数 * @param $uniacid [平台id] * @param int $origin [1.小程序支付2.公众号支付] * @param null $storeId [商家id] * @param null $payType [退款专用 1.普通支付2.服务商支付] * @param null $subMchId [退款专用 支付时的商户号] * @return array */ public static function getWxPayConfig($uniacid,$origin=1,$storeId=null,$payType=null,$subMchId=null){ $payConfig=Config::getSystemSet('payConfig',$uniacid);//服务商配置 $config=Config::getSystemSet('miniConfig',$uniacid); if($origin==2){ //公众号支付 $config=Config::getSystemSet('weChatConfig',$uniacid); } $storeSet=[]; if($storeId){ $storeSet=Config::getStoreSet('serviceCharge',$storeId);//商户子商户号设置 } if(($storeSet['sonService']==1 AND $storeSet['subMchId']) || ($payConfig['sonMchId'] AND $payConfig['wxPayType']==2 AND $payConfig['payOpen']==1) || $payType==2 ){ if(!$subMchId){ $subMchId=$storeSet['subMchId']?:$payConfig['sonMchId']; } //echo $subMchId;die; //服务商支付 return [ // 必要配置 'app_id' => $payConfig['serviceAppId'],//服务商appId 'sub_appid' => $config['appId'],//小程序或公众号appId 'mch_id' => $payConfig['serviceMchId'],//服务商商户号 'sub_mch_id' => $subMchId,//服务商的子商户号 'key' => $payConfig['serviceKey'], // 服务商商户秘钥 'cert_path' => Yii::$app->basePath."/payment/" . 'service_apiclient_cert_' . $uniacid . '.pem', // XXX: 绝对路径!!!! 'key_path' => Yii::$app->basePath."/payment/" . 'service_apiclient_key_' . $uniacid . '.pem', // XXX: 绝对路径!!!! 'notify_url' => '', // 你也可以在下单时单独设置来想覆盖它 ]; }else{ $payConfig=Config::getSystemSet('payConfig',$uniacid); //普通支付 return [ // 必要配置 'app_id' => $config['appId'], 'mch_id' => $payConfig['mchId'], 'key' => $payConfig['key'], // API 密钥 'cert_path' => Yii::$app->basePath."/payment/" . 'apiclient_cert_' . $uniacid . '.pem', // XXX: 绝对路径!!!! 'key_path' => Yii::$app->basePath."/payment/" . 'apiclient_key_' . $uniacid . '.pem', // XXX: 绝对路径!!!! 'notify_url' => '', // 你也可以在下单时单独设置来想覆盖它 ]; } } //获取小程序码 public static function getQrCode($uniacid,$module,$url,$ident,$scene=''){ $app = Factory::miniProgram(self::getMiniConfig($uniacid)); if($scene){ $response =$app->app_code->getUnlimit($scene,['page'=>$url],$uniacid); }else{ $response =$app->app_code->get($url); } $dir="web/static/".$module."/".$uniacid."/miniCode"; $file=md5($scene.$ident.$uniacid.$url).'.jpg'; if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) { $filename = $response->save($dir,$file); //微擎版本 if(Yii::$app->params['isDev']==true){ $host=Yii::$app->request->hostInfo.'/addons/'.$module.'/'; }else{ $host=Yii::$app->request->hostInfo.'/'; } return $host.$dir."/".$filename; }else{ return false; } } //公众号登陆 public static function wechatLogin($uniacid,$code){ $app =self::getWechatConfig($uniacid); return $app->auth->session($code); } //小程序登录 public static function miniLogin($uniacid,$code){ $app = Factory::miniProgram(self::getMiniConfig($uniacid)); return $app->auth->session($code); } //小程序解密 public static function miniDecrypt($uniacid,$session,$iv,$encryptedData){ $app = Factory::miniProgram(self::getMiniConfig($uniacid)); return $app->encryptor->decryptData($session, $iv, $encryptedData); } /** 微信支付 * @param $uniacid [小程序id] * @param $origin [1.小程序支付2.公众号支付] * @param $outTradeNo [商户单号] * @param $money [金额] * @param $notifyUrl [回调地址] * @param $title [支付标题] * @param $openId [用户openId] * @param $storeId [商家id] * * @param $profit_sharing [商家id] * @return mixed * @throws \yii\db\Exception */ public static function wxPay($uniacid,$origin,$outTradeNo,$money,$notifyUrl,$title,$module,$openId=null,$storeId=null,$profit_sharing='N'){ if(Yii::$app->params['isDev']==true){ $url=Yii::$app->request->hostInfo.'/addons/'.$module.'/index.php/'.$notifyUrl; }else{ $url=Yii::$app->request->hostInfo.'/index.php/'.$notifyUrl; } $res=self::getWxPayConfig($uniacid,$origin,$storeId); //var_dump($res);die; $app = Factory::payment($res); $unifyData=[ 'body' => $title, 'out_trade_no' => $outTradeNo, 'total_fee' => $money*100, 'notify_url' => $url, // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型 'profit_sharing'=>$profit_sharing ]; if($res['sub_appid']){ Yii::$app->db->createCommand()->update('{{%ybwm_takeout_order}}', ['payType'=>2], ['outTradeNo'=>$outTradeNo])->execute(); $unifyData['sub_openid']=$openId; }else{ $unifyData['openid']=$openId; } //file_put_contents('1.txt',json_encode($unifyData)); $result=$app->order->unify($unifyData); //var_dump($result);die; if ($result['return_code'] == 'SUCCESS') { $jsSdk = $app->jssdk; return json_decode($jsSdk->bridgeConfig($result['prepay_id']),true); }else{ return $result['return_msg']; } } /** 微信退款 * @param $uniacid [小程序id] * @param $origin [1.小程序支付2.公众号支付] * @param $payType [1.普通支付2.服务商支付] * @param $subMchId [支付商户号] * @param $outTradeNo [商户单号] * @param $refundNumber [退款单号] * @param $totalFee [订单金额] * @param $refundFee [退款金额] * @param array $other [其他] * @return mixed */ public static function wxRefund($uniacid,$origin,$payType,$subMchId,$outTradeNo,$refundNumber,$totalFee,$refundFee,$other=[]){ $app = Factory::payment(self::getWxPayConfig($uniacid,$origin,'',$payType,$subMchId)); return $app->refund->byOutTradeNumber($outTradeNo, $refundNumber, $totalFee*100, $refundFee*100,$other); } /**企业付款到零钱 * @param $uniacid [小程序id] * @param $outTradeNo [商户单号] * @param $openId [用户openId] * @param $money [金额] * @param $note [备注] * @return mixed */ public static function toBalance($uniacid,$outTradeNo,$openId,$money,$note){ $app = Factory::payment(self::getWxPayConfig($uniacid)); return $app->transfer->toBalance([ 'partner_trade_no' => $outTradeNo, // 商户订单号,需保持唯一性(只能是字母或者数字,不能包含有符号) 'openid' => $openId, 'check_name' => 'NO_CHECK', // NO_CHECK:不校验真实姓名, FORCE_CHECK:强校验真实姓名 // 're_user_name' => '王小帅', // 如果 check_name 设置为FORCE_CHECK,则必填用户真实姓名 'amount' => $money*100, // 企业付款金额,单位为分 'desc' => $note, // 企业付款操作说明信息。必填 ]); } //请求调用(模板消息专用) static function templateHttpRequest($url, $data = null) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); if (!empty($data)) { curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $data); } curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); //执行 $output = curl_exec($curl); curl_close($curl); return $output; } //获取小程序模板列表 public static function getMiniTemplates($uniacid,$id, $keywords,$note='外卖'){ $app = Factory::miniProgram(self::getMiniConfig($uniacid)); $token = $app->access_token->getToken(true); $url = 'https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatekeywords?access_token=' . $token['access_token'] . '&tid=' . $id; $data = httpRequest($url); $key = json_decode($data, true)['data']; $list = []; for ($i = 0; $i < count($keywords); $i++) { for ($k = 0; $k < count($key); $k++) { if ($keywords[$i] == $key[$k]['name']) { $list[] = $key[$k]['kid']; } } } $url = 'https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate?access_token=' . $token['access_token']; $formWork = [ 'tid' => $id, 'kidList' => $list, 'sceneDesc' => $note, ]; $data = self::templateHttpRequest($url, http_build_query($formWork)); // print_R($data);die; return json_decode($data, true)['priTmplId']; } //获取直播列表 public static function getMiniLive($uniacid,$page,$size){ $app = Factory::miniProgram(self::getMiniConfig($uniacid)); $token = $app->access_token->getToken(); $url = "https://api.weixin.qq.com/wxa/business/getliveinfo?access_token=" . $token['access_token']; $data = json_encode([ 'start' => $page, 'limit' => $size, ]); $res=httpRequest($url,$data); // print_R($res);die; return $res; } //创建直播 public static function saveMiniLive($uniacid,$data){ $app = Factory::miniProgram(self::getMiniConfig($uniacid)); $token = $app->access_token->getToken(); $url = "https://api.weixin.qq.com/wxaapi/broadcast/room/create?access_token=" . $token['access_token']; $arr['name']=$data['name']; $arr['coverImg']=$data['shareImg']; $arr['startTime']=strtotime($data['startTime']); $arr['endTime']=strtotime($data['endTime']); $arr['anchorName']=$data['anchorName']; $arr['anchorWechat']=$data['anchorWechat']; $arr['shareImg']=$data['shareImg']; $arr['feedsImg']=$data['feedsImg']; $arr['type']=$data['type']; $arr['screenType']=$data['screenType']; $arr['closeLike']=$data['closeLike']; $arr['closeGoods']=$data['closeGoods']; $arr['closeComment']=$data['closeComment']; $header=array('Content-Type: application/json', 'Accept: application/json'); $res=httpRequest($url,json_encode($arr),$header); return $res; } //获取商品列表 static function goodsList($uniacid,$page,$size,$status){ $app = Factory::miniProgram(self::getMiniConfig($uniacid)); $token = $app->access_token->getToken(); // $token['access_token']="38_fAwUCBSJ3QOYFYO5Ofke42iVHBnR3McGB8VbtqTc07CKcrky9Z2uZV3K1JwtMvHjh1VRDC5T4Ork8DeKGz5fP87YCHR4SYors4PFt4LweXAR5ykFMd1bS_ci8Mxc6tGvSVKAn7w0IyoEgn53AKPdAAASCH"; $url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/getapproved?access_token=" . $token['access_token']."&offset=".$page."&limit=".$size."&status=".$status; $res=httpRequest($url); //var_dump($res);die; return $res; } //获取mediaid static function getMediaId($uniacid,$path){ $app = Factory::miniProgram(self::getMiniConfig($uniacid)); $token = $app->access_token->getToken(); $url = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=" . $token['access_token']."&type=image"; $content = file_get_contents($path); $pathUrl="/web/static/yb_wm/".$uniacid."/wexinUpload/test".rand(1111,9999).".jpg"; $path = "web/static/yb_wm/".$uniacid."/wexinUpload"; if (!file_exists($path)) { mkdir($path, 0777,true); chmod($path, 0777); } $saveUrl=".".$pathUrl; $ress=file_put_contents($saveUrl, $content); $src=Yii::$app->basePath.$pathUrl; $data['media']=new \CURLFile($src); $res=httpRequest($url,$data); unlink($src); return $res; } //添加商品 public static function saveGoods($uniacid,$data,$type){ $app = Factory::miniProgram(self::getMiniConfig($uniacid)); $token = $app->access_token->getToken(); //$token['access_token']="38_fAwUCBSJ3QOYFYO5Ofke42iVHBnR3McGB8VbtqTc07CKcrky9Z2uZV3K1JwtMvHjh1VRDC5T4Ork8DeKGz5fP87YCHR4SYors4PFt4LweXAR5ykFMd1bS_ci8Mxc6tGvSVKAn7w0IyoEgn53AKPdAAASCH"; $url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/add?access_token=" . $token['access_token']; if($type=='update'){ $url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/update?access_token=" . $token['access_token']; $params['goodsInfo']['goodsId']=$data['goodsId']; } $params['goodsInfo']['coverImgUrl']=$data['coverImgUrl']; $params['goodsInfo']['name']=$data['name']; $params['goodsInfo']['priceType']=$data['priceType']; $params['goodsInfo']['price']=$data['price']; $params['goodsInfo']['price2']=$data['price2']; $params['goodsInfo']['url']=$data['url']; $header=array('Content-Type: application/json', 'Accept: application/json'); //var_dump(json_encode($params));die; $res=httpRequest($url,json_encode($params),$header); // var_dump($res);die; return $res; } public static function delGoods($uniacid,$data){ $app = Factory::miniProgram(self::getMiniConfig($uniacid)); $token = $app->access_token->getToken(); // $token['access_token']="38_fAwUCBSJ3QOYFYO5Ofke42iVHBnR3McGB8VbtqTc07CKcrky9Z2uZV3K1JwtMvHjh1VRDC5T4Ork8DeKGz5fP87YCHR4SYors4PFt4LweXAR5ykFMd1bS_ci8Mxc6tGvSVKAn7w0IyoEgn53AKPdAAASCH"; $url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/delete?access_token=" . $token['access_token']; $params['goodsId']=$data['goodsId']?:8; $header=["content-type:application/json"]; // var_dump($params);die; $res=httpRequest($url,json_encode($params),$header); //$res=curl_post($url,$params,$header); //var_dump($res);die; return $res; } public static function goodsDetails($uniacid,$data){ $app = Factory::miniProgram(self::getMiniConfig($uniacid)); $token = $app->access_token->getToken(); //$token['access_token']="38_UExAx0c7eqTl5FsTiU5rezVCILTTLO002yEaaUK_g_sjhwQCsImePS-38_fAwUCBSJ3QOYFYO5Ofke42iVHBnR3McGB8VbtqTc07CKcrky9Z2uZV3K1JwtMvHjh1VRDC5T4Ork8DeKGz5fP87YCHR4SYors4PFt4LweXAR5ykFMd1bS_ci8Mxc6tGvSVKAn7w0IyoEgn53AKPdAAASCH"; $url = "https://api.weixin.qq.com/wxa/business/getgoodswarehouse?access_token=" . $token['access_token']; $params['goods_ids']=$data['goodsId']; //var_dump(json_encode($params));die; $res=httpRequest($url,json_encode($params)); return $res; } //通过openId获取用户信息 public static function getUserInfoByOpenId($openId,$data){ $app = Factory::officialAccount($data); $user = $app->user->get($openId); return $user; } public static function curl($param = "", $url, $uniacid) { $postUrl = $url; $curlPost = $param; $ch = curl_init(); //初始化curl curl_setopt($ch, CURLOPT_URL, $postUrl); //抓取指定网页 curl_setopt($ch, CURLOPT_HEADER, 0); //设置header curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //要求结果为字符串且输出到屏幕上 curl_setopt($ch, CURLOPT_POST, 1); //post提交方式 curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost); // 增加 HTTP Header(头)里的字段 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 终止从服务端进行验证 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_SSLCERT, Yii::$app->basePath."/payment/" . 'service_apiclient_cert_' . $uniacid . '.pem'); //这个是证书的位置绝对路径 curl_setopt($ch, CURLOPT_SSLKEY, Yii::$app->basePath."/payment/" . 'service_apiclient_key_' . $uniacid . '.pem'); //这个也是证书的位置绝对路径 $data = curl_exec($ch); //运行curl curl_close($ch); return $data; } /** * @param $orderId * @param int $type[1.外卖2店内快餐3收银] * @return bool * @throws \yii\db\Exception */ public static function profitSharing($orderId,$type=1) { $tableName='ybwm_takeout_order'; if($type==2){ $tableName='ybwm_instore_order'; } if($type==3){ $tableName='ybwm_cashier_order'; } $orderInfo = (new \yii\db\Query()) ->from('{{%'.$tableName.'}}') ->where(['id' =>$orderId]) ->one(); if($orderInfo['payMode']!=1){ return true; } $bill= (new \yii\db\Query()) ->from('{{%ybwm_bill}}') ->where(['outTradeNo' =>$orderInfo['outTradeNo']]) ->one(); $money=bcsub($bill['money'],$bill['storeActualMoney'],2); if($money<=0 || $bill['storeActualMoney']<=0){ self::profitSharingFinish($orderId,'金额不合法完结分账',$type); return true; } $uniacid=$orderInfo['uniacid']; $res=Config::getSystemSet('miniConfig',$uniacid); $storeSet=Config::getStoreSet('serviceCharge',$orderInfo['storeId']); $mchId=$storeSet['giveMchid'];//分账方商户号 $system = Config::getSystemSet('payConfig', $uniacid); //1.设置分账账号 $receivers = [ 0 => [ 'type' => "MERCHANT_ID", 'account' => $mchId, 'amount' => (int)bcmul($money,100,0), 'description' => '平台服务费', ], ]; $receivers = json_encode($receivers, JSON_UNESCAPED_UNICODE); //2.生成签名 $postArr = array( 'appid' => $system['serviceAppId'], 'mch_id' => $system['serviceMchId'], 'sub_mch_id' => $orderInfo['subMchId'], 'sub_appid' => $res['appId'], 'nonce_str' => md5(time() . rand(1000, 9999)), 'transaction_id' => $orderInfo['transaction_id'], 'out_order_no' => date("YmdHis") . rand(111111, 999999), 'receivers' => $receivers, ); $sign = ProfitSharingSign::getSign($postArr, 'HMAC-SHA256', $system['serviceKey']); $postArr['sign'] = $sign; //3.发送请求 $url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharing'; $postXML = arrayToXml($postArr); $curl_res = self::curl($postXML, $url, $uniacid); $ret = xmlToArray($curl_res); $ret['orderId']=$orderId; $ret['orderType']=$type; if($ret['result_code']=='FAIL'){ echo json_encode(['code'=>2,'msg'=>$ret['err_code_des']]);die; } file_put_contents('fenzhang.log','[' . date('Y-m-d H:i:s') . ']' .json_encode($ret,JSON_UNESCAPED_UNICODE). PHP_EOL); //var_dump($ret);die; if ($ret['return_code'] == 'SUCCESS' and $ret['result_code'] == 'SUCCESS' || $ret['err_code_des'] == '可分账金额不足') { Yii::$app->db->createCommand()->update('{{%'.$tableName.'}}', ['profitSharingState'=>1], 'id=:id', ['id' =>$orderId])->execute(); Yii::$app->db->createCommand()->update('{{%ybwm_bill}}', ['profitSharingState'=>1], 'outTradeNo=:outTradeNo', ['outTradeNo' =>$orderInfo['outTradeNo']])->execute(); return true; } else { return false; } } //添加分账方 public static function AddProfitSharing($uniacid,$mchId, $name, $subMchid) { $res=Config::getSystemSet('miniConfig',$uniacid); $system = Config::getSystemSet('payConfig', $uniacid); //1.设置分账账号 $receivers = [ 'type' => "MERCHANT_ID", 'account' => $mchId, 'relation_type' => 'SERVICE_PROVIDER', 'name' => $name, ]; $receivers = json_encode($receivers, JSON_UNESCAPED_UNICODE); //2.生成签名 $postArr = array( 'appid' => $system['serviceAppId'], 'mch_id' => $system['serviceMchId'], 'sub_mch_id' => $subMchid, 'sub_appid' => $res['appId'], 'nonce_str' => md5(time() . rand(1000, 9999)), 'receiver' => $receivers, ); $sign = ProfitSharingSign::getSign($postArr, 'HMAC-SHA256', $system['serviceKey']); $postArr['sign'] = $sign; //3.发送请求 $url = 'https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver'; $postXML = arrayToXml($postArr); // function curl($param = "", $url) { // $postUrl = $url; // $curlPost = $param; // $ch = curl_init(); //初始化curl // curl_setopt($ch, CURLOPT_URL, $postUrl); //抓取指定网页 // curl_setopt($ch, CURLOPT_HEADER, 0); //设置header // curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //要求结果为字符串且输出到屏幕上 // curl_setopt($ch, CURLOPT_POST, 1); //post提交方式 // curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost); // 增加 HTTP Header(头)里的字段 // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 终止从服务端进行验证 // curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // $data = curl_exec($ch); //运行curl // curl_close($ch); // return $data; // } $curl_res = httpRequest($url,$postXML); $ret = xmlToArray($curl_res); if ($ret['return_code'] == 'SUCCESS' and $ret['result_code'] == 'SUCCESS') { return true; } else { return false; } } // //删除分账方 // public static function DelProfitSharing($uniacid, $storeId, $mchId) { // $res = pdo_get('account_wxapp', array('uniacid' => $uniacid)); // $storeSet = Common::storeSet('servicepay', $storeId); // $system = Common::systemConfig('payset', $uniacid); // //1.设置分账账号 // $receivers = [ // 'type' => "MERCHANT_ID", // 'account' => $mchId, // 'relation_type' => 'SERVICE_PROVIDER', // ]; // $receivers = json_encode($receivers, JSON_UNESCAPED_UNICODE); // //2.生成签名 // $postArr = array( // 'appid' => $system['appId'], // 'mch_id' => $system['mchId'], // 'sub_mch_id' => $storeSet['subMchid'], // 'sub_appid' => $res['key'], // 'nonce_str' => md5(time() . rand(1000, 9999)), // 'receiver' => $receivers, // ); // // $sign = ProfitSharingSign::getSign($postArr, 'HMAC-SHA256', $system['screct']); // $postArr['sign'] = $sign; // // //3.发送请求 // $url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharing'; // $postXML = Common::arrayToXml($postArr); // function curl($param = "", $url, $uniacid) { // global $_GPC, $_W; // $postUrl = $url; // $curlPost = $param; // $ch = curl_init(); //初始化curl // curl_setopt($ch, CURLOPT_URL, $postUrl); //抓取指定网页 // curl_setopt($ch, CURLOPT_HEADER, 0); //设置header // curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //要求结果为字符串且输出到屏幕上 // curl_setopt($ch, CURLOPT_POST, 1); //post提交方式 // curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost); // 增加 HTTP Header(头)里的字段 // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 终止从服务端进行验证 // curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // $data = curl_exec($ch); //运行curl // curl_close($ch); // return $data; // } // $curl_res = curl($postXML, $url, $uniacid); // $ret = Common::xmlToArray($curl_res); // if ($ret['return_code'] == 'SUCCESS' and $ret['result_code'] == 'SUCCESS') { // return true; // } else { // return false; // } // // } //完结分账 public static function profitSharingFinish($orderId,$description,$type=1) { $tableName='ybwm_takeout_order'; if($type==2){ $tableName='ybwm_instore_order'; } if($type==3){ $tableName='ybwm_cashier_order'; } $orderInfo = (new \yii\db\Query()) ->from('{{%'.$tableName.'}}') ->where(['id' =>$orderId]) ->one(); $uniacid=$orderInfo['uniacid']; $system = Config::getSystemSet('payConfig', $uniacid); //2.生成签名 $postArr = array( 'appid' => $system['serviceAppId'], 'mch_id' => $system['serviceMchId'], 'sub_mch_id' => $orderInfo['subMchId'], 'nonce_str' => md5(time() . rand(1000, 9999)), 'transaction_id' => $orderInfo['transaction_id'], 'out_order_no' => date("YmdHis") . rand(111111, 999999), 'description' => $description, ); $sign = ProfitSharingSign::getSign($postArr, 'HMAC-SHA256', $system['serviceKey']); $postArr['sign'] = $sign; //3.发送请求 $url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharingfinish'; $postXML = arrayToXml($postArr); $curl_res = self::curl($postXML, $url, $uniacid); $ret = xmlToArray($curl_res); if ($ret['return_code'] == 'SUCCESS' and $ret['result_code'] == 'SUCCESS' || $ret['err_code_des'] == '可分账金额不足') { Yii::$app->db->createCommand()->update('{{%'.$tableName.'}}', ['profitSharingState'=>3], 'id=:id', ['id' =>$orderId])->execute(); Yii::$app->db->createCommand()->update('{{%ybwm_bill}}', ['profitSharingState'=>3], 'outTradeNo=:outTradeNo', ['outTradeNo' =>$orderInfo['outTradeNo']])->execute(); return true; } else { return false; } } //创建卡券 public static function createCard($uniacid) { $app=Factory::officialAccount(self::getWeChatTemplateConfig($uniacid)); $cardInfo=Config::getSystemSet('vipSet',$uniacid); $config=Config::getSystemSet('miniConfig',$uniacid); $card = $app->card; $cardType='member_card'; $attributes=array( 'base_info' => array( 'logo_url' => $cardInfo['logo'], 'brand_name' => $cardInfo['brandName'], 'code_type' => 'CODE_TYPE_TEXT', 'title' => $cardInfo['title'], 'color' => 'Color010', 'notice' => $cardInfo['notice'], 'description' =>$cardInfo['description'], 'service_phone' => $cardInfo['serviceTel'], 'date_info' => array( 'type' => 'DATE_TYPE_PERMANENT', ), 'sku' => array( 'quantity' => 500000, ), ), "custom_field1" => array( "name_type" => "FIELD_NAME_TYPE_LEVEL", "app_brand_user_name" => $config['originalAppId'] . "@app", "app_brand_pass" => "yb_wm/index/my-index", "url" => "pages/index/index", ), "custom_field2" => array( "name" => "余额", "app_brand_user_name" => $config['originalAppId'] . "@app", "app_brand_pass" => "yb_wm/index/my-index", "url" => "pages/index/index", ), "wx_activate" => true, "wx_activate_after_submit" => false, "wx_activate_after_submit_url" => "yb_wm/index/index", "custom_cell1" => array( "name" => $cardInfo['xcxName'] ?: "小程序入口", "tips" => '点击进入', "app_brand_user_name" => $config['originalAppId'] . "@app", "app_brand_pass" => "yb_wm/index/index", ), 'prerogative' => $cardInfo['prerogative'], 'supply_bonus' => true, 'supply_balance' => false, ); $result=$card->create($cardType,$attributes); return $result; } //设置会员卡注册字段 public static function setField($cardId,$uniacid) { $app=Factory::officialAccount(self::getWeChatTemplateConfig($uniacid)); $card = $app->card; $cardInfo=Config::getSystemSet('vipSet',$uniacid); $register=[ 'required_form' => [ 'common_field_id_list' => $cardInfo['register'], ], ]; $card->member_card->setActivationForm($cardId, $register); } //修改会员卡 public static function updateCard($uniacid) { $app=Factory::officialAccount(self::getWeChatTemplateConfig($uniacid)); $cardInfo=Config::getSystemSet('vipSet',$uniacid); $card = $app->card; $cardId=$cardInfo['cardId']; $cardType='member_card'; $attributes=array( 'base_info' => array( 'logo_url' => $cardInfo['logo'], 'title' => $cardInfo['title'], 'notice' => $cardInfo['notice'], 'description' =>$cardInfo['description'], 'service_phone' => $cardInfo['serviceTel'], ), 'prerogative' => $cardInfo['prerogative'], 'supply_bonus' => true, 'supply_balance' => false, 'auto_activate' => true, ); $result=$card->update($cardId, $cardType, $attributes); self::setField($cardId,$uniacid); return $result; } //删除会员卡 public static function deleteCard($cardId,$uniacid) { $app=Factory::officialAccount(self::getWeChatTemplateConfig($uniacid)); $card = $app->card; $result=$card->delete($cardId); return $result; } //同步会员卡 public static function weChatCard($uniacid) { $cardInfo=Config::getSystemSet('vipSet',$uniacid); $cardId=$cardInfo['cardId']; if($cardId){ $res=self::updateCard($uniacid); }else{ $res=self::createCard($uniacid); $cardInfo['cardId']=$res['card_id']; self::setField($res['card_id'],$uniacid); } if($res['errcode']==0){ if(!$cardId) { Yii::$app->db->createCommand()->update('{{%ybwm_core_system}}', ['data' => json_encode($cardInfo)], ['uniacid' => $uniacid, 'ident' => 'vipSet'])->execute(); } return true; }else{ return false; } } public static function payConfig($uniacid,$payType){ if(!$payType){ echo json_encode(['code'=>1,'msg'=>'无效的请求方式']);die; } switch ($payType){ case 1; $config=Config::getSystemSet('miniConfig',$uniacid); $payConfig=Config::getSystemSet('payConfig',$uniacid); //普通支付 return [ 'app_id'=> $config['appId'], 'mch_id'=> $payConfig['mchId'], 'key'=> $payConfig['key'], // API 密钥 'cert_path'=> Yii::$app->basePath."/payment/" . 'apiclient_cert_' . $uniacid . '.pem', // XXX: 绝对路径!!!! 'key_path'=> Yii::$app->basePath."/payment/" . 'apiclient_key_' . $uniacid . '.pem', // XXX: 绝对路径!!!! ]; break; case 2; $config=Config::getSystemSet('alipayConfig',$uniacid); //普通支付 return [ // 必要配置 'app_id' => $config['app_id'], 'ali_public_key' => $config['ali_public_key'],//公钥 'private_key'=> $config['private_key'], //私钥 ]; break; } } //公众号创建二维码 public static function createQrcode($uniacid,$fileName,$type=1){ $app=self::getWechatConfig($uniacid); if($type==1){ //创建临时二维码 $result = $app->qrcode->temporary('foo', 6 * 24 * 3600); }else{ //创建永久二维码 $result =$app->qrcode->forever("foo"); } $ticket=$result['ticket']; $url = $app->qrcode->url($ticket); $shortUrl = $app->url->shorten($url); $content = file_get_contents($shortUrl); // 得到二进制图片内容 file_put_contents($fileName, $content); // 写入文件 } //获取微信公众号菜单 public static function getWechatMenu($uniacid){ $app=self::getWechatConfig($uniacid); $list = $app->menu->list(); return $list; } //创建公众号菜单 public static function crateWechatMenu($uniacid,$buttons){ $app=self::getWechatConfig($uniacid); $app->menu->create($buttons); //删除菜单 $app->menu->delete(); // 全部 //$app->menu->delete($menuId); } //公众号获取accessToken $array jssdk事件组成的数组 public static function getToken($uniacid,$array){ $app=self::getWechatConfig($uniacid); try{ $jssdk = $app->jssdk->buildConfig($array, $debug = true, $beta = false, $json = false); }catch (Exception $e){ echo $e->getMessage();die; } return $jssdk; } public static function getAccessToken($uniacid){ // $data =Yii::$app->cache->get($uniacid.'AccessToken'); // if ($data){ // return $data; // } $config=Config::getSystemSet('wechatConfig',$uniacid); $app_id = $config['appId']; $app_secret = $config['appSecret']; $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$app_id."&secret=".$app_secret; // 微信返回的信息 $returnData = json_decode(httpRequest($url)); $accessToken= $returnData->access_token; //Yii::$app->cache->set($uniacid.'AccessToken', $accessToken, 7000); return $accessToken; } public static function checkAuth($acid,$code){ $config=Config::getSystemSet('wechatConfig',$acid); $app_id = $config['appId']; $app_secret = $config['appSecret']; $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $app_id . '&secret=' . $app_secret . '&code=' . $code . '&grant_type=authorization_code'; return httpRequest($url); } public static function getJsApiTicket($uniacid) { // $data =Yii::$app->cache->get($uniacid.'JsApiTicket'); // if ($data){ // return $data; // } $accessToken=self::getAccessToken($uniacid); $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$accessToken&&type=jsapi"; // 微信返回的信息 $returnData = json_decode(httpRequest($url)); $jsApiTicket = $returnData->ticket; //Yii::$app->cache->set($uniacid.'JsApiTicket', $jsApiTicket, 7000); return $jsApiTicket; } // 获取签名 public static function getSignPackage($uniacid,$url) { $config=Config::getSystemSet('wechatConfig',$uniacid); $appId = $config['appId']; // 获取ticket $jsApiTicket = self::getJsApiTicket($uniacid); // 生成时间戳 $timestamp = time(); // 生成随机字符串 $nonceStr = self::createNoncestr(); // 这里参数的顺序要按照 key 值 ASCII 码升序排序 $string = "jsapi_ticket=$jsApiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url"; $signature = sha1($string); $signPackage = array( "appId" => $appId, "nonceStr" => $nonceStr, "timestamp" => $timestamp, "url" => $url, "signature" => $signature, "rawString" => $string ); return $signPackage; } // 创建随机字符串 public static function createNoncestr($length = 16) { $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $str = ""; for($i = 0; $i < $length; $i ++) { $str .= substr ( $chars, mt_rand ( 0, strlen ( $chars ) - 1 ), 1 ); } return $str; } static function getWxLink($uniacid,$path,$is_expire,$scene,$title,$expire_time=0){ $app = Factory::miniProgram(self::getMiniConfig($uniacid)); $tokenData = $app->access_token->getToken(); $token=$tokenData['access_token']; $expire_type = 0; $expire_time=time()+$expire_time*60*60*24; $postData=[]; if($is_expire==false){$expire_time=0;} //$scene = 'id=19'; $path = 'pages/myindex/myjoinguide'; $url = "https://api.weixin.qq.com/wxa/generatescheme?access_token=".$token; $postData = [ 'jump_wxa' => array( "path" => $path, "query" => $scene ), 'is_expire' =>$is_expire, 'expire_type' => $expire_type, 'expire_time' => $expire_time,//最长有效期为1年。is_expire 为 true 且 expire_type 为 0 时必填 ]; $data = json_decode(httpRequest($url,json_encode($postData)),true); $scene=$data['openlink']; $postData=[]; $url = "https://api.weixin.qq.com/wxa/generate_urllink?access_token=".$token; $postData = [ "path" => $path, "query" => $scene, 'is_expire' =>$is_expire, 'expire_type' => $expire_type, 'expire_time' => $expire_time,//最长有效期为1年。is_expire 为 true 且 expire_type 为 0 时必填 ]; $res= json_decode(httpRequest($url,json_encode($postData)),true); $link=$res['url_link']; if($data['errcode']==0&&$data['errmsg']=='ok'&&$res['errcode']==0&&$res['errmsg']=='ok'){ $res= (new \yii\db\Query()) ->from('{{%ybwm_wxapp_link}}') ->where(['path'=>$path,'uniacid'=>$uniacid]) ->one(); if(!$res){ $array=array( 'link'=>$link, 'scene'=>$scene, 'uniacid'=>$uniacid, 'path'=>$path, 'is_expire'=>$is_expire, 'expire_time'=>$expire_time, 'createdAt'=>time(), 'title'=>$title ); try{ Yii::$app->db->createCommand()->insert('{{%ybwm_wxapp_link}}', $array)->execute(); }catch (Exception $e) { echo $e->getMessage();die; } echo json_encode(['code'=>1,'msg'=>'成功']);die; }else{ echo json_encode(['code'=>1,'msg'=>'该路径已生成二维码']);die; } } } }