async = $async; $this->data = $data; $this->channel = $channel; $this->product = $product; if ($this->channel) { if (isset($this->channel['host']) && $this->channel['host']) { $this->host = $this->channel['host']; } if (isset($this->channel['mid']) && $this->channel['mid']) { $this->mid = $this->channel['mid']; } if (isset($this->channel['token']) && $this->channel['token']) { $this->token = $this->channel['token']; } } } # 通用的充值 public function def($method, $param) { if (strstr($method, '_')) { $temp = explode('_', $method); $method = $temp[1]; return $this->$method($param); } else { return false; } } # 检测传入数据 protected function param($param, $check) { if (empty($param['order'])) { return 'order'; } if (!isset($param['cash'])) { $param['cash'] = 0; } $detail = array(); if ($check) { foreach ($check as $k => $v) { if (!isset($param[$k])) { return $k; } elseif (empty($param[$k]) && $param[$k] != 0) { return $k; } else { $detail[$v] = $param[$k]; } } } # 获取订单号 $merchant_order = $param['order']; $param['order'] = $this->createOrder($param['order']); $account = ''; if (isset($param['card']) && $param['card']) { $account = $param['card']; } elseif (isset($param['mobile']) && $param['mobile']) { $account = $param['mobile']; } elseif (isset($param['qq']) && $param['qq']) { $account = $param['qq']; } elseif (isset($param['account']) && $param['account']) { $account = $param['account']; } $parent_order_id = ''; if (isset($param['parent_order_id']) && $param['parent_order_id']) { $parent_order_id = $param['parent_order_id']; } $response = array(); if ($this->async) { $this->data['order'] = $param['order']; $log['type'] = 'merchant_request'; $log['config'] = $this->data; $this->log($log); # 下单 $status = 1; if (isset($this->data['product_key']) && ($this->data['product_key'] != 'zshcz1')) { } elseif ($account) { $account_state = OrderService::instance()->countByAccount($account); if (!$account_state) { return '已达到最大下单次数'; } # 检测该账号是否最近5分钟之内下单,如果有,就延迟下单 $account_order = OrderService::instance()->getByAccount($account, $param['cash']); if ($account_order) { $this->data['time'] = time() + 900; $status = -1; } else { /* # 检测汇天下当前石化渠道是否同时有80个处理中 if ($this->product && isset($this->product['limit_order']) && $this->product['limit_order'] > 0) { $total = OrderService::instance()->getNum($this->data['product']); if ($total >= $this->product['limit_order']) { $status = -3; } } */ } } if (isset($param['s']) && $param['s']) { $this->channel['order_limit'] = 0; unset($param['s']); } if (isset($this->channel['order_limit']) && $this->channel['order_limit'] > 0) { $status = -3; } $state = $this->create($param['order'], '', $merchant_order, $param['cash'], '', $this->data, $response, $status, $account, $parent_order_id, $this->card_id, false); if (!$state) { return '余额不足下单失败'; } if ($status == 1) { $this->queue('submit', $this->data); } return array('order' => $param['order'], 'account' => $account, 'status' => 1); } elseif ($this->data['merchant'] == 6000 && $account) { # 检测该账号是否最近5分钟之内下单,如果有,就延迟下单 $account_order = OrderService::instance()->getByAccount($account, $param['cash']); if ($account_order) { $this->data['order'] = $param['order']; $this->data['time'] = time() + 300; $status = -1; $this->create($param['order'], '', $merchant_order, $param['cash'], '', $this->data, $response, $status, $account, $parent_order_id, $this->card_id, false); return 'order'; } } elseif (!$this->data['use_product']) { $order = OrderService::instance()->get($param['order']); if ($order && $order['status'] > 1 && $order['status'] != 5) { return 'order'; } } /* if (!$this->async) { $merchant_info = MerchantService::instance()->get($this->data['merchant']); if ($merchant_info['account_surplus'] < $param['cash'] && $merchant_info['credit_surplus'] < $param['cash']) { $response['msg'] = 'error'; $response['data'] = '余额不足下单失败'; $this->create($param['order'], '', $merchant_order, $param['cash'], '', $this->data, $response, 3, $account); return $response['data']; } } */ return array ( 'order' => $param['order'], 'merchant_order' => $merchant_order, 'cash' => $param['cash'], 'detail' => $detail, 'account' => $account, 'status' => -1 ); } # 获取店铺id protected function shop() { if ($this->data) { $product = $this->product ? $this->product : ProductService::instance()->get($this->data['merchant'], $this->data['product']); if ($product && $product['shop_id'] > 0) { $shop = ShopService::instance()->get($product['shop_id']); if ($shop && $shop['shop_id']) { return $shop['shop_id']; } } } return 0; } protected function getUrl($url,$version = 3) { $host = sysconf('system_host'); $api_host = sysconf('api_notify_host'); if($api_host && $version == 4){ $host = $api_host; } if (!$host) { if (isset($_SERVER['SERVER_PORT']) && isset($_SERVER['HTTP_HOST'])) { $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; $host = $protocol.$_SERVER['HTTP_HOST']; } else { $host = 'https://reapi.gcdat.com'; } } return $host . $url; } # 通知回调地址 protected function getNotify($order, $type, $api_id = false): string { if ($api_id) { $type .= '&s_api_id=' . $api_id; } $api_host = sysconf('api_notify_host'); if($api_host){ $url = $this->getUrl('/call?s_order=' . $order . '&s_type=' . $type.'&version=v4.0',4); }else{ $url = $this->getUrl('/gateway/api.notify/call?s_order=' . $order . '&s_type=' . $type);#修改原为v3.0之前版本 } return $url; } # 创建订单 protected function create($order_id, $channel_order_id, $merchant_order_id, $cash, $url, $request, &$response, $status = 1, $account = '', $parent_order_id = '', $card_id = false, $kou = true) { $response_data = ''; if ($response) { if ($response['msg'] == 'success') { # 直接成功 $status = 2; } elseif ($response['msg'] == 'ok') { $status = 4; } elseif ($response['msg'] == 'yescard') { $status = 7; } else { $status = 3; } $response_data = $response['data']; } if ($this->data) { $product = $this->product ? $this->product : ProductService::instance()->get($this->data['merchant'], $this->data['product']); if ($product) { if ($card_id == -1) { $status = 3; } $channel = ChannelService::instance()->get($product['cid']); if ($channel && $product['cid'] == $channel['id']) { if (isset($this->data['project_id']) && $this->data['project_id']) { $project_id = $this->data['project_id']; } else { $project_id = false; } $order = OrderService::instance()->up($this->data['merchant'], $channel['id'], $product['id'], $product['key'], $order_id, $channel_order_id, $merchant_order_id, $cash, $url, $request, $response_data, $status, $account, $parent_order_id, $project_id, $card_id, $this->data['param'], $kou); if (!$order) { return false; } # 商户后续操作 $merchant = MerchantService::instance()->get($this->data['merchant']); if ($status == 3 && $merchant['id'] == 2 && isset($this->data['product_key']) && $channel['id'] == '2' && isset($request['szProductId']) && strstr($request['szProductId'], '3000')) { # 如果直接下单失败,就获取另外一个相同key的商品吧 $use_product = array(); if (empty($this->data['use_product'])) { $this->data['use_product'] = array(); } $this->data['use_product'][] = $product['id']; $isp = false; if (isset($order['isp']) && $order['isp']) { $isp_config = \app\merchant\service\PercentService::instance()->getIsp(); $isp = $isp_config[$order['isp']]; } $new_product = $this->getProduct($this->data['merchant'], $this->data['product_key'], $this->data['use_product'], $cash, $isp); if ($new_product) { # 记录失败的订单信息 OrderAutoService::instance()->up($order['id']); $response['msg'] = ChannelService::instance()->use($this->data['merchant'], $new_product, $this->data['param'], false, $order_id, $this->data['use_product']); return true; } } if ($status == 3 && isset($merchant['stop']) && ($merchant['stop'] == 2 || $merchant['stop'] == 4)) { # 是否暂停 $num = 1; $order_id = $order['order_id'] . '_' . $num; # 该渠道下单失败,重新下单,并暂停,等待手动启动 # 记录失败的订单信息 OrderAutoService::instance()->up($order['id']); # 修改状态 OrderService::instance()->upStatus($order['order_id'], -5, '', false, $num); return true; } elseif ($status == 3 && $merchant['order_auto'] == 2 && isset($this->data['product_key'])) { # 如果直接下单失败,就获取另外一个相同key的商品吧 $use_product = array(); if (empty($this->data['use_product'])) { $this->data['use_product'] = array(); } $this->data['use_product'][] = $product['id']; $isp = false; if (isset($order['isp']) && $order['isp']) { $isp_config = \app\merchant\service\PercentService::instance()->getIsp(); $isp = $isp_config[$order['isp']]; } $new_product = $this->getProduct($this->data['merchant'], $this->data['product_key'], $this->data['use_product'], $cash, $isp); if ($new_product) { # 记录失败的订单信息 OrderAutoService::instance()->up($order['id']); $response['msg'] = ChannelService::instance()->use($this->data['merchant'], $new_product, $this->data['param'], false, $order_id, $this->data['use_product']); return true; } } /* if ($status == 3 && $product['id'] == 13 && isset($response['array']['status_code']) && $response['array']['status_code'] == '40000' && isset($response['array']['status_msg']) && strstr($response['array']['status_msg'], '账户余额')) { # 如果是八达通失败,并且账户余额不足,就不通知用户失败,直接延迟到失败表中 $this->data['order'] = $order_id; OrderService::instance()->upStatus($order_id, -2, $this->data); return true; } */ $result = array(); $result['project_id'] = $project_id; $result['order_id'] = $order_id; $result['merchant_order_id'] = $order['merchant_order_id']; $result['status'] = $order['status']; $result['notify_num'] = $order['merchant_callback_num']; $result['cash'] = $order['cash']; $result['account'] = $order['account']; if (isset($order['isp']) && $order['isp']) { $result['isp'] = $order['isp']; } $result['order'] = $order; if (isset($this->data['param']['notify']) && $this->data['param']['notify']) { $result['notify'] = $this->data['param']['notify']; } MerchantService::instance()->up($order['id'], $merchant, $product['id'], $product['key'], $result); return true; } } } return false; } private function getProduct($mid, $product, $use_product, $cash, $isp = false) { $product_data = MerchantProductService::instance()->getAll($mid, $product); if ($product_data) { foreach ($product_data as $k => $v) { if ($v['cash']) { if ($isp && (strstr($v['cash'], '联通') || strstr($v['cash'], '移动') || strstr($v['cash'], '电信'))) { $cash = $isp; } $temp = explode(',', $v['cash']); if (!in_array($cash, $temp)) { continue; } } if (!in_array($v['pid'], $use_product)) { return $v['pid']; } } } return false; } # 创建订单号 protected function createOrder($order) { if (isset($this->data['order']) && $this->data['order']) { return $this->data['order']; } $order = $this->createOrderId(); $info = OrderService::instance()->get($order); if (!$info) { return $order; } else { return $this->createOrder($order); } //return sha1($this->data['merchant'] . '_' . $this->data['product'] . '_' . $this->createOrderId() . '_' . $order); } # 生成订单号 protected function createOrderId() { $prefix = sysconf('system_order_perfix'); if (!$prefix) { $prefix = 'Q'; } return $prefix . date('Ymd').substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%02d', mt_rand(100000, 999999)); // if (function_exists('session_create_id')) { // return strtoupper(session_create_id()); // } else { // $charid = strtoupper(md5(uniqid(mt_rand(), true))); // return substr($charid, 0, 8) . substr($charid, 8, 4) . substr($charid, 12, 4) . substr($charid, 16, 4) . substr($charid, 20, 12); // } } # 队列 protected function queue($key, $value = false) { $redis = RedisService::getInstance(); if (!$value) { return $redis->pop($key); } else { return $redis->push($key, $value); } } # 请求数据 protected function curl($method, $url, $param = array(), $json = false, $header = false) { $log['type'] = 'request'; $log['url'] = $url; $log['param'] = $param; $log['config'] = $this->data; $this->log($log); $data = CurlService::getInstance($url, $param, $method, $json, $header)->result(); if (!$data) { $data = CurlService::getInstance($url, $param, $method, $json, $header)->result(); } return $data; } public function http_send($type,$url,$data,$json = false) { $header = 'Content-type: application/x-www-form-urlencoded'; $payload = $data; if($json){ $payload = json_encode($data); // 将数据编码为JSON $header = 'Content-type: application/json'; } $options = array( 'http' => array( 'header' => $header, 'method' => $type, 'content' => $payload, ), ); $context = stream_context_create($options); // 创建流上下文 $result = file_get_contents($url, false, $context); // 发送请求 if ($result === FALSE) { return 'Error'; } return $result; // 解码JSON响应 // return $this->async; } # 通用签名方法,如果有渠道不同的签名方式,需要单独实现 protected function sign($request, $type = 'sha1', $suffix = '', $empty = true) { return AuthService::signature($request, $type, $suffix, $empty); } protected function getParam($param, $token, $sign_type = 1) { return AuthService::get($param, $token, $sign_type); } protected function timestamp() { return AuthService::timestamp(); } # 记录日志 protected function log($data) { Log::write('gateway', 'log', $data); } protected function json_decode($data) { $array = json_decode($data, true); if (!is_array($array) || is_null($array) || json_last_error() != JSON_ERROR_NONE) { return false; } return $array; } # 获取手机号 protected function getMobile($card, $n = 1) { $info = \app\merchant\service\MobileService::instance()->get($card); if ($info && $info['mobile']) { return $info['mobile']; } $tel_arr = array( '130','131','132','133','134','135','136','137','138','139','144','147','150','151','152','153','155','156','157','158','159','176','177','178','180','181','182','183','184','185','186','187','188','189','199', ); for($i = 0; $i < $n; $i++) { $tmp[] = $tel_arr[array_rand($tel_arr)].mt_rand(1000,9999).mt_rand(1000,9999); // $tmp[] = $tel_arr[array_rand($tel_arr)].'xxxx'.mt_rand(1000,9999); } $tem = array_unique($tmp); if (isset($tem[0])) { $mobile = $tem[0]; \app\merchant\service\MobileService::instance()->up($card, $mobile); } else { $mobile = '13800138000'; } return $mobile; } # 获取手机运营商 protected function isp($mobile) { return ChannelService::instance()->isp($mobile); } # 获取产品id protected function getGid($cash) { $info = $this->product; if ($info) { if (isset($info['gid_rule']) && $info['gid_rule']) { $rule = json_decode($info['gid_rule'], true); if (isset($rule[$cash]) && $rule[$cash]) { $gid = $rule[$cash]; return $gid; } } if (isset($info['gid']) && $info['gid']) { return $info['gid']; } } return -1; } //随机生成n条手机号 protected function randomMobile($n = 1) { $tel_arr = array( '130','131','132','133','134','135','136','137','138','139','144','147','150','151','152','153','155','156','157','158','159','176','177','178','180','181','182','183','184','185','186','187','188','189', ); for($i = 0; $i < $n; $i++) { $tmp[] = $tel_arr[array_rand($tel_arr)].$this->rands().$this->rands(); } return array_unique($tmp); } //随机生成身份证号 protected function randomShenfen() { $city = array(11,12,13,14,15,21,22,23,31,32,33,34,35,36,37,41,42,43,44,45,46,50,51,52,53,54,61,62,63,64,65,71,81,82,91); //校验位 $parity = array('1','0','X','9','8','7','6','5','4','3','2'); // $a = array('a','b','c'); $arr = array(0,1,2,3,4,5); $str = ''; // echo $city[array_rand($city)]; //前两位 $str .=$city[array_rand($city)]; //地区位后四位 for($i=0;$i<4;$i++){ $str .=$arr[array_rand($arr)]; } //出生年 随机20世纪 $str .= '19'.mt_rand(0,9).mt_rand(0,9); //月份 $month = array('01','02','03','04','05','06','07','08','09','10','11','12'); $str .=$month[array_rand($month)]; //天 $day = mt_rand(0,3); if($day==3){ $str .=$day.mt_rand(0,1); }else{ $str .=$day.mt_rand(0,9); } //顺序码 for($i=0;$i<3;$i++){ $str .=mt_rand(0,9); } //计算加权因子 for($i=18;$i>1;$i--){ $factor[] = fmod(pow(2,$i-1),11); } //将加权因子和身份证号对应相乘,再求和 $sum = 0; for($i=0;$igetName(); } protected function rands() { $s = mt_rand(1000,9999); if ($s == '1234') { return $this->rands(); } elseif ($s == '2345') { return $this->rands(); } elseif ($s == '3456') { return $this->rands(); } elseif ($s == '4567') { return $this->rands(); } elseif ($s == '5678') { return $this->rands(); } elseif ($s == '6789') { return $this->rands(); } return $s; } protected function maketime($v) { if (!$v) { return ''; } if (is_numeric($v)) { return $v; } if (is_array($v)) { $v = $v[1]; } if (strstr($v, ' ')) { $t = explode(' ', $v); $v = $t[0]; $s = explode(':', $t[1]); } else { $s = array(0, 0, 0); } if (!isset($s[1])) { $s[1] = 0; } if (!isset($s[2])) { $s[2] = 0; } if (strstr($v, '-')) { $t = explode('-', $v); } elseif (strstr($v, '/')) { $u = explode('/', $v); $t[0] = $u[2]; $t[1] = $u[0]; $t[2] = $u[1]; } if (!isset($t)) { $t = array(0, 0, 0); } if (!isset($t[1])) { $t[1] = 0; } if (!isset($t[2])) { $t[2] = 0; } $v = mktime($s[0], $s[1], $s[2], $t[1], $t[2], $t[0]); return $v; } # 获取手机运营商 protected function getMobileInfo($mobile) { //git clone https://github.com/shitoudev/phone-location /www/wwwroot/api/extend/phone # 此处不同服务器需改动的绝对路径 // $file = '/www/wwwroot/bao111/extend/phone/src/PhoneLocation.php'; $file = dirname(__DIR__, 4).'/extend/phone/src/PhoneLocation.php'; include $file; $pl = new \Shitoudev\Phone\PhoneLocation(); $info = $pl->find($mobile); return $info; } public function diy_send_post($notify_url, $post_data, $type): mixed { $postdate = http_build_query($post_data); $options = array( 'http' => array( 'method' => $type, 'header' => 'Content-type:application/x-www-form-urlencoded', 'content' => $postdate, 'timeout' => 15 * 60 // 超时时间(单位:s) ) ); $context = stream_context_create($options); return file_get_contents($notify_url, false, $context); } }