ToutiaopayController.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. <?php
  2. /**
  3. * Author: 芸众商城 www.yunzshop.com
  4. * Date: 2019/4/24
  5. * Time: 下午3:10
  6. */
  7. namespace app\payment\controllers;
  8. use app\common\facades\EasyWeChat;
  9. use app\common\helpers\Url;
  10. use app\common\models\AccountWechats;
  11. use app\common\models\Order;
  12. use app\common\models\OrderPay;
  13. use app\common\services\Pay;
  14. use app\payment\PaymentController;
  15. class ToutiaopayController extends PaymentController
  16. {
  17. private $attach = [];
  18. public function preAction()
  19. {
  20. parent::preAction();
  21. if (empty(\YunShop::app()->uniacid)) {
  22. $post = $this->getResponseResult();
  23. if (\YunShop::request()->attach) {
  24. \Setting::$uniqueAccountId = \YunShop::app()->uniacid = \YunShop::request()->attach;
  25. } else {
  26. $this->attach = explode(':', $post['attach']);
  27. \Setting::$uniqueAccountId = \YunShop::app()->uniacid = $this->attach[0];
  28. }
  29. \Log::debug('---------attach数组--------', \YunShop::app()->uniacid);
  30. AccountWechats::setConfig(AccountWechats::getAccountByUniacid(\YunShop::app()->uniacid));
  31. }
  32. }
  33. public function notifyUrlWechat()
  34. {
  35. $post = $this->getResponseResult();
  36. $this->log($post,'微信支付--TT');
  37. $verify_result = $this->getWechatSignResult();
  38. if ($verify_result) {
  39. $data = [
  40. 'total_fee' => $post['total_fee'] ,
  41. 'out_trade_no' => $post['out_trade_no'],
  42. 'trade_no' => $post['transaction_id'],
  43. 'unit' => 'fen',
  44. 'pay_type' => '微信支付--TT',
  45. 'pay_type_id' => 51
  46. ];
  47. $this->payResutl($data);
  48. echo "success";
  49. } else {
  50. echo "fail";
  51. }
  52. }
  53. public function notifyUrlAlipay()
  54. {
  55. $this->log($_POST, '支付宝支付--TT');
  56. $verify_result = $this->get_RSA2_SignResult($_POST);
  57. \Log::debug(sprintf('支付回调验证结果[%d]', intval($verify_result)));
  58. if ($verify_result) {
  59. if ($_POST['trade_status'] == 'TRADE_SUCCESS') {
  60. if (strpos($_POST['out_trade_no'], '_') !== false) {
  61. $out_trade_no = substr($_POST['out_trade_no'], strpos($_POST['out_trade_no'], '_')+1);
  62. } else {
  63. $out_trade_no = $_POST['out_trade_no'];
  64. }
  65. $data = [
  66. 'total_fee' => $_POST['total_amount'],
  67. 'out_trade_no' => $out_trade_no,
  68. 'trade_no' => $_POST['trade_no'],
  69. 'unit' => 'yuan',
  70. 'pay_type' => '支付宝支付--TT',
  71. 'pay_type_id' => 52
  72. ];
  73. $this->payResutl($data);
  74. }
  75. echo "success";
  76. } else {
  77. echo "fail";
  78. }
  79. }
  80. public function returnUrl()
  81. {
  82. $trade = \Setting::get('shop.trade');
  83. if (!is_null($trade) && isset($trade['redirect_url']) && !empty($trade['redirect_url'])) {
  84. return redirect($trade['redirect_url'].'&outtradeno='.\YunShop::request()->outtradeno)->send();
  85. }
  86. if (\YunShop::request()->outtradeno) {
  87. $orderPay = OrderPay::where('pay_sn', \YunShop::request()->outtradeno)->first();
  88. $orders = Order::whereIn('id', $orderPay->order_ids)->get();
  89. if (is_null($orderPay)) {
  90. redirect(Url::absoluteApp('home'))->send();
  91. }
  92. //优惠卷分享页
  93. $share_bool = \app\frontend\modules\coupon\services\ShareCouponService::showIndex($orderPay->order_ids, $orderPay->uid);
  94. if ($share_bool) {
  95. $ids = rtrim(implode('_', $orderPay->order_ids), '_');
  96. redirect(Url::absoluteApp('coupon/share/'.$ids, ['i' => \YunShop::app()->uniacid, 'mid'=> $orderPay->uid]))->send();
  97. }
  98. if ($orders->count() > 1) {
  99. redirect(Url::absoluteApp('member/orderlist/', ['i' => \YunShop::app()->uniacid]))->send();
  100. } else {
  101. redirect(Url::absoluteApp('member/orderdetail/'.$orders->first()->id, ['i' => \YunShop::app()->uniacid]))->send();
  102. }
  103. } else {
  104. redirect(Url::absoluteApp('home'))->send();
  105. }
  106. }
  107. /**
  108. * 微信签名验证
  109. *
  110. * @return bool
  111. */
  112. public function getWechatSignResult()
  113. {
  114. $pay = \Setting::get('shop.pay');
  115. $payment = $this->getEasyWeChatApp($pay);
  116. try {
  117. $message = (new \EasyWeChat\Payment\Notify\Paid($payment))->getMessage();
  118. return $message;
  119. } catch (\Exception $exception) {
  120. \Log::debug('微信签名验证:'.$exception->getMessage());
  121. return false;
  122. }
  123. $message = (new \EasyWeChat\Payment\Notify\Paid($payment))->getMessage();
  124. return $message;
  125. }
  126. /**
  127. * 支付宝签名验证
  128. *
  129. * @return bool
  130. */
  131. public function get_RSA2_SignResult($params)
  132. {
  133. $sign = $params['sign'];
  134. $params['sign_type'] = null;
  135. $params['sign'] = null;
  136. return $this->verify2($this->getSignContent($params), $sign);
  137. }
  138. /**
  139. * 通过支付宝公钥验证回调信息
  140. *
  141. * @param $data
  142. * @param $sign
  143. * @return bool
  144. */
  145. function verify2($data, $sign) {
  146. $set = \Setting::get('shop.pay');
  147. $alipay_sign_public =decrypt($set['rsa_public_key']);
  148. //如果isnewalipay为1,则为rsa2支付类型
  149. $isnewalipay = \Setting::get('shop.pay.alipay_pay_api');
  150. if(!$this->checkEmpty($alipay_sign_public)){
  151. $res = "-----BEGIN PUBLIC KEY-----\n" .
  152. wordwrap($alipay_sign_public, 64, "\n", true) .
  153. "\n-----END PUBLIC KEY-----";
  154. }
  155. ($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确');
  156. //调用openssl内置方法验签,返回bool值
  157. if ($isnewalipay) {
  158. $result = (bool)openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_SHA256);
  159. } else {
  160. $result = (bool)openssl_verify($data, base64_decode($sign), $res);
  161. }
  162. openssl_free_key($res);
  163. return $result;
  164. }
  165. /**
  166. * 验证数组重组
  167. *
  168. * @param $params
  169. * @return string
  170. */
  171. public function getSignContent($params) {
  172. ksort($params);
  173. $stringToBeSigned = "";
  174. $i = 0;
  175. foreach ($params as $k => $v) {
  176. if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) {
  177. // 转换成目标字符集
  178. $v = $this->characet($v, 'UTF-8');
  179. if ($i == 0) {
  180. $stringToBeSigned .= "$k" . "=" . "$v";
  181. } else {
  182. $stringToBeSigned .= "&" . "$k" . "=" . "$v";
  183. }
  184. $i++;
  185. }
  186. }
  187. unset ($k, $v);
  188. return $stringToBeSigned;
  189. }
  190. /**
  191. * 校验$value是否非空
  192. * if not set ,return true;
  193. * if is null , return true;
  194. **/
  195. protected function checkEmpty($value) {
  196. if (!isset($value))
  197. return true;
  198. if ($value === null)
  199. return true;
  200. if (trim($value) === "")
  201. return true;
  202. return false;
  203. }
  204. /**
  205. * 转换字符集编码
  206. * @param $data
  207. * @param $targetCharset
  208. * @return string
  209. */
  210. function characet($data, $targetCharset) {
  211. if (!empty($data)) {
  212. $fileType = $this->fileCharset;
  213. if (strcasecmp($fileType, $targetCharset) != 0) {
  214. $data = mb_convert_encoding($data, $targetCharset, $fileType);
  215. // $data = iconv($fileType, $targetCharset.'//IGNORE', $data);
  216. }
  217. }
  218. return $data;
  219. }
  220. /**
  221. * 创建支付对象
  222. *
  223. * @param $pay
  224. * @return \EasyWeChat\Payment\Payment
  225. */
  226. public function getEasyWeChatApp($pay)
  227. {
  228. $options = [
  229. 'app_id' => $pay['weixin_appid'],
  230. 'secret' => $pay['weixin_secret'],
  231. // payment
  232. 'payment' => [
  233. 'merchant_id' => $pay['weixin_mchid'],
  234. 'key' => $pay['weixin_apisecret'],
  235. 'cert_path' => $pay['weixin_cert'],
  236. 'key_path' => $pay['weixin_key']
  237. ]
  238. ];
  239. $app = EasyWeChat::payment($options);
  240. return $app;
  241. }
  242. /**
  243. * 获取微信回调结果
  244. *
  245. * @return array|mixed|\stdClass
  246. */
  247. public function getResponseResult()
  248. {
  249. $input = file_get_contents('php://input');
  250. if (!empty($input) && empty($_POST['out_trade_no'])) {
  251. //禁止引用外部xml实体
  252. $disableEntities = libxml_disable_entity_loader(true);
  253. $data = json_decode(json_encode(simplexml_load_string($input, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  254. libxml_disable_entity_loader($disableEntities);
  255. if (empty($data)) {
  256. exit('fail');
  257. }
  258. if ($data['result_code'] != 'SUCCESS' || $data['return_code'] != 'SUCCESS') {
  259. exit('fail');
  260. }
  261. $post = $data;
  262. } else {
  263. $post = $_POST;
  264. }
  265. return $post;
  266. }
  267. /**
  268. * 支付日志
  269. *
  270. * @param $post
  271. */
  272. public function log($post,$desc)
  273. {
  274. //访问记录
  275. Pay::payAccessLog();
  276. //保存响应数据
  277. Pay::payResponseDataLog($post['out_trade_no'], $desc, json_encode($post));
  278. }
  279. }