pay_method; if (count($this->gateway_list) <= 0) { self::addError(['msg' => '通道支付不存在']); } if (!isset($this->gateway_list[$pay_method])) { self::addError(['msg' => '通道支付类型不存在']); } } /** * 支付包配置实列化 * @param $type * @param array $setConfig * @return $this */ public function payConfig($type, $setConfig = []) { $config = $this->getPayAccount($type); $extend_config = [ 'log' => [ // optional 'file' => to_linux_path(base_path()) . '/paylogs/' . $type . '_pay.log', 'level' => 'info', // 建议生产环境等级调整为 info,开发环境为 debug 'type' => 'daily', // optional, 可选 daily. 'max_file' => 30, // optional, 当 type 为 daily 时有效,默认 30 天 ], 'return_url' => action('Pay\PayController@returnNotify', ['type' => $type]), 'notify_url' => action('Pay\PayController@notify', ['type' => $type]), 'http' => [ // optional 'timeout' => 5.0, 'connect_timeout' => 5.0, // 更多配置项请参考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html) ] ]; if ($this->pay_gateway['is_dev'] == 1) { $extend_config['mode'] = 'dev';//沙箱 } $this->pay_config = $setConfig + $extend_config + $config; Log::info(json_encode($this->pay_config)); switch ($type) { case 'alipay': $this->pay_model = Pay::alipay($this->pay_config); //dump('我用了支付宝'); break; case 'weixin': $this->pay_model = Pay::wechat($this->pay_config); break; } return $this; } //回调指定通道配置信息gateway public function getConfig($gateway_id, $pay_method) { $this->pay_method = $pay_method; return $this->pay_model = config('gateway.config')[$gateway_id]; } public function getPayConfig() { return $this->pay_config; } public function pay($pay_data) { $method = $this->pay_method; $pay = $this->pay_model->$method($pay_data); if (in_array($method, ['web', 'wap', 'app'])) { return $pay->send();//直接发送支付 } else { //扫码返回 return $pay; } } /* * 验证签名 */ public function verify() { return $this->pay_model->verify(); } /** * 支付账号信息 * @param $type * @return array */ public function getPayAccount($type) { $config = []; switch ($type) { //支付宝配置 case 'alipay': $config = [ 'app_id' => $this->pay_gateway['app_id'], 'ali_public_key' => trim($this->pay_gateway['cert_pub']), 'private_key' => trim($this->pay_gateway['cert_key']) ]; break; //微信 case 'weixin': $config = [ 'app_id' => $this->pay_gateway['app_id'], 'mch_id' => $this->pay_gateway['mch_id'], 'key' => $this->pay_gateway['app_key'] ]; break; //小程序 case 'mini': $config = [ 'miniapp_id' => $this->pay_gateway['app_id'], 'mch_id' => $this->pay_gateway['mch_id'], 'key' => $this->pay_gateway['app_key'] ]; break; } return $config; } public function setLogName($pay_type) { $name = ''; switch ($pay_type) { case 'alipay': $name = 'alipay_'; break; case 'weixin': $name = 'weixin_'; break; } $this->log_name = $name; } public function notify($return = 1, $pay_type, $request) { $this->request = $request; $this->pay_type = $pay_type; $this->setLogName($this->pay_type); switch ($this->pay_type) { case 'alipay': //取得支付宝类型的订单 $this->getOrder($this->request->input('out_trade_no')); if ($return) { return $this->returnAlipay(); } return $this->alipayNotify(); break; case 'weixin': if ($return) { return $this->returnWeixin(); } return $this->weixinNotify(); break; } } /** * 支付宝同步回调 * */ public function returnAlipay() { //判断是否是商户id if ($this->order->merchant_id == 0) { return redirect()->route('web.user.index'); } // return $this->merchantReturnSend(); } /** * 同步回调给微信支付 * @return \Illuminate\Http\RedirectResponse */ public function returnWeixin() { $this->getOrder($this->request->input('out_trade_no'));//取得微信类型的订单 //判断是否是商户id if ($this->order->merchant_id == 0) { return redirect()->route('web.user.index'); } // return $this->merchantReturnSend(); } public function weixinNotify() { //$this->getOrder($this->request->input('out_trade_no')); $content = $content ?? $this->request->createFromGlobals()->getContent(); $data = Support::fromXml($content); $order_sn = $data['out_trade_no']; $data = new Collection($data); Log::info('微信过来参数' . json_encode($data->toArray())); $this->getOrder($order_sn); $this->commonNotify(); } /** * 支付宝异步回调 */ public function alipayNotify() { $this->commonNotify(); } /** * 取得订单,支付宝和微信返回的订单号都有差异,需要分开处理 * @param $order_sn */ public function getOrder($order_sn) { $this->order = Order::where('order_sn', $order_sn)->first(); $this->pay_method = $this->order->gateway_method;//支付方法 $this->gateway_id = $this->order->gateway_id;//通道ID $this->merchant = Merchant::find($this->order->merchant_id); } /** * 支付宝统一设置参数 * @param $data * @return bool */ public function alipayHandle($data) { $result = [ 'order_sn' => $data->out_trade_no, 'pay_order_sn' => $data->trade_no, 'pay_money' => $data->total_amount, 'pay_type' => 'alipay', 'account' => $data->buyer_logon_id ]; $this->setResult($result); Log::channel('pay_success')->info('支付宝支付成功', ['pay_type' => 'alipay', 'pay_money' => $data->total_amount, 'account' => $data->buyer_logon_id, 'order_sn' => $data->out_trade_no, 'pay_order_sn' => $data->trade_no]); } public function wechatHandle($data) { $data = $data->toArray(); $result = [ 'order_sn' => $data['out_trade_no'], 'pay_order_sn' => $data['transaction_id'],//微信订单号 'pay_money' => $data['total_fee'] / 100,//订单金额,单位分/100=元 'pay_type' => 'weixin', 'account' => $data['openid'] //openid ]; $this->setResult($result); Log::channel('pay_success')->info('微信支付成功', ['pay_type' => 'weixin', 'pay_money' => $result['pay_money'], 'account' => $result['account'], 'order_sn' => $result['order_sn'], 'pay_order_sn' => $result['pay_order_sn']]); // Log::channel('pay_success')->info('小程序支付成功',['total'=>$data->total_fee,'openid'=>$data->openid,'out_trade_no'=>$data->out_trade_no,'order_type'=>$data->attach]); } public function commonNotify() { //取得通道信息内容 $this->gateway = $this->pay_gateway = config('gateway.config')[$this->gateway_id]; //加载通道的支付配置信息 //这里取得支付实例化$this->pay_model $this->payConfig($this->pay_type); //验证签名 $data = $this->verify(); $this->debugLog('-------------' . $this->order->order_sn . '--选择----' . $this->pay_type . '----' . $this->pay_method . '----开始回调处理-------------------------'); if (empty($data)) { return $this->debugLog('验证签名失败', $this->request->all()); } try { $pay_cn_name = ''; switch ($this->pay_type) { case 'alipay': //支付宝异步回掉也是会未支付 if (!in_array($data->trade_status, ['TRADE_SUCCESS', 'TRADE_FINISHED'])) { return false; exit();//终止 } $this->alipayHandle($data); $pay_cn_name = '支付宝'; break; case 'weixin': $pay_cn_name = '微信'; $this->wechatHandle($data); break; } $this->debugLog('验证签名成功,准备订单更新'); //支付返回信息 $this->pay_data = $data; $this->debugLog('验证签名成功,数据', $data); //更新订单 $this->updateOrder(); $this->debugLog('updateOrder Ok'); } catch (\Exception $exception) { $this->debugLog('失败异常内容:' . $exception->getMessage()); if ($this->pay_type == 'alipay') { //支付宝异步回调也是会有未支付,需要这2个判断 if (!in_array($data->trade_status, ['TRADE_SUCCESS', 'TRADE_FINISHED'])) { return false; } } $this->order->notify_status = 1;//支付回调成功 $this->order->pay_status = 1;//支付状态 $this->order->pay_ok_at = date('Y-m-d H:i:s'); $this->order->save();//保存 Log::channel('pay_success')->info($pay_cn_name . '支付成功,但处理订单失败', ['data' => json_encode($data)]); } } /** * 更新订单操作 * @return mixed|void */ public function updateOrder() { $order = $this->order; //判断是否本站 if ($order->merchant_id == 0) { //本地订单处理 return $this->locationOrder(); } else { //外站订单处理 //支付宝会异步发送未支付的操作 if ($this->pay_type == 'alipay') { $this->debugLog('alipay'); //支付宝异步回调也是会有未支付,需要这2个判断 if (!in_array($this->pay_data->trade_status, ['TRADE_SUCCESS', 'TRADE_FINISHED'])) { return false; } } return $this->outOrder(); } } //成功完成异步回调返回给支付商 public function success() { $this->pay_model->success()->send(); } }