addHeaders(); //添加头部请求 $user_info = $this->checkUserIsExist($_POST['uid']); //检查用户 $uid = $_POST['uid']; $time_unix=$this->getUnixTimestamp(); //用户id //选择支付类型,通道支付宝1、支付宝2、微信1 $channel = $_POST['channel']; $pay_amount = $_POST['payAmount']; //充值金额 //1是没首充 0有奖励 $yn_first_pay = $_POST['yn_first_pay']; //获取通道编码 $channel_info = M("td_zf")->where("tongdao='$channel' and $pay_amount>=min_ and $pay_amount<=max_")->find(); $pay_bankcode = $channel_info["td_id"]; $beizhu = $channel_info["td_name"]; $number=$uid.$time_unix.$this->random_num(5); //提交时间 $ttime = time(); $pay_applydate = date("Y-m-d H:i:s",$ttime);; //服务端通知 $pay_notifyurl = C("appUrl").'/bibidd/YiyunPay/call_back_coins'; //页面跳转通知 $pay_callbackurl = C("appUrl").'/bibidd/YiyunPay/call_back_coins'; //付款人 IP $pay_ip = $this->getIp(); //商户号 $pay_memberid = 10067; //密钥 $member_key = 'M2R7R7JJRETCYOLCMCA3S5P4B0NVDDYZ2V6WETSPRJTZLAPQLARPBX3ZYVQTWGFFSUO26MOZRPYQDDOF08J2TOV9QVVZ4DFPF6SK5QQVE0PPJBOUNUMCGSVLIBZJMKZG'; //订单号 $pay_orderid = "$number" ; //商品名称 $pay_productname = $uid.$beizhu.$pay_bankcode; $dingdan['order_id'] = $number; $dingdan['uid'] = $uid; $dingdan['order_str'] = $pay_productname; $dingdan['order_ip'] = $pay_ip; $dingdan['apply_date'] = $pay_applydate; $dingdan['apply_time'] = $ttime; $dingdan['order_type'] = '待支付'; $dingdan['amount'] = $pay_amount; $tmpl_amount= $pay_amount*100; //通道是以分为单位 $stringSignTemp="mchId=$pay_memberid&productId=$pay_bankcode&mchOrderNo=$pay_orderid&amount=$tmpl_amount¬ifyUrl=$pay_notifyurl&returnUrl=$pay_callbackurl¶m2=$yn_first_pay" ; $md5Value =$this-> generateSortedMd5($stringSignTemp,$member_key); M("pay_test")->add($dingdan); $post_data = array( 'mchId' => $pay_memberid, 'productId' =>$pay_bankcode, 'mchOrderNo' => $pay_orderid, 'amount' => $tmpl_amount, 'param2' => $yn_first_pay, 'notifyUrl' => $pay_notifyurl, 'returnUrl' => $pay_callbackurl, 'sign' => $md5Value, ); $rs= $this->send_post('http://pay.yunmei.cfd/api/pay/create_order', $post_data); if (empty($rs) || $rs['retCode']=='FAIL') { $e_data['status'] = '0'; $e_data['code'] = '204';//未携带参数,请求失败 $e_data['pay_url'] = '';//未携带参数,请求失败 $e_data['message'] = '请重试。'; echo json_encode($e_data); }else{ $rs['code'] = 200; echo json_encode($rs); } } /** * md5 * @param $params * @return string */ private function generateSortedMd5($params,$key) { // 解析参数字符串为关联数组 parse_str($params, $paramArray); // 过滤空值参数(包括null和空字符串) $filteredParams = array_filter($paramArray, function($value) { return $value !== '' && $value !== null && $value !== 0; }); // 按键名进行字典序排序 ksort($filteredParams); // 构建查询字符串(不进行URL编码) $queryString = $this->buildRawQueryString($filteredParams,$key); // 计算MD5哈希 $md5 = md5($queryString); return $md5; } /** * 构建原始查询字符串(不进行URL编码) */ private function buildRawQueryString($params,$key1) { $base_string = ''; foreach ($params as $key => $value) { $base_string .= $key . '=' . $value . '&'; } $base_string.= 'key='.$key1; return $base_string; } function send_post($url, $post_data) { // 构建 multipart/form-data 格式数据 $boundary = uniqid(); $content = $this->buildFormDataBody($post_data, $boundary); $options = array( 'http' => array( 'method' => 'POST', 'header' => "Content-Type: multipart/form-data; boundary=$boundary\r\n", 'content' => $content, 'timeout' => 15 * 60 // 超时时间(单位:s) ) ); $context = stream_context_create($options); // 使用错误抑制符@防止警告直接输出,我们会捕获异常 $result = @file_get_contents($url, false, $context); // 检查请求是否成功 if ($result === false) { $error = error_get_last(); throw new Exception('HTTP请求失败: ' . ($error['message'] ?? '未知错误')); } // 尝试解码JSON响应 $decoded_result = json_decode($result, true); // 检查JSON解码是否成功 if (json_last_error() !== JSON_ERROR_NONE) { // 如果不是JSON响应,返回原始结果 return $result; } return $decoded_result; } private function buildFormDataBody($data, $boundary) { $eol = "\r\n"; $body = ''; foreach ($data as $key => $value) { $body .= "--$boundary$eol"; $body .= "Content-Disposition: form-data; name=\"$key\"$eol$eol"; $body .= $value . $eol; } $body .= "--$boundary--$eol"; return $body; } /** * 领航回调地址 * @return void */ public function call_back_coins(){ $this->addHeaders(); //验签 $params = $this->validate_sign(); $post = $_POST; if ($post == null) { $post = file_get_contents("php://input"); } //支付状态,0-订单生成,1-支付中,2-支付成功,3-业务处理完成 $chenggong['name'] = $post['status']; //商户编号 $memberid = $post['mchId']; //订单号 $orderid = $post['mchOrderNo']; //订单金额 $amount = $post['amount']/100; //交易流水号 $transaction_id = $post['payOrderId']; //交易时间 $datetime = $post['paySuccTime']; //交易状态 $returncode = $post['status']; //扩展返回 $attach = $post['param2']; //attach 如果是0 //防止重复回调,2024-4-15 $idempotent_check = M("huidiao_test")->where("memberid = '$memberid' AND orderid = '$orderid' AND transaction_id = '$transaction_id'")->find(); if(!empty($idempotent_check)) { exit('success'); die(); } //防止重复回调,2024-6-1 $uid = M("pay_test")->where("order_id='$orderid'")->getField("uid"); if(empty($uid)) { exit('success'); die(); } $post['uid'] = $uid; $post['time'] = time(); try { //添加回调表用户来源add_url $add_url1= M("user_info")->where("id='$uid'")->getField("add_url"); //回调 $callback_info['uid']=$uid; $callback_info['time']=time(); $callback_info['name']=$post['productId']; $callback_info['code']=$post['productId']; $callback_info['memberid']=$post['mchId']; $callback_info['orderid']=$post['mchOrderNo']; $callback_info['amount']=$post['amount']/100; $callback_info['transaction_id']=$post['payOrderId']; $callback_info['datetime']=$post['paySuccTime']; $callback_info['returncode']=$post['status']; $callback_info['attach']=$post['param2']; $callback_info['add_url']=$add_url1; $callback_info['ip']=$this->getIp(); M("huidiao_test")->add($callback_info); }catch (Exception $e) { exit('success'); die(); } //end,2024-6-1 //支付成功 if ($chenggong['name']==2) { //交易成功 将用户改成会员 $now_time_chuo = time(); $chenggong['order_type'] = '已支付'; $chenggong['pay_time'] = $now_time_chuo; $chenggong['amount_due'] =$amount; $chenggong['mifeng_id'] =$transaction_id; if($attach=='-1') { //加金币 switch ($amount) { case '40.0000': $ks = M("user_info")->where("id=$uid")->setInc('gold_coins_number',40); break; case '60.0000': $ks = M("user_info")->where("id=$uid")->setInc('gold_coins_number',60); break; case '100.0000': M("user_info")->where("id=$uid")->setInc('gold_coins_number',100); break; case '200.0000': M("user_info")->where("id=$uid")->setInc('gold_coins_number',200); break; case '500.0000': M("user_info")->where("id=$uid")->setInc('gold_coins_number',500); break; case '1000.0000': M("user_info")->where("id=$uid")->setInc('gold_coins_number',1000); break; default: M("user_info")->where("id=$uid")->setInc('gold_coins_number',$amount); } }elseif ($attach=='xx') { //直冲添加会员 switch ($amount) { case '50.0000': //永久会员 //永久会员 $over_time_chuo_jj = '9999999999'; $huiyuan['vip_over_time'] =$over_time_chuo_jj; $huiyuan['vip_yn'] = '1'; $this->xiaofei_detail($uid,"开通会员","永久会员",$amount); //另外的统计表 $vip_table_list['code'] = 1; $vip_table_list['time'] = time() ; $vip_table_list['uid'] = $uid; $vip_table_list['amount'] = $amount; M("vip_add_list")->add($vip_table_list); break; case '50.0000': //一个月会员 //一个月会员 $over_time_chuo_jj = $now_time_chuo + (3600*24*30); $huiyuan['vip_over_time'] =$over_time_chuo_jj; $huiyuan['vip_yn'] = '2'; $this->xiaofei_detail($uid,"开通会员","月会员",$amount); //另外的统计表 $vip_table_list['code'] = 2; $vip_table_list['time'] = time() ; $vip_table_list['uid'] = $uid; $vip_table_list['amount'] = $amount; M("vip_add_list")->add($vip_table_list); break; case '40.0000': //周会员 //7天 $over_time_chuo_yue = $now_time_chuo + (3600*24*7); $huiyuan['vip_over_time'] = $over_time_chuo_yue; $huiyuan['vip_yn'] = '3'; $this->xiaofei_detail($uid,"开通会员","7天会员",$amount); //另外的统计表 $vip_table_list['code'] = 3; $vip_table_list['time'] = time() ; $vip_table_list['uid'] = $uid; $vip_table_list['amount'] = $amount; M("vip_add_list")->add($vip_table_list); break; default: echo "type error"; die(); } //更新为会员 M("user_info")->where("id=$uid")->save($huiyuan); }//end huiyuan //更新用户充值金额 M("user_info")->where("id=$uid")->setInc('vip_money',$amount); //修改订单相关 并且添加支付表 M("pay_test")->where("order_id='$orderid'")->save($chenggong); //统计用户充值总额 2024-11-15(上线时间为切割点) $this->count_chongzhi($uid,$amount); //代理返佣,统计 $this->proxy_pay_count($uid,$amount); exit('success'); } } private function validate_sign() { $params = [ 'payOrderId' => $_POST['payOrderId'], 'mchId' => $_POST['mchId'], 'productId' => $_POST['productId'], 'mchOrderNo' => $_POST['mchOrderNo'], 'amount' => $_POST['amount'], 'status' => $_POST['status'], 'paySuccTime' => $_POST['paySuccTime'], 'sign' => $_POST['sign'], 'param2' => $_POST['param2'], ]; ksort($params); //自然排序 //拼接请求 $base_string = ''; foreach ($params as $key => $value) { if($key=='sign') continue; $base_string .= $key . '=' . $value . '&'; } $base_string.= 'key=M2R7R7JJRETCYOLCMCA3S5P4B0NVDDYZ2V6WETSPRJTZLAPQLARPBX3ZYVQTWGFFSUO26MOZRPYQDDOF08J2TOV9QVVZ4DFPF6SK5QQVE0PPJBOUNUMCGSVLIBZJMKZG'; $sign_check = md5($base_string); //校验签名 $sign = $_POST['sign']; if(strcasecmp($sign_check , $sign)!=0) { // 验签失败 $trans_id = $_POST['payOrderId']; $update_inf["mifeng_id"]='验签失败:'.$sign_check.'对方签名'.$sign; M("pay_test")->where("mifeng_id='$trans_id'")->save($update_inf); $data['code'] = '200'; $data['message'] = '非法请求'; //echo json_encode($data); exit('success'); die(); } return $params; } }