Pay.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  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 Pay extends Api
  12. {
  13. protected $noNeedLogin = ['notify','notifycz','notifydsf'];
  14. protected $noNeedRight = '*';
  15. public function _initialize()
  16. {
  17. parent::_initialize();
  18. $this->Usermodel = model('User');
  19. }
  20. public function index()
  21. {
  22. // // 启动事务
  23. // Db::startTrans();
  24. // try {
  25. if(input('id',0)>0){
  26. $id=input('id');
  27. $data=Db::name('task')->where('id',$id)->find();
  28. if($data){
  29. $number = date('ymdh', time()) . rand(10000, 99999);//订单编号
  30. Db::name('task')->where('id',$id)->update(['out_trade_no'=>$number,'buytype'=>input('buytype')]);
  31. $data=Db::name('task')->where('id',$id)->find();
  32. }else{
  33. $this->error(__('订单数据不对'));
  34. }
  35. }else {
  36. $number = date('ymdh', time()) . rand(10000, 99999);//订单编号
  37. if(!input('price')){
  38. $this->error(__('金额不对'));
  39. }
  40. $datapost =input('param.');//订单数据
  41. $datapost['buzs']=htmlspecialchars_decode($datapost['buzs']);
  42. if(input('endtime')=='数量完成自动结束'){
  43. $endtimesjc=100000000000;
  44. }else{
  45. $endtimesjc=strtotime(input('endtime'));
  46. }
  47. $up=[
  48. 'type'=>input('type'),
  49. 'uid'=>input('uid'),
  50. 'name'=>input('name'),
  51. 'rwurl'=>input('rwurl'),
  52. 'buz'=>$datapost['buzs'],
  53. 'price'=>input('price'),
  54. 'sum'=>input('sum'),
  55. 'sumsy'=>input('sum'),
  56. 'endtime'=>input('endtime'),
  57. 'subtime'=>input('subtime'),
  58. 'shetime'=>input('shetime'),
  59. 'endtimesjc'=>$endtimesjc,
  60. 'buytype'=>input('buytype'),
  61. 'zprice'=>input('price')*input('sum'),
  62. 'out_trade_no'=>$number,
  63. 'createtime'=>time(),
  64. ];
  65. $id=Db::name('task')->insertGetId($up);
  66. $data=$up;
  67. }
  68. $site=config('site');
  69. $amount=$data['zprice'];
  70. if(!$amount){
  71. $this->error(__('金额不对'));
  72. }
  73. // 异步通知地址
  74. $notify_url = $site['zfb']['notifyurl'];
  75. // 订单标题
  76. $subject = 'wool订单';
  77. // 订单详情
  78. $body = 'wool致力于打造最好的移动服务平台';
  79. // 订单号,示例代码使用时间值作为唯一的订单ID号
  80. if($data['buytype']=='支付宝'){
  81. $this->allpay($amount,$subject,$body,$number,$notify_url);
  82. }else if($data['buytype']=='余额'){
  83. $this->yuepay($amount,input('uid'),$id);
  84. }
  85. // // 提交事务
  86. // Db::commit();
  87. // } catch (\Exception $e) {
  88. // // 回滚事务
  89. // var_dump($e);
  90. // Db::rollback();
  91. // }
  92. }
  93. public function videopay()
  94. {
  95. $datavideo_order=Db::name('video_order')->where(['sid'=>input('id'),'uid'=>input('uid'),'lx'=>2])->find();
  96. $datavideo_order1=Db::name('video_order')->where(['sid'=>input('id'),'uid'=>input('uid'),'lx'=>1])->find();
  97. $sad=1;
  98. $lx=input('lx');
  99. if($datavideo_order1){
  100. if($datavideo_order1['type']==2){
  101. $sad=2;
  102. $this->error(__('已经全集购买'));
  103. }
  104. }
  105. if($datavideo_order and $lx==2){
  106. if($datavideo_order['type']==2){
  107. $this->error(__('已经单集购买'));
  108. }
  109. $number = date('ymdh', time()) . rand(10000, 99999);//订单编号
  110. $price=input('priceq');
  111. $pricebuy=input('pricebuy');
  112. if(input('lx')==2){
  113. $price=input('priced');
  114. $pricebuy=input('pricebuy');
  115. }
  116. $up=[
  117. 'type'=>1,
  118. 'lx'=>$lx,//1 全章购买 2单集购买
  119. 'uid'=>input('uid'),
  120. 'name'=>input('namet'),
  121. 'img'=>input('img'),
  122. 'price'=>$price,
  123. 'sum'=>input('sum'),
  124. 'sid'=>input('pid'),
  125. 'smid'=>input('smid'),
  126. 'paytype'=>input('buytype'),
  127. 'zprice'=>$pricebuy*input('sum'),
  128. 'out_trade_no'=>$number,
  129. ];
  130. Db::name('video_order')->where(['id'=>$datavideo_order['id']])->update($up);
  131. $id=$datavideo_order['id'];
  132. $data=$up;
  133. }else{
  134. $number = date('ymdh', time()) . rand(10000, 99999);//订单编号
  135. if(!input('pricebuy')){
  136. $this->error(__('金额不对'));
  137. }
  138. $price=input('priceq');
  139. $pricebuy=input('pricebuy');
  140. if(input('lx')==2){
  141. $price=input('priced');
  142. $pricebuy=input('pricebuy');
  143. }
  144. $up=[
  145. 'type'=>1,
  146. 'lx'=>$lx,//1 全章购买 2单集购买
  147. 'uid'=>input('uid'),
  148. 'name'=>input('namet'),
  149. 'img'=>input('img'),
  150. 'price'=>$price,
  151. 'sum'=>input('sum'),
  152. 'sid'=>input('pid'),
  153. 'smid'=>input('smid'),
  154. 'paytype'=>input('buytype'),
  155. 'zprice'=>$pricebuy*input('sum'),
  156. 'out_trade_no'=>$number,
  157. 'createtime'=>time(),
  158. 'updatetime'=>time(),
  159. ];
  160. //$this->error($up);
  161. $id=Db::name('video_order')->insertGetId($up);
  162. $data=$up;
  163. }
  164. $site=config('site');
  165. $amount=$data['zprice'];
  166. if(!$amount){
  167. $this->error(__('金额不对'));
  168. }
  169. // 异步通知地址
  170. $notify_url = $site['zfb']['notifyurl'];
  171. // 订单标题
  172. $subject = 'wool订单';
  173. // 订单详情
  174. $body = 'wool致力于打造最好的移动服务平台';
  175. // 订单号,示例代码使用时间值作为唯一的订单ID号
  176. //var_dump($data['paytype']);
  177. if($data['paytype']=='支付宝'){
  178. $this->allpay($amount,$subject,$body,$number,$notify_url);
  179. }else if($data['paytype']=='余额'){
  180. $this->videoyuepay($amount,input('uid'),$id);
  181. }else if($data['paytype']=='微信'){
  182. $wxlx=input('wxlx');
  183. if($wxlx=='wxxcx'){
  184. $openid=input('openid');
  185. if(!$openid){
  186. $this->error(__('openid不对'));
  187. }
  188. $this->paywxxcx($id,$number,$amount,$openid);
  189. }else if($wxlx=='wxh5'){
  190. $buytype='微信h5';
  191. $this->paywxh5($id,$number,$amount,$buytype);
  192. }else if($wxlx=='wxgzh'){
  193. $buytype='微信公众号';
  194. $this->paywxh5($id,$number,$amount,$buytype);
  195. }
  196. }
  197. }
  198. public function paywxh5($oid,$number,$amount,$buytype){
  199. $site=config('site');
  200. $user = $this->auth->getUser();
  201. if(!$user){
  202. $this->error(__('user不对'));
  203. }
  204. if($amount<=0){
  205. $this->error(__('金额不对'));
  206. }
  207. $up=[
  208. 'type'=>1,
  209. 'uid'=>$user['id'],
  210. 'tdnum'=>input('tdnum'),//支付通道
  211. 'amount'=>$amount,
  212. 'out_trade_no'=>$number,
  213. 'createtime'=>time(),
  214. 'buytype'=>$buytype,
  215. 'oid'=>$oid,
  216. ];
  217. $id=Db::name('paylog')->insertGetId($up);
  218. $urls=$site['imgurl'].'/index/paydsf/wxh5?out_trade_no='.$number;
  219. if($buytype=='微信公众号'){
  220. $urls=$site['imgurl'].'/index/index/pay?id='.$id;
  221. }
  222. $this->success('订单提交成功 正在跳转支付',$urls);
  223. }
  224. public function paywxxcx($oid,$number,$amount,$openid){
  225. $site=config('site');
  226. $user = $this->auth->getUser();
  227. if(!$user){
  228. $this->error(__('user不对'));
  229. }
  230. if($amount<=0){
  231. $this->error(__('金额不对'));
  232. }
  233. $up=[
  234. 'type'=>1,
  235. 'uid'=>$user['id'],
  236. 'amount'=>$amount,
  237. 'out_trade_no'=>$number,
  238. 'createtime'=>time(),
  239. 'buytype'=>'微信小程序',
  240. 'oid'=>$oid,
  241. ];
  242. $id=Db::name('paylog')->insertGetId($up);
  243. $modelxcx = new \app\api\controller\Paywx;
  244. $trs=$modelxcx->wxxcx($number,$amount,$openid);
  245. $this->success('提交成功',$trs);
  246. }
  247. public function videoyuepay($money,$user_id,$id)//余额支付
  248. {
  249. $user = $this->Usermodel::get($user_id);
  250. if ($user && $money != 0) {
  251. $data=Db::name('video_order')->where('id',$id)->find();
  252. if($user->money<$money){
  253. $this->error(__('余额不足'));
  254. }
  255. $before = $user->money;
  256. $after = $user->money - $money;
  257. if($data['type']==1){
  258. Db::startTrans();
  259. try {
  260. //更新会员信息
  261. $user->save(['money' => $after]);
  262. //写入日志
  263. MoneyLog::create(['user_id' => $user_id, 'money' => $money, 'before' => $before, 'after' => $after, 'memo' => '用户消费']);
  264. Db::name('video_order')->where('id',$id)->update(['type'=>2,'paytype'=>'余额','ftime'=>time()]);
  265. $this->yongjin($id,$user_id,$money,'级消费佣金结算');//佣金结算
  266. $this->dailiyongjin($id,$data['sid'],$data['smid'],$user_id,$money,'佣金结算');//后台代理佣金结算
  267. Db::commit();
  268. $this->success(__('操作成功'));
  269. }catch (Exception $e){
  270. Db::rollback();
  271. $this->error($e->getMessage());
  272. }
  273. }else if($data['type']>1){
  274. $this->error(__('已经支付'));
  275. }
  276. }else{
  277. $this->error(__('金额不对'));
  278. }
  279. }
  280. public function yuepay($money,$user_id,$id)//余额支付
  281. {
  282. $user = $this->Usermodel::get($user_id);
  283. if ($user && $money != 0) {
  284. $data=Db::name('task')->where('id',$id)->find();
  285. if($user->money<$money){
  286. $this->error(__('余额不足'));
  287. }
  288. $before = $user->money;
  289. $after = $user->money - $money;
  290. //更新会员信息
  291. $user->save(['money' => $after]);
  292. //写入日志
  293. MoneyLog::create(['user_id' => $user_id, 'money' => $money, 'before' => $before, 'after' => $after, 'memo' => '用户消费']);
  294. if($data['paytype']==1){
  295. $up=[
  296. 'paytype'=>2,
  297. 'buytype'=>'余额',
  298. 'ftime'=>time()
  299. ];
  300. if (Db::name('task')->where('id',$id)->update($up)){
  301. $this->success(__('操作成功'));
  302. }
  303. }else if($data['paytype']>1){
  304. $this->error(__('已经支付'));
  305. }
  306. }else{
  307. $this->error(__('金额不对'));
  308. }
  309. }
  310. public function czpay(){
  311. $site=config('site');
  312. $user = $this->auth->getUser();
  313. if(!$user){
  314. $this->error(__('user不对'));
  315. }
  316. $number = date('ymdh', time()) . rand(10000, 99999);//订单编
  317. $amount=input('total',0);
  318. $notify_url = $site['zfb']['notifyurlcz'];
  319. // 订单标题
  320. $subject = 'wool充值';
  321. // 订单详情
  322. $body = 'wool致力于打造最好的移动服务平台';
  323. if($amount<=0){
  324. $this->error(__('金额不对'));
  325. }
  326. $up=[
  327. 'type'=>1,
  328. 'uid'=>$user['id'],
  329. 'amount'=>input('total'),
  330. 'out_trade_no'=>$number,
  331. 'createtime'=>time(),
  332. ];
  333. $id=Db::name('paylog')->insertGetId($up);
  334. if(input('type','allpay')=='iap'){
  335. $this->success('请求成功',$number);
  336. }else{
  337. $this->allpay($amount,$subject,$body,$number,$notify_url);
  338. }
  339. }
  340. public function dsfczpay(){
  341. $site=config('site');
  342. $user = $this->auth->getUser();
  343. if(!$user){
  344. $this->error(__('user不对'));
  345. }
  346. $number = date('ymdh', time()) . rand(10000, 99999);//订单编
  347. $amount=input('total',0);
  348. if($amount<=0){
  349. $this->error(__('金额不对'));
  350. }
  351. $up=[
  352. 'type'=>1,
  353. 'uid'=>$user['id'],
  354. 'tdnum'=>input('tdnum'),
  355. 'amount'=>$amount,
  356. 'out_trade_no'=>$number,
  357. 'createtime'=>time(),
  358. 'buytype'=>isset($site['dsfzf']['zfname'])?$site['dsfzf']['zfname']:'',
  359. ];
  360. $id=Db::name('paylog')->insertGetId($up);
  361. $urls=$site['imgurl'].'/index/paydsf?out_trade_no='.$number;
  362. $this->success('订单提交成功 正在跳转支付',$urls);
  363. }
  364. public function czpayiaptz(){
  365. $out_trade_no=input('out_trade_no');
  366. $order=Db::name('paylog')->where('out_trade_no',$out_trade_no)->find();
  367. //$this->dingding_log($order);
  368. if($order['type']==1){
  369. $up=[
  370. 'type'=>2,
  371. 'payment'=>null,
  372. 'trade_no'=>null,
  373. 'buyer'=>null,
  374. 'buytype'=>'苹果',
  375. 'ftime'=>time()
  376. ];
  377. Db::startTrans();
  378. try {
  379. $this->money($order['amount'],$order['uid'],0,$sxf=0);
  380. Db::name('paylog')->where('out_trade_no',$out_trade_no)->update($up);
  381. Db::commit();
  382. $this->success('支付成功');
  383. }catch (Exception $e){
  384. Db::rollback();
  385. $this->error($e->getMessage());
  386. }
  387. }else{
  388. $this->success('已经支付');
  389. }
  390. }
  391. public function allpay($amount,$subject,$body,$out_trade_no,$notify_url)//支付宝支付
  392. {
  393. $total = floatval($amount);
  394. if(!$total){
  395. $this->error(__('金额不对'));
  396. }
  397. //require_once('/vendor/alipayrsa2/AopSdk.php');
  398. //Vendor('AopSdk.alipayrsa2');
  399. // require_once './vendor/alipayrsa2/aop/AopClient.php';
  400. // require_once './vendor/alipayrsa2/aop/request/AlipayTradeAppPayRequest.php';
  401. vendor('alipayrsa2.AopSdk');
  402. $site=config('site');
  403. $aop = new \AopClient;
  404. $aop->gatewayUrl = "https://openapi.alipay.com/gateway.do";
  405. $aop->appId = $site['zfb']['appId'];
  406. //开发者私钥去头去尾去回车,一行字符串
  407. $aop->rsaPrivateKey = $site['zfb']['rsaPrivateKey'];
  408. $aop->format = "json";
  409. $aop->charset = "UTF-8";
  410. $aop->signType = "RSA2";
  411. //请填写支付宝公钥,一行字符串
  412. $aop->alipayrsaPublicKey = $site['zfb']['alipayrsaPublicKey'];
  413. //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
  414. $request = new \AlipayTradeAppPayRequest();
  415. //SDK已经封装掉了公共参数,这里只需要传入业务参数
  416. $bizcontent = "{\"body\":\"".$body."\","
  417. . "\"subject\": \"".$subject."\","
  418. . "\"out_trade_no\": \"".$out_trade_no."\","
  419. . "\"timeout_express\": \"30m\","
  420. . "\"total_amount\": \"".$total."\","
  421. . "\"product_code\":\"QUICK_MSECURITY_PAY\""
  422. . "}";
  423. $request->setNotifyUrl($notify_url);
  424. $request->setBizContent($bizcontent);
  425. //这里和普通的接口调用不同,使用的是sdkExecute
  426. $response = $aop->sdkExecute($request);
  427. // 注意:这里不需要使用htmlspecialchars进行转义,直接返回即可
  428. //$this->success(__('获取成功'),$response);
  429. echo $response;
  430. }
  431. public function notify()
  432. {
  433. if ($_POST){
  434. //Db::transaction(function () {
  435. if($_POST['trade_status'] == 'TRADE_SUCCESS' or $_POST['trade_status'] == 'TRADE_FINISHED'){//处理交易完成或者支付成功的通知 //获取订单号
  436. $out_trade_no = $_POST['out_trade_no'];//交易号
  437. $trade_no = $_POST['trade_no'];//订单支付时间
  438. $gmt_payment = $_POST['gmt_payment'];//转换为时间戳
  439. $order=Db::name('task')->where('out_trade_no',$out_trade_no)->find();
  440. if($order['paytype']==1){
  441. $up=[
  442. 'paytype'=>2,
  443. 'payment'=>$gmt_payment,
  444. 'trade_no'=>$trade_no,
  445. 'buyer'=>$_POST['buyer_logon_id'],
  446. 'buytype'=>'支付宝',
  447. 'ftime'=>time()
  448. ];
  449. if (Db::name('task')->where('out_trade_no',$out_trade_no)->update($up)){
  450. echo 'success';
  451. }
  452. }else{
  453. echo 'success';
  454. }
  455. }
  456. //});
  457. }
  458. }
  459. public function notifycz()
  460. {
  461. if ($_POST){
  462. //$this->dingding_log($_POST);
  463. //Db::transaction(function () {
  464. if($_POST['trade_status'] == 'TRADE_SUCCESS' or $_POST['trade_status'] == 'TRADE_FINISHED'){//处理交易完成或者支付成功的通知 //获取订单号
  465. $out_trade_no = $_POST['out_trade_no'];//交易号
  466. $trade_no = $_POST['trade_no'];//订单支付时间
  467. $gmt_payment = $_POST['gmt_payment'];//转换为时间戳
  468. $order=Db::name('paylog')->where('out_trade_no',$out_trade_no)->find();
  469. //$this->dingding_log($order);
  470. if($order['type']==1){
  471. $up=[
  472. 'type'=>2,
  473. 'payment'=>$gmt_payment,
  474. 'trade_no'=>$trade_no,
  475. 'buyer'=>$_POST['buyer_logon_id'],
  476. 'buytype'=>'支付宝',
  477. 'ftime'=>time()
  478. ];
  479. Db::startTrans();
  480. try {
  481. $this->money($order['amount'],$order['uid'],0,$sxf=0);
  482. Db::name('paylog')->where('out_trade_no',$out_trade_no)->update($up);
  483. Db::commit();
  484. echo 'success';
  485. }catch (Exception $e){
  486. Db::rollback();
  487. $this->error($e->getMessage());
  488. }
  489. }else{
  490. echo 'success';
  491. }
  492. }
  493. //});
  494. }
  495. }
  496. public function notifydsf()//第三方充值回调
  497. {
  498. $this->dingding_log($_REQUEST);
  499. //Db::transaction(function () {
  500. $returncode=isset($_REQUEST["returncode"])?$_REQUEST["returncode"]:1;
  501. if($returncode == "00"){//处理交易完成或者支付成功的通知 //获取订单号
  502. $out_trade_no = isset($_REQUEST["orderid"])?$_REQUEST["orderid"]:'';
  503. $order=Db::name('paylog')->where('out_trade_no',$out_trade_no)->find();
  504. $this->dingding_log($order);
  505. if($order['type']==1){
  506. $up=[
  507. 'type'=>2,
  508. 'ftime'=>time()
  509. ];
  510. Db::startTrans();
  511. try {
  512. $this->money($order['amount'],$order['uid'],0,$sxf=0);
  513. Db::name('paylog')->where('out_trade_no',$out_trade_no)->update($up);
  514. Db::commit();
  515. echo 'OK';
  516. }catch (Exception $e){
  517. Db::rollback();
  518. $this->error($e->getMessage());
  519. }
  520. }else{
  521. echo 'OK';
  522. }
  523. }
  524. //});
  525. }
  526. public function money($money,$user_id,$id,$sxf=0){
  527. $user = $this->Usermodel::get($user_id);
  528. if ($user && $money != 0) {
  529. $before = $user->money;
  530. $after = $user->money + $money;
  531. //更新会员信息
  532. $user->save(['money' => $after]);
  533. //写入日志
  534. MoneyLog::create(['user_id' => $user_id, 'money' => $money, 'before' => $before, 'after' => $after,'fid' => $id, 'sxf' =>$sxf,'memo' => '用户充值']);
  535. }else{
  536. $this->error(__('金额不对'));
  537. }
  538. }
  539. public function dingding_log($content)
  540. {
  541. $r = $_SERVER['DOCUMENT_ROOT'] . '/api_log/' . date('Y-m-d_H-i-s', time()) . '.txt';
  542. $fp = fopen($r, 'w+');
  543. fwrite($fp, "执行日期:" . date('Y-m-d H:i:s', time()) . ' ' . var_export($content, true));
  544. fclose($fp);
  545. }
  546. public function FromXml($xml)
  547. {
  548. //将XML转为array
  549. //禁止引用外部xml实体
  550. libxml_disable_entity_loader(true);
  551. $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  552. return $values;
  553. }
  554. }