'微信', 'APP' => '微信APP']; private $attach = []; public function preAction() { parent::preAction(); if (empty(\YunShop::app()->uniacid)) { $post = $this->getResponseResult(); if (\YunShop::request()->attach) { \Setting::$uniqueAccountId = \YunShop::app()->uniacid = \YunShop::request()->attach; } else { $this->attach = explode(':', $post['attach']); \Setting::$uniqueAccountId = \YunShop::app()->uniacid = $this->attach[0]; } \Log::debug('---------attach数组--------', \YunShop::app()->uniacid); AccountWechats::setConfig(AccountWechats::getAccountByUniacid(\YunShop::app()->uniacid)); } } public function notifyUrl() { $post = $this->getResponseResult(); $this->log($post); $verify_result = $this->getSignResult($post); if ($verify_result) { //区分公众号、小程序、app支付 if ($post['trade_type'] == 'JSAPI') { $pay_type_id = (isset($this->attach[1]) && $this->attach[1] == 'wechat') ? PayFactory::WECHAT_MIN_PAY : PayFactory::PAY_WEACHAT; } else { if (isset($this->attach[2]) && $this->attach[2] == PayFactory::WECHAT_CPS_APP_PAY){ $pay_type_id = PayFactory::WECHAT_CPS_APP_PAY; }else{ $pay_type_id = PayFactory::PAY_APP_WEACHAT; } } $data = [ 'total_fee' => $post['total_fee'] , 'out_trade_no' => $post['out_trade_no'], 'trade_no' => $post['transaction_id'], 'unit' => 'fen', 'pay_type' => $this->pay_type[$post['trade_type']], 'pay_type_id' => $pay_type_id, ]; $this->payResutl($data); echo "success"; } else { echo "fail"; } } public function jsapiNotifyUrl() { $post = $this->getResponseResult(); $this->log($post); //todo 做签名验证 $verify_result = true; if ($verify_result) { $data = [ 'total_fee' => $post['total_fee'] , 'out_trade_no' => $post['out_trade_no'], 'trade_no' => $post['transaction_id'], 'unit' => 'fen', 'pay_type' => $this->pay_type[$post['trade_type']], 'pay_type_id' => PayFactory::WECHAT_JSAPI_PAY ]; $attach = explode(':', $post['attach']); $WechatPayOrder = [ 'uniacid' => \Yunshop::app()->uniacid, 'account_id' => $attach[3], 'pay_sn' => $post['out_trade_no'], 'transaction_id' => $post['transaction_id'], 'total_fee' => $post['total_fee'], 'profit_sharing' => $attach[2] == 'Y' ? 1:0, ]; $orderPay = OrderPay::where('pay_sn', $data['out_trade_no'])->orderBy('id', 'desc')->first(); if ($orderPay && !$orderPay->orders->isEmpty()) { $order = $orderPay->orders->first(); $WechatPayOrder['order_id'] = $order->id; $WechatPayOrder['member_id'] = $order->uid; } else { $payOrder = PayOrder::where('out_order_no', $data['out_trade_no'])->first(); $WechatPayOrder['order_id'] = 0; $WechatPayOrder['member_id'] = $payOrder->member_id; } WechatPayOrder::create($WechatPayOrder); $this->payResutl($data); echo "success"; } else { echo "fail"; } } /** * @param $post * @return array|false */ public function verifyH5Sign($post) { $pay = \Setting::get('shop.pay'); /** @var $app Application */ $payment = $this->getEasyWeChatApp($pay); try { $message = (new \EasyWeChat\Payment\Notify\Paid($payment))->getMessage(); return $message; } catch (\Exception $exception) { \Log::debug('微信签名验证:'.$exception->getMessage()); return false; } } //微信h5支付 public function notifyH5() { $post = $this->getResponseResult(); $this->log($post); $verify_result = $this->verifyH5Sign($post); \Log::debug('微信H5支付回调验证结果', $verify_result); if ($verify_result) { $data = [ 'total_fee' => $post['total_fee'] , 'out_trade_no' => $post['out_trade_no'], 'trade_no' => $post['transaction_id'], 'unit' => 'fen', 'pay_type' => '微信H5', 'pay_type_id' => PayFactory::WECHAT_H5, ]; $this->payResutl($data); echo "success"; } else { echo "fail"; } } //微信NATIVE支付 public function notifyPc() { $post = $this->getResponseResult(); $this->log($post); $verify_result = $this->verifyH5Sign($post); \Log::debug('微信扫码支付回调验证结果', $verify_result); if ($verify_result) { $data = [ 'total_fee' => $post['total_fee'] , 'out_trade_no' => $post['out_trade_no'], 'trade_no' => $post['transaction_id'], 'unit' => 'fen', 'pay_type' => '微信扫码支付', 'pay_type_id' => PayFactory::WECHAT_NATIVE, ]; $this->payResutl($data); echo "success"; } else { echo "fail"; } } public function returnUrl() { if (\YunShop::request()->outtradeno) { $orderPay = OrderPay::where('pay_sn', \YunShop::request()->outtradeno)->first(); if (is_null($orderPay)) { redirect(Url::absoluteApp('home'))->send(); } else { $redirect = Url::absoluteApp('orderPaySuccess',['pay'=> $orderPay->id]); $trade = \Setting::get('shop.trade'); if (!is_null($trade) && isset($trade['redirect_url']) && !empty($trade['redirect_url'])) { $redirect = $trade['redirect_url']; preg_match("/^(http:\/\/)?([^\/]+)/i", $trade['redirect_url'], $matches); $host = $matches[2]; // 从主机名中取得后面两段 preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches); if ($matches){//判断域名是否一致 $redirect = $trade['redirect_url'].'&outtradeno='.\YunShop::request()->outtradeno; } redirect($redirect)->send(); } $orders = Order::whereIn('id', $orderPay->order_ids)->get(); event($event = new AfterOrderPaidRedirectEvent($orders, $orderPay->id)); if (isset($event)) { $redirect = $event->getData()['redirect'] ?: $redirect; } redirect($redirect)->send(); } } else { redirect(Url::absoluteApp('home'))->send(); } } /** * 签名验证 * * @return bool */ public function getSignResult($post) { switch ($post['trade_type']) { case 'JSAPI': $pay = \Setting::get('shop.pay'); if (isset($this->attach[1]) && $this->attach[1] == 'wechat') { $min_set = \Setting::get('plugin.min_app'); $pay = [ 'weixin_appid' => $min_set['key'], 'weixin_secret' => $min_set['secret'], 'weixin_mchid' => $min_set['mchid'], 'weixin_apisecret' => $min_set['api_secret'], 'weixin_cert' => '', 'weixin_key' => '' ]; } break; case 'APP' : if (isset($this->attach[2]) && $this->attach[2] == PayFactory::WECHAT_CPS_APP_PAY){ $pay = \Setting::get('plugin.aggregation-cps.pay_info'); }else{ $pay = \Setting::get('shop_app.pay'); } break; } $payment = $this->getEasyWeChatApp($pay); try { $message = (new \EasyWeChat\Payment\Notify\Paid($payment))->getMessage(); return $message; } catch (\Exception $exception) { \Log::debug('微信签名验证:'.$exception->getMessage()); return false; } } /** * 创建支付对象 * * @param $pay * @return \EasyWeChat\Payment\Payment */ public function getEasyWeChatApp($pay) { $options = [ 'app_id' => $pay['weixin_appid'], 'secret' => $pay['weixin_secret'], 'mch_id' => $pay['weixin_mchid'], 'key' => $pay['weixin_apisecret'], 'cert_path' => $pay['weixin_cert'], 'key_path' => $pay['weixin_key'] ]; $app = EasyWeChat::payment($options); return $app; } /** * 获取回调结果 * * @return array|mixed|\stdClass */ public function getResponseResult() { $input = file_get_contents('php://input'); if (!empty($input) && empty($_POST['out_trade_no'])) { //禁止引用外部xml实体 $disableEntities = libxml_disable_entity_loader(true); $data = json_decode(json_encode(simplexml_load_string($input, 'SimpleXMLElement', LIBXML_NOCDATA)), true); libxml_disable_entity_loader($disableEntities); if (empty($data)) { exit('fail'); } if ($data['result_code'] != 'SUCCESS' || $data['return_code'] != 'SUCCESS') { exit('fail'); } $post = $data; } else { $post = $_POST; } return $post; } /** * 支付日志 * * @param $post */ public function log($post) { //访问记录 Pay::payAccessLog(); //保存响应数据 Pay::payResponseDataLog($post['out_trade_no'], '微信支付', json_encode($post)); } public function notifyAuth() { $post = $this->getResponseResult(); $verify_result = $this->verifyH5Sign($post); \Log::debug('微信H5支付回调验证结果', $verify_result); if ($verify_result && $verify_result['result_code'] == 'SUCCESS' && $verify_result['return_code'] == 'SUCCESS') { $subOrder = \Yunshop\AuthPayment\models\SubOrder::where('sub_pay_sn', $verify_result['out_trade_no'])->first(); \Log::debug('打印微信H5支付子订单模型: ' . json_encode($subOrder, true)); if ($subOrder) { $subOrder->update(['status' => 1]); $json = [ "data" => [ "pay_sn" => $subOrder->sub_pay_sn, "uniacid" => $subOrder->belongsToManage->sub_uniacid, "amount" => $subOrder->amount ], "appid" => $subOrder->belongsToManage->appid, ]; $manageService = new ManageService; $json['sign'] = $manageService->sign($json, $subOrder->belongsToManage->secret); // 每三秒循环5次发送通知给子平台 发送通知给子平台 $subOrder->belongsToManage $count = 3; for ($x = 0; $x < $count; $x++) { \Log::debug('借权支付子平台发送回调数据: ' . json_encode($json, true)); $result = $subOrder->sendNotify(json_encode($json)); if ($result['result'] == 1) { break; } sleep(3); } } echo "success"; } else { echo "fail"; } } }