diff --git a/.env.example b/.env.example
index ec44a12..0082503 100644
--- a/.env.example
+++ b/.env.example
@@ -6,6 +6,9 @@ APP_URL=http://localhost
LOG_CHANNEL=stack
+NOTIFY_URL=http://test.local.com
+BASE_URL=http://test.local.com
+
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
diff --git a/app/Http/Controllers/Admin/GatewayController.php b/app/Http/Controllers/Admin/GatewayController.php
index a6577df..ac25108 100644
--- a/app/Http/Controllers/Admin/GatewayController.php
+++ b/app/Http/Controllers/Admin/GatewayController.php
@@ -4,8 +4,10 @@ namespace App\Http\Controllers\Admin;
use App\Models\Bank;
use App\Models\Gateway;
+use App\Services\DateServices;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
+use Illuminate\Support\Facades\DB;
class GatewayController extends BaseDefaultController
{
@@ -71,6 +73,46 @@ class GatewayController extends BaseDefaultController
}
+ public function statics(){
+
+ $this->title='通道统计';
+ // dump($config);
+ $this->setTitle();
+ return $this->display([]);
+ }
+
+ public function statics_data(){
+
+ $requestData = request()->all();
+ if (isset($requestData['timeday'])) {
+ $time = str_replace('~', ',', $requestData['timeday']);
+
+ $time = explode(",", $time);
+
+ $date['start_at'] = $time[0] ?? '';
+ $date['end_at'] = $time[1] ?? '';
+ } else {
+ $date = DateServices::today();
+ }
+
+ if (empty($date['start_at']) || empty($date['end_at'])) {
+ $date = DateServices::today();
+ }
+
+ $data = DB::select("select t.gateway_id,t.total,t.created_at ,t.order_money,g.`name`,
+ (select sum(p.order_money) from orders p where p.gateway_id=t.gateway_id and pay_status='1' and p.created_at>='" . $date['start_at'] . "' and p.created_at <='" . $date['end_at'] . "') as ok_money,
+ (select count(p.pay_status) from orders p where p.gateway_id=t.gateway_id and pay_status='1'and p.created_at>='" . $date['start_at'] . "' and p.created_at <='" . $date['end_at'] . "') as ok_total
+ from (select count(pay_status) as total,sum(order_money)as order_money,gateway_id,created_at from orders where created_at>='" . $date['start_at'] . "' and created_at <='" . $date['end_at'] . "' group by gateway_id) t JOIN gateways g ON t.gateway_id=g.id
+ ORDER BY order_money desc");
+ $json = [
+ "status"=>1,
+ 'code'=>count($data)>0?0:1,
+ 'msg'=>count($data)>0?'请求数据成功':'暂无数据',
+ 'count' => count($data),
+ 'data' => $data
+ ];
+ return response()->json($json);
+ }
public function setModel()
{
diff --git a/app/Http/Controllers/Admin/HandleController.php b/app/Http/Controllers/Admin/HandleController.php
index 493bd9f..de79e56 100644
--- a/app/Http/Controllers/Admin/HandleController.php
+++ b/app/Http/Controllers/Admin/HandleController.php
@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Admin;
use App\Events\CouponCardEvent;
use App\Models\CouponCard;
use App\Models\Scenic;
+use App\Models\UploadQrcode;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use DB;
@@ -124,6 +125,8 @@ class HandleController extends BaseController
];
return response()->json($data);
}
+
+
$id_arr = explode(",", $id);
if (count($id_arr) <= 0) {
$data = [
@@ -159,6 +162,22 @@ class HandleController extends BaseController
'type' => 'del'
];
+
+ if ($table == 'upload_qrcodes') {
+ $where[] = [function ($query) use ($id_arr) {
+ $query->whereIn('id', $id_arr);
+ }];
+ $res = DB::table($table)->where($where)->get(['id', 'uid']);
+ $uidArr = [];
+ foreach ($res as $r) {
+ $uidArr[] = $r->uid;
+ }
+ $uidArr = array_unique($uidArr);
+ Log::channel('zhanxin')->info('删除请求数据', $uidArr);
+ foreach ($uidArr as $r) {
+ $this->delUid($r);
+ }
+ }
return response()->json($data);
}
DB::rollBack();
@@ -203,4 +222,37 @@ class HandleController extends BaseController
break;
}
}
+
+ private function delUid($uid){
+ $ts = time();
+ $chanxinconfig = config('qrcodeurl.zhanxin');
+ $data['userid'] = $uid;
+ $data['ts'] = strval($ts);
+ $str = 'uid=' . $uid . '&ts=' . $ts . '&' . $chanxinconfig['secret'];
+ Log::channel('zhanxin')->info('删除请求' . $str, []);
+ $data['key'] = strtolower(md5($str));
+ Log::channel('zhanxin')->info('删除请求数据', $data);
+ $url = $chanxinconfig['baseurl'] . $chanxinconfig['del'];
+ $data = (is_array($data)) ? json_encode($data, JSON_UNESCAPED_UNICODE) : $data;
+ $curl = curl_init();
+ $headerArray = array("Content-type:application/json;charset='utf-8'", "Accept:application/json");
+ curl_setopt_array($curl, array(
+ CURLOPT_URL => $url,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_ENCODING => '',
+ CURLOPT_MAXREDIRS => 10,
+ CURLOPT_TIMEOUT => 0,
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
+ CURLOPT_CUSTOMREQUEST => 'DELETE',
+ CURLOPT_HTTPHEADER => $headerArray,
+ ));
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
+ $response = curl_exec($curl);
+ curl_close($curl);
+ Log::channel('zhanxin')->info('删除返回数据' . $response, is_array($response) ? $response : []);
+ return $response;
+ }
}
diff --git a/app/Http/Controllers/Admin/OrderController.php b/app/Http/Controllers/Admin/OrderController.php
index ce55e08..bad92cf 100644
--- a/app/Http/Controllers/Admin/OrderController.php
+++ b/app/Http/Controllers/Admin/OrderController.php
@@ -108,9 +108,10 @@ class OrderController extends BaseDefaultController
{
$param['guma']=1;
}
+
$search =(new SearchServices($this->setModel(),$param,$order_type));
- // $search->setTimeType('order');
- // dump($search->echoWhere());
+ // $search->setTimeType('order');
+// dump($search->echoWhere());
$model=$search->getList();
$total = $model->count();
$result = $model->skip($offset)->with('users','merchants','gateways')->orderBy($order_id, $order_type_desc)->orderBy('id', 'desc')->take($pagesize)->get();;
diff --git a/app/ServicePay/CengJingServices.php b/app/ServicePay/CengJingServices.php
new file mode 100644
index 0000000..bbcd9a4
--- /dev/null
+++ b/app/ServicePay/CengJingServices.php
@@ -0,0 +1,351 @@
+ $this->getGateUrl() . '/payment',
+ 'debug' => 1,//调试
+ 'logDir' => to_linux_path(storage_path() . '/logs/'),
+ 'mch_id' => $this->pay_gateway['app_id'], //客户交易者账号
+ 'token' => $this->pay_gateway['app_key'],//密钥
+ 'interface' => $this->pay_gateway['mch_id'],//账号名称 一般用来存放三方通道
+ 'return_url' => action('Pay\PayController@returnNotify', ['type' => $type]),
+ 'notify_url' => action('Pay\PayController@notify', ['type' => $type]),
+ ];
+ $this->pay_config = $config;
+ }
+
+ //统一下单支付
+
+ /**
+ * @param $pay_data
+ * @return array|\Illuminate\Http\RedirectResponse
+ */
+ public function pay($pay_data)
+ {
+// echo number_format( 500, 2,'.','');exit;
+ //商户号
+ $accountId = $this->pay_config['mch_id'];
+ //商户秘钥
+ $key = $this->pay_config['token'];
+ $payData = [
+ 'merchant_code' => $accountId,//商户
+ 'channel' => $this->pay_gateway['mch_id'],//对应的三方通道
+ 'notify_url' => strval($this->pay_config['notify_url']),// //异步回调地址
+ 'order_id' => strval($pay_data['out_trade_no']),//订单号
+ 'amount' => $pay_data['total_amount'], //支付金额为元
+ 'callback_url' => strval($this->pay_config['return_url']),//页面跳转通知
+ ];
+ $sign = $this->sign($payData, $key);//签名
+ $payData['sign'] = $sign;
+ $res = Curl::to($this->pay_config['url'])->withData($payData)->post();
+ var_dump($res);
+ $this->debugLog('下单接口请求内容' . json_encode($payData, true), []);
+ exit;
+
+ return redirect()->away($this->pay_config['url'] . '?' . http_build_query($payData));
+ }
+
+ private function sign($tempArr, $signKey): string
+ {
+ $keyVal = '';
+
+ if (isset($tempArr['callback_url'])) {
+ unset($tempArr['callback_url']);
+ }
+
+ $data = [];
+ foreach ($tempArr as $key => $value) {
+ array_push($data, "{$key}{$value}");
+ }
+ $keyVal = implode('', $data);
+
+ if (!empty($signKey) && is_string($signKey)) {
+ $keyVal .= $signKey;
+ }
+// echo $keyVal;exit;
+ return md5($keyVal);
+ }
+
+ /**
+ * 检查订单
+ * @param $orderid
+ * @return bool|string
+ */
+ private function checkOrder($orderid)
+ {
+ $url = $this->getGateUrl() . '/payment/orderStatus';
+ $payData = [
+ 'merchant_code' => $this->pay_gateway['app_id'],//商户号
+ 'order_id' => $orderid,
+ ];
+ $key = $this->pay_config['token'];
+ $payData['sign'] = $this->sign($payData, $key);
+ Log::channel('pay_order')->info('查询接口请求', $payData);
+
+ $responseRaw = $this->ddcurl($url, $payData, false,'get');
+ $response = is_array($responseRaw) ? $responseRaw : json_decode($responseRaw, 256);
+// $this->debugLog('查询接口返回' . is_array($res) ? json_encode($res, true) : json_encode(json_decode($res, 256), true));
+ Log::channel('pay_order')->info('查询接口返回', $response);
+ if (is_array($response)
+ && isset($response['code']) && $response['code'] == 'S-100'
+ && isset($response['order_id']) && $response['order_id'] == $orderid
+ && isset($response['status']) && $response['status']=='notified'
+ ) {
+ return true;
+ }
+ return false;
+ }
+
+
+ //统一验证签名
+ public function verify()
+ {
+ $params = $this->result_data;
+ $signParam=[
+ 'merchant_code'=>$params['merchant_code'],
+ 'status'=>$params['status'],
+ 'order_id'=>$params['order_id'],
+ 'amount'=>$params['amount'],
+ ];
+ $md5sign = $this->sign($signParam, $this->pay_config['token']);
+
+ if (isset($params['sign']) && $md5sign == $params['sign']
+ && isset($params['status']) && in_array($params['status'], [1])
+ ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+ //返回给支付商的成功
+ public function success()
+ {
+ echo 'success';
+ exit;
+ }
+
+ //统一回调处理
+
+ /**
+ * 回调第一部,如果是同步,直接回传
+ * @param $return
+ * @param $pay_type
+ * @param $request
+ * @return bool|\Illuminate\Http\RedirectResponse
+ */
+ public function notify($return, $pay_type, $request)
+ {
+ $request = json_decode(file_get_contents('php://input'), true);
+ $this->setLogName($pay_type);
+ $this->debugLog('回调原始数据', $request);
+ $this->pay_type = $pay_type;
+ $this->request = $request;
+ //取得订单,是否有此订单,如果没有直接返回空
+ $order_sn = $request['order_id'];
+ $status = $request['status'];
+ if ($status != 1) {
+ return '未支付成功';
+ }
+
+ $checkresult = $this->checkIP();//检查回调IP
+ if (!$checkresult) {
+ return 'ip 不合法';
+ }
+ //取得订单
+ $this->getOrder($order_sn);
+
+ $return = ($return) ? 1 : 0;
+ if ($return) {
+
+ //判断是否是商户id
+ if ($this->order->merchant_id == 0) {
+ return redirect()->route('web.user.index');
+ }
+ //
+ return $this->merchantReturnSend();
+ }
+ //取得通道id
+ $this->gateway = $this->pay_gateway = config('gateway.config')[$this->gateway_id];
+ //dd($this->gateway);
+ //取得支付配置
+ $this->payConfig($this->pay_type);
+
+ $this->result_data = $request;
+ //检查三方的订单
+ $checkorder = $this->checkOrder($order_sn);
+ if (!$checkorder) {
+ $this->debugLog('查询三方订单未支付成功');
+ return '查询三方订单未支付成功';
+ }
+ //dump($this->result_data);
+ //进行验证签名
+ if (!$this->verify()) {
+ $this->debugLog('签名以及支付状态验证失败');
+ return '签名以及支付状态验证失败';
+ }
+
+ return $this->payNotify();
+ }
+
+
+ /**
+ * 同步回调
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function returnPay()
+ {
+ //判断是否是商户id
+ if ($this->order->merchant_id == 0) {
+ return redirect()->route('web.user.index');
+ }
+ //
+ return $this->merchantReturnSend();
+ }
+
+ //异步回调
+
+ /**
+ * 获得通道信息,取得支付配置模型,验证签名,
+ * @return bool|void
+ */
+ private function payNotify()
+ {
+ //取得通道信息内容
+ $data = $this->result_data;
+ $this->pay_data = $this->result_data;
+ //如果应答状态不是01/A6表示支付失败
+ $this->debugLog(json_encode($data, true));
+ $this->debugLog('-------------' . $this->order->order_sn . '--选择----' . $this->pay_type . '----' . $this->pay_method . '----开始回调处理-------------------------');
+ if (empty($data)) {
+ return $this->debugLog('验证签名失败', $data);
+ }
+ 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());
+ $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['order_id'],//我方订单号
+ 'pay_order_sn' => $data['order_id'],//三方的订单号
+// 'pay_money' => number_format($data['payamount'] / 100, 2, '.', ''), //支付金额,
+ 'pay_money' => $data['amount'], //支付金额,
+ 'pay_type' => $this->pay_type,
+ 'account' => ''
+ ];
+
+ $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)
+ {
+ $this->log_name = $pay_type;
+ }
+
+ /**
+ * 模拟post提交 json数据 请求接口
+ * @param string $url
+ * @param bool|true $https
+ * @param string $method
+ * @param string $param
+ * @return mixed
+ */
+ private function ddcurl($url = '', $param = '', $https = true, $method = 'post')
+ {
+ $param = json_encode($param, 320);
+ $ch = curl_init($url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+
+ #判断是否为https请求
+ if ($https === true) {
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ }
+ #判断是否为post请求
+ if ($method == 'post') {
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
+ }
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type:application/json'));
+
+ $str = curl_exec($ch);
+
+ curl_close($ch);
+ return $str;
+ }
+}
diff --git a/app/ServicePay/DaliPayServices.php b/app/ServicePay/DaliPayServices.php
new file mode 100644
index 0000000..1c7fb04
--- /dev/null
+++ b/app/ServicePay/DaliPayServices.php
@@ -0,0 +1,363 @@
+ $this->getGateUrl() . '/api/index',
+ 'debug' => 1,//调试
+ 'logDir' => to_linux_path(storage_path() . '/logs/'),
+ 'mch_id' => $this->pay_gateway['app_id'], //客户交易者账号
+ 'token' => $this->pay_gateway['app_key'],//密钥
+ 'interface' => $this->pay_gateway['mch_id'],//账号名称 一般用来存放三方通道
+ 'return_url' => action('Pay\PayController@returnNotify', ['type' => $type]),
+ 'notify_url' => action('Pay\PayController@notify', ['type' => $type]),
+ ];
+ $this->pay_config = $config;
+ }
+
+ //统一下单支付
+
+ /**
+ * @param $pay_data
+ * @return array|\Illuminate\Http\RedirectResponse
+ */
+ public function pay($pay_data)
+ {
+// echo number_format( 500, 2,'.','');exit;
+ //商户号
+ $accountId = $this->pay_config['mch_id'];
+ //商户秘钥
+ $key = $this->pay_config['token'];
+ $payData = [
+ 'bid' => $accountId,//商户
+ 'pay_type' => $this->pay_gateway['mch_id'],//对应的三方通道
+ 'notify_url' => strval($this->pay_config['notify_url']),// //异步回调地址
+ 'order_sn' => strval($pay_data['out_trade_no']),//订单号
+ 'money' => $pay_data['total_amount'], //支付金额为元
+ 'callback_url' => strval($this->pay_config['return_url']),//页面跳转通知
+ ];
+ $sign = $this->sign($payData, $key);//签名
+ $payData['sign'] = $sign;
+ $res = Curl::to($this->pay_config['url'])->withData($payData)->post();
+ $this->debugLog('下单接口请求内容' . json_encode($payData, true), []);
+
+ $res = is_array($res) ? $res : json_decode($res, 256);
+ if (is_array($res) && isset($res['code']) && $res['code'] == 100) {
+ $data = $res['data'];
+ $url = $data['url'];
+ return redirect()->away($url);
+ } else {
+ $msg = $res['msg'] ?? '未知错误';
+ return ['code' => 0, 'msg' => $msg];
+ }
+
+ }
+
+ private function sign($tempArr, $signKey): string
+ {
+ $keyVal='';
+
+ if (isset($tempArr['sign'])) {
+ unset($tempArr['sign']);
+ }
+
+ ksort($tempArr);
+
+ $data = [];
+ foreach ($tempArr as $key=>$value) {
+ array_push($data, "{$key}={$value}");
+ }
+ $keyVal = implode('&', $data);
+
+ if (!empty($signKey) && is_string($signKey)) {
+ $keyVal .= $signKey;
+ }
+
+ return strtolower(md5($keyVal));
+ }
+
+ /**
+ * 检查订单
+ * @param $orderid
+ * @return bool|string
+ */
+ private function checkOrder($orderid)
+ {
+ $url = $this->getGateUrl() . '/api/detail';
+ $payData = [
+ 'bid' => $this->pay_gateway['app_id'],//商户号
+ 'order_sn' => $orderid,
+ ];
+ $key = $this->pay_config['token'];
+ $sign=$this->sign($payData, $key);
+ $payData['sign'] = $sign;
+ Log::channel('pay_order')->info('查询接口请求', $payData);
+ $responseRaw = Curl::to($url)->withData($payData)->post();
+// $responseRaw = $this->ddcurl($url, $payData, false);
+ $response = is_array($responseRaw) ? $responseRaw : json_decode($responseRaw, 256);
+// $this->debugLog('查询接口返回' . is_array($res) ? json_encode($res, true) : json_encode(json_decode($res, 256), true));
+ Log::channel('pay_order')->info('查询接口返回', $response);
+ if (is_array($response)
+ && isset($response['code']) && $response['code'] == 100
+ && isset($response['data']['order_sn']) && $response['data']['order_sn'] == $orderid
+ && isset($response['data']['pay_state']) && $response['data']['pay_state']==1
+ && isset($response['data']['sign']) && $response['data']['sign']==$sign
+ ) {
+ return true;
+ }
+ return false;
+ }
+
+
+ //统一验证签名
+ public function verify()
+ {
+ $params = $this->result_data;
+
+ $md5sign = $this->sign($params, $this->pay_config['token']);
+
+ if (isset($params['sign']) && $md5sign == $params['sign']
+ && isset($params['pay_state']) && $params['pay_state'] ==1
+ ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+ //返回给支付商的成功
+ public function success()
+ {
+ echo 'success';
+ exit;
+ }
+
+ //统一回调处理
+
+ /**
+ * 回调第一部,如果是同步,直接回传
+ * @param $return
+ * @param $pay_type
+ * @param $request
+ * @return bool|\Illuminate\Http\RedirectResponse
+ */
+ public function notify($return, $pay_type, $request)
+ {
+// $request = json_decode(file_get_contents('php://input'), true);
+ $allData = $request->all();
+ $this->setLogName($pay_type);
+ $this->debugLog('回调原始数据', $allData);
+ $this->pay_type = $pay_type;
+ $this->request = $request;
+ //取得订单,是否有此订单,如果没有直接返回空
+// $order_sn = $request->input('order_sn');
+ $order_sn = $allData['order_sn'];
+
+ $status = $allData['pay_state'];
+// $status = $request->input('pay_state');
+
+ if ($status != 1) {
+ return '未支付成功';
+ }
+
+ $checkresult = $this->checkIP();//检查回调IP
+ if (!$checkresult) {
+ return 'ip 不合法';
+ }
+ //取得订单
+ $this->getOrder($order_sn);
+
+ $return = ($return) ? 1 : 0;
+ if ($return) {
+
+ //判断是否是商户id
+ if ($this->order->merchant_id == 0) {
+ return redirect()->route('web.user.index');
+ }
+ //
+ return $this->merchantReturnSend();
+ }
+ //取得通道id
+ $this->gateway = $this->pay_gateway = config('gateway.config')[$this->gateway_id];
+ //dd($this->gateway);
+ //取得支付配置
+ $this->payConfig($this->pay_type);
+
+ $this->result_data = $allData;
+ //检查三方的订单
+ $checkorder = $this->checkOrder($order_sn);
+ if (!$checkorder) {
+ $this->debugLog('查询三方订单未支付成功');
+ return '查询三方订单未支付成功';
+ }
+ //dump($this->result_data);
+ //进行验证签名
+ if (!$this->verify()) {
+ $this->debugLog('签名以及支付状态验证失败');
+ return '签名以及支付状态验证失败';
+ }
+
+ return $this->payNotify();
+ }
+
+
+ /**
+ * 同步回调
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function returnPay()
+ {
+ //判断是否是商户id
+ if ($this->order->merchant_id == 0) {
+ return redirect()->route('web.user.index');
+ }
+ //
+ return $this->merchantReturnSend();
+ }
+
+ //异步回调
+
+ /**
+ * 获得通道信息,取得支付配置模型,验证签名,
+ * @return bool|void
+ */
+ private function payNotify()
+ {
+ //取得通道信息内容
+ $data = $this->result_data;
+ $this->pay_data = $this->result_data;
+ //如果应答状态不是01/A6表示支付失败
+ $this->debugLog(json_encode($data, true));
+ $this->debugLog('-------------' . $this->order->order_sn . '--选择----' . $this->pay_type . '----' . $this->pay_method . '----开始回调处理-------------------------');
+ if (empty($data)) {
+ return $this->debugLog('验证签名失败', $data);
+ }
+ 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());
+ $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['order_sn'],//我方订单号
+ 'pay_order_sn' => $data['sys_order_sn'],//三方的订单号
+// 'pay_money' => number_format($data['payamount'] / 100, 2, '.', ''), //支付金额,
+ 'pay_money' => $data['pay_money'], //支付金额,
+ 'money' => $data['money'],
+ 'pay_type' => $this->pay_type,
+ 'account' => ''
+ ];
+
+ $this->setResult($result);
+ Log::channel('pay_success')->info('支付成功', [
+ 'pay_type' => $result['pay_type'], 'pay_money' => $result['pay_money'],
+ 'account' => $result['money'], 'order_sn' => $result['order_sn'],
+ 'pay_order_sn' => $result['pay_order_sn']]);
+
+ }
+
+
+ /**
+ * 这个调试需要配置在config/logging.php
+ * @param $pay_type
+ */
+ public function setLogName($pay_type)
+ {
+ $this->log_name = $pay_type;
+ }
+
+ /**
+ * 模拟post提交 json数据 请求接口
+ * @param string $url
+ * @param bool|true $https
+ * @param string $method
+ * @param string $param
+ * @return mixed
+ */
+ private function ddcurl($url = '', $param = '', $https = true, $method = 'post')
+ {
+ $param = json_encode($param, 320);
+ $ch = curl_init($url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+
+ #判断是否为https请求
+ if ($https === true) {
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ }
+ #判断是否为post请求
+ if ($method == 'post') {
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
+ }
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type:application/json'));
+
+ $str = curl_exec($ch);
+
+ curl_close($ch);
+ return $str;
+ }
+}
+
diff --git a/app/ServicePay/KoulinghbPayServices.php b/app/ServicePay/KoulinghbPayServices.php
new file mode 100644
index 0000000..72e5c15
--- /dev/null
+++ b/app/ServicePay/KoulinghbPayServices.php
@@ -0,0 +1,366 @@
+ $this->getGateUrl() . '/pay/Preorder/get',
+ 'debug' => 1,//调试
+ 'logDir' => to_linux_path(storage_path() . '/logs/'),
+ 'mch_id' => $this->pay_gateway['app_id'], //客户交易者账号
+ 'token' => $this->pay_gateway['app_key'],//密钥
+ 'interface' => $this->pay_gateway['mch_id'],//账号名称 一般用来存放三方通道
+ 'return_url' => action('Pay\PayController@returnNotify', ['type' => $type]),
+ 'notify_url' => action('Pay\PayController@notify', ['type' => $type]),
+ ];
+ $this->pay_config = $config;
+ }
+
+ //统一下单支付
+
+ /**
+ * @param $pay_data
+ * @return array|\Illuminate\Http\RedirectResponse
+ */
+ public function pay($pay_data)
+ {
+// echo number_format( 500, 2,'.','');exit;
+ //商户号
+ $accountId = $this->pay_config['mch_id'];
+ //商户秘钥
+ $key = $this->pay_config['token'];
+ $payData = [
+ 'paytype' => $this->pay_gateway['mch_id'],//对应的三方通道
+ 'amount' => intval($pay_data['total_amount'] * 100), //支付金额为分
+ 'cpid' => $accountId,//商户
+ 'orderid' => strval($pay_data['out_trade_no']),//订单号
+ 'describe' => $pay_data['subject'],
+ 'product' => mt_rand(100000, 999999), //商品名称
+ 'ip' => request()->getClientIp(),
+ 'synurl' => strval($this->pay_config['notify_url']),// //异步回调地址
+ 'jumpurl' => strval($this->pay_config['return_url']),// //页面跳转通知
+ ];
+ $sign= $this->sign($payData,$key,['ip', 'jumpurl','paytype']);
+ $payData['sign'] = $sign;
+// $res=$this->ddcurl($this->pay_config['url'],$pay_data,false);
+ $res = Curl::to($this->pay_config['url'])->withHeaders( array('Content-type'=>'application/json') )->withData($payData)->get();
+ $this->debugLog('下单接口请求内容' . json_encode($payData, true), []);
+ $this->debugLog('返回内容' . json_encode($res, true), []);
+
+ $res = is_array($res) ? $res : json_decode($res, 256);
+ if (is_array($res) && isset($res['status']) && $res['status'] == 0) {
+ $url = $res['payurl'];
+ return redirect()->away($url);
+ } else {
+ $msg = $res['msg'] ?? '未知错误';
+ return ['code' => 0, 'msg' => $msg];
+ }
+
+ }
+
+ private function sign($tempArr, $signKey,$filter=[]): string
+ {
+ $keyVal = '';
+
+ if (isset($tempArr['sign'])) {
+ unset($tempArr['sign']);
+ }
+
+ ksort($tempArr);
+
+ $data = [];
+ foreach ($tempArr as $key => $value) {
+ if(!in_array($key,$filter)){
+ array_push($data, "{$value}");
+ }
+ }
+ $keyVal = implode('|', $data);
+
+ if (!empty($signKey) && is_string($signKey)) {
+ $keyVal .= '|'.$signKey;
+ }
+
+ return strtolower(md5($keyVal));
+ }
+
+ /**
+ * 检查订单
+ * @param $orderid
+ * @return bool|string
+ */
+ private function checkOrder($orderid)
+ {
+ $url = $this->getGateUrl() . '/pay/Checkorder/check';
+ $payData = [
+ 'cpid' => $this->pay_gateway['app_id'],//商户号
+ 'orderid' => $orderid,
+ ];
+ $key = $this->pay_config['token'];
+ $sign = $this->sign($payData, $key);
+ $payData['sign'] = $sign;
+ Log::channel('pay_order')->info('查询接口请求', $payData);
+ $responseRaw = Curl::to($url)->withData($payData)->post();
+// $responseRaw = $this->ddcurl($url, $payData, false);
+ $response = is_array($responseRaw) ? $responseRaw : json_decode($responseRaw, 256);
+// $this->debugLog('查询接口返回' . is_array($res) ? json_encode($res, true) : json_encode(json_decode($res, 256), true));
+ Log::channel('pay_order')->info('查询接口返回', $response);
+ if (is_array($response)
+ && isset($response['status']) && $response['status'] == 0
+ && isset($response['ispay']) && $response['ispay'] == 1
+ ) {
+ return true;
+ }
+ return false;
+ }
+
+
+ //统一验证签名
+ public function verify()
+ {
+ $params = $this->result_data;
+ //{"status": 0,"orderid": "1001_152490169760595","cpid": 1001,"amount": 100,"real_fee": 90,"paytime"
+ //: 1533887495,"ext": "123131","sign": "05685bc967a9c5c2c58ef0706056ccab"}
+ //(amount|cpid|ordered|paytime|key),例
+ $key = $this->pay_config['token'];
+// echo $params['amount'] . '|' . $params['cpid'] . '|' . $params['orderid'] . '|' . $params['paytime'] . '|' . $key;exit;
+// $sign = strtolower(md5($params['amount'] . '|' . $params['cpid'] . '|' . $params['orderid'] . '|' . $params['paytime'] . '|' . $key));
+ $sign=$this->sign($this->result_data,$key,['status','real_fee','ext','sign']);
+ if (isset($params['sign']) && $sign == $params['sign']
+ && isset($params['status']) && $params['status'] == 0
+ ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+ //返回给支付商的成功
+ public function success()
+ {
+ echo 'SUCCESS';
+ exit;
+ }
+
+ //统一回调处理
+
+ /**
+ * 回调第一部,如果是同步,直接回传
+ * @param $return
+ * @param $pay_type
+ * @param $request
+ * @return bool|\Illuminate\Http\RedirectResponse
+ */
+ public function notify($return, $pay_type, $request)
+ {
+// $request = json_decode(file_get_contents('php://input'), true);
+ $allData = $request->all();
+ $this->setLogName($pay_type);
+ $this->debugLog('回调原始数据', $allData);
+ $this->pay_type = $pay_type;
+ $this->request = $request;
+ //取得订单,是否有此订单,如果没有直接返回空
+ $order_sn = $allData['orderid'];
+
+ $status = $allData['status'];
+
+ if ($status != 0) {
+ return '未支付成功';
+ }
+
+ $checkresult = $this->checkIP();//检查回调IP
+ if (!$checkresult) {
+ return 'ip 不合法';
+ }
+ //取得订单
+ $this->getOrder($order_sn);
+
+ $return = ($return) ? 1 : 0;
+ if ($return) {
+
+ //判断是否是商户id
+ if ($this->order->merchant_id == 0) {
+ return redirect()->route('web.user.index');
+ }
+ //
+ return $this->merchantReturnSend();
+ }
+ //取得通道id
+ $this->gateway = $this->pay_gateway = config('gateway.config')[$this->gateway_id];
+ //dd($this->gateway);
+ //取得支付配置
+ $this->payConfig($this->pay_type);
+
+ $this->result_data = $allData;
+ //检查三方的订单
+ $checkorder = $this->checkOrder($order_sn);
+ if (!$checkorder) {
+ $this->debugLog('查询三方订单未支付成功');
+ return '查询三方订单未支付成功';
+ }
+// dump($this->result_data);
+ //进行验证签名
+ if (!$this->verify()) {
+ $this->debugLog('签名以及支付状态验证失败');
+ return '签名以及支付状态验证失败';
+ }
+
+ return $this->payNotify();
+ }
+
+
+ /**
+ * 同步回调
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function returnPay()
+ {
+ //判断是否是商户id
+ if ($this->order->merchant_id == 0) {
+ return redirect()->route('web.user.index');
+ }
+ //
+ return $this->merchantReturnSend();
+ }
+
+ //异步回调
+
+ /**
+ * 获得通道信息,取得支付配置模型,验证签名,
+ * @return bool|void
+ */
+ private function payNotify()
+ {
+ //取得通道信息内容
+ $data = $this->result_data;
+ $this->pay_data = $this->result_data;
+ //如果应答状态不是01/A6表示支付失败
+ $this->debugLog(json_encode($data, true));
+ $this->debugLog('-------------' . $this->order->order_sn . '--选择----' . $this->pay_type . '----' . $this->pay_method . '----开始回调处理-------------------------');
+ if (empty($data)) {
+ return $this->debugLog('验证签名失败', $data);
+ }
+ 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());
+ $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['orderid'],//三方的订单号
+ 'pay_money' => number_format($data['real_fee'] / 100, 2, '.', ''), //支付金额,
+// 'pay_money' => $data['real_fee'], //支付金额,
+ 'money' => number_format($data['amount'] / 100, 2, '.', ''),
+ 'pay_type' => $this->pay_type,
+ 'account' => ''
+ ];
+
+ $this->setResult($result);
+ Log::channel('pay_success')->info('支付成功', [
+ 'pay_type' => $result['pay_type'], 'pay_money' => $result['pay_money'],
+ 'account' => $result['money'], 'order_sn' => $result['order_sn'],
+ 'pay_order_sn' => $result['pay_order_sn']]);
+
+ }
+
+
+ /**
+ * 这个调试需要配置在config/logging.php
+ * @param $pay_type
+ */
+ public function setLogName($pay_type)
+ {
+ $this->log_name = $pay_type;
+ }
+
+ /**
+ * 模拟post提交 json数据 请求接口
+ * @param string $url
+ * @param bool|true $https
+ * @param string $method
+ * @param string $param
+ * @return mixed
+ */
+ private function ddcurl($url = '', $param = '', $https = true, $method = 'post')
+ {
+ $param = json_encode($param, 320);
+ $ch = curl_init($url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+
+ #判断是否为https请求
+ if ($https === true) {
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ }
+ #判断是否为post请求
+ if ($method == 'post') {
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
+ }
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type:application/json'));
+
+ $str = curl_exec($ch);
+
+ curl_close($ch);
+ return $str;
+ }
+}
+
diff --git a/app/ServicePay/PayApiProvidesTrait.php b/app/ServicePay/PayApiProvidesTrait.php
index a2b6248..d332382 100644
--- a/app/ServicePay/PayApiProvidesTrait.php
+++ b/app/ServicePay/PayApiProvidesTrait.php
@@ -61,6 +61,14 @@ trait PayApiProvidesTrait
return $this->pay_service = new RongYiServices();
case 'zhanxinpay':
return $this->pay_service = new ZhanXinPayServices();
+ case 'dalipay':
+ return $this->pay_service = new DaliPayServices();
+ case 'pingguopay':
+ return $this->pay_service = new PingguopayServices();
+ case 'koulinghbpay':
+ return $this->pay_service = new KoulinghbPayServices();
+ case 'yihuibaopay':
+ return $this->pay_service = new YiHuiBaoPayServices();
break;
}
}
diff --git a/app/ServicePay/PayTrait.php b/app/ServicePay/PayTrait.php
index e01ca11..406ced3 100644
--- a/app/ServicePay/PayTrait.php
+++ b/app/ServicePay/PayTrait.php
@@ -82,9 +82,10 @@ trait PayTrait
* 取得当前支付通道的类型信息实例,$this->pay_gateway
* @param $pay_type
* @param array $custom_gateways
+ * @param string $pay_channel
* @return bool
*/
- public function getGateway($pay_type, $custom_gateways = [])
+ public function getGateway($pay_type, $custom_gateways = [],$pay_channel='')
{
//取得支付方法和类型
$pay_config = $this->payMethod($pay_type);
@@ -110,7 +111,7 @@ trait PayTrait
return false;
}
if (count($custom_gateways) > 0) {
- $this->pay_gateway = $this->randomCustomGateways($all_gateways, $custom_gateways);
+ $this->pay_gateway = $this->randomCustomGateways($all_gateways, $custom_gateways,$pay_channel);
} else {
$this->pay_gateway = $this->randomAllGateways($all_gateways);
}
@@ -136,21 +137,28 @@ trait PayTrait
* 随机切换用户选择支付通道
* @param $all_gateways 所有通道
* @param $custom_gateways 用户自定义选择通道
+ * @param $pay_channel
* @return bool|mixed
*/
- public function randomCustomGateways($all_gateways, $custom_gateways)
+ public function randomCustomGateways($all_gateways, $custom_gateways,$pay_channel='')
{
$on_user_gateway_id = [];
foreach ($all_gateways as $k => $v) {
if (in_array($v['id'], $custom_gateways)) {
- $on_user_gateway_id[] = $v;
+ if ($pay_channel != '') {
+ if ($v['mch_id'] == $pay_channel) {
+ $on_user_gateway_id[] = $v;
+ }
+ } else {
+ $on_user_gateway_id[] = $v;
+ }
}
- $total = count($on_user_gateway_id);
- if ($total <= 0) {
- return false;
- }
- return $on_user_gateway_id[mt_rand(0, $total - 1)];
}
+ $total = count($on_user_gateway_id);
+ if ($total <= 0) {
+ return false;
+ }
+ return $on_user_gateway_id[mt_rand(0, $total - 1)];
}
/**
@@ -264,9 +272,11 @@ trait PayTrait
public function checkGateway($request)
{
$pay_type = $request->input('pay_type');
+ $pay_channel = $request->input('pay_channel');
$this->debugLog('-------------订单开始-------------');
$this->debugLog('支付类型->' . $pay_type);
+ $this->debugLog('channel->' . $pay_channel);
//选择服务类型
$this->setPayService($pay_type);
@@ -281,7 +291,8 @@ trait PayTrait
}
- $this->gateway = $this->pay_service->getGateway($pay_type, $custorm_gateways);
+ $this->gateway = $this->pay_service->getGateway($pay_type, $custorm_gateways,$pay_channel);
+
if (!$this->gateway) {
return $this->addError(['error' => 1, 'msg' => '通道不存在']);
}
@@ -378,7 +389,10 @@ trait PayTrait
$data['up_ratio'] = $this->gateway['up_ratio'];//通道单独上浮费率
$data['original_ratio'] = $this->merchant->ratio;//原始费率
//结算费率=商户费率+上浮费率
- $data['ratio'] = $this->merchant->ratio + $data['up_ratio'];
+
+// $data['ratio'] = $this->merchant->ratio + $data['up_ratio'];
+ // 总费率:3% (通道成本+上浮) 2021-07-12 改成
+ $data['ratio'] = $data['up_ratio'] + $this->gateway['ratio'];
//手续费=(商户费率+上浮费率)* 支付金额/1000
$pate = $data['ratio'] * $money / 1000;
//通道费率
@@ -432,9 +446,13 @@ trait PayTrait
$data['system_ratio'] = ($ratio_info['up_ratio'] + $data['up_ratio']);
//上级的话,计算最后盈利,通道成本和费率不变,变得盈利资金和盈利费率
//最后盈利=(平台费率 - 通道费率)* 金额 /1000,(平台费率-通道费率) *金额 /1000
- $data['final_money'] = ($data['system_ratio'] - $this->gateway['ratio']) * $money / 1000;
+// $data['final_money'] = ($data['system_ratio'] - $this->gateway['ratio']) * $money / 1000;
+ // 佣金盈利2021-07-12 改为 上浮费率X金额
+ $data['final_money'] = ($data['ratio'] - $this->gateway['ratio']) * $money / 1000;
//盈利费率=平台费率 - 通道费率
- $data['final_ratio'] = $data['system_ratio'] - $this->gateway['ratio'];//最后盈利费率
+// $data['final_ratio'] = $data['system_ratio'] - $this->gateway['ratio'];//最后盈利费率
+ //改为上浮费率
+ $data['final_ratio'] = $data['ratio'] - $this->gateway['ratio'];//最后盈利费率
//股东-》商户,上下和顶级都是股东,
$data['next_ratio'] = $data['top_ratio'];
$data['next_money'] = $data['top_money'];
diff --git a/app/ServicePay/PingguopayServices.php b/app/ServicePay/PingguopayServices.php
new file mode 100644
index 0000000..83bee17
--- /dev/null
+++ b/app/ServicePay/PingguopayServices.php
@@ -0,0 +1,358 @@
+ $this->getGateUrl() . '/sfjoin/orderdata',
+ 'debug' => 1,//调试
+ 'logDir' => to_linux_path(storage_path() . '/logs/'),
+ 'mch_id' => $this->pay_gateway['app_id'], //客户交易者账号
+ 'token' => $this->pay_gateway['app_key'],//密钥
+ 'interface' => $this->pay_gateway['mch_id'],//账号名称 一般用来存放三方通道
+ 'return_url' => action('Pay\PayController@returnNotify', ['type' => $type]),
+ 'notify_url' => action('Pay\PayController@notify', ['type' => $type]),
+ ];
+ $this->pay_config = $config;
+ }
+
+ //统一下单支付
+
+ /**
+ * @param $pay_data
+ * @return array|\Illuminate\Http\RedirectResponse
+ */
+ public function pay($pay_data)
+ {
+// echo number_format( 500, 2,'.','');exit;
+ //商户号
+ $accountId = $this->pay_config['mch_id'];
+ //商户秘钥
+ $key = $this->pay_config['token'];
+ $payData = [
+ 'appId' => $accountId,//商户
+ 'channelNo' => $this->pay_gateway['mch_id'],//对应的三方通道
+ 'notifyCallback' => strval($this->pay_config['notify_url']),// //异步回调地址
+ 'orderNo' => strval($pay_data['out_trade_no']),//订单号
+ 'amount' => $pay_data['total_amount'], //支付金额为元
+ 'payType' => 1, //固定1
+ ];
+ $sign = strtolower(md5($key . $payData['orderNo'] . $payData['appId'] . $payData['amount'] . $payData['notifyCallback']));
+
+ $payData['sign'] = $sign;
+// $res=$this->ddcurl($this->pay_config['url'],$pay_data,false);
+ $res = Curl::to($this->pay_config['url'])->withHeaders(['Content-type'=>'application/json'])->withData($payData)->post();
+ $this->debugLog('下单接口请求内容' . json_encode($payData, true), []);
+ $this->debugLog('返回内容' . json_encode($res, true), []);
+
+ $res = is_array($res) ? $res : json_decode($res, 256);
+ if (is_array($res) && isset($res['code']) && $res['code'] == 1) {
+ $url = $res['payUrl'];
+ return redirect()->away($url);
+ } else {
+ $msg = $res['msg'] ?? '未知错误';
+ return ['code' => 0, 'msg' => $msg];
+ }
+
+ }
+
+ private function sign($tempArr, $signKey): string
+ {
+ $keyVal = '';
+
+ if (isset($tempArr['sign'])) {
+ unset($tempArr['sign']);
+ }
+
+ ksort($tempArr);
+
+ $data = [];
+ foreach ($tempArr as $key => $value) {
+ array_push($data, "{$key}={$value}");
+ }
+ $keyVal = implode('&', $data);
+
+ if (!empty($signKey) && is_string($signKey)) {
+ $keyVal .= $signKey;
+ }
+
+ return strtolower(md5($keyVal));
+ }
+
+ /**
+ * 检查订单
+ * @param $orderid
+ * @return bool|string
+ */
+ private function checkOrder($orderid)
+ {
+ $url = $this->getGateUrl() . '/sfjoin/search';
+ $payData = [
+ 'appId' => $this->pay_gateway['app_id'],//商户号
+ 'orderNo' => $orderid,
+ ];
+ $key = $this->pay_config['token'];
+ $sign = strtolower(md5($key . $payData['orderNo'] . $payData['appId']));
+// $sign = $this->sign($payData, $key);
+ $payData['sign'] = $sign;
+ Log::channel('pay_order')->info('查询接口请求', $payData);
+ $responseRaw = Curl::to($url)->withData($payData)->post();
+// $responseRaw = $this->ddcurl($url, $payData, false);
+ $response = is_array($responseRaw) ? $responseRaw : json_decode($responseRaw, 256);
+// $this->debugLog('查询接口返回' . is_array($res) ? json_encode($res, true) : json_encode(json_decode($res, 256), true));
+ Log::channel('pay_order')->info('查询接口返回', $response);
+ if (is_array($response)
+ && isset($response['code']) && $response['code'] == 1
+ && isset($response['state']) && $response['state'] == 1
+ && isset($response['orderNo']) && $response['orderNo'] == $orderid
+ ) {
+ return true;
+ }
+ return false;
+ }
+
+
+ //统一验证签名
+ public function verify()
+ {
+ $params = $this->result_data;
+ $md5sign = strtolower(md5($this->pay_config['token'] . $params['orderNo'] . $this->pay_config['mch_id'] . $params['amount']));
+ if (isset($params['sign']) && $md5sign == $params['sign']
+ && isset($params['status']) && $params['status'] == 1
+ ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+ //返回给支付商的成功
+ public function success()
+ {
+ echo 'success';
+ exit;
+ }
+
+ //统一回调处理
+
+ /**
+ * 回调第一部,如果是同步,直接回传
+ * @param $return
+ * @param $pay_type
+ * @param $request
+ * @return bool|\Illuminate\Http\RedirectResponse
+ */
+ public function notify($return, $pay_type, $request)
+ {
+// $request = json_decode(file_get_contents('php://input'), true);
+ $allData = $request->all();
+ $this->setLogName($pay_type);
+ $this->debugLog('回调原始数据', $allData);
+ $this->pay_type = $pay_type;
+ $this->request = $request;
+ //取得订单,是否有此订单,如果没有直接返回空
+ $order_sn = $allData['orderNo'];
+
+ $status = $allData['status'];
+
+ if ($status != 1) {
+ return '未支付成功';
+ }
+
+ $checkresult = $this->checkIP();//检查回调IP
+ if (!$checkresult) {
+ return 'ip 不合法';
+ }
+ //取得订单
+ $this->getOrder($order_sn);
+
+ $return = ($return) ? 1 : 0;
+ if ($return) {
+
+ //判断是否是商户id
+ if ($this->order->merchant_id == 0) {
+ return redirect()->route('web.user.index');
+ }
+ //
+ return $this->merchantReturnSend();
+ }
+ //取得通道id
+ $this->gateway = $this->pay_gateway = config('gateway.config')[$this->gateway_id];
+ //dd($this->gateway);
+ //取得支付配置
+ $this->payConfig($this->pay_type);
+
+ $this->result_data = $allData;
+ //检查三方的订单
+ $checkorder = $this->checkOrder($order_sn);
+ if (!$checkorder) {
+ $this->debugLog('查询三方订单未支付成功');
+ return '查询三方订单未支付成功';
+ }
+ //dump($this->result_data);
+ //进行验证签名
+ if (!$this->verify()) {
+ $this->debugLog('签名以及支付状态验证失败');
+ return '签名以及支付状态验证失败';
+ }
+
+ return $this->payNotify();
+ }
+
+
+ /**
+ * 同步回调
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function returnPay()
+ {
+ //判断是否是商户id
+ if ($this->order->merchant_id == 0) {
+ return redirect()->route('web.user.index');
+ }
+ //
+ return $this->merchantReturnSend();
+ }
+
+ //异步回调
+
+ /**
+ * 获得通道信息,取得支付配置模型,验证签名,
+ * @return bool|void
+ */
+ private function payNotify()
+ {
+ //取得通道信息内容
+ $data = $this->result_data;
+ $this->pay_data = $this->result_data;
+ //如果应答状态不是01/A6表示支付失败
+ $this->debugLog(json_encode($data, true));
+ $this->debugLog('-------------' . $this->order->order_sn . '--选择----' . $this->pay_type . '----' . $this->pay_method . '----开始回调处理-------------------------');
+ if (empty($data)) {
+ return $this->debugLog('验证签名失败', $data);
+ }
+ 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());
+ $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['order_sn'],//我方订单号
+ 'pay_order_sn' => $data['sys_order_sn'],//三方的订单号
+// 'pay_money' => number_format($data['payamount'] / 100, 2, '.', ''), //支付金额,
+ 'pay_money' => $data['pay_money'], //支付金额,
+ 'money' => $data['money'],
+ 'pay_type' => $this->pay_type,
+ 'account' => ''
+ ];
+
+ $this->setResult($result);
+ Log::channel('pay_success')->info('支付成功', [
+ 'pay_type' => $result['pay_type'], 'pay_money' => $result['pay_money'],
+ 'account' => $result['money'], 'order_sn' => $result['order_sn'],
+ 'pay_order_sn' => $result['pay_order_sn']]);
+
+ }
+
+
+ /**
+ * 这个调试需要配置在config/logging.php
+ * @param $pay_type
+ */
+ public function setLogName($pay_type)
+ {
+ $this->log_name = $pay_type;
+ }
+
+ /**
+ * 模拟post提交 json数据 请求接口
+ * @param string $url
+ * @param bool|true $https
+ * @param string $method
+ * @param string $param
+ * @return mixed
+ */
+ private function ddcurl($url = '', $param = '', $https = true, $method = 'post')
+ {
+// $param = json_encode($param, 320);
+ $ch = curl_init($url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+
+ #判断是否为https请求
+ if ($https === true) {
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ }
+ #判断是否为post请求
+ if ($method == 'post') {
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
+ }
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type:application/json'));
+
+ $str = curl_exec($ch);
+
+ curl_close($ch);
+ return $str;
+ }
+}
+
diff --git a/app/ServicePay/YiHuiBaoPayServices.php b/app/ServicePay/YiHuiBaoPayServices.php
new file mode 100644
index 0000000..d5d84d8
--- /dev/null
+++ b/app/ServicePay/YiHuiBaoPayServices.php
@@ -0,0 +1,371 @@
+ $this->getGateUrl() . '/gateway/payApiJson.asp',
+ 'debug' => 1,//调试
+ 'logDir' => to_linux_path(storage_path() . '/logs/'),
+ 'mch_id' => $this->pay_gateway['app_id'], //客户交易者账号
+ 'token' => $this->pay_gateway['app_key'],//密钥
+ 'interface' => $this->pay_gateway['mch_id'],//账号名称 一般用来存放三方通道
+ 'return_url' => action('Pay\PayController@returnNotify', ['type' => $type]),
+ 'notify_url' => action('Pay\PayController@notify', ['type' => $type]),
+ ];
+ $this->pay_config = $config;
+ }
+
+ //统一下单支付
+
+ /**
+ * @param $pay_data
+ * @return array|\Illuminate\Http\RedirectResponse
+ */
+ public function pay($pay_data)
+ {
+// echo number_format( 500, 2,'.','');exit;
+ //商户号
+ $accountId = $this->pay_config['mch_id'];
+ //商户秘钥
+ $key = $this->pay_config['token'];
+ $payData = [
+ 'customerid' => $accountId,//商户
+ 'sdcustomno' => strval($pay_data['out_trade_no']),//订单号
+ 'cardno' => $this->pay_gateway['mch_id'],//对应的三方通道
+ 'orderamount' => intval($pay_data['total_amount'] * 100), //支付金额为分
+ 'zftype'=>'casher',
+ 'device'=>'mobile',
+ 'ordertime'=>time(),
+ 'mark' => mt_rand(100000, 999999), //
+ 'clientip' => request()->getClientIp(),
+ 'noticeurl' => strval($this->pay_config['notify_url']),// //异步回调地址
+ 'backurl' => strval($this->pay_config['return_url']),// //页面跳转通知
+ ];
+ $sign= $this->sign($payData,$key,['customerid', 'sdcustomno','orderamount','cardno','noticeurl','backurl','ordertime']);
+ $payData['sign'] = $sign;
+// $res=$this->ddcurl($this->pay_config['url'],$pay_data,false);
+ $res = Curl::to($this->pay_config['url'])->withData($payData)->post();
+ $this->debugLog('下单接口请求内容' . json_encode($payData, true), []);
+ $this->debugLog('返回内容' . json_encode($res, true), []);
+
+ $res = is_array($res) ? $res : json_decode($res, 256);
+ if (is_array($res) && isset($res['state']) && $res['state'] == 1 && $res['qrurl']!='') {
+ $url = $res['qrurl'];
+ return redirect()->away($url);
+ } else {
+ $msg = $res['errmsg'] ?? '未知错误';
+ $this->debugLog('错误' . $msg, []);
+ return json_encode(['code' => 0, 'msg' => $msg],256);
+ }
+
+ }
+
+ private function sign($tempArr, $signKey,$signSortArr=[]): string
+ {
+ $keyVal = '';
+
+ if (isset($tempArr['sign'])) {
+ unset($tempArr['sign']);
+ }
+
+ $data = [];
+ foreach ($signSortArr as $key){
+ if(isset($tempArr[$key])){
+ array_push($data, "{$key}={$tempArr[$key]}");
+ }
+ }
+
+ ksort($tempArr);
+
+
+ $keyVal = implode('&', $data);
+
+ if (!empty($signKey) && is_string($signKey)) {
+ $keyVal .= $signKey;
+ }
+
+ return strtoupper(md5($keyVal));
+ }
+
+ /**
+ * 检查订单
+ * @param $orderid
+ * @return bool|string
+ */
+ private function checkOrder($orderid)
+ {
+ try {
+ $url = $this->getGateUrl() . '/gateway/zx_orderquery.asp';
+ $payData = [
+ 'customerid' => $this->pay_gateway['app_id'],//商户号
+ 'sdcustomno' => $orderid,
+ 'format' => 'json',
+ ];
+ $key = $this->pay_config['token'];
+ $sign = $this->sign($payData, $key,['customerid','sdcustomno']);
+ $payData['sign'] = $sign;
+ Log::channel('pay_order')->info('查询接口请求', $payData);
+ $responseRaw = Curl::to($url)->withData($payData)->get();
+// $responseRaw = $this->ddcurl($url, $payData, false);
+ $response = is_array($responseRaw) ? $responseRaw : json_decode($responseRaw, 256);
+// $this->debugLog('查询接口返回' . is_array($res) ? json_encode($res, true) : json_encode(json_decode($res, 256), true));
+ Log::channel('pay_order')->info('查询接口返回', $response);
+ if (is_array($response)
+ && isset($response['state']) && $response['state'] == 1
+ && isset($response['sdcustomno']) && $response['sdcustomno'] == $orderid
+ ) {
+ return true;
+ }
+ return false;
+ }catch (\Exception $e){
+ Log::channel('pay_order')->info('err', $e->getMessage());
+ }
+ return false;
+ }
+
+
+ //统一验证签名
+ public function verify()
+ {
+ $params = $this->result_data;
+ $key = $this->pay_config['token'];
+ $key='&key='.$key;
+ $sign=$this->sign($params,$key,['customerid','sd51no','sdcustomno','mark']);
+ if (isset($params['sign']) && $sign == $params['sign']) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+ //返回给支付商的成功
+ public function success()
+ {
+ echo '