Paywx.php 16 KB

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