Paywx.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. <?php
  2. namespace app\api\controller;
  3. use app\common\controller\Api;
  4. use fast\Random;
  5. use think\Validate;
  6. use think\Db;
  7. use app\common\model\MoneyLog;
  8. /**
  9. * 会员接口
  10. */
  11. class Paywx extends Api
  12. {
  13. protected $noNeedLogin = ['notifwxh5','wxh5','wxxcx'];
  14. protected $noNeedRight = '*';
  15. public function _initialize()
  16. {
  17. parent::_initialize();
  18. $this->Usermodel = model('User');
  19. }
  20. public function paywxh5(){
  21. $site=config('site');
  22. $user = $this->auth->getUser();
  23. if(!$user){
  24. $this->error(__('user不对'));
  25. }
  26. $number = date('ymdh', time()) . rand(10000, 99999);//订单编
  27. $amount=input('total',0);
  28. if($amount<=0){
  29. $this->error(__('金额不对'));
  30. }
  31. $iswx=input('iswx');
  32. $buytype='微信h5';
  33. if($iswx=='wxgzh'){
  34. $buytype='微信公众号';
  35. }
  36. $up=[
  37. 'type'=>1,
  38. 'uid'=>$user['id'],
  39. 'tdnum'=>input('tdnum'),//支付通道
  40. 'amount'=>$amount,
  41. 'out_trade_no'=>$number,
  42. 'createtime'=>time(),
  43. 'buytype'=>$buytype,
  44. ];
  45. $id=Db::name('paylog')->insertGetId($up);
  46. $urls=$site['imgurl'].'/index/paydsf/wxh5?out_trade_no='.$number;
  47. if($iswx=='wxgzh'){
  48. $urls=$site['imgurl'].'/index/index/pay?id='.$id;
  49. }
  50. $this->success('订单提交成功 正在跳转支付',$urls);
  51. }
  52. public function notifwxh5(){
  53. header('Access-Control-Allow-Origin: *');
  54. header('Content-type: text/plain');
  55. $xmlData = file_get_contents('php://input');
  56. $data = $this->FromXml($xmlData);
  57. $this->dingding_log($data);
  58. $result_code=isset($data['result_code'])?$data['result_code']:'1';
  59. if($result_code == "SUCCESS"){//处理交易完成或者支付成功的通知 //获取订单号
  60. $out_trade_no = isset($data["out_trade_no"])?$data["out_trade_no"]:'';
  61. $trade_no = isset($data["transaction_id"])?$data["transaction_id"]:'';
  62. $order=Db::name('paylog')->where('out_trade_no',$out_trade_no)->find();
  63. //$this->dingding_log($order);
  64. if($order['type']==1){
  65. Db::startTrans();
  66. try {
  67. if($order['oid']>0){
  68. $ordervd=Db::name('video_order')->where('id',$order['oid'])->find();
  69. if($ordervd){
  70. Db::name('video_order')->where('id',$order['oid'])->update(['type'=>2,'paytype'=>'微信','ftime'=>time()]);
  71. $this->yongjin($order['oid'],$order['uid'],$order['amount'],'级消费佣金结算');//佣金结算
  72. $this->dailiyongjin($order['oid'],$ordervd['sid'],$ordervd['smid'],$order['uid'],$order['amount'],'佣金结算');//后台代理佣金结算
  73. }
  74. }else{
  75. $this->money($order['amount'],$order['uid'],0,$sxf=0);
  76. }
  77. $up=['type'=>2,'trade_no'=>$trade_no,'ftime'=>time()];
  78. Db::name('paylog')->where('out_trade_no',$out_trade_no)->update($up);
  79. Db::commit();
  80. echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
  81. }catch (Exception $e){
  82. Db::rollback();
  83. $this->error($e->getMessage());
  84. }
  85. }else{
  86. echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
  87. }
  88. }
  89. }
  90. public function notifydsf()//第三方充值回调
  91. {
  92. $this->dingding_log($_REQUEST);
  93. //Db::transaction(function () {
  94. $returncode=isset($_REQUEST["returncode"])?$_REQUEST["returncode"]:1;
  95. if($returncode == "00"){//处理交易完成或者支付成功的通知 //获取订单号
  96. $out_trade_no = isset($_REQUEST["orderid"])?$_REQUEST["orderid"]:'';
  97. $order=Db::name('paylog')->where('out_trade_no',$out_trade_no)->find();
  98. $this->dingding_log($order);
  99. if($order['type']==1){
  100. $up=[
  101. 'type'=>2,
  102. 'ftime'=>time()
  103. ];
  104. Db::startTrans();
  105. try {
  106. $this->money($order['amount'],$order['uid'],0,$sxf=0);
  107. Db::name('paylog')->where('out_trade_no',$out_trade_no)->update($up);
  108. Db::commit();
  109. echo 'OK';
  110. }catch (Exception $e){
  111. Db::rollback();
  112. $this->error($e->getMessage());
  113. }
  114. }else{
  115. echo 'OK';
  116. }
  117. }
  118. //});
  119. }
  120. public function paywxxcx(){
  121. $site=config('site');
  122. $user = $this->auth->getUser();
  123. if(!$user){
  124. $this->error(__('user不对'));
  125. }
  126. $number = date('ymdh', time()) . rand(10000, 99999);//订单编
  127. $amount=input('total',0);
  128. $openid=input('openid',0);
  129. if($amount<=0){
  130. $this->error(__('金额不对'));
  131. }
  132. $up=[
  133. 'type'=>1,
  134. 'uid'=>$user['id'],
  135. 'amount'=>$amount,
  136. 'out_trade_no'=>$number,
  137. 'createtime'=>time(),
  138. 'buytype'=>'微信小程序',
  139. ];
  140. $id=Db::name('paylog')->insertGetId($up);
  141. $trs=$this->wxxcx($number,$amount,$openid);
  142. $this->success('提交成功',$trs);
  143. }
  144. public function wxxcx($number,$amount,$openid){
  145. $site=config('site');
  146. $appid =$site['weixinxcx']['appid'];//小程序的appid
  147. $key=$site['wxpay']['key'];
  148. $data=[
  149. 'appid'=>$appid,
  150. 'mch_id'=>$site['wxpay']['mch_id'],//账户号
  151. 'nonce_str'=>$this->getNonceStr(),//随机字符串,不长于32位
  152. 'body'=>'测试商品',//商品描述
  153. 'out_trade_no'=>$number,//商户订单号,不长于32位
  154. 'total_fee'=>$amount*100,//总金额,以分为单位
  155. 'spbill_create_ip'=>$_SERVER['REMOTE_ADDR'],//用户端请求支付时的IP
  156. 'notify_url'=>$site['imgurl'].'/api/paywx/notifwxh5',//异步通知回调地址,必须是可直接访问地址,不能携带参数
  157. // 'timeStamp'=> time(),
  158. 'openid' => $openid, //用户id
  159. 'trade_type'=>'JSAPI',
  160. ];
  161. $data['sign']=$this->genSign($data, $key);
  162. $params=$this->array_to_xml($data);
  163. //var_dump($params);
  164. $request=$this->postda($params);
  165. //$objectxml = simplexml_load_string($request);//将文件转换成 对象
  166. $objectxml = simplexml_load_string($request,"SimpleXMLElement", LIBXML_NOCDATA);
  167. $xmljson= json_encode($objectxml );//将对象转换个JSON
  168. $xmlarray=json_decode($xmljson,true);//将json转换成数组
  169. $prepay_id=isset($xmlarray['prepay_id'])?$xmlarray['prepay_id']:'';
  170. $parameters1 = array(
  171. 'appId' => $appid, //小程序 ID
  172. 'timeStamp' => '' . time() . '', //时间戳
  173. 'nonceStr' => $this->getNonceStr(), //随机串
  174. 'package' => 'prepay_id=' . $prepay_id, //数据包
  175. 'signType' => 'MD5'//签名方式
  176. );
  177. $parameters1['sign'] = $this->genSign($parameters1,$key);//签名
  178. $parameters1['timeStamp']=$parameters1['timeStamp'];
  179. if($prepay_id){
  180. return $parameters1;
  181. }else{
  182. $this->error($xmlarray);
  183. }
  184. }
  185. /**
  186. *
  187. * 产生随机字符串,不长于32位
  188. * @param int $length
  189. * @return 产生的随机字符串
  190. */
  191. public function getNonceStr($length = 32)
  192. {
  193. $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
  194. $str ="";
  195. for ( $i = 0; $i < $length; $i++ ) {
  196. $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
  197. }
  198. return $str;
  199. }
  200. /**
  201. * 组建签名
  202. * @param array $params 请求参数
  203. * @param string $key 秘钥
  204. */
  205. public function genSign($params, $key)
  206. {
  207. foreach ($params as $k=>$v) {
  208. if (!$v) {
  209. unset($params[$k]);
  210. }
  211. }
  212. ksort($params);
  213. $paramStr = '';
  214. foreach ($params as $k => $v) {
  215. $paramStr = $paramStr . $k . '=' . $v . '&';
  216. }
  217. $paramStr = $paramStr . 'key='.$key;
  218. $sign = strtoupper(md5($paramStr));
  219. return $sign;
  220. }
  221. /**
  222. * 将数组转为XML
  223. * @param array $params 支付请求参数
  224. */
  225. public function array_to_xml($params)
  226. {
  227. if(!is_array($params)|| count($params) <= 0) {
  228. return false;
  229. }
  230. $xml = "<xml>";
  231. foreach ($params as $key=>$val) {
  232. if (is_numeric($val)) {
  233. $xml.="<".$key.">".$val."</".$key.">";
  234. } else {
  235. $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
  236. }
  237. }
  238. $xml.="</xml>";
  239. return $xml;
  240. }
  241. public function postda($params){
  242. $ch = curl_init();
  243. curl_setopt($ch, CURLOPT_URL, 'https://api.mch.weixin.qq.com/pay/unifiedorder');
  244. curl_setopt($ch, CURLOPT_HEADER, 0);
  245. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  246. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  247. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  248. curl_setopt($ch, CURLOPT_POST, 1);
  249. curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
  250. $return = curl_exec($ch);
  251. curl_close($ch);
  252. return $return;
  253. }
  254. public function money($money,$user_id,$id,$sxf=0){
  255. $user = $this->Usermodel::get($user_id);
  256. if ($user && $money != 0) {
  257. $before = $user->money;
  258. $after = $user->money + $money;
  259. //更新会员信息
  260. $user->save(['money' => $after]);
  261. //写入日志
  262. MoneyLog::create(['user_id' => $user_id, 'money' => $money, 'before' => $before, 'after' => $after,'fid' => $id, 'sxf' =>$sxf,'memo' => '用户充值']);
  263. }else{
  264. $this->error(__('金额不对'));
  265. }
  266. }
  267. public function dingding_log($content)
  268. {
  269. $r = $_SERVER['DOCUMENT_ROOT'] . '/api_log/' . date('Y-m-d_H-i-s', time()) . '.txt';
  270. $fp = fopen($r, 'w+');
  271. fwrite($fp, "执行日期:" . date('Y-m-d H:i:s', time()) . ' ' . var_export($content, true));
  272. fclose($fp);
  273. }
  274. public function FromXml($xml)
  275. {
  276. //将XML转为array
  277. //禁止引用外部xml实体
  278. libxml_disable_entity_loader(true);
  279. $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  280. return $values;
  281. }
  282. }