getRow("SELECT * FROM pre_channel WHERE id='$id' LIMIT 1"); if(!$value) return null; $channel = ['id'=>$value['id'], 'name'=>$value['name'], 'mode'=>$value['mode'], 'type'=>$value['type'], 'plugin'=>$value['plugin'], 'apptype'=>$value['apptype'], 'appwxmp'=>$value['appwxmp'], 'appwxa'=>$value['appwxa'], 'costrate'=>$value['costrate'], 'daytop'=>$value['daytop']]; $config = json_decode($value['config'], true); if(!empty($channelinfo) && !empty($config)){ $arr = json_decode($channelinfo, true); foreach($config as $configkey => $configrow){ if($configrow && substr($configrow, 0, 1) == '['){ $key = substr($configrow,1,-1); $config[$configkey] = $arr[$key]; } } } if(!empty($config)){ $channel = array_merge($channel, $config); } return $channel; } static public function getSub($id){ global $DB; $value=$DB->getRow("SELECT A.*,B.info,B.id subid FROM pre_subchannel B INNER JOIN pre_channel A ON B.channel=A.id WHERE B.id='$id'"); if(!$value) return null; $channel = ['id'=>$value['id'], 'subid'=>$value['subid'], 'name'=>$value['name'], 'mode'=>$value['mode'], 'type'=>$value['type'], 'plugin'=>$value['plugin'], 'apptype'=>$value['apptype'], 'appwxmp'=>$value['appwxmp'], 'appwxa'=>$value['appwxa'], 'costrate'=>$value['costrate'], 'daytop'=>$value['daytop']]; $config = json_decode($value['config'], true); if(!empty($value['info']) && !empty($config)){ $arr = json_decode($value['info'], true); foreach($config as $configkey => $configrow){ if($configrow && substr($configrow, 0, 1) == '['){ $key = substr($configrow,1,-1); $config[$configkey] = $arr[$key]; } } if(isset($arr['apptype']) && !empty($arr['apptype'])){ $channel['apptype'] = $arr['apptype']; } if(isset($arr['appwxmp']) && $arr['appwxmp']>0){ $channel['appwxmp'] = $arr['appwxmp']; $channel['subappwxmp'] = 1; } if(isset($arr['appwxa']) && $arr['appwxa']>0){ $channel['appwxa'] = $arr['appwxa']; $channel['subappwxa'] = 1; } } if(!empty($config)){ $channel = array_merge($channel, $config); } return $channel; } static public function getGroup($gid){ global $DB; $group=$DB->getRow("SELECT * FROM pre_group WHERE gid='{$gid}' LIMIT 1"); if(!$group)$group=$DB->getRow("SELECT * FROM pre_group WHERE gid=0 LIMIT 1"); $info = json_decode($group['info'],true); $rows = $DB->getAll("SELECT * FROM pre_type WHERE status=1 ORDER BY id ASC"); $paytype = []; foreach($rows as $row){ $paytype[$row['id']] = $row['name']; } $subchannel_type = []; foreach($info as $id=>$row){ if(!isset($paytype[$id]))continue; if($row['channel'] == -2){ $subchannel_type[] = $paytype[$id]; } } $group['subchannel_type'] = $subchannel_type; return $group; } static public function info($id, $gid = 0){ global $DB; $value=$DB->getRow("SELECT id,plugin,type,rate,apptype,mode,paymin,paymax FROM pre_channel WHERE id='$id' LIMIT 1"); $money_rate = $value['rate']; if($gid>0)$groupinfo=$DB->getColumn("SELECT info FROM pre_group WHERE gid='$gid' LIMIT 1"); if(!$groupinfo)$groupinfo=$DB->getColumn("SELECT info FROM pre_group WHERE gid=0 LIMIT 1"); if($groupinfo){ $info = json_decode($groupinfo,true); $groupinfo = $info[$value['type']]; if(is_array($groupinfo) && !empty($groupinfo['rate'])){ $money_rate = $groupinfo['rate']; } } return ['typeid'=>$value['type'], 'plugin'=>$value['plugin'], 'channel'=>$value['id'], 'rate'=>$money_rate, 'apptype'=>$value['apptype'], 'mode'=>$value['mode'], 'paymin'=>$value['paymin'], 'paymax'=>$value['paymax']]; } static public function getWeixin($id){ global $DB; $value=$DB->getRow("SELECT * FROM pre_weixin WHERE id='$id' LIMIT 1"); return $value; } // 支付提交处理(输入支付方式名称) static public function submit($type, $uid=0, $gid=0, $money=0, $device=null){ global $DB; if($device == 'mobile' || $device == 'qq' || $device == 'wechat' || $device == 'alipay' || checkmobile()==true){ $sqls = " AND (device=0 OR device=2)"; }else{ $sqls = " AND (device=0 OR device=1)"; } $paytype=$DB->getRow("SELECT id,name,status FROM pre_type WHERE name=:type{$sqls} LIMIT 1", [':type'=>$type]); if(!$paytype || $paytype['status']==0)sysmsg('支付方式(type)不存在'); $typeid = $paytype['id']; $typename = $paytype['name']; return self::getSubmitInfo($typeid, $typename, $uid, $gid, $money); } // 支付提交处理2(输入支付方式ID) static public function submit2($typeid, $uid=0, $gid=0, $money=0){ global $DB; $paytype=$DB->getRow("SELECT id,name,status FROM pre_type WHERE id='$typeid' LIMIT 1"); if(!$paytype || $paytype['status']==0)sysmsg('支付方式(type)不存在'); $typename = $paytype['name']; return self::getSubmitInfo($typeid, $typename, $uid, $gid, $money); } //获取通道、插件、费率信息 static public function getSubmitInfo($typeid, $typename, $uid, $gid, $money){ global $DB; if($gid>0)$groupinfo=$DB->getColumn("SELECT info FROM pre_group WHERE gid='$gid' LIMIT 1"); if(!$groupinfo)$groupinfo=$DB->getColumn("SELECT info FROM pre_group WHERE gid=0 LIMIT 1"); if($groupinfo){ $info = json_decode($groupinfo,true); $groupinfo = $info[$typeid]; if(is_array($groupinfo)){ $channel = $groupinfo['channel']; $money_rate = $groupinfo['rate']; } else{ $channel = -1; $money_rate = null; } if($channel==0){ //当前商户关闭该通道 return false; } elseif($channel==-1){ //随机可用通道 $rows=$DB->getAll("SELECT id,plugin,status,rate,apptype,mode,paymin,paymax FROM pre_channel WHERE type='$typeid' AND status=1 AND daystatus=0"); if(count($rows)>0){ $newrows = []; foreach($rows as $row){ if($money>0 && !empty($row['paymin']) && $row['paymin']>0 && $money<$row['paymin'])continue; if($money>0 && !empty($row['paymax']) && $row['paymax']>0 && $money>$row['paymax'])continue; $newrows[] = $row; } if(count($newrows)>0){ $row = $newrows[array_rand($newrows)]; }else{ $row = $rows[array_rand($rows)]; } if(empty($money_rate))$money_rate = $row['rate']; return ['typeid'=>$typeid, 'typename'=>$typename, 'plugin'=>$row['plugin'], 'channel'=>$row['id'], 'subchannel'=>0, 'rate'=>$money_rate, 'apptype'=>$row['apptype'], 'mode'=>$row['mode'], 'paymin'=>$row['paymin'], 'paymax'=>$row['paymax']]; } } elseif($channel==-2){ //用户自定义子通道 $rows=$DB->getAll("SELECT A.id,plugin,A.status,rate,apptype,mode,paymin,paymax,B.id subid FROM pre_subchannel B INNER JOIN pre_channel A ON B.channel=A.id WHERE B.uid='$uid' AND A.type='$typeid' AND A.status=1 AND B.status=1 AND daystatus=0 ORDER BY B.usetime ASC"); if(count($rows)>0){ $newrows = []; foreach($rows as $row){ if($money>0 && !empty($row['paymin']) && $row['paymin']>0 && $money<$row['paymin'])continue; if($money>0 && !empty($row['paymax']) && $row['paymax']>0 && $money>$row['paymax'])continue; $newrows[] = $row; } if(count($newrows)>0){ $row = $newrows[0]; }else{ $row = $rows[0]; } if(empty($money_rate))$money_rate = $row['rate']; $DB->exec("UPDATE pre_subchannel SET usetime=NOW() WHERE id='{$row['subid']}'"); return ['typeid'=>$typeid, 'typename'=>$typename, 'plugin'=>$row['plugin'], 'channel'=>$row['id'], 'subchannel'=>$row['subid'], 'rate'=>$money_rate, 'apptype'=>$row['apptype'], 'mode'=>$row['mode'], 'paymin'=>$row['paymin'], 'paymax'=>$row['paymax']]; } } else{ if($groupinfo['type']=='roll'){ //解析轮询组 $channel = self::getChannelFromRoll($channel, $money); if(!$channel || $channel==0){ //当前轮询组未开启 return false; } } //获取轮询组对应通道 $row=$DB->getRow("SELECT plugin,status,rate,apptype,mode,paymin,paymax FROM pre_channel WHERE id='$channel' LIMIT 1"); if($row['status']==1 && $row['daystatus']==0){ if(empty($money_rate))$money_rate = $row['rate']; return ['typeid'=>$typeid, 'typename'=>$typename, 'plugin'=>$row['plugin'], 'channel'=>$channel, 'subchannel'=>0, 'rate'=>$money_rate, 'apptype'=>$row['apptype'], 'mode'=>$row['mode'], 'paymin'=>$row['paymin'], 'paymax'=>$row['paymax']]; } } }else{ //未设置用户组 $row=$DB->getRow("SELECT id,plugin,status,rate,apptype,mode,paymin,paymax FROM pre_channel WHERE type='$typeid' AND status=1 AND daystatus=0 ORDER BY rand() LIMIT 1"); if($row){ return ['typeid'=>$typeid, 'typename'=>$typename, 'plugin'=>$row['plugin'], 'channel'=>$row['id'], 'subchannel'=>0, 'rate'=>$row['rate'], 'apptype'=>$row['apptype'], 'mode'=>$row['mode'], 'paymin'=>$row['paymin'], 'paymax'=>$row['paymax']]; } } return false; } // 获取当前商户可用支付方式 static public function getTypes($uid, $gid=0){ global $DB; if(checkmobile()==true){ $sqls = " AND (device=0 OR device=2)"; }else{ $sqls = " AND (device=0 OR device=1)"; } $rows = $DB->getAll("SELECT * FROM pre_type WHERE status=1{$sqls} ORDER BY id ASC"); $paytype = []; foreach($rows as $row){ $paytype[$row['id']] = $row; } if($gid>0)$groupinfo=$DB->getColumn("SELECT info FROM pre_group WHERE gid='$gid' LIMIT 1"); if(!$groupinfo)$groupinfo=$DB->getColumn("SELECT info FROM pre_group WHERE gid=0 LIMIT 1"); if($groupinfo){ $info = json_decode($groupinfo,true); foreach($info as $id=>$row){ if(!isset($paytype[$id]))continue; if($row['channel']==0){ unset($paytype[$id]); }elseif($row['channel']==-1){ $channel=$DB->getRow("SELECT rate,status FROM pre_channel WHERE type='$id' AND status=1 LIMIT 1"); if(!$channel){ unset($paytype[$id]); }elseif(empty($row['rate'])){ $paytype[$id]['rate']=$channel['rate']; }else{ $paytype[$id]['rate']=$row['rate']; } }elseif($row['channel']==-2){ $channel=$DB->getRow("SELECT A.id,A.status,rate FROM pre_subchannel B INNER JOIN pre_channel A ON B.channel=A.id WHERE B.uid='$uid' AND A.type='$id' AND A.status=1 AND B.status=1 LIMIT 1"); if(!$channel){ unset($paytype[$id]); }elseif(empty($row['rate'])){ $paytype[$id]['rate']=$channel['rate']; }else{ $paytype[$id]['rate']=$row['rate']; } }else{ if($row['type']=='roll'){ $status=$DB->getColumn("SELECT status FROM pre_roll WHERE id='{$row['channel']}' LIMIT 1"); }else{ $status=$DB->getColumn("SELECT status FROM pre_channel WHERE id='{$row['channel']}' LIMIT 1"); } if(!$status || $status==0)unset($paytype[$id]); else $paytype[$id]['rate']=$row['rate']; } } }else{ foreach($paytype as $id=>$row){ $status=$DB->getColumn("SELECT status FROM pre_channel WHERE type='$id' AND status=1 limit 1"); if(!$status || $status==0)unset($paytype[$id]); else{ $paytype[$id]['rate']=$DB->getColumn("SELECT rate FROM pre_channel WHERE type='$id' AND status=1 limit 1"); } } } return $paytype; } //根据轮询组ID获取支付通道ID static private function getChannelFromRoll($channel, $money){ global $DB; $row=$DB->getRow("SELECT * FROM pre_roll WHERE id='$channel' LIMIT 1"); if($row['status']==1){ $info = self::rollinfo_decode($row['info'],true); //先根据支付金额与限额过滤可用支付通道 $channelids = []; foreach($info as $inforow){ $channelids[] = $inforow['name']; } $channelids = implode(',',$channelids); $rows=$DB->getAll("SELECT id,paymin,paymax FROM pre_channel WHERE id IN ($channelids) AND status=1 AND daystatus=0"); $newids = []; foreach($rows as $channelrow){ if($money>0 && !empty($channelrow['paymin']) && $channelrow['paymin']>0 && $money<$channelrow['paymin'])continue; if($money>0 && !empty($channelrow['paymax']) && $channelrow['paymax']>0 && $money>$channelrow['paymax'])continue; $newids[] = $channelrow['id']; } if(count($newids)==0)return false; $newinfo = []; foreach($info as $inforow){ if(in_array($inforow['name'], $newids))$newinfo[]=$inforow; } if($row['kind']==2){ return $newids[0]; }elseif($row['kind']==1){ $channel = self::random_weight($newinfo); }else{ $channel = $newinfo[$row['index']]['name']; $index = ($row['index'] + 1) % count($newinfo); $DB->exec("UPDATE pre_roll SET `index`='$index' WHERE id='{$row['id']}'"); } return $channel; } return false; } //解析轮询组info static private function rollinfo_decode($content){ $result = []; $arr = explode(',',$content); foreach($arr as $row){ $a = explode(':',$row); $result[] = ['name'=>$a[0], 'weight'=>$a[1]]; } return $result; } //加权随机 static private function random_weight($arr){ $weightSum = 0; foreach ($arr as $value) { $weightSum += intval($value['weight']); } if($weightSum<=0)return false; $randNum = mt_rand(1, $weightSum); foreach ($arr as $v) { if ($randNum <= $v['weight']) { return $v['name']; } $randNum -=$v['weight']; } } }