LinghangPayController.class.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. <?php
  2. namespace bibidd\Controller;
  3. use Bibidd\Controller\CommonBaseController;
  4. /**
  5. * 领航支付通道
  6. */
  7. class LinghangPayController extends CommonBaseController
  8. {
  9. /**
  10. * 领航支付
  11. * @return void
  12. */
  13. public function pay()
  14. {
  15. $this->addHeaders(); //添加头部请求
  16. $user_info = $this->checkUserIsExist($_POST['uid']); //检查用户
  17. $uid = $_POST['uid'];
  18. $time_unix=$this->getUnixTimestamp();
  19. //用户id
  20. //选择支付类型,通道支付宝1、支付宝2、微信1
  21. $channel = $_POST['channel'];
  22. $pay_amount = $_POST['payAmount']; //充值金额
  23. //1是没首充 0有奖励
  24. $yn_first_pay = $_POST['yn_first_pay'];
  25. //获取通道编码
  26. $channel_info = M("td_zf")->where("tongdao='$channel' and $pay_amount>=min_ and $pay_amount<=max_")->find();
  27. $pay_bankcode = $channel_info["td_id"];
  28. $beizhu = $channel_info["td_name"];
  29. $number=$uid.$time_unix.$this->random_num(5);
  30. //提交时间
  31. $ttime = time();
  32. $pay_applydate = date("Y-m-d H:i:s",$ttime);;
  33. //服务端通知
  34. $pay_notifyurl = C("appUrl").'/bibidd/LinghangPay/call_back_coins';
  35. //页面跳转通知
  36. $pay_callbackurl = C("appUrl").'/bibidd/LinghangPay/huidiao_gold_coins';
  37. //付款人 IP
  38. $pay_ip = $this->getIp();
  39. //商户号
  40. $pay_memberid = 'M1746445379';
  41. //密钥
  42. $member_key = 'r4sucel7kfdqvagjdu9kap1otlgr82jy';
  43. //订单号
  44. $pay_orderid = "$number" ;
  45. //商品名称
  46. $pay_productname = $uid.$beizhu.$pay_bankcode;
  47. $dingdan['order_id'] = $number;
  48. $dingdan['uid'] = $uid;
  49. $dingdan['order_str'] = $pay_productname;
  50. $dingdan['order_ip'] = $pay_ip;
  51. $dingdan['apply_date'] = $pay_applydate;
  52. $dingdan['apply_time'] = $ttime;
  53. $dingdan['order_type'] = '待支付';
  54. $dingdan['amount'] = $pay_amount;
  55. $tmpl_amount= $pay_amount*100; //通道是以分为单位
  56. $stringSignTemp="mchId=$pay_memberid&wayCode=$pay_bankcode&subject=$pay_productname&outTradeNo=$pay_orderid&amount=$tmpl_amount&extParam=$yn_first_pay&clientIp=198.2.208.143&notifyUrl=$pay_notifyurl&returnUrl=$pay_callbackurl&reqTime=$ttime" ;
  57. $md5Value =$this-> generateSortedMd5($stringSignTemp,$member_key);
  58. M("pay_test")->add($dingdan);
  59. $post_data = array(
  60. 'mchId' => $pay_memberid,
  61. 'wayCode' =>$pay_bankcode,
  62. 'subject' => $pay_productname,
  63. 'outTradeNo' => $pay_orderid,
  64. 'amount' => $tmpl_amount,
  65. 'extParam' => $yn_first_pay,
  66. 'clientIp' => '198.2.208.143',
  67. 'notifyUrl' => $pay_notifyurl,
  68. 'returnUrl' => $pay_callbackurl,
  69. 'reqTime' => $ttime,
  70. 'sign' => $md5Value,
  71. );
  72. $rs= $this->send_post('https://r6rivnnp.abkoiuhnbrqwkjngpay.xyz/Pay_SG', $post_data);
  73. if (empty($rs) || $rs['status']=='error') {
  74. $e_data['status'] = '0';
  75. $e_data['code'] = '204';//未携带参数,请求失败
  76. $e_data['pay_url'] = '';//未携带参数,请求失败
  77. $e_data['message'] = '请重试。';
  78. echo json_encode($e_data);
  79. }else{
  80. $rs['code'] = 200;
  81. echo json_encode($rs);
  82. }
  83. }
  84. /**
  85. * md5
  86. * @param $params
  87. * @return string
  88. */
  89. private function generateSortedMd5($params,$key)
  90. {
  91. // 解析参数字符串为关联数组
  92. parse_str($params, $paramArray);
  93. // 过滤空值参数(包括null和空字符串)
  94. $filteredParams = array_filter($paramArray, function($value) {
  95. return $value !== '' && $value !== null && $value !== 0;
  96. });
  97. // 按键名进行字典序排序
  98. ksort($filteredParams);
  99. // 构建查询字符串(不进行URL编码)
  100. $queryString = $this->buildRawQueryString($filteredParams,$key);
  101. // 计算MD5哈希
  102. $md5 = md5($queryString);
  103. return $md5;
  104. }
  105. /**
  106. * 构建原始查询字符串(不进行URL编码)
  107. */
  108. private function buildRawQueryString($params,$key1)
  109. {
  110. $base_string = '';
  111. foreach ($params as $key => $value) {
  112. $base_string .= $key . '=' . $value . '&';
  113. }
  114. $base_string.= 'key='.$key1;
  115. return $base_string;
  116. }
  117. function send_post($url, $post_data) {
  118. // 将数据编码为JSON格式
  119. $json_data = json_encode($post_data);
  120. // 检查JSON编码是否成功
  121. if ($json_data === false) {
  122. throw new Exception('JSON编码失败: ' . json_last_error_msg());
  123. }
  124. $options = array(
  125. 'http' => array(
  126. 'method' => 'POST',
  127. 'header' => "Content-Type: application/json\r\n" .
  128. "Accept: application/json\r\n",
  129. 'content' => $json_data,
  130. 'timeout' => 15 * 60 // 超时时间(单位:s)
  131. )
  132. );
  133. $context = stream_context_create($options);
  134. // 使用错误抑制符@防止警告直接输出,我们会捕获异常
  135. $result = @file_get_contents($url, false, $context);
  136. // 检查请求是否成功
  137. if ($result === false) {
  138. $error = error_get_last();
  139. throw new Exception('HTTP请求失败: ' . ($error['message'] ?? '未知错误'));
  140. }
  141. // 尝试解码JSON响应
  142. $decoded_result = json_decode($result, true);
  143. // 检查JSON解码是否成功
  144. if (json_last_error() !== JSON_ERROR_NONE) {
  145. // 如果不是JSON响应,返回原始结果
  146. return $result;
  147. }
  148. return $decoded_result;
  149. }
  150. /**
  151. * 领航回调地址
  152. * @return void
  153. */
  154. public function call_back_coins(){
  155. $this->addHeaders();
  156. //验签
  157. $params = $this->validate_sign();
  158. $post = $_POST;
  159. if ($post == null) {
  160. $post = file_get_contents("php://input");
  161. }
  162. $chenggong['name'] = $params['state'];
  163. //商户编号
  164. $memberid = $params['mchId'];
  165. //订单号
  166. $orderid = $params['outTradeNo'];
  167. //订单金额
  168. $amount = $params['amount']/100;
  169. //交易流水号
  170. $transaction_id = $params['tradeNo'];
  171. //交易时间
  172. $datetime = $params['notifyTime'];
  173. //交易状态
  174. $returncode = $params['state'];
  175. //扩展返回
  176. $attach = $params['extParam'];
  177. //attach 如果是0
  178. //防止重复回调,2024-4-15
  179. $idempotent_check = M("huidiao_test")->where("memberid = '$memberid' AND orderid = '$orderid' AND transaction_id = '$transaction_id'")->find();
  180. if(!empty($idempotent_check))
  181. {
  182. exit('SUCCESS');
  183. die();
  184. }
  185. //防止重复回调,2024-6-1
  186. $uid = M("pay_test")->where("order_id='$orderid'")->getField("uid");
  187. if(empty($uid))
  188. {
  189. exit('SUCCESS');
  190. die();
  191. }
  192. $post['uid'] = $uid;
  193. $post['time'] = time();
  194. try {
  195. //添加回调表用户来源add_url
  196. $add_url1= M("user_info")->where("id='$uid'")->getField("add_url");
  197. //回调
  198. $callback_info['uid']=$uid;
  199. $callback_info['time']=time();
  200. $callback_info['name']=$params['subject'];
  201. $callback_info['code']=$params['originTradeNo'];
  202. $callback_info['memberid']=$params['mchId'];
  203. $callback_info['orderid']=$params['outTradeNo'];
  204. $callback_info['amount']=$params['amount']/100;
  205. $callback_info['transaction_id']=$params['tradeNo'];
  206. $callback_info['datetime']=$params['notifyTime'];
  207. $callback_info['returncode']=$params['state'];
  208. $callback_info['attach']=$params['extParam'];
  209. $callback_info['add_url']=$add_url1;
  210. $callback_info['ip']=$this->getIp();
  211. M("huidiao_test")->add($callback_info);
  212. }catch (Exception $e)
  213. {
  214. exit('SUCCESS');
  215. die();
  216. }
  217. //end,2024-6-1
  218. //支付成功
  219. if ($chenggong['name']==1) {
  220. //交易成功 将用户改成会员
  221. $now_time_chuo = time();
  222. $chenggong['order_type'] = '已支付';
  223. $chenggong['pay_time'] = $now_time_chuo;
  224. $chenggong['amount_due'] =$amount;
  225. $chenggong['mifeng_id'] =$transaction_id;
  226. if($attach=='-1')
  227. {
  228. //加金币
  229. switch ($amount) {
  230. case '40.0000':
  231. $ks = M("user_info")->where("id=$uid")->setInc('gold_coins_number',40);
  232. break;
  233. case '60.0000':
  234. $ks = M("user_info")->where("id=$uid")->setInc('gold_coins_number',60);
  235. break;
  236. case '100.0000':
  237. M("user_info")->where("id=$uid")->setInc('gold_coins_number',100);
  238. break;
  239. case '200.0000':
  240. M("user_info")->where("id=$uid")->setInc('gold_coins_number',200);
  241. break;
  242. case '500.0000':
  243. M("user_info")->where("id=$uid")->setInc('gold_coins_number',500);
  244. break;
  245. case '1000.0000':
  246. M("user_info")->where("id=$uid")->setInc('gold_coins_number',1000);
  247. break;
  248. default:
  249. M("user_info")->where("id=$uid")->setInc('gold_coins_number',$amount);
  250. }
  251. }elseif ($attach=='xx')
  252. {
  253. //直冲添加会员
  254. switch ($amount) {
  255. case '50.0000': //永久会员
  256. //永久会员
  257. $over_time_chuo_jj = '9999999999';
  258. $huiyuan['vip_over_time'] =$over_time_chuo_jj;
  259. $huiyuan['vip_yn'] = '1';
  260. $this->xiaofei_detail($uid,"开通会员","永久会员",$amount);
  261. //另外的统计表
  262. $vip_table_list['code'] = 1;
  263. $vip_table_list['time'] = time() ;
  264. $vip_table_list['uid'] = $uid;
  265. $vip_table_list['amount'] = $amount;
  266. M("vip_add_list")->add($vip_table_list);
  267. break;
  268. case '50.0000': //一个月会员
  269. //一个月会员
  270. $over_time_chuo_jj = $now_time_chuo + (3600*24*30);
  271. $huiyuan['vip_over_time'] =$over_time_chuo_jj;
  272. $huiyuan['vip_yn'] = '2';
  273. $this->xiaofei_detail($uid,"开通会员","月会员",$amount);
  274. //另外的统计表
  275. $vip_table_list['code'] = 2;
  276. $vip_table_list['time'] = time() ;
  277. $vip_table_list['uid'] = $uid;
  278. $vip_table_list['amount'] = $amount;
  279. M("vip_add_list")->add($vip_table_list);
  280. break;
  281. case '40.0000': //周会员
  282. //7天
  283. $over_time_chuo_yue = $now_time_chuo + (3600*24*7);
  284. $huiyuan['vip_over_time'] = $over_time_chuo_yue;
  285. $huiyuan['vip_yn'] = '3';
  286. $this->xiaofei_detail($uid,"开通会员","7天会员",$amount);
  287. //另外的统计表
  288. $vip_table_list['code'] = 3;
  289. $vip_table_list['time'] = time() ;
  290. $vip_table_list['uid'] = $uid;
  291. $vip_table_list['amount'] = $amount;
  292. M("vip_add_list")->add($vip_table_list);
  293. break;
  294. default:
  295. echo "type error";
  296. die();
  297. }
  298. //更新为会员
  299. M("user_info")->where("id=$uid")->save($huiyuan);
  300. }//end huiyuan
  301. //更新用户充值金额
  302. M("user_info")->where("id=$uid")->setInc('vip_money',$amount);
  303. //修改订单相关 并且添加支付表
  304. M("pay_test")->where("order_id='$orderid'")->save($chenggong);
  305. //统计用户充值总额 2024-11-15(上线时间为切割点)
  306. $this->count_chongzhi($uid,$amount);
  307. //代理返佣,统计
  308. $this->proxy_pay_count($uid,$amount);
  309. exit('SUCCESS');
  310. }
  311. }
  312. private function validate_sign()
  313. {
  314. // $params = [
  315. // 'mchId' => $_POST['mchId'],
  316. // 'tradeNo' => $_POST['tradeNo'],
  317. // 'outTradeNo' => $_POST['outTradeNo'],
  318. // 'originTradeNo' => $_POST['originTradeNo'],
  319. // 'amount' => $_POST['amount'],
  320. // 'subject' => $_POST['subject'],
  321. // 'extParam' => $_POST['extParam'],
  322. // 'state' => $_POST['state'],
  323. // 'notifyTime' => $_POST['notifyTime'],
  324. // 'sign' => $_POST['sign'],
  325. // ];
  326. $params = json_decode(file_get_contents('php://input'), true);
  327. ksort($params); //自然排序
  328. //拼接请求
  329. $base_string = '';
  330. foreach ($params as $key => $value) {
  331. if($key=='sign') continue;
  332. $base_string .= $key . '=' . $value . '&';
  333. }
  334. $base_string.= 'key=r4sucel7kfdqvagjdu9kap1otlgr82jy';
  335. $sign_check = md5($base_string);
  336. //校验签名
  337. $sign = $params['sign'];
  338. if(strcasecmp($sign_check , $sign)!=0)
  339. {
  340. // 验签失败
  341. $trans_id = $_POST['transaction_id'];
  342. $update_inf["mifeng_id"]='验签失败:'.$sign_check.'对方签名'.$sign;
  343. M("pay_test")->where("mifeng_id='$trans_id'")->save($update_inf);
  344. $data['code'] = '200';
  345. $data['message'] = '非法请求';
  346. //echo json_encode($data);
  347. exit('SUCCESS');
  348. die();
  349. }
  350. return $params;
  351. }
  352. }