Pay.php 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. <?php
  2. namespace app\newhome\controller;
  3. use think\Controller;
  4. use think\Db;
  5. use app\user\model\PayPlugin;
  6. use app\user\model\User;
  7. use app\user\model\UserPay;
  8. class Pay extends Controller{
  9. private $payPluginModel, $userModel;
  10. public function _initialize(){
  11. $this->payPluginModel= new PayPlugin();
  12. $this->userModel = new User();
  13. }
  14. public function pay(){
  15. $data = decode($this->request->post());
  16. // $data['i'] = 'com.dashgame.garden.packone';
  17. // $data['t'] = 1;
  18. // $data['u'] = 1704251601802555535;
  19. $iapInfo = Db::name('iap_config')->where(['item_id'=>$data['i']])->find();
  20. if(empty($iapInfo)) return (json(['error'=>1111]));
  21. $plugin = $this->payPluginModel->getPayPluginByType($data['t']);
  22. if(empty($plugin)) return (json(['error'=>1111]));
  23. $biz_content = $this->getAliTradeInfo($iapInfo, $data['u']);
  24. $val = $this->getAliPayInfo($plugin, $biz_content);
  25. return http_build_query($val);
  26. }
  27. public function sdk_notify(){
  28. $data = $this->request->post();
  29. self::log("sdk_notify ".json_encode($data, JSON_UNESCAPED_UNICODE));
  30. $order_id = $data['order_id'];
  31. $pay_money = $data['pay_money'];
  32. $pay_time = $data['pay_time'];
  33. $exinfo = $data['exinfo'];
  34. if($data['sign'] != md5($order_id.$pay_money.$pay_time.$exinfo."o6knhm0BhXBDVn3D"))
  35. {
  36. return json(["errno"=>101, "msg"=>"签名不对"]);
  37. }
  38. $arr = explode("|", $exinfo);
  39. $item_id = $arr[0];
  40. $user_id = $arr[1];
  41. $iapInfo = Db::name('iap_config')->where(['item_id'=>$item_id])->find();
  42. if(empty($iapInfo)) return (json(['errno'=>1111, "msg"=>"商品ID错误"]));
  43. $user = Db::name('user')->where(['id'=>$user_id])->find();
  44. if(empty($user)) return (json(['errno'=>1112, 'msg'=>"用户ID错误"]));
  45. $exist = Db::name('user_pay')->where(["out_trade_no"=>$order_id])->find();
  46. if($exist) return (json(['errno'=>1113, 'msg'=>"订单已经存在"]));
  47. $arr = array();
  48. $arr['user_id'] = $user_id;
  49. $arr['pay_id'] = $iapInfo['id'];
  50. $arr['out_trade_no'] = $order_id;
  51. $arr['cost'] = $pay_money/100;
  52. $arr['create_time'] = date("Y-m-d H:i:s", $pay_time);
  53. Db::name('user_pay')->insert($arr);
  54. self::log("pay_save ".json_encode($arr, JSON_UNESCAPED_UNICODE));
  55. return json(['errno'=>1, 'msg'=>""]);
  56. }
  57. public function get_reward()
  58. {
  59. $data = decode($this->request->post());
  60. $user_id = $data['user_id'];
  61. $user_pay = Db::name('user_pay')->where(['user_id'=>$user_id, "reward"=>0])->order('id DESC')->find();
  62. if(!$user_pay)
  63. {
  64. return json(['error'=>0]);
  65. }
  66. Db::name('user_pay')->where(["id"=>$user_pay['id']])->update(["reward"=>1, "reward_time"=>date("Y-m-d H:i:s")]);
  67. $pay_id = $user_pay['pay_id'];
  68. $iap_info = Db::name('iap_config')->where(['id'=>$pay_id])->find();
  69. if(!$iap_info)
  70. {
  71. return json(['error'=>0]);
  72. }
  73. self::log("pay_reward ".json_encode($user_pay, JSON_UNESCAPED_UNICODE));
  74. return json(['error'=>0, "reward"=>$iap_info["reward"]]);
  75. }
  76. public function notify(){
  77. echo 'success';
  78. }
  79. private function getAliTradeInfo($ipa, $user){
  80. $content = [];
  81. $content['subject'] = $ipa['desc'];
  82. $content['out_trade_no'] = $tradeNo = 'D'.getId();
  83. $content['total_amount'] = $ipa['price'];
  84. // $content['total_amount'] = 0.01;
  85. $content['product_code'] = 'QUICK_MSECURITY_PAY';
  86. $content['timeout_express'] = '90m';
  87. $content['body'] = $ipa['desc'];
  88. $userPay = new UserPay();
  89. $userPay->add(['user_id'=>$user, 'cost'=>$ipa['price'], 'pay_id'=>$ipa['id'], 'out_trade_no'=>$tradeNo]);
  90. return json_encode($content);
  91. }
  92. private function getAliPayInfo($plugin, $biz_content){
  93. $params = [];
  94. $params['app_id'] = $plugin['appid'];
  95. $params['method'] = 'alipay.trade.app.pay';
  96. $params['format'] = "JSON";
  97. $params['charset'] = "UTF-8";
  98. $params['version'] = "1.0";
  99. $params['timestamp'] = getCurrentTime();
  100. $params['sign_type'] = "RSA2";
  101. $params['notify_url'] = 'http://'.$_SERVER['SERVER_NAME']._PHP_FILE_.'/'.$this->request->module().'/'.$this->request->controller().'/notify';
  102. $params['biz_content'] = $biz_content;
  103. ksort($params);
  104. $sign = aliSign($plugin['private_key'], getAliSignContent($params));
  105. $params['sign'] = $sign;
  106. foreach ($params as &$value) {
  107. $value = urlencode($value);
  108. }
  109. return $params;
  110. }
  111. public function wxPay()
  112. {
  113. $data = decode($this->request->post());
  114. // $data['i'] = 'com.dashgame.garden.packone';
  115. // $data['t'] = 1;
  116. // $data['u'] = 1704251601802555535;
  117. $iapInfo = Db::name('iap_config')->where(['item_id'=>$data['i']])->find();
  118. if(empty($iapInfo)) return (json(['error'=>1111]));
  119. $user_id = $data['u'];
  120. $price = $iapInfo['price'];
  121. $out_trade_no = 'D'.getId();
  122. $order_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
  123. $data = array();
  124. $data['appid'] = "wx47450ab76d65a1b3";
  125. $data['mch_id'] = "1495332042";
  126. $data['nonce_str'] = md5(time());
  127. $data['sign_type'] = "MD5";
  128. $data['body'] = $iapInfo['desc'];
  129. $data['out_trade_no'] = $out_trade_no;
  130. $data['total_fee'] = $price*100;
  131. $data['spbill_create_ip'] = $this->getip();
  132. $data['notify_url'] = 'http://'.$_SERVER['SERVER_NAME'].'/wx_notify.php';
  133. $data['trade_type'] = "APP";
  134. $data['attach'] = $user_id;
  135. ksort($data);
  136. // print_r($data);
  137. $data['sign'] = $this->generateSign($data);
  138. $xml = $this->arrayToXml($data);
  139. $opts = array (
  140. 'http' => array(
  141. 'method' => 'POST',
  142. 'header' => "Content-type: application/x-www-form-urlencoded ",
  143. 'content' => $xml
  144. ),
  145. );
  146. $context = stream_context_create($opts);
  147. $html = file_get_contents($order_url, false, $context);
  148. // echo $html;
  149. $xml = simplexml_load_string($html);
  150. if(strval($xml->return_code) != "SUCCESS" || strval($xml->result_code) != "SUCCESS")
  151. {
  152. return (json(['error'=>2]));
  153. }
  154. $pay = array();
  155. $pay['appid'] = strval($xml->appid);
  156. $pay['partnerid'] = strval($xml->mch_id);
  157. $pay['prepayid'] = strval($xml->prepay_id);
  158. $pay['package'] = "Sign=WXPay";
  159. $pay['noncestr'] = md5(time());
  160. $pay['timestamp'] = strval(time());
  161. $pay['sign'] = $this->generateSign($pay);
  162. $userPay = new UserPay();
  163. $userPay->add(['user_id'=>$user_id, 'cost'=>$price, 'pay_id'=>$iapInfo['id'], 'out_trade_no'=>$out_trade_no]);
  164. return (json($pay));
  165. }
  166. function getip() {
  167. $unknown = 'unknown';
  168. if ( isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] && strcasecmp($_SERVER['HTTP_X_FORWARDED_FOR'], $unknown) ) {
  169. $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
  170. } elseif ( isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], $unknown) ) {
  171. $ip = $_SERVER['REMOTE_ADDR'];
  172. }
  173. /*
  174. 处理多层代理的情况
  175. 或者使用正则方式:$ip = preg_match("/[\d\.]{7,15}/", $ip, $matches) ? $matches[0] : $unknown;
  176. */
  177. if (false !== strpos($ip, ','))
  178. $ip = reset(explode(',', $ip));
  179. return $ip;
  180. }
  181. private function generateSign($params)
  182. {
  183. ksort($params);
  184. $stringToBeSigned = "";
  185. $i = 0;
  186. foreach ($params as $k => $v) {
  187. if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) {
  188. // 转换成目标字符集
  189. //$v = $this->characet($v, $this->postCharset);
  190. if ($i == 0) {
  191. $stringToBeSigned .= "$k" . "=" . "$v";
  192. } else {
  193. $stringToBeSigned .= "&" . "$k" . "=" . "$v";
  194. }
  195. $i++;
  196. }
  197. }
  198. unset ($k, $v);
  199. $stringSignTemp = $stringToBeSigned."&key=N6a0xVVV4IyMwQrneiCweaVQ7sypOEbS";
  200. return strtoupper(md5($stringSignTemp));
  201. }
  202. private function checkEmpty($value) {
  203. if (!isset($value))
  204. return true;
  205. if ($value === null)
  206. return true;
  207. if (trim($value) === "")
  208. return true;
  209. return false;
  210. }
  211. private function arrayToXml($arr)
  212. {
  213. $xml = "<xml>\n";
  214. foreach ($arr as $key=>$val)
  215. {
  216. if(is_numeric($val))
  217. {
  218. $xml .= "<".$key.">".$val."</".$key.">\n";
  219. }
  220. else
  221. {
  222. $xml .= "<".$key."><![CDATA[".$val."]]></".$key.">\n";
  223. }
  224. }
  225. $xml .= "</xml>";
  226. return $xml;
  227. }
  228. public static function log($message, $tag='notify')
  229. {
  230. $folder = ROOT_PATH.'log/'.$tag;
  231. if(!is_dir($folder))
  232. {
  233. mkdir($folder, 0777, true);
  234. }
  235. $path = $folder.'/'.date('Y_m_d').'.log';
  236. if(!file_exists($path))
  237. {
  238. $fp = fopen($path, "a");
  239. flock($fp, LOCK_EX) ;
  240. fwrite($fp, "");
  241. flock($fp, LOCK_UN);
  242. fclose($fp);
  243. }
  244. error_log(date('Y-m-d H:i:s').' >> '.$message."\r\n", 3, $path);
  245. }
  246. }