新增加支付
This commit is contained in:
parent
93fe66ac4d
commit
17bfb1de66
|
@ -0,0 +1,368 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\ServicePay;
|
||||||
|
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Ixudra\Curl\Facades\Curl;
|
||||||
|
|
||||||
|
class FxPayServices extends BasePay implements PayApiInterface
|
||||||
|
{
|
||||||
|
use PayTrait;
|
||||||
|
use ThirdPaySignTrait;
|
||||||
|
|
||||||
|
public $gateway_list;//当前类型的支付通道列表
|
||||||
|
public $pay_type;//支付类型
|
||||||
|
public $pay_method;//支付方法
|
||||||
|
public $pay_gateway;//当前的支付通道实例
|
||||||
|
public $pay_config;//这个通道的支付配置信息
|
||||||
|
public $order;
|
||||||
|
public $request;
|
||||||
|
public $gateway_id;
|
||||||
|
public $pay_data;
|
||||||
|
public $log_name;
|
||||||
|
public $result_data;
|
||||||
|
public static $result;
|
||||||
|
|
||||||
|
|
||||||
|
//统一下单支付
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $pay_data
|
||||||
|
* @return array|\Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function pay($pay_data)
|
||||||
|
{
|
||||||
|
$createUrl=$this->getGateUrl().'/api/Apipay/subOrderInfo';
|
||||||
|
$return = request()->all();
|
||||||
|
$re_type = 'html';
|
||||||
|
if (isset($return['re_type'])) {
|
||||||
|
$re_type = $return['re_type'];
|
||||||
|
}
|
||||||
|
//商户号
|
||||||
|
$accountId = $this->pay_config['mch_id'];
|
||||||
|
//商户秘钥
|
||||||
|
$key = $this->pay_config['token'];
|
||||||
|
$payData = [
|
||||||
|
'merchant_code' => $accountId,//商户
|
||||||
|
'merchant_order' => strval($pay_data['out_trade_no']),//订单号
|
||||||
|
'trans_amount' => $pay_data['total_amount']*100, //支付金额为fen
|
||||||
|
'pay_type' => $this->pay_gateway['mch_id'],//对应的三方通道
|
||||||
|
'goods_info' => $pay_data['subject'],
|
||||||
|
'notify_url' => strval($this->pay_config['notify_url']),// //异步回调地址
|
||||||
|
'return_url' => strval($this->pay_config['return_url']),// //
|
||||||
|
'buyer_ip'=>'127.0.0.1',
|
||||||
|
'input_charset'=>'utf-8',
|
||||||
|
'bank_code'=>'ICBC',
|
||||||
|
'return_params'=>1,
|
||||||
|
'extra'=>1,
|
||||||
|
];
|
||||||
|
// $signParam = [
|
||||||
|
// 'merchantNum' => $payData['merchantNum'],
|
||||||
|
// 'orderNo' => $payData['orderNo'],
|
||||||
|
// 'amount' => $payData['amount'],
|
||||||
|
// 'notifyUrl' => $payData['notifyUrl'],
|
||||||
|
// ];
|
||||||
|
$sign= $this->sign($payData,$key,[]);
|
||||||
|
$payData['sign'] = $sign;
|
||||||
|
// $res=$this->ddcurl($createUrl,$pay_data,false);
|
||||||
|
$res = Curl::to($createUrl)->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'] == 'ok') {
|
||||||
|
$msg = $res['msg'] ?? '未知错误';
|
||||||
|
$data = $res['data'];
|
||||||
|
if ($data['show_type'] == 'jump_url') {
|
||||||
|
$url = $data['url_info'];
|
||||||
|
return $this->returnPayRes($re_type, '', 1, $url);
|
||||||
|
} else {
|
||||||
|
return $this->returnPayRes($re_type, $msg, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$msg = $res['msg'] ?? '未知错误';
|
||||||
|
$this->debugLog('错误' . $msg, []);
|
||||||
|
return $this->returnPayRes($re_type, $msg, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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, "{$key}={$value}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$keyVal = implode('&', $data);
|
||||||
|
|
||||||
|
if (!empty($signKey) && is_string($signKey)) {
|
||||||
|
$keyVal .= '&key='.$signKey;
|
||||||
|
}
|
||||||
|
return md5($keyVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查订单
|
||||||
|
* @param $orderid
|
||||||
|
* @return bool|string
|
||||||
|
*/
|
||||||
|
private function checkOrder($orderid)
|
||||||
|
{
|
||||||
|
$url = $this->getGateUrl() . '/api/Apipay/queryOrderInfo';
|
||||||
|
$payData = [
|
||||||
|
'merchant_code' => $this->pay_gateway['app_id'],//商户号
|
||||||
|
'out_trade_no' => $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'] == 'ok'
|
||||||
|
&& isset($response['data']['order_status']) && $response['data']['order_status'] == 'success'
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (!is_array($allData)) {
|
||||||
|
$this->debugLog('参数异常');
|
||||||
|
return '参数异常';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->pay_type = $pay_type;
|
||||||
|
$this->request = $request;
|
||||||
|
//取得订单,是否有此订单,如果没有直接返回空
|
||||||
|
$order_sn = $allData['merchant_order'];
|
||||||
|
|
||||||
|
$status = $allData['order_status'];
|
||||||
|
|
||||||
|
if ($status != 'success') {
|
||||||
|
return '未支付成功';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//取得订单
|
||||||
|
$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);
|
||||||
|
$checkresult = $this->checkWhiteIP($this->gateway);//检查回调IP
|
||||||
|
if (!$checkresult) {
|
||||||
|
$this->debugLog('ip 不合法');
|
||||||
|
return 'ip 不合法';
|
||||||
|
}
|
||||||
|
//取得支付配置
|
||||||
|
$this->payConfig($this->pay_type);
|
||||||
|
|
||||||
|
$this->result_data = $allData;
|
||||||
|
// $this->debugLog('回调原始数据', $this->result_data);
|
||||||
|
//检查三方的订单
|
||||||
|
$out_trade_no=strval($allData['out_trade_no']);
|
||||||
|
$checkorder = $this->checkOrder($out_trade_no);
|
||||||
|
if (!$checkorder) {
|
||||||
|
$this->debugLog('查询三方订单未支付成功');
|
||||||
|
return '查询三方订单未支付成功';
|
||||||
|
}
|
||||||
|
// dump($this->result_data);
|
||||||
|
//进行验证签名
|
||||||
|
if (!$this->verify()) {
|
||||||
|
$this->debugLog('签名以及支付状态验证失败');
|
||||||
|
return '签名以及支付状态验证失败';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->payNotify();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//统一验证签名
|
||||||
|
public function verify()
|
||||||
|
{
|
||||||
|
$params = $this->result_data;
|
||||||
|
|
||||||
|
$key = $this->pay_config['token'];
|
||||||
|
// $sinParam=[
|
||||||
|
// 'state'=>$params['state'],
|
||||||
|
// 'merchantNum'=>$params['merchantNum'],
|
||||||
|
// 'orderNo'=>$params['orderNo'],
|
||||||
|
// 'amount'=>$params['amount'],
|
||||||
|
// ];
|
||||||
|
$sign=$this->sign($params,$key,['sign']);
|
||||||
|
if (isset($params['sign']) && $sign == $params['sign']) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步回调
|
||||||
|
* @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['merchant_order'],//我方订单号
|
||||||
|
'pay_order_sn' => $data['out_trade_no'],//三方的订单号
|
||||||
|
'pay_money' => number_format($data['trans_amount']/100, 2, '.', ''), //支付金额,
|
||||||
|
// 'pay_money' => $data['real_fee'], //支付金额,
|
||||||
|
'money' => number_format($data['yufu_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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -87,6 +87,10 @@ trait PayApiProvidesTrait
|
||||||
return $this->pay_service = new WangWangPayServices();
|
return $this->pay_service = new WangWangPayServices();
|
||||||
case '1012':
|
case '1012':
|
||||||
return $this->pay_service = new QunHongBaoServices();
|
return $this->pay_service = new QunHongBaoServices();
|
||||||
|
case '1013':
|
||||||
|
return $this->pay_service = new WeixinManchongServices();
|
||||||
|
case '1014':
|
||||||
|
return $this->pay_service = new FxPayServices();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,22 +76,6 @@ class ShouJiPayServices extends BasePay implements PayApiInterface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function returnPayRes($re_type,$msg,$code,$url=''){
|
|
||||||
if ($code == 1) {
|
|
||||||
if ($re_type == 'json') {
|
|
||||||
return json_encode(['code' => 1, 'qrurl' => $url], 256);
|
|
||||||
} else {
|
|
||||||
return redirect()->away($url);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ($re_type == 'json') {
|
|
||||||
return json_encode(['code' => 0, 'msg' => $msg], 256);
|
|
||||||
} else {
|
|
||||||
return $msg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function sign($tempArr, $signKey,$signSortArr=[]): string
|
private function sign($tempArr, $signKey,$signSortArr=[]): string
|
||||||
{
|
{
|
||||||
$keyVal = '';
|
$keyVal = '';
|
||||||
|
@ -213,10 +197,10 @@ class ShouJiPayServices extends BasePay implements PayApiInterface
|
||||||
return '未支付成功';
|
return '未支付成功';
|
||||||
}
|
}
|
||||||
|
|
||||||
$checkresult = $this->checkIP();//检查回调IP
|
// $checkresult = $this->checkIP();//检查回调IP
|
||||||
if (!$checkresult) {
|
// if (!$checkresult) {
|
||||||
return 'ip 不合法';
|
// return 'ip 不合法';
|
||||||
}
|
// }
|
||||||
//取得订单
|
//取得订单
|
||||||
$this->getOrder($order_sn);
|
$this->getOrder($order_sn);
|
||||||
|
|
||||||
|
@ -233,6 +217,11 @@ class ShouJiPayServices extends BasePay implements PayApiInterface
|
||||||
//取得通道id
|
//取得通道id
|
||||||
$this->gateway = $this->pay_gateway = config('gateway.config')[$this->gateway_id];
|
$this->gateway = $this->pay_gateway = config('gateway.config')[$this->gateway_id];
|
||||||
//dd($this->gateway);
|
//dd($this->gateway);
|
||||||
|
$checkresult = $this->checkWhiteIP($this->gateway);//检查回调IP
|
||||||
|
if (!$checkresult) {
|
||||||
|
$this->debugLog('ip 不合法');
|
||||||
|
return 'ip 不合法';
|
||||||
|
}
|
||||||
//取得支付配置
|
//取得支付配置
|
||||||
$this->payConfig($this->pay_type);
|
$this->payConfig($this->pay_type);
|
||||||
|
|
||||||
|
|
|
@ -126,4 +126,33 @@ trait ThirdPaySignTrait
|
||||||
}
|
}
|
||||||
return trim($keyVal, $split);
|
return trim($keyVal, $split);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $publicKey
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function formatPublicKey($publicKey){
|
||||||
|
$publicKey = "-----BEGIN PUBLIC KEY-----\n" . chunk_split($publicKey, 64, "\n") . "-----END PUBLIC KEY-----";
|
||||||
|
return $publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证签名
|
||||||
|
* @param string $data 数据
|
||||||
|
* @param string $sign 签名
|
||||||
|
* @param string $publicKey 公钥
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function verifySign($data = '', $sign = '', $publicKey = '')
|
||||||
|
{
|
||||||
|
if (!is_string($sign) || !is_string($sign)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (bool)openssl_verify(
|
||||||
|
$data,
|
||||||
|
base64_decode($sign),
|
||||||
|
$publicKey,
|
||||||
|
OPENSSL_ALGO_SHA256
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,364 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\ServicePay;
|
||||||
|
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Ixudra\Curl\Facades\Curl;
|
||||||
|
|
||||||
|
class WeixinManchongServices extends BasePay implements PayApiInterface
|
||||||
|
{
|
||||||
|
use PayTrait;
|
||||||
|
use ThirdPaySignTrait;
|
||||||
|
|
||||||
|
public $gateway_list;//当前类型的支付通道列表
|
||||||
|
public $pay_type;//支付类型
|
||||||
|
public $pay_method;//支付方法
|
||||||
|
public $pay_gateway;//当前的支付通道实例
|
||||||
|
public $pay_config;//这个通道的支付配置信息
|
||||||
|
public $order;
|
||||||
|
public $request;
|
||||||
|
public $gateway_id;
|
||||||
|
public $pay_data;
|
||||||
|
public $log_name;
|
||||||
|
public $result_data;
|
||||||
|
public static $result;
|
||||||
|
|
||||||
|
//统一下单支付
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $pay_data
|
||||||
|
* @return array|\Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function pay($pay_data)
|
||||||
|
{
|
||||||
|
$createUrl=$this->getGateUrl().'/pay/unifiedorder';
|
||||||
|
$return = request()->all();
|
||||||
|
$re_type = 'html';
|
||||||
|
if (isset($return['re_type'])) {
|
||||||
|
$re_type = $return['re_type'];
|
||||||
|
}
|
||||||
|
//商户号
|
||||||
|
$accountId = $this->pay_config['mch_id'];
|
||||||
|
//商户秘钥
|
||||||
|
$key = $this->pay_config['token'];
|
||||||
|
$payData = [
|
||||||
|
'mch_id' => $accountId,//商户
|
||||||
|
'trade_type' => $this->pay_gateway['mch_id'],//对应的三方通道
|
||||||
|
'nonce'=>uniqid(),
|
||||||
|
'timestamp' => time(), //
|
||||||
|
'subject' => $pay_data['subject'], //
|
||||||
|
'out_trade_no' => strval($pay_data['out_trade_no']),//订单号
|
||||||
|
'total_fee' => $pay_data['total_amount'] * 100, //金额,单位为分
|
||||||
|
'spbill_create_ip' => request()->getClientIp(), //
|
||||||
|
'sign_type'=>'MD5',
|
||||||
|
'notify_url' => strval($this->pay_config['notify_url']),// //异步回调地址
|
||||||
|
'return_url' => strval($this->pay_config['return_url']),// //页面跳转通知
|
||||||
|
];
|
||||||
|
$sign = self::md5Verify('create',$payData,$key);//签名
|
||||||
|
$payData['sign'] = $sign;
|
||||||
|
$res=$this->ddcurl($createUrl,$payData,false);
|
||||||
|
// $res = Curl::to($createUrl)->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['result_code']) && $res['result_code'] == 'SUCCESS') {
|
||||||
|
$url = $res['pay_url'];
|
||||||
|
$msg = $res['message'] ?? '未知错误';
|
||||||
|
return $this->returnPayRes($re_type,$msg,1,$url);
|
||||||
|
} else {
|
||||||
|
$msg = $res['message'] ?? '未知错误';
|
||||||
|
$this->debugLog('错误' . $msg, []);
|
||||||
|
return $this->returnPayRes($re_type,$msg,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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() . '/pay/query';
|
||||||
|
$payData = [
|
||||||
|
'mch_id' => $this->pay_gateway['app_id'],//商户号
|
||||||
|
'nonce' => uniqid(),
|
||||||
|
'sign_type' => 'MD5',
|
||||||
|
'out_trade_no' => $orderid,
|
||||||
|
];
|
||||||
|
$key = $this->pay_config['token'];
|
||||||
|
$sign = self::md5Verify('create',$payData,$key);//签名
|
||||||
|
|
||||||
|
$payData['sign'] = $sign;
|
||||||
|
Log::channel('pay_order')->info('查询接口请求', $payData);
|
||||||
|
$res=$this->ddcurl($url,$payData,false);
|
||||||
|
// $res = Curl::to($url)->withData($payData)->post();
|
||||||
|
$response = is_array($res) ? $res : json_decode($res, 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['result_code']) && $response['result_code'] == 'SUCCESS'
|
||||||
|
&& isset($response['out_trade_no']) && $response['out_trade_no'] == $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'];
|
||||||
|
$pub = $this->pay_gateway['cert_pub'];
|
||||||
|
$platformPublicKey = openssl_get_publickey($this->formatPublicKey($pub));
|
||||||
|
|
||||||
|
|
||||||
|
ksort($params);
|
||||||
|
$data = "";
|
||||||
|
foreach ($params as $key => $value) {
|
||||||
|
if($value == '' || $value == null || $key == 'sign'){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$data .= $key . '=' . $value .'&';
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = preg_replace("/&$/", '',$data);
|
||||||
|
$plaintext = md5($data);
|
||||||
|
return $this->verifySign($plaintext, $params['sign'], $platformPublicKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//返回给支付商的成功
|
||||||
|
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['out_trade_no'];
|
||||||
|
|
||||||
|
$status = $allData['result_code'];
|
||||||
|
|
||||||
|
if ($status != 'SUCCESS') {
|
||||||
|
return '未支付成功';
|
||||||
|
}
|
||||||
|
|
||||||
|
//取得订单
|
||||||
|
$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);
|
||||||
|
$checkresult = $this->checkWhiteIP($this->gateway);//检查回调IP
|
||||||
|
if (!$checkresult) {
|
||||||
|
$this->debugLog('ip 不合法');
|
||||||
|
return 'ip 不合法';
|
||||||
|
}
|
||||||
|
//取得支付配置
|
||||||
|
$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['out_trade_no'],//我方订单号
|
||||||
|
'pay_order_sn' => $data['platform_trade_no'],//三方的订单号
|
||||||
|
'pay_money' => number_format($data['real_price']/100, 2, '.', ''), //支付金额,
|
||||||
|
// 'pay_money' => $data['ordermoney'], //支付金额,
|
||||||
|
'money' => number_format($data['total_fee']/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, 256);
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
// dd($param);
|
||||||
|
#判断是否为post请求
|
||||||
|
if ($method == 'post') {
|
||||||
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, '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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ use Ixudra\Curl\Facades\Curl;
|
||||||
/**
|
/**
|
||||||
* @package App\ServicePay
|
* @package App\ServicePay
|
||||||
*/
|
*/
|
||||||
class YiHuiBaoPayServices implements PayApiInterface
|
class YiHuiBaoPayServices extends BasePay implements PayApiInterface
|
||||||
{
|
{
|
||||||
use PayTrait;
|
use PayTrait;
|
||||||
use ThirdPaySignTrait;
|
use ThirdPaySignTrait;
|
||||||
|
@ -26,14 +26,6 @@ class YiHuiBaoPayServices implements PayApiInterface
|
||||||
public $result_data;
|
public $result_data;
|
||||||
public static $result;
|
public static $result;
|
||||||
|
|
||||||
/**
|
|
||||||
* 网关域名
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function getGateUrl(): string
|
|
||||||
{
|
|
||||||
return 'http://api.huhu199.com';
|
|
||||||
}
|
|
||||||
|
|
||||||
//第二部配置支付信息,payConfig
|
//第二部配置支付信息,payConfig
|
||||||
public function payConfig($type, $setConfig = [])
|
public function payConfig($type, $setConfig = [])
|
||||||
|
@ -101,21 +93,6 @@ class YiHuiBaoPayServices implements PayApiInterface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function returnPayRes($re_type,$msg,$code,$url=''){
|
|
||||||
if ($code == 1) {
|
|
||||||
if ($re_type == 'json') {
|
|
||||||
return json_encode(['code' => 1, 'qrurl' => $url], 256);
|
|
||||||
} else {
|
|
||||||
return redirect()->away($url);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ($re_type == 'json') {
|
|
||||||
return json_encode(['code' => 0, 'msg' => $msg], 256);
|
|
||||||
} else {
|
|
||||||
return $msg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function sign($tempArr, $signKey,$signSortArr=[]): string
|
private function sign($tempArr, $signKey,$signSortArr=[]): string
|
||||||
{
|
{
|
||||||
|
@ -229,10 +206,10 @@ class YiHuiBaoPayServices implements PayApiInterface
|
||||||
return '未支付成功';
|
return '未支付成功';
|
||||||
}
|
}
|
||||||
|
|
||||||
$checkresult = $this->checkIP();//检查回调IP
|
// $checkresult = $this->checkIP();//检查回调IP
|
||||||
if (!$checkresult) {
|
// if (!$checkresult) {
|
||||||
return 'ip 不合法';
|
// return 'ip 不合法';
|
||||||
}
|
// }
|
||||||
//取得订单
|
//取得订单
|
||||||
$this->getOrder($order_sn);
|
$this->getOrder($order_sn);
|
||||||
|
|
||||||
|
@ -249,6 +226,11 @@ class YiHuiBaoPayServices implements PayApiInterface
|
||||||
//取得通道id
|
//取得通道id
|
||||||
$this->gateway = $this->pay_gateway = config('gateway.config')[$this->gateway_id];
|
$this->gateway = $this->pay_gateway = config('gateway.config')[$this->gateway_id];
|
||||||
//dd($this->gateway);
|
//dd($this->gateway);
|
||||||
|
$checkresult = $this->checkWhiteIP($this->gateway);//检查回调IP
|
||||||
|
if (!$checkresult) {
|
||||||
|
$this->debugLog('ip 不合法');
|
||||||
|
return 'ip 不合法';
|
||||||
|
}
|
||||||
//取得支付配置
|
//取得支付配置
|
||||||
$this->payConfig($this->pay_type);
|
$this->payConfig($this->pay_type);
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,8 @@ return [
|
||||||
'1010' =>'支付宝天然气',
|
'1010' =>'支付宝天然气',
|
||||||
'1011' =>'支付宝扫码',
|
'1011' =>'支付宝扫码',
|
||||||
'1012' =>'微信红包',
|
'1012' =>'微信红包',
|
||||||
|
'1013' =>'微信慢充扫码',
|
||||||
|
'1014' =>'fx_支付宝直充',
|
||||||
],
|
],
|
||||||
'payfor_status' => [
|
'payfor_status' => [
|
||||||
0 => '等待处理',
|
0 => '等待处理',
|
||||||
|
|
|
@ -32,6 +32,8 @@ return [
|
||||||
'47.241.164.229',
|
'47.241.164.229',
|
||||||
'43.132.190.48',
|
'43.132.190.48',
|
||||||
'113.130.126.248',
|
'113.130.126.248',
|
||||||
|
'1.14.138.207',
|
||||||
|
'43.128.19.164',
|
||||||
],
|
],
|
||||||
'api'=>[
|
'api'=>[
|
||||||
'45.195.84.39'
|
'45.195.84.39'
|
||||||
|
@ -65,15 +67,16 @@ return [
|
||||||
'1003'=>[
|
'1003'=>[
|
||||||
'117.120.61.66'
|
'117.120.61.66'
|
||||||
],
|
],
|
||||||
'pingguopay'=>[
|
'1000'=>[
|
||||||
'47.243.44.247'
|
'47.243.44.247'
|
||||||
],
|
],
|
||||||
'1004'=>[
|
'1004'=>[
|
||||||
'8.129.172.207'
|
'8.129.172.207'
|
||||||
],
|
],
|
||||||
'1002'=>[
|
'1002'=>[
|
||||||
'18.163.134.231',
|
// '18.163.134.231',
|
||||||
'16.162.65.204'
|
// '16.162.65.204',
|
||||||
|
'18.162.145.173',//2021-08-24
|
||||||
],
|
],
|
||||||
'1005'=>[
|
'1005'=>[
|
||||||
'154.89.11.174'
|
'154.89.11.174'
|
||||||
|
|
Loading…
Reference in New Issue