PayController.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2013-2014 http://www.thinkcmf.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Author: Dean <zxxjjforever@163.com>
  8. // +----------------------------------------------------------------------
  9. namespace app\appapi\controller;
  10. use cmf\controller\HomeBaseController;
  11. use think\facade\Db;
  12. use think\db\Query;
  13. /**
  14. * 支付回调
  15. */
  16. class PayController extends HomebaseController {
  17. private $wxDate = null;
  18. //支付宝 回调
  19. public function notify_ali() {
  20. $configpri=getConfigPri();
  21. require_once(CMF_ROOT."sdk/alipay/alipay_app/alipay.config.php");
  22. $alipay_config['partner']= $configpri['aliapp_partner'];
  23. require_once(CMF_ROOT."sdk/alipay/alipay_app/lib/alipay_core.function.php");
  24. require_once(CMF_ROOT."sdk/alipay/alipay_app/lib/alipay_rsa.function.php");
  25. require_once(CMF_ROOT."sdk/alipay/alipay_app/lib/alipay_notify.class.php");
  26. //计算得出通知验证结果
  27. $alipayNotify = new \AlipayNotify($alipay_config);
  28. $verify_result = $alipayNotify->verifyNotify();
  29. $this->logali("ali_data:".json_encode($_POST));
  30. if($verify_result) {//验证成功
  31. //商户订单号
  32. $out_trade_no = $_POST['out_trade_no'];
  33. //支付宝交易号
  34. $trade_no = $_POST['trade_no'];
  35. //交易状态
  36. $trade_status = $_POST['trade_status'];
  37. //交易金额
  38. $total_fee = $_POST['total_fee'];
  39. if($_POST['trade_status'] == 'TRADE_FINISHED') {
  40. //判断该笔订单是否在商户网站中已经做过处理
  41. //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
  42. //如果有做过处理,不执行商户的业务程序
  43. //注意:
  44. //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
  45. //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
  46. //调试用,写文本函数记录程序运行情况是否正常
  47. //logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
  48. }else if ($_POST['trade_status'] == 'TRADE_SUCCESS') {
  49. //判断该笔订单是否在商户网站中已经做过处理
  50. //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
  51. //如果有做过处理,不执行商户的业务程序
  52. //注意:
  53. //付款完成后,支付宝系统发送该交易状态通知
  54. //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
  55. //调试用,写文本函数记录程序运行情况是否正常
  56. //logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
  57. $orderinfo=Db::name("user_charge")
  58. ->where("orderno='{$out_trade_no}' and money='{$total_fee}' and status='0' and type='1'")
  59. ->find();
  60. $this->logali("orderinfo:".json_encode($orderinfo));
  61. if($orderinfo){
  62. /* 更新会员虚拟币 */
  63. $coin=$orderinfo['coin']+$orderinfo['coin_give'];
  64. Db::name("user")->where("id='{$orderinfo['touid']}'")->inc("coin",$coin)->update();
  65. /* 更新 订单状态 */
  66. Db::name("user_charge")->where("id='{$orderinfo['id']}'")->update(array("status"=>1,"trade_no"=>$trade_no));
  67. $this->logali("成功");
  68. echo "success"; //请不要修改或删除
  69. return;
  70. }else{
  71. $this->logali("orderno:".$out_trade_no.' 订单信息不存在');
  72. }
  73. }
  74. //——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
  75. echo "fail"; //请不要修改或删除
  76. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  77. }else {
  78. $this->logali("验证失败");
  79. //验证失败
  80. echo "fail";
  81. //调试用,写文本函数记录程序运行情况是否正常
  82. //logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
  83. }
  84. }
  85. /* 支付宝支付 */
  86. /* 微信支付 */
  87. public function notify_wx(){
  88. $config=getConfigPri();
  89. //$xmlInfo = $GLOBALS['HTTP_RAW_POST_DATA'];
  90. $xmlInfo=file_get_contents("php://input");
  91. //解析xml
  92. $arrayInfo = $this -> xmlToArray($xmlInfo);
  93. $this -> wxDate = $arrayInfo;
  94. //$this -> logwx("wx_data:".json_encode($arrayInfo));//log打印保存
  95. if($arrayInfo['return_code'] == "SUCCESS"){
  96. // if($return_msg != null){
  97. // echo $this -> returnInfo("FAIL","签名失败");
  98. // $this -> logwx("签名失败:".$sign);//log打印保存
  99. // return;
  100. // }else{
  101. $wxSign = $arrayInfo['sign'];
  102. unset($arrayInfo['sign']);
  103. $arrayInfo['appid'] = $config['wx_appid'];
  104. $arrayInfo['mch_id'] = $config['wx_mchid'];
  105. $key = $config['wx_key'];
  106. ksort($arrayInfo);//按照字典排序参数数组
  107. $sign = $this -> sign($arrayInfo,$key);//生成签名
  108. $this -> logwx("数据打印测试签名signmy:".$sign.":::微信sign:".$wxSign);//log打印保存
  109. if($this -> checkSign($wxSign,$sign)){
  110. echo $this -> returnInfo("SUCCESS","OK");
  111. $this -> logwx("签名验证结果成功:".$sign);//log打印保存
  112. $this -> orderServer();//订单处理业务逻辑
  113. return;
  114. }else{
  115. echo $this -> returnInfo("FAIL","签名失败");
  116. $this -> logwx("签名验证结果失败:本地加密:".$sign.':::::三方加密'.$wxSign);//log打印保存
  117. return;
  118. }
  119. //}
  120. }else{
  121. echo $this -> returnInfo("FAIL","签名失败");
  122. $this -> logwx($arrayInfo['return_code']);//log打印保存
  123. return;
  124. }
  125. }
  126. private function returnInfo($type,$msg){
  127. if($type == "SUCCESS"){
  128. return $returnXml = "<xml><return_code><![CDATA[{$type}]]></return_code></xml>";
  129. }else{
  130. return $returnXml = "<xml><return_code><![CDATA[{$type}]]></return_code><return_msg><![CDATA[{$msg}]]></return_msg></xml>";
  131. }
  132. }
  133. //签名验证
  134. private function checkSign($sign1,$sign2){
  135. return trim($sign1) == trim($sign2);
  136. }
  137. /* 订单查询加值业务处理
  138. * @param orderNum 订单号
  139. */
  140. private function orderServer(){
  141. $info = $this -> wxDate;
  142. $this->logwx("info:".json_encode($info));
  143. $orderinfo=Db::name("user_charge")->where("orderno='{$info['out_trade_no']}' and status='0' and type='2'")->find();
  144. $this->logwx("orderinfo:".json_encode($orderinfo));
  145. if($orderinfo){
  146. /* 更新会员虚拟币 */
  147. $coin=$orderinfo['coin']+$orderinfo['coin_give'];
  148. Db::name("user")->where("id='{$orderinfo['touid']}'")->inc("coin",$coin)->update();
  149. /* 更新 订单状态 */
  150. Db::name("user_charge")->where("id='{$orderinfo['id']}'")->update(array("status"=>1,"trade_no"=>$info['transaction_id']));
  151. }else{
  152. $this->logwx("orderno:".$out_trade_no.' 订单信息不存在');
  153. return false;
  154. }
  155. }
  156. /**
  157. * sign拼装获取
  158. */
  159. private function sign($param,$key){
  160. $sign = "";
  161. foreach($param as $k => $v){
  162. $sign .= $k."=".$v."&";
  163. }
  164. $sign .= "key=".$key;
  165. $sign = strtoupper(md5($sign));
  166. return $sign;
  167. }
  168. /**
  169. * xml转为数组
  170. */
  171. private function xmlToArray($xmlStr){
  172. $msg = array();
  173. $postStr = $xmlStr;
  174. $msg = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
  175. return $msg;
  176. }
  177. /* 微信支付 */
  178. /* 苹果支付 */
  179. public function notify_ios(){
  180. $content=file_get_contents("php://input");
  181. $data = json_decode($content,true);
  182. $receipt = $data["receipt-data"];
  183. $version_ios = $data["version_ios"];
  184. $out_trade_no = $data["out_trade_no"];
  185. $info = $this->getReceiptData($receipt, $version_ios);
  186. $this->logios("info:".json_encode($info));
  187. $iforderinfo=Db::name("user_charge")->where("trade_no='{$info['transaction_id']}' and type='3'")->find();
  188. if($iforderinfo){
  189. echo '{"status":"fail","info":"非法提交-001"}';return;
  190. }
  191. //判断订单是否存在
  192. $orderinfo=Db::name("user_charge")->where("orderno='{$out_trade_no}' and status='0' and type='3'")->find();
  193. if($orderinfo){
  194. /* 更新会员虚拟币 */
  195. $coin=$orderinfo['coin']+$orderinfo['coin_give'];
  196. Db::name("user")->where("id='{$orderinfo['touid']}'")->inc("coin",$coin)->update();
  197. /* 更新 订单状态 */
  198. Db::name("user_charge")->where("id='{$orderinfo['id']}'")->update(array("status"=>1,"trade_no"=>$info['transaction_id']));
  199. }else{
  200. $this->logios("orderno:".$out_trade_no.' 订单信息不存在');
  201. echo '{"status":"fail","info":"订单信息不存在-003"}';
  202. return;
  203. }
  204. echo '{"status":"success","info":"充值支付成功"}';
  205. }
  206. public function getReceiptData($receipt, $version_ios){
  207. $config=getConfigPub();
  208. if ($version_ios == $config['ios_shelves']) {
  209. //沙盒
  210. $endpoint = 'https://sandbox.itunes.apple.com/verifyReceipt';
  211. }else {
  212. //生产
  213. $endpoint = 'https://buy.itunes.apple.com/verifyReceipt';
  214. }
  215. $postData = json_encode(
  216. array('receipt-data' => $receipt)
  217. );
  218. $ch = curl_init($endpoint);
  219. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  220. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //关闭安全验证
  221. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //关闭安全验证
  222. curl_setopt($ch, CURLOPT_POST, true);
  223. curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
  224. $response = curl_exec($ch);
  225. $errno = curl_errno($ch);
  226. $errmsg = curl_error($ch);
  227. curl_close($ch);
  228. if($errno != 0) {
  229. echo '{"status":"fail","info":"服务器出错,请联系管理员"}';
  230. return;
  231. }
  232. $data = json_decode($response,1);
  233. if (!is_array($data)) {
  234. echo '{"status":"fail","info":"验证失败,如有疑问请联系管理"}';
  235. return;
  236. }
  237. if (!isset($data['status']) || $data['status'] != 0) {
  238. echo '{"status":"fail","info":"验证失败,如有疑问请联系管理"}';
  239. return;
  240. }
  241. return array(
  242. 'product_id' => $data['receipt']['in_app'][0]['product_id'],
  243. 'transaction_id' => $data['receipt']['in_app'][0]['transaction_id'],
  244. );
  245. }
  246. /* 苹果支付 */
  247. /* 打印log */
  248. public function logali($msg){
  249. file_put_contents(CMF_ROOT.'data/log/paylog/logali_'.date('Y-m-d').'.txt',date('Y-m-d H:i:s').' msg:'.$msg."\r\n",FILE_APPEND);
  250. }
  251. /* 打印log */
  252. public function logwx($msg){
  253. file_put_contents(CMF_ROOT.'data/log/paylog/logwx_'.date('Y-m-d').'.txt',date('Y-m-d H:i:s').' msg:'.$msg."\r\n",FILE_APPEND);
  254. }
  255. /* 打印log */
  256. public function logios($msg){
  257. file_put_contents(CMF_ROOT.'data/log/paylog/logios_'.date('Y-m-d').'.txt',date('Y-m-d H:i:s').' msg:'.$msg."\r\n",FILE_APPEND);
  258. }
  259. }