admin/app/payment/controllers/WechatController.php

406 lines
13 KiB
PHP

<?php
/**
* Created by PhpStorm.
* Author:
* Date: 2017/3/28
* Time: 上午6:50
*/
namespace app\payment\controllers;
use app\common\events\order\AfterOrderPaidRedirectEvent;
use app\common\facades\EasyWeChat;
use app\common\helpers\Url;
use app\common\models\AccountWechats;
use app\common\models\Order;
use app\common\models\OrderPay;
use app\common\models\PayOrder;
use app\common\modules\wechat\models\WechatPayOrder;
use app\common\services\Pay;
use app\common\services\PayFactory;
use app\payment\PaymentController;
use Yunshop\AuthPayment\services\ManageService;
class WechatController extends PaymentController
{
private $pay_type = ['JSAPI' => '微信', '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";
}
}
}