Paywx.php 11 KB

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