Paymentdo.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <?php
  2. namespace app\common\model;
  3. use \think\Db;
  4. /*
  5. *处理支付结果 接受服务器和服务器之间的通知
  6. */
  7. class Paymentdo
  8. {
  9. //接受服务器的通知
  10. public function receive($orderId)
  11. {
  12. filePut('[payment][receive]异步回调开始'.$orderId);
  13. if (!$orderId)
  14. {
  15. filePut('[payment][receive]支付号未匹配');
  16. return false;
  17. }
  18. $where = array();
  19. $where['pay_no'] = $orderId;
  20. $info = Db::name('pay_order')->where($where)->find();
  21. if ($info)
  22. {
  23. if($info['status'])
  24. {
  25. filePut('[payment][receive]本支付号已处理过 '.$orderId);
  26. return true;
  27. }
  28. else
  29. {
  30. filePut('[payment][receive]开始支付 '.$orderId);
  31. }
  32. if (1 === 1)
  33. {
  34. $this->touchEvent('success', $orderId);
  35. filePut('[payment][receive]支付完成,结果 success, '.$orderId);
  36. return true;
  37. }
  38. else
  39. {
  40. $this->touchEvent('failed', $orderId);
  41. filePut('[payment][receive]支付完成,结果 failed, '.$orderId);
  42. }
  43. //filePut('[payment][receive]支付完成,结果 '.json_encode($rs).', '.$orderId);
  44. }
  45. else
  46. {
  47. filePut('[payment][receive]无效支付号 '.$orderId);
  48. return false;
  49. }
  50. return false;
  51. //1.服务器发回处理结果
  52. //2.这里交给核心类处理
  53. //3.核心类交给支付接口判断支付成功还是失败
  54. //4.根据支付接口的返回结果,核心类调用之前绑定好的事件.
  55. }
  56. /**
  57. * 执行绑定事件
  58. * @param string $event 事件名称
  59. * @param string $order_id 订单号
  60. */
  61. public function touchEvent($event, $orderId)
  62. {
  63. //检查该订单是否已绑定事件
  64. $where = [];
  65. $where['pay_no'] = $orderId;
  66. $where['event'] = $event;
  67. $info = Db::name('pay_event')->where($where)->find();
  68. if(!$info||!isset($info['class']))
  69. {return;}
  70. $class = new $info['class'];
  71. Db::startTrans();
  72. $orderInfo = Db::name('pay_order')->where(['pay_no' => $orderId])->lock(true)->find();
  73. filePut("[PAY][touchEvent] STRAT" . $orderId);
  74. //如果找到了绑定的事件
  75. if ($info) {
  76. $args = json_decode($info['args'], true); //强制转换为数组格式
  77. //$args['moneynumber'] = $orderInfo['money'];//兼容以前的设计,追加money
  78. if ($event === 'success') {
  79. if($orderInfo['status'] === 0)//成功事件只触发1次
  80. {
  81. Db::name('pay_order')->where(['pay_no' => $orderId])->update(['status'=>2]);
  82. Db::commit();
  83. filePut('[PAY][touchEvent] success start'.$orderId);//.$info['args']
  84. call_user_func_array([$class, $info['method']], [$orderId, $args]);
  85. //得到事件模型类
  86. filePut('[PAY][touchEvent] success end '.$orderId);
  87. }
  88. }
  89. else
  90. {
  91. call_user_func_array([$class, $info['method']], [$orderId, $args]);
  92. filePut('[PAY][touchEvent] '.$event.' fail'.$orderId);
  93. }
  94. }
  95. }
  96. //接受浏览器的同步通知
  97. public function callback()
  98. {
  99. filePut('[payment][callback]同步回调开始');
  100. $orderId = Pay::getOrderId();
  101. if (!$orderId)
  102. {
  103. filePut('[payment][callback]无法分析到支付号未匹配');
  104. $this->error('无效支付!');
  105. }
  106. $where = array();
  107. $where['pay_no'] = $orderId;
  108. $info = Db::name('pay_order')->where($where)->find();
  109. if ($info)
  110. {
  111. //获取到它使用的支付接口
  112. $pay = new Pay($info['payment_class']);
  113. $rs = $pay->callback();
  114. if (!$info['status'])
  115. {
  116. filePut('[payment][callback]开始支付 '.$orderId);
  117. //Db::startTrans(); 修改为:充值+扣款,防止扣款失败时充值也回滚
  118. if ($rs)
  119. {
  120. $pay->touchEvent('success', $orderId);
  121. $pay->printMessage('success', 'callback结果 success, '.$orderId);
  122. filePut('[payment][callback]支付完成,结果 success, '.$orderId);
  123. filePut('[payment][callback]支付完成,结果 '.json_encode($rs).', '.$orderId);
  124. }
  125. else
  126. {
  127. $pay->touchEvent('failed', $orderId);
  128. $pay->printMessage('failed', 'callback结果 failed, '.$orderId);
  129. filePut('[payment][callback]支付完成,结果 failed, '.$orderId);
  130. filePut('[payment][callback]支付完成,结果 '.json_encode($rs).', '.$orderId);
  131. /*if (IS_MOBILE)
  132. {
  133. $url = session('redirect_fail_uri', '','user')?:'/wap/';
  134. session('redirect_fail_uri', null,'user');
  135. $this->redirect($url);
  136. }
  137. else
  138. {*/
  139. $this->error('支付失败!');
  140. /*}*/
  141. }
  142. }
  143. }
  144. else
  145. {
  146. filePut('[payment][callback]无效支付号 '.$orderId);
  147. /*if (IS_MOBILE)
  148. {
  149. $url = session('redirect_fail_uri', '','user')?:'/wap/';
  150. session('redirect_fail_uri', null,'user');
  151. $this->redirect($url);
  152. }
  153. else
  154. {*/
  155. $this->error('无效支付订单号!');
  156. /* }*/
  157. }
  158. //以下代码用于同步支付成功后回跳,请定制
  159. /*$pays = Pay::getInstalled();
  160. $pinfo = $pays[Pay::$payname];*/
  161. $pinfo = ['type'=>'pc'];
  162. filePut('[payment][callback]回调地址 '.json_encode(session('redirect_uri','','user')));
  163. //同步通知处理完进行回跳转
  164. if ('app'==$pinfo['type']||request()->isAjax())
  165. {
  166. //app同步请求
  167. if($rs)
  168. $pay->printMessage('success', 'app callback结果 success, '.$orderId);
  169. else
  170. $pay->printMessage('failed', 'app callback结果 failed, '.$orderId);
  171. }
  172. else
  173. {
  174. if (session('redirect_uri','','user'))
  175. {
  176. $url = str_replace('.html', '', session('redirect_uri','','user'));
  177. session('redirect_uri', null, 'user');
  178. $this->redirect($url);
  179. }
  180. elseif('wap'==$pinfo['type'])
  181. $this->redirect('/wap/');
  182. else
  183. $this->redirect('/index/user/walletcenter');
  184. }
  185. exit();
  186. //1.服务器发回处理结果
  187. //2.这里交给核心类处理
  188. //3.核心类交给支付接口判断支付成功还是失败
  189. //4.根据支付接口的返回结果,核心类调用之前绑定好的事件.
  190. }
  191. }
  192. ?>