Supay.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. <?php
  2. namespace app\api\controller;
  3. use app\common\controller\Api;
  4. use think\Db;
  5. use addons\epay\library\Service;
  6. use app\common\model\Wallet;
  7. use think\Exception;
  8. /**
  9. * 苏宁支付h5拉起
  10. */
  11. class Supay extends Api
  12. {
  13. protected $noNeedLogin = ['testpay','notify'];
  14. protected $noNeedRight = ['*'];
  15. public function vip_recharge()
  16. {
  17. Db::startTrans();
  18. try {
  19. $rc_id = input('rc_id',0);
  20. $pay_type = input('pay_type','wechat');
  21. $uid = $this->auth->id;
  22. if(!$rc_id){
  23. throw new Exception('请选择会员套餐');
  24. }
  25. //赋值money
  26. $recharge_config = Db::name('payvip_config')->where('id',$rc_id)->find();
  27. $money = $recharge_config['money'];
  28. if($money <= 0) {
  29. throw new Exception('支付金额必须大于0');
  30. }
  31. if($money > 10000){
  32. throw new Exception('支付金额太大');
  33. }
  34. //会员等级冲突
  35. //当前是会员,但是却要向下级续费,直接提示报错
  36. //修改等级,向上立刻改,向下不允许
  37. $wallet_info = model('wallet')->getWallet($this->auth->id);
  38. if($wallet_info['vip_endtime'] > time() && $recharge_config['vip_level'] < $wallet_info['vip_level']){
  39. throw new Exception('当前会员没有过期,不能续费');
  40. }
  41. //创建订单
  42. $data = [];
  43. $data['status'] = 0;
  44. $pay_no = createUniqueNo('V',$uid);
  45. $data['pay_no'] = $pay_no;
  46. $data['money'] = $money;
  47. $data['payment_class'] = $pay_type;
  48. $data['user_id'] = $uid;
  49. $data['ext_info'] = json_encode(['subject'=>'充值vip支付']);
  50. $data['memo'] = '充值会员支付';
  51. $data['createtime'] = time();
  52. //$data['payment'] = 'miniapp';
  53. $data['payment'] = 'app';
  54. $orderid = Db::name('pay_order')->insertGetId($data);
  55. //创建回调
  56. $even_data = [];
  57. $even_data['event'] = 'success';
  58. $even_data['class'] = 'app\common\model\Recharge';
  59. $even_data['method'] = 'vippaysucc';
  60. $even_data['args'] = json_encode(['user_id'=>$uid,'days'=>$recharge_config['days'],'vip_level'=>$recharge_config['vip_level'],'gold_num'=>$recharge_config['gold_num'],'money'=>$money]);
  61. $even_data['pay_no'] = $pay_no;
  62. Db::name('pay_event')->insertGetId($even_data);
  63. $res[] = '';
  64. if ($pay_type == 'wechat') {
  65. //$money = 0.01;
  66. $sandpay = new \app\common\library\SuningPay();
  67. $sandpayParams = [
  68. 'order_no' => $pay_no,
  69. 'goods_name' => '充值vip支付',
  70. 'money' => $money,
  71. 'type' => 'vip',
  72. ];
  73. $sandRes = $sandpay->wechath5($sandpayParams);
  74. if ($sandRes['status'] != 1) {
  75. throw new Exception('失败');
  76. }
  77. $res = json_decode($sandRes['data']['params'],true);
  78. $url = 'https://h5-min-pay-1gczed24bbbe3db8-1317709175.tcloudbaseapp.com/suning-pay.html';
  79. $ress['url'] = $url.'?orderId='.$res['tradeOrderId'];
  80. } else {
  81. //下单
  82. $params = [
  83. 'type' => $pay_type,
  84. 'orderid' => $pay_no,
  85. 'title' => $data['memo'],
  86. 'amount' => $data['money'],
  87. //'amount' => 0.01,
  88. 'method' => 'app',
  89. 'notifyurl' => 'http://app.zhiyinvip001.com/notify.php/paytype/'.$pay_type,
  90. 'returnurl' => '',
  91. ];
  92. $res = Service::submitOrder($params);
  93. }
  94. Db::commit();
  95. $this->success('success',$ress);
  96. } catch (Exception $e) {
  97. Db::rollback();
  98. $this->error($e->getMessage());
  99. }
  100. }
  101. //金币充值
  102. public function gold_config(){
  103. $list = Db::name('paygold_config')->where('is_show',1)->order('weight asc,id asc')->select();
  104. $data['goldconfig'] = $list;
  105. $data['gold'] = model('wallet')->getWallet($this->auth->id,'gold');
  106. $data['money_to_gold'] = config('site.money_to_gold');
  107. $data['is_first'] = Db::name('user_paygold_log')->where(['uid' => $this->auth->id])->count('id');
  108. if ($list) {
  109. $arr = [
  110. 'id' => -1,
  111. 'money' => 0,
  112. 'gold' => 0,
  113. 'title' => '自定义',
  114. 'is_show' => 1,
  115. 'weight' => 1,
  116. 'first_gold' => 0,
  117. 'first_vipdays' => 0
  118. ];
  119. array_push($data['goldconfig'], $arr);
  120. foreach ($data['goldconfig'] as &$v) {
  121. $v['is_first'] = $data['is_first'];
  122. }
  123. }
  124. $this->success('success',$data);
  125. }
  126. //充值金币 创建订单
  127. public function gold_recharge()
  128. {
  129. Db::startTrans();
  130. try {
  131. $rc_id = input_post('rc_id',0);
  132. $pay_type = 'wechat';
  133. $freemoney = input_post('freemoney', 0, 'intval');
  134. $uid = $this->auth->id;
  135. if(!$rc_id && !$freemoney){
  136. throw new Exception('请选择或填写充值金额');
  137. }
  138. if (!in_array($pay_type,['wechat','alipay'])) {
  139. throw new Exception('错误的支付类型');
  140. }
  141. //赋值money
  142. if($rc_id){
  143. $recharge_config = Db::name('paygold_config')->where('id',$rc_id)->find();
  144. $money = $recharge_config ? $recharge_config['money']: 0;
  145. $gold = $recharge_config ? $recharge_config['gold'] : 0;
  146. $first_gold = $recharge_config ? $recharge_config['first_gold'] : 0;
  147. $first_vipdays = $recharge_config ? $recharge_config['first_vipdays'] : 0;
  148. $vip_gold = $recharge_config ? $recharge_config['vip_gold'] : 0;
  149. }
  150. //自由输入覆盖
  151. if(!empty($freemoney)){
  152. $rc_id = 0;
  153. $money = floatval($freemoney);
  154. $bili = config('site.money_to_gold') ?: 10;
  155. $gold = bcmul($money,$bili,0);
  156. $first_gold = 0;
  157. $first_vipdays = 0;
  158. $vip_gold = 0;
  159. }
  160. if($money <= 0) {
  161. throw new Exception('支付金额必须大于0');
  162. }
  163. if($money > 10000){
  164. throw new Exception('支付金额太大');
  165. }
  166. //查询是不是会员,若不是则不赠送金币
  167. $vip_endtime = Db::name('user_wallet')->where('user_id',$this->auth->id)->value('vip_endtime');
  168. if ($vip_endtime < time()) {
  169. $vip_gold = 0;
  170. }
  171. //创建订单
  172. $data = [];
  173. $data['status'] = 0;
  174. $pay_no = createUniqueNo('P',$uid);
  175. $data['pay_no'] = $pay_no;
  176. $data['money'] = $money;
  177. $data['payment_class'] = $pay_type;
  178. $data['user_id'] = $uid;
  179. $data['ext_info'] = json_encode(['subject'=>'充值金币支付']);
  180. $data['memo'] = '充值金币支付';
  181. $data['createtime'] = time();
  182. $data['payment'] = 'app';
  183. $orderid = Db::name('pay_order')->insertGetId($data);
  184. //创建回调
  185. $even_data = [];
  186. $even_data['event'] = 'success';
  187. $even_data['class'] = 'app\common\model\Recharge';
  188. $even_data['method'] = 'goldpaysucc';
  189. $even_data['args'] = json_encode(['user_id'=>$uid,'gold'=>$gold,'money'=>$money,'pg_id'=>$rc_id,'first_gold'=>$first_gold,'first_vipdays'=>$first_vipdays, 'intro_uid' => $this->auth->intro_uid, 'vip_gold' => $vip_gold]);
  190. $even_data['pay_no'] = $pay_no;
  191. Db::name('pay_event')->insertGetId($even_data);
  192. //$money = 0.01;
  193. $suningpay = new \app\common\library\SuningPay();
  194. $suningpayParams = [
  195. 'order_no' => $pay_no,
  196. 'goods_name' => '充值金币支付',
  197. 'money' => $money,
  198. 'type' => 'gold',
  199. ];
  200. $suningRes = $suningpay->wechath5($suningpayParams);
  201. if ($suningRes['status'] != 1) {
  202. throw new Exception('失败');
  203. }
  204. $res = json_decode($suningRes['data']['params'],true);
  205. $url = 'https://h5-min-pay-1gczed24bbbe3db8-1317709175.tcloudbaseapp.com/suning-pay.html';
  206. $ress['url'] = $url.'?orderId='.$res['tradeOrderId'];
  207. Db::commit();
  208. $this->success('成功', $ress);
  209. } catch (Exception $e) {
  210. Db::rollback();
  211. $this->error($e->getMessage());
  212. }
  213. }
  214. /**
  215. * 支付成功
  216. */
  217. public function notify()
  218. {
  219. //$input_post_data = json_encode($_POST);
  220. //filePut('[wallet][paySucc]充值参数 recharge money post'.$input_post_data);
  221. //$postData = isset($_POST['data']) ? $_POST['data'] : [];
  222. //$sign = isset($_POST['sign']) ? $_POST['sign'] : '';
  223. $postData=file_get_contents('php://input');
  224. $postData = urldecode($postData);
  225. $arr = explode('&', $postData);
  226. $nowArr = array();
  227. foreach($arr as $v) {
  228. $kv = explode('=', $v);
  229. $nowArr[$kv[0]] = $kv[1];
  230. }
  231. if($nowArr['responseCode'] == 'SJ0000' && $nowArr['transactStatus'] == '00')
  232. {
  233. $data = $this->verification($postData);
  234. if($data == 1)
  235. { //验签名通过
  236. //查询订单信息
  237. $PayResult = Db::name('pay_order');
  238. $where['pay_no'] = $nowArr['orderId'];
  239. $order_info = $PayResult->where($where)->find();
  240. if(!$order_info)
  241. {
  242. filePut('[wallet][paySucc]充值入账更新余额失败 recharge money fail 订单数据库检索不到'.$nowArr['orderId'],'suningno.txt');
  243. exit;
  244. }
  245. if ($order_info['status'] == 1 || $order_info['status'] == 2)
  246. {
  247. filePut('[wallet][paySucc]充值入账更新余额失败 recharge money fail status已更新过'.$order_info['status'].'___'.$nowArr['orderId'],'suningno.txt');
  248. echo 'true';exit;
  249. }
  250. $orderCode = $nowArr['orderId'];
  251. $extendType = '';
  252. //区分vip 还是 冲金币
  253. $is_g = stripos($orderCode,'P');
  254. if($is_g !== false)
  255. {
  256. $extendType = 'gold';
  257. }else{
  258. $is_v = stripos($orderCode,'V');
  259. if($is_v !== false)
  260. {
  261. $extendType = 'vip';
  262. }
  263. }
  264. //status已更新过
  265. $_data['status'] = 2;
  266. $result = $PayResult->where($where)->setField($_data);
  267. if ($result || 1)
  268. {
  269. //你可以在此编写订单逻辑
  270. $payEventWhere['pay_no'] = $orderCode;
  271. $payEvent = Db::name('pay_event')->where($payEventWhere)->find();
  272. $args = isset($payEvent['args']) ? $payEvent['args'] : '';
  273. $args = json_decode($args,true);
  274. $rechargeM = new \app\common\model\Recharge();
  275. if ($extendType == 'gold') {
  276. $payRes = $rechargeM->goldpaysucc($orderCode,$args);
  277. $payTypeStr = '充值';
  278. } elseif($extendType == 'vip') {
  279. $payRes = $rechargeM->vippaysucc($orderCode,$args);
  280. $payTypeStr = 'vip';
  281. } else {
  282. $payRes = false;
  283. $payTypeStr = '未知支付类型';
  284. }
  285. if(!$payRes)
  286. {
  287. filePut('[wallet][paySucc]'.$payTypeStr.'更新失败请查看问题'.$orderCode,'suningno.txt');
  288. exit;
  289. }
  290. filePut('[wallet][paySucc]回调成功'.$orderCode,'suningno.txt');
  291. echo "true";exit;
  292. }
  293. filePut('[wallet][paySucc]充值入账更新余额失败 更新状态2不成功'.$orderCode."\n".' data:'.$postData."\n",'suningno.txt');
  294. exit;
  295. }
  296. }
  297. else
  298. {
  299. filePut(' recharge gold fail 用户交易操作失败'.$postData,'suningno.txt');
  300. echo '支付异常';exit;
  301. }
  302. filePut('[wallet][paySucc]充值入账更新余额失败 验证签名不通过'.$orderCode."\n".' data:'.$postData."\n",'suningno.txt');
  303. echo 'Fail';exit;
  304. }
  305. protected function verification($str)
  306. {
  307. if($str != '') {
  308. $arr = explode('&', $str);
  309. $nowArr = array();
  310. foreach($arr as $v) {
  311. $kv = explode('=', $v);
  312. $nowArr[$kv[0]] = $kv[1];
  313. }
  314. ksort($nowArr);
  315. $newstr = '';
  316. foreach($nowArr as $key => $value) {
  317. if($value == '' || $key == 'signature' || $key== 'signAlgorithm') {
  318. continue;
  319. }
  320. if($key == 'version')
  321. {
  322. $newstr .= $key.'='.$value;
  323. } else
  324. {
  325. $newstr .= $key.'='.$value.'&';
  326. }
  327. }
  328. // print_r($nowArr);
  329. //var_dump($newstr);
  330. $sign = base64_decode($nowArr['signature']);
  331. // exit;
  332. $newstr = strtoupper(md5($newstr));
  333. // var_dump($newstr);
  334. $pubfile = file_get_contents(APP_PATH.'common/library/suning/publicnew.pem');
  335. $ret = openssl_verify($newstr,$sign,$pubfile);
  336. return $ret;
  337. }
  338. }
  339. }