ConvergequickpayController.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: blank
  5. * Date: 2020/4/8
  6. * Time: 14:14
  7. */
  8. namespace app\payment\controllers;
  9. use app\common\models\AccountWechats;
  10. use app\common\models\OrderPay;
  11. use app\common\models\refund\RefundApply;
  12. use app\common\services\Pay;
  13. use app\common\services\PayFactory;
  14. use app\payment\PaymentController;
  15. use app\backend\modules\refund\services\RefundOperationService;
  16. use app\backend\modules\refund\services\RefundMessageService;
  17. use Yunshop\ConvergePay\common\quick\EncryptUtil;
  18. use Yunshop\ConvergePay\models\QuickPayOrder;
  19. use Yunshop\ConvergePay\models\QuickPayRefundOrder;
  20. class ConvergequickpayController extends PaymentController
  21. {
  22. protected $parameters;
  23. public $responseData;
  24. public function __construct()
  25. {
  26. parent::__construct();
  27. $this->setResponseData();
  28. $this->head();
  29. }
  30. protected function setResponseData()
  31. {
  32. $data = $this->getResponseResult();
  33. //保存原始的data json字符串
  34. $this->responseData = $data['data'];
  35. if (!empty($data['data']) && is_string($data['data'])) {
  36. $data['data'] = json_decode($data['data'], true);
  37. }
  38. $this->parameters = $data;
  39. }
  40. protected function getResponseResult()
  41. {
  42. $post = file_get_contents('php://input');
  43. if (empty($post)) {
  44. $post = $_POST;
  45. }
  46. \Log::debug('<<---汇聚快捷支付回调-----', $post);
  47. if (!is_array($post)) {
  48. $post = json_decode($post, true);
  49. }
  50. return $post;
  51. }
  52. protected function head()
  53. {
  54. if (empty(\YunShop::app()->uniacid)) {
  55. $script_info = pathinfo($_SERVER['SCRIPT_NAME']);
  56. \Log::debug($script_info);
  57. if (!empty($script_info)) {
  58. switch ($script_info['filename']) {
  59. case 'payNotify':
  60. \YunShop::app()->uniacid = $this->getDataParameter('callback_param');
  61. break;
  62. case 'refundNotify':
  63. $i = explode('NO',$this->getDataParameter('refund_order_no'));
  64. \YunShop::app()->uniacid = $i[0];
  65. break;
  66. default:
  67. break;
  68. }
  69. }
  70. \Setting::$uniqueAccountId = \YunShop::app()->uniacid;
  71. AccountWechats::setConfig(AccountWechats::getAccountByUniacid(\YunShop::app()->uniacid));
  72. }
  73. if (empty(\YunShop::app()->uniacid)) {
  74. \Log::debug('---------汇聚快捷支付回调无法获取公众号------------');
  75. echo '无法获取公众号'; exit();
  76. }
  77. }
  78. //支付
  79. public function payNotify()
  80. {
  81. $this->log($this->getDataParameter('mch_order_no'), $this->parameters, '汇聚快捷支付--支付');
  82. if ($this->verifySign() && $this->isSuccess()) {
  83. $payOrder = QuickPayOrder::uniacid()->where('pay_no', $this->getDataParameter('mch_order_no'))->first();
  84. if (!$payOrder) {
  85. \Log::debug('---------汇聚快捷支付回调--支付记录不存在--'. $this->getDataParameter('mch_order_no'));
  86. echo '支付记录不存在'; exit();
  87. }
  88. $this->updatePayOrder($payOrder);
  89. if ($this->getDataParameter('order_status') == 'P1000') {
  90. $data = [
  91. 'total_fee' => floatval($this->getDataParameter('order_amount')),
  92. 'out_trade_no' => $payOrder->mch_order_no,
  93. 'trade_no' => $payOrder->pay_no,
  94. 'unit' => 'yuan',
  95. 'pay_type' => '汇聚快捷支付',
  96. 'pay_type_id' => PayFactory::CONVERGE_QUICK_PAY,
  97. ];
  98. $this->payResutl($data);
  99. echo 'success'; exit();
  100. }
  101. \Log::debug('<---------汇聚快捷支付回调--交易未成功--->'. $this->getDataParameter('mch_order_no'), $this->parameters);
  102. if ($this->getDataParameter('order_status') == 'P3000') {
  103. echo 'fail';exit();
  104. }
  105. echo 'success'; exit();
  106. }
  107. \Log::debug('---------汇聚快捷支付回调-支付失败---'. $this->getDataParameter('mch_order_no'), $this->parameters);
  108. echo 'fail';exit();
  109. }
  110. public function updatePayOrder($payOrder)
  111. {
  112. $data['order_status'] = $this->getDataParameter('order_status');
  113. $data['jp_order_no'] = $this->getDataParameter('jp_order_no');
  114. if ($this->getDataParameter('pay_success_time')) {
  115. $data['pay_at'] = strtotime($this->getDataParameter('pay_success_time'));
  116. }
  117. if ($this->getDataParameter('bank_trx_no')) {
  118. $data['bank_trx_no'] = $this->getDataParameter('bank_trx_no');
  119. }
  120. if ($this->getDataParameter('errCode')) {
  121. $data['err_code'] = $this->getDataParameter('errCode');
  122. }
  123. if ($this->getDataParameter('errMsg')) {
  124. $data['err_msg'] = $this->getDataParameter('errMsg');
  125. }
  126. $payOrder->fill($data);
  127. $payOrder->save();
  128. }
  129. //退款
  130. public function refundNotify()
  131. {
  132. $this->log($this->getDataParameter('refund_order_no'), $this->parameters, '汇聚快捷支付-退款');
  133. if ($this->verifySign() && $this->isSuccess()) {
  134. $refundOrder = QuickPayRefundOrder::uniacid()->where('refund_no', $this->getDataParameter('refund_order_no'))->first();
  135. if (!$refundOrder) {
  136. \Log::debug('---------汇聚快捷支付回调--退款记录不存在--'. $this->getDataParameter('refund_order_no'));
  137. echo '退款记录不存在'; exit();
  138. }
  139. $data['refund_trx_no'] = $this->getDataParameter('refund_trx_no');
  140. $data['refund_status'] = $this->getDataParameter('refund_status');
  141. if ($this->getDataParameter('refund_complete_time')) {
  142. $data['refund_at'] = strtotime($this->getDataParameter('refund_complete_time'));
  143. }
  144. if ($this->getDataParameter('errCode')) {
  145. $data['err_code'] = $this->getDataParameter('errCode');
  146. }
  147. if ($this->getDataParameter('errMsg')) {
  148. $data['err_msg'] = $this->getDataParameter('errMsg');
  149. }
  150. $refundOrder->fill($data);
  151. $refundOrder->save();
  152. try {
  153. if ($this->getDataParameter('refund_status') == '100') {
  154. $orderPay = OrderPay::where('pay_sn', $refundOrder->mch_order_no)->first();
  155. $refundApply = \app\common\models\refund\RefundApply::
  156. whereIn('order_id', $orderPay->order_ids)
  157. ->where('refund_type', '!=', RefundApply::REFUND_TYPE_EXCHANGE_GOODS)
  158. ->where('status', '>=', RefundApply::WAIT_CHECK)
  159. ->where('status', '<', RefundApply::COMPLETE)->get();
  160. \Log::debug('---------汇聚快捷支付回调退款售后ID--', $refundApply->pluck('id')->toArray());
  161. if (!$refundApply->isEmpty()) {
  162. foreach ($refundApply as $refund) {
  163. if (bccomp($refund->price, $this->getDataParameter('refund_amount'), 2) == 0) {
  164. \Log::debug('---------汇聚快捷支付回调退款售后:'.$refund->id);
  165. //退款状态设为完成
  166. RefundOperationService::refundComplete(['refund_id' => $refund->id]);
  167. break;
  168. }
  169. }
  170. }
  171. }
  172. } catch (\Exception $exception) {
  173. \Log::debug('---------汇聚快捷支付回调--退款报错--:'. $exception->getMessage(), [$exception->getFile(),$exception->getLine()]);
  174. }
  175. \Log::debug('---------汇聚快捷支付回调--退款成功-->>'. $this->getDataParameter('refund_order_no'));
  176. echo 'success'; exit();
  177. } else {
  178. \Log::debug('---------汇聚快捷支付回调--退款失败-->>'. $this->getDataParameter('refund_order_no'), $this->parameters);
  179. echo 'fail';exit();
  180. }
  181. }
  182. //签名验证
  183. public function verifySign()
  184. {
  185. $set = \Setting::get('plugin.convergePay_set');
  186. $bool = EncryptUtil::verify($this->toQueryString($this->parameters), $this->getParameter('sign'), $set['quick_pay']['platform_public_key']);
  187. if (!$bool) {
  188. \Log::debug('<-------汇聚快捷支付回调签名验证失败--------------->');
  189. }
  190. return $bool;
  191. }
  192. /**
  193. * 判断本次请求是否成功
  194. * @return bool
  195. */
  196. public function isSuccess()
  197. {
  198. return "JS000000" === $this->getParameter('biz_code');
  199. }
  200. /**
  201. * 获取参数值
  202. * @param string $key
  203. * @return string
  204. */
  205. public function getParameter($key)
  206. {
  207. return array_get($this->parameters, $key, '');
  208. }
  209. public function getDataParameter($key)
  210. {
  211. return array_get($this->parameters['data'], $key, '');
  212. }
  213. public function getResponseData()
  214. {
  215. return $this->responseData?$this->responseData:'';
  216. }
  217. /**
  218. * 将参数转换成k=v拼接的形式
  219. */
  220. public function toQueryString($parameter)
  221. {
  222. //按key的字典序升序排序,并保留key值
  223. ksort($parameter);
  224. $strQuery="";
  225. foreach ($parameter as $k=>$v){
  226. //不参与签名、验签
  227. if($k == "sign" || $k == "sec_key") {
  228. continue;
  229. }
  230. if($v === null) {$v = '';}
  231. // if (is_array($v)) {
  232. // $v = json_encode($v, JSON_UNESCAPED_UNICODE);
  233. // }
  234. //获取原始的data json字符串
  235. if ($k == 'data') {
  236. $v = $this->getResponseData();
  237. }
  238. $strQuery .= strlen($strQuery) == 0 ? "" : "&";
  239. $strQuery.=$k."=".$v;
  240. }
  241. return $strQuery;
  242. }
  243. /**
  244. * 支付日志
  245. * @param $out_trade_no
  246. * @param $data
  247. * @param string $msg
  248. */
  249. public function log($out_trade_no, $data, $msg = '汇聚快捷支付')
  250. {
  251. //访问记录
  252. Pay::payAccessLog();
  253. //保存响应数据
  254. Pay::payResponseDataLog($out_trade_no, $msg, json_encode($data));
  255. }
  256. }