canyin-project/ybcy/models/common/WeChat.php
2024-11-01 16:07:54 +08:00

1049 lines
43 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\models\common;
use Yii;
use yii\db\ActiveRecord;
use EasyWeChat\Factory;
use app\models\common\Config;
use app\models\common\ProfitSharingSign;
class WeChat extends ActiveRecord{
public static function cashierConfig($uniacid,$storeId,$origin){
$res=self::getWxPayConfig($uniacid,$origin,$storeId);
$app = Factory::payment($res);
return $app;
}
//公众号参数
public static function getWechatConfig($uniacid){
$config=Config::getSystemSet('wechatConfig',$uniacid);
$options=[
'app_id' => $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&timestamp=$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;
}
}
}
}