where($where)->find(); if ($info) { if($info['status']) { filePut('[payment][receive]本支付号已处理过 '.$orderId); return true; } else { filePut('[payment][receive]开始支付 '.$orderId); } if (1 === 1) { $this->touchEvent('success', $orderId); filePut('[payment][receive]支付完成,结果 success, '.$orderId); return true; } else { $this->touchEvent('failed', $orderId); filePut('[payment][receive]支付完成,结果 failed, '.$orderId); } //filePut('[payment][receive]支付完成,结果 '.json_encode($rs).', '.$orderId); } else { filePut('[payment][receive]无效支付号 '.$orderId); return false; } return false; //1.服务器发回处理结果 //2.这里交给核心类处理 //3.核心类交给支付接口判断支付成功还是失败 //4.根据支付接口的返回结果,核心类调用之前绑定好的事件. } /** * 执行绑定事件 * @param string $event 事件名称 * @param string $order_id 订单号 */ public function touchEvent($event, $orderId) { //检查该订单是否已绑定事件 $where = []; $where['pay_no'] = $orderId; $where['event'] = $event; $info = Db::name('pay_event')->where($where)->find(); if(!$info||!isset($info['class'])) {return;} $class = new $info['class']; Db::startTrans(); $orderInfo = Db::name('pay_order')->where(['pay_no' => $orderId])->lock(true)->find(); filePut("[PAY][touchEvent] STRAT" . $orderId); //如果找到了绑定的事件 if ($info) { $args = json_decode($info['args'], true); //强制转换为数组格式 //$args['moneynumber'] = $orderInfo['money'];//兼容以前的设计,追加money if ($event === 'success') { if($orderInfo['status'] === 0)//成功事件只触发1次 { Db::name('pay_order')->where(['pay_no' => $orderId])->update(['status'=>2]); Db::commit(); filePut('[PAY][touchEvent] success start'.$orderId);//.$info['args'] call_user_func_array([$class, $info['method']], [$orderId, $args]); //得到事件模型类 filePut('[PAY][touchEvent] success end '.$orderId); } } else { call_user_func_array([$class, $info['method']], [$orderId, $args]); filePut('[PAY][touchEvent] '.$event.' fail'.$orderId); } } } //接受浏览器的同步通知 public function callback() { filePut('[payment][callback]同步回调开始'); $orderId = Pay::getOrderId(); if (!$orderId) { filePut('[payment][callback]无法分析到支付号未匹配'); $this->error('无效支付!'); } $where = array(); $where['pay_no'] = $orderId; $info = Db::name('pay_order')->where($where)->find(); if ($info) { //获取到它使用的支付接口 $pay = new Pay($info['payment_class']); $rs = $pay->callback(); if (!$info['status']) { filePut('[payment][callback]开始支付 '.$orderId); //Db::startTrans(); 修改为:充值+扣款,防止扣款失败时充值也回滚 if ($rs) { $pay->touchEvent('success', $orderId); $pay->printMessage('success', 'callback结果 success, '.$orderId); filePut('[payment][callback]支付完成,结果 success, '.$orderId); filePut('[payment][callback]支付完成,结果 '.json_encode($rs).', '.$orderId); } else { $pay->touchEvent('failed', $orderId); $pay->printMessage('failed', 'callback结果 failed, '.$orderId); filePut('[payment][callback]支付完成,结果 failed, '.$orderId); filePut('[payment][callback]支付完成,结果 '.json_encode($rs).', '.$orderId); /*if (IS_MOBILE) { $url = session('redirect_fail_uri', '','user')?:'/wap/'; session('redirect_fail_uri', null,'user'); $this->redirect($url); } else {*/ $this->error('支付失败!'); /*}*/ } } } else { filePut('[payment][callback]无效支付号 '.$orderId); /*if (IS_MOBILE) { $url = session('redirect_fail_uri', '','user')?:'/wap/'; session('redirect_fail_uri', null,'user'); $this->redirect($url); } else {*/ $this->error('无效支付订单号!'); /* }*/ } //以下代码用于同步支付成功后回跳,请定制 /*$pays = Pay::getInstalled(); $pinfo = $pays[Pay::$payname];*/ $pinfo = ['type'=>'pc']; filePut('[payment][callback]回调地址 '.json_encode(session('redirect_uri','','user'))); //同步通知处理完进行回跳转 if ('app'==$pinfo['type']||request()->isAjax()) { //app同步请求 if($rs) $pay->printMessage('success', 'app callback结果 success, '.$orderId); else $pay->printMessage('failed', 'app callback结果 failed, '.$orderId); } else { if (session('redirect_uri','','user')) { $url = str_replace('.html', '', session('redirect_uri','','user')); session('redirect_uri', null, 'user'); $this->redirect($url); } elseif('wap'==$pinfo['type']) $this->redirect('/wap/'); else $this->redirect('/index/user/walletcenter'); } exit(); //1.服务器发回处理结果 //2.这里交给核心类处理 //3.核心类交给支付接口判断支付成功还是失败 //4.根据支付接口的返回结果,核心类调用之前绑定好的事件. } } ?>