HuanxunController.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: yunzhong
  5. * Date: 2018/6/27
  6. * Time: 13:50
  7. */
  8. namespace app\payment\controllers;
  9. use app\common\events\withdraw\WithdrawSuccessEvent;
  10. use app\common\helpers\Url;
  11. use app\common\models\AccountWechats;
  12. use app\common\services\Pay;
  13. use app\payment\PaymentController;
  14. use app\common\models\UniAccount;
  15. class HuanxunController extends PaymentController
  16. {
  17. private $attach = [];
  18. private $set = [];
  19. public function preAction()
  20. {
  21. parent::preAction();
  22. if (empty(\YunShop::app()->uniacid)) {
  23. if(empty($_REQUEST)) {
  24. return false;
  25. }
  26. if ($_REQUEST['paymentResult']) {
  27. $paymentResult = $_REQUEST['paymentResult'];
  28. $xmlResult = new \SimpleXMLElement($paymentResult);
  29. if (isset($xmlResult->GateWayRsp->body->Attach)) {
  30. $uniacid = $xmlResult->GateWayRsp->body->Attach;
  31. } else {
  32. $attach = explode(':', $xmlResult->WxPayRsp->body->MerBillno);
  33. \Log::debug('---------wx attach-----', $attach);
  34. if (isset($attach[1])) {
  35. $uniacid = $attach[1];
  36. }
  37. }
  38. }
  39. if ($_REQUEST['ipsResponse']) {
  40. $xmlResult = simplexml_load_string($_REQUEST['ipsResponse'], 'SimpleXMLElement', LIBXML_NOCDATA);
  41. $uniAccount = UniAccount::getEnable();
  42. foreach ($uniAccount as $u) {
  43. \YunShop::app()->uniacid = $u->uniacid;
  44. \Setting::$uniqueAccountId = $u->uniacid;
  45. $set = \Setting::get('plugin.huanxun_set');
  46. if ($set['mchntid'] == $xmlResult->argMerCode) {
  47. $this->set = $set;
  48. }
  49. }
  50. $ipsResult = $this->parseData($_REQUEST['ipsResponse']);
  51. $customerCode = str_replace($this->set['user_prefix'],'',$ipsResult['customerCode']);
  52. $uniacid = \Yunshop\Huanxun\frontend\models\AccountApply::getUniacidByCustomerCode($customerCode)['uniacid'];
  53. }
  54. \Setting::$uniqueAccountId = \YunShop::app()->uniacid = intval($uniacid);
  55. AccountWechats::setConfig(AccountWechats::getAccountByUniacid(\YunShop::app()->uniacid));
  56. }
  57. }
  58. public function notifyUrl()
  59. {
  60. $parameter = $_POST;
  61. $this->log($parameter);
  62. if(!empty($parameter)){
  63. $paymentResult = $parameter['paymentResult'];
  64. $xmlResult = new \SimpleXMLElement($paymentResult);
  65. $status = $xmlResult->WxPayRsp->body->Status;
  66. $amount = $xmlResult->WxPayRsp->body->OrdAmt;
  67. $trade_no = $xmlResult->WxPayRsp->body->IpsBillno;
  68. $attach = explode(':', $xmlResult->WxPayRsp->body->MerBillno);
  69. $order_no = $attach[0];
  70. if($this->getSignResult('wx')) {
  71. if (strval($status) == "Y") {
  72. \Log::debug('------wx验证成功-----');
  73. $data = [
  74. 'total_fee' => floatval($amount),
  75. 'out_trade_no' => (string)$order_no,
  76. 'trade_no' => (string)$trade_no,
  77. 'unit' => 'yuan',
  78. 'pay_type' => '微信',
  79. 'pay_type_id' => 22
  80. ];
  81. $this->payResutl($data);
  82. \Log::debug('----结束----');
  83. echo 'SUCCESS';
  84. } elseif (strval($status) == "N") {
  85. $message = "交易失败";
  86. } else {
  87. $message = "交易处理中";
  88. }
  89. } else {
  90. //签名验证失败
  91. }
  92. }else {
  93. echo 'FAIL';
  94. }
  95. }
  96. public function notifyQuickUrl()
  97. {
  98. $parameter = $_POST;
  99. \Log::debug('------notifyQuickUrl-----');
  100. $this->log($parameter);
  101. if(!empty($parameter)){
  102. $paymentResult = $parameter['paymentResult'];
  103. $xmlResult = new \SimpleXMLElement($paymentResult);
  104. $status = $xmlResult->GateWayRsp->body->Status;
  105. $order_no = $xmlResult->GateWayRsp->body->MerBillNo;
  106. $amount = $xmlResult->GateWayRsp->body->Amount;
  107. $trade_no = $xmlResult->GateWayRsp->body->IpsBillNo;
  108. if($this->getSignResult()) {
  109. \Log::debug('------notify验证成功-----');
  110. if (strval($status) == "Y") {
  111. $data = [
  112. 'total_fee' => floatval($amount),
  113. 'out_trade_no' => (string)$order_no,
  114. 'trade_no' => (string)$trade_no,
  115. 'unit' => 'yuan',
  116. 'pay_type' => '银联快捷支付',
  117. 'pay_type_id' => 18
  118. ];
  119. // $this->payResutl($data);
  120. \Log::debug('----结束----');
  121. echo 'SUCCESS';
  122. } elseif (strval($status) == "N") {
  123. $message = "交易失败";
  124. } else {
  125. $message = "交易处理中";
  126. }
  127. } else {
  128. $message = "验证失败";
  129. }
  130. }else {
  131. echo 'FAIL';
  132. }
  133. }
  134. public function notifyWithdrawalsUrl()
  135. {
  136. $parameter = $this->parseData($_REQUEST['ipsResponse']);
  137. \Log::debug('------notifyWithdrawalsUrl-----');
  138. $this->log($parameter);
  139. if(!empty($parameter)){
  140. if ($parameter['tradeState'] == 10) {
  141. \Log::debug('------环迅打款成功-----');
  142. event(new WithdrawSuccessEvent($parameter['merBillNo']));
  143. echo 'ipsCheckOk';
  144. }
  145. }else {
  146. echo 'FAIL';
  147. }
  148. }
  149. public function returnUrl()
  150. {
  151. $trade = \Setting::get('shop.trade');
  152. if(empty($_REQUEST)) {
  153. return false;
  154. }
  155. $paymentResult = $_REQUEST['paymentResult'];
  156. $xmlResult = new \SimpleXMLElement($paymentResult);
  157. $status = $xmlResult->WxPayRsp->body->Status;
  158. $amount = $xmlResult->WxPayRsp->body->OrdAmt;
  159. $trade_no = $xmlResult->WxPayRsp->body->IpsBillNo;
  160. $attach = explode(':', $xmlResult->WxPayRsp->body->MerBillno);
  161. $order_no = $attach[0];
  162. if (isset($attach[1])) {
  163. $uniacid = $attach[1];
  164. }
  165. $url = Url::shopSchemeUrl("?menu#/member/payErr?i={$uniacid}");
  166. if ($this->getSignResult('wx')) { // 验证成功
  167. \Log::debug('-------验证成功wx-----');
  168. if (strval($status) == "Y") {
  169. $data = [
  170. 'total_fee' => floatval($amount),
  171. 'out_trade_no' => (string)$order_no,
  172. 'trade_no' => (string)$trade_no,
  173. 'unit' => 'yuan',
  174. 'pay_type' => '微信',
  175. 'pay_type_id' => 22
  176. ];
  177. //$this->payResutl($data);
  178. $url = str_replace('https','http', Url::shopSchemeUrl("?menu#/member/payYes?i={$uniacid}"));
  179. if (!is_null($trade) && isset($trade['redirect_url']) && !empty($trade['redirect_url'])) {
  180. $url = str_replace('https','http', $trade['redirect_url']);
  181. }
  182. $message = "交易成功";
  183. }elseif(strval($status) == "N")
  184. {
  185. $message = "交易失败";
  186. }else {
  187. $message = "交易处理中";
  188. }
  189. } else {
  190. $message = "验证失败";
  191. }
  192. \Log::debug("-----wx支付{$uniacid}-{$order_no}----", [$message]);
  193. redirect($url)->send();
  194. }
  195. public function returnQuickUrl()
  196. {
  197. $trade = \Setting::get('shop.trade');
  198. if(empty($_REQUEST)) {
  199. return false;
  200. }
  201. $paymentResult = $_REQUEST['paymentResult'];
  202. $xmlResult = new \SimpleXMLElement($paymentResult);
  203. $status = $xmlResult->GateWayRsp->body->Status;
  204. $uniacid = $xmlResult->GateWayRsp->body->Attach;
  205. $order_no =$xmlResult->GateWayRsp->body->MerBillNo;
  206. $amount = $xmlResult->GateWayRsp->body->Amount;
  207. $trade_no = $xmlResult->GateWayRsp->body->IpsBillNo;
  208. $url = Url::shopSchemeUrl("?menu#/member/payErr?i={$uniacid}");
  209. if ($this->getSignResult()) { // 验证成功
  210. \Log::debug('-------验证成功-----');
  211. if (strval($status) == "Y") {
  212. $data = [
  213. 'total_fee' => floatval($amount),
  214. 'out_trade_no' => (string)$order_no,
  215. 'trade_no' => (string)$trade_no,
  216. 'unit' => 'yuan',
  217. 'pay_type' => '银联快捷支付',
  218. 'pay_type_id' => 18
  219. ];
  220. $this->payResutl($data);
  221. $url = Url::shopSchemeUrl("?menu#/member/payYes?i={$uniacid}");
  222. if (!is_null($trade) && isset($trade['redirect_url']) && !empty($trade['redirect_url'])) {
  223. $url = $trade['redirect_url'];
  224. }
  225. $message = "交易成功";
  226. }elseif(strval($status) == "N")
  227. {
  228. $message = "交易失败";
  229. }else {
  230. $message = "交易处理中";
  231. }
  232. } else {
  233. $message = "验证失败";
  234. }
  235. \Log::debug("-----快捷支付{$uniacid}-{$order_no}----", [$message]);
  236. redirect($url)->send();
  237. }
  238. public function returnAccountUrl()
  239. {
  240. $url = Url::absoluteApp('member', ['i' => \YunShop::app()->uniacid]);
  241. redirect($url)->send();
  242. }
  243. public function frontUrl()
  244. {
  245. $trade = \Setting::get('shop.trade');
  246. if (!is_null($trade) && isset($trade['redirect_url']) && !empty($trade['redirect_url'])) {
  247. return redirect($trade['redirect_url'])->send();
  248. }
  249. if (0 == $_GET['state'] && $_GET['errorDetail'] == '成功') {
  250. redirect(Url::absoluteApp('member', ['i' => $_GET['attach']]))->send();
  251. } else {
  252. redirect(Url::absoluteApp('home', ['i' => $_GET['attach']]))->send();
  253. }
  254. }
  255. public function refundUrl()
  256. {
  257. $parameter = $_POST;
  258. if (!empty($parameter)) {
  259. if ($this->getSignResult()) {
  260. if ($_POST['respCode'] == '0000') {
  261. //验证成功,业务逻辑
  262. } else {
  263. //其他错误
  264. }
  265. } else {
  266. //签名验证失败
  267. }
  268. } else {
  269. echo 'FAIL';
  270. }
  271. }
  272. public function refundQuickUrl()
  273. {
  274. $parameter = $_POST;
  275. if (!empty($parameter)) {
  276. if ($this->getSignResult()) {
  277. if ($_POST['respCode'] == '0000') {
  278. //验证成功,业务逻辑
  279. } else {
  280. //其他错误
  281. }
  282. } else {
  283. //签名验证失败
  284. }
  285. } else {
  286. echo 'FAIL';
  287. }
  288. }
  289. /**
  290. * 签名验证
  291. *
  292. * @return bool
  293. */
  294. public function getSignResult($type='quick')
  295. {
  296. $pay = \Setting::get('plugin.huanxun_set');
  297. $notify = app('Yunshop\Huanxun\services\HuanxunPayNotifyService');
  298. $notify->setKey($pay['key']);
  299. $notify->setCert($pay['cert']);
  300. $notify->setMerCode($pay['mchntid']);
  301. $result = $notify->verifySign();
  302. if ($type == 'wx') {
  303. \Log::debug('----------verifySignWx--------');
  304. $result = $notify->verifySignWx();
  305. }
  306. return $result;
  307. }
  308. /**
  309. * 支付日志
  310. *
  311. * @param $post
  312. */
  313. public function log($data)
  314. {
  315. $orderNo = explode(':', $data['orderNo']);
  316. //访问记录
  317. Pay::payAccessLog();
  318. //保存响应数据
  319. Pay::payResponseDataLog($orderNo[0], '芸微信支付', json_encode($data));
  320. }
  321. //环迅回调信息验证
  322. protected function parseData($message)
  323. {
  324. $obj = simplexml_load_string($message, 'SimpleXMLElement', LIBXML_NOCDATA);
  325. $body = simplexml_load_string($this->decrypt($obj->p3DesXmlPara), 'SimpleXMLElement', LIBXML_NOCDATA);;
  326. return (array)$body->body;
  327. }
  328. /**
  329. * 数据解密
  330. * @param $encrypted
  331. * @return bool|string
  332. */
  333. public function decrypt($encrypted)
  334. {
  335. $set =
  336. $encrypted = base64_decode($encrypted);
  337. $key = str_pad($this->set['3des_key'], 24, '0');
  338. $td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CBC, '');
  339. $iv = $this->set['3des_vector'];
  340. $ks = mcrypt_enc_get_key_size($td);
  341. @mcrypt_generic_init($td, $key, $iv);
  342. $decrypted = mdecrypt_generic($td, $encrypted);
  343. mcrypt_generic_deinit($td);
  344. mcrypt_module_close($td);
  345. $y = $this->pkcs5_unpad($decrypted);
  346. return $y;
  347. }
  348. private function pkcs5_unpad($text)
  349. {
  350. $pad = ord($text{strlen($text) - 1});
  351. if ($pad > strlen($text)) {
  352. return false;
  353. }
  354. if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
  355. return false;
  356. }
  357. return substr($text, 0, -1 * $pad);
  358. }
  359. }