payMethod($pay_type); $this->pay_type = $pay_config['pay_type']; $this->pay_method = $pay_config['method']; //取得配置通道文件 $this->gateway_list = config('gateway.' . $this->pay_type); $this->checkGatewayConfig(); if (count(self::$errorArr) > 0) { return false; } //当前的支付类型方法的通道,比如扫码支付,有多个这样子 $all_gateways = $this->gateway_list[$this->pay_method]; //当前用户是否指定了支付通道 try { if (!is_array($custom_gateways)) { return false; } if (count($custom_gateways) > 0) { $this->pay_gateway = $this->randomCustomGateways($all_gateways, $custom_gateways); } else { $this->pay_gateway = $this->randomAllGateways($all_gateways); } //dump($this->pay_gateway); return $this->pay_gateway;//支付数据库信息 } catch (\Exception $e) { return false; } } /** * 检查通道是否存在错误 */ public function checkGatewayConfig() { $pay_method = $this->pay_method; if (count($this->gateway_list) <= 0) { self::addError(['msg' => '通道支付不存在']); } if (!isset($this->gateway_list[$pay_method])) { self::addError(['msg' => '通道支付类型不存在']); } } //第二部配置支付信息,payConfig public function payConfig($type, $setConfig = []) { //将支付配置模型赋值给$this->pay_model,发起支付的时候使用 $gateway = Omnipay\Omnipay::create('UnionPay_Express'); $gateway->setMerId($this->pay_gateway['app_id']); //商户号 //to_linux_path(public_path()) . $cert_key = to_linux_path(public_path()) . $this->pay_gateway['cert_key']; //dd($cert_key); $gateway->setCertPath($cert_key); // 商户私钥证书 //$gateway->setCertDir( $this->pay_gateway['cert_pub']); //测试环境银联公钥证书 //$gateway->setCertPath(to_linux_path(public_path()) . '/certs/700000000000001_acp.p12'); // 商户私钥证书 $gateway->setCertDir(to_linux_path(app_path()) . '/certs/verify_sign_acp.cer'); //测试环境银联公钥证书 //dump($this->pay_gateway['cert_pub']); $gateway->setPublicKey(to_linux_path(public_path()) . $this->pay_gateway['cert_pub']); // path or content $gateway->setReturnUrl(action('Pay\PayController@returnNotify', ['type' => $type])); // 支付后同步通知页面地址 $gateway->setNotifyUrl(action('Pay\PayController@notify', ['type' => $type])); // dd($this->pay_gateway['app_key']); $gateway->setCertPassword($this->pay_gateway['app_key']); // 密码 $this->pay_model = $gateway; } //统一下单支付 public function pay($pay_data) { //dd($pay_data); $response = $this->pay_model->purchase($pay_data)->send(); $response->redirect(); // 发起银联支付请求 } //统一验证签名 public function verify() { $response = $this->pay_model->completePurchase(['request_params' => $this->request->all()])->send(); $this->result_data = $response->getData(); return $response->isPaid(); } //返回给支付商的成功 public function success() { return 'success'; } //统一回调处理 /** * 回调第一部,如果是同步,直接回传 * @param $return * @param $pay_type * @param $request * @return bool|\Illuminate\Http\RedirectResponse */ public function notify($return, $pay_type, $request) { $this->request = $request; $this->pay_type = $pay_type; $this->setLogName($this->pay_type); // self::$result = $request->all(); // self::$result['pay_order_sn'] = $request->input('queryId'); //取得订单 $this->getOrder($this->request->input('orderId')); if ($return) { //return $this->unionPayNotify(); return $this->returnUnionPay(); } return $this->unionPayNotify(); } /** * 取得订单,支付宝和微信返回的订单号都有差异,需要分开处理 * @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); } /** * 同步回调 * @return \Illuminate\Http\RedirectResponse */ public function returnUnionPay() { //判断是否是商户id if ($this->order->merchant_id == 0) { return redirect()->route('web.user.index'); } // return $this->merchantReturnSend(); } //异步回调 /** * 获得通道信息,取得支付配置模型,验证签名, * @return bool|void */ public function unionPayNotify() { //取得通道信息内容 $this->gateway = $this->pay_gateway = config('gateway.config')[$this->gateway_id]; //加载通道的支付配置信息 //这里取得支付实例化$this->pay_model $this->payConfig($this->pay_type); //验证签名 if (!$this->verify()) { $this->debugLog('订单验证签名失败', $this->request->all()); return false; } $data = $this->result_data; $this->pay_data = $this->result_data; //如果应答状态不是01/A6表示支付失败 if (!in_array($data['respCode'], ['00', 'A6'])) { $this->debugLog('订单支付失败', $this->request->all()); return false;//支付失败 } $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 = ''; //统一格式化 $this->unionHandle($data); //支付返回信息 $this->pay_data = $data; $this->debugLog('验证签名成功,数据', $data); //更新订单 $this->updateOrder(); $this->debugLog('updateOrder Ok'); } catch (\Exception $exception) { $this->debugLog('失败异常内容:' . $exception->getMessage()); if (!in_array($data['respCode'], ['00', 'A6'])) { $this->debugLog('订单支付失败', $this->request->all()); 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)]); } } /** * 统一格式化 */ public function unionHandle($data) { $result = [ 'order_sn' => $data['orderId'], 'pay_order_sn' => $data['queryId'], 'pay_money' => $data['settleAmt'] / 100,//单位分需要/100等于元 'pay_type' => 'unionpay', 'account' => $data['accNo'] ]; // dd($result); $this->setResult($result); Log::channel('pay_success')->info('银联支付成功', [ 'pay_type' => $result['pay_type'], 'pay_money' => $result['pay_money'], 'account' => $result['account'], 'order_sn' => $result['order_sn'], 'pay_order_sn' => $result['pay_order_sn']]); } /** * 这个调试需要配置在config/logging.php * @param $pay_type */ public function setLogName($pay_type) { $name = ''; switch ($pay_type) { case 'unionpay': $name = 'unionpay_'; break; } $this->log_name = $name; } }