You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
4.7 KiB

<?php
namespace tencent\wechat\pay;
use think\facade\Cache;
use SimpleXMLElement;
use think\facade\Request;
class Qqwxpay extends Base
{
/**
* QQ小程序调取微信支付
* @param string $openid 微信号
* @param double $money 支付金额
* @param string $order_number 订单编号
* @param string $body 商品描述
* @param string $notify_url 回调函数地址
* @date 2021-03-01
*/
public function qqWxPay($openid, $money, $order_number, $body = '', $notify_url = '', $user_agent = 'weixin')
{
//统一下单接口 获取PrepayId 生成预支付交易单 不需要证书
$appid = $this->wxpayConfig['mp_qq_app_id'];
$access_token = $this->getAccessToken();
$notify_url_url_encode = urlencode($notify_url);
$url = "https://api.q.qq.com/wxpay/unifiedorder?appid=$appid&access_token=$access_token&&real_notify_url=$notify_url_url_encode";
$data = [
'appid' => $this->wxpayConfig['app_id'],
'mch_id' => $this->wxpayConfig['mch_id'],
'nonce_str' => createNonceStr(32),
'body' => $body,
'out_trade_no' => $order_number,
'total_fee' => (int)($money * 100),
'spbill_create_ip' => getUserIp(),
'notify_url' => 'https://api.q.qq.com/wxpay/notify',
'trade_type' => 'MWEB',
'scene_info' => (string)json_encode([
'h5_info' => [
'type' => 'Wap',
'wap_url' => Request::domain(),
'wap_name' => $this->wxpayConfig['mp_qq_app_name']
]
]),
];
$data['sign'] = $this->getPaySign($data);
//转为XML
$data_xml = dataToXml($data);
$response = httpXmlPost($data_xml, $url);
$result = xml_to_array($response);
platformLog($data, $result, 'get_pre_pay_id');
return $result;
}
/**
* 微信支付回调验证
* @date 2021-07-20
*/
public function checkNotifySign($xml)
{
$data = xml_to_array($xml);
$tmp_data = $data;
unset($tmp_data['sign']);
$sign = $this->getPaySign($tmp_data);//本地签名
//收到微信支付结果通知后,返回参数给微信支付
if ($data['sign'] === $sign) {
$check_sign = true;
$return_data = [
'return_code' => 'SUCCESS',
'return_msg' => 'OK'
];
} else {
$check_sign = false;
$return_data = [
'return_code' => 'FAIL',
'return_msg' => '签名失败'
];
}
$returnXml = dataToXml($return_data);
echo $returnXml;
platformLog($data, $return_data, 'check_notify_sign');
if ($check_sign) {
return [
'code' => 0,
'data' => $data
];
} else {
return [
'code' => 4001,
'data' => '验签失败'
];
}
}
/**
* 获取ACCESS_TOKEN
* @date 2021-07-20
*/
public function getAccessToken()
{
$platform = config('platform');
$access_token = Cache::store('redis')->get('mp_qq_access_token_' . $this->wxpayConfig['uid']);
if (!isset($access_token['expires_time']) || 0 < time()) {
$appid = $this->wxpayConfig['mp_qq_app_id'];
$secret = $this->wxpayConfig['mp_qq_app_secret'];
$url = "https://api.q.qq.com/api/getToken?grant_type=client_credential&appid=$appid&secret=$secret";
$res = http_data_get($url);
if ($res['errcode'] == 0) {
$access_token = [
'access_token' => $res['access_token'],
'expires_time' => time() + $res['expires_in'] - 300
];
Cache::store('redis')->set('mp_qq_access_token_' . $this->wxpayConfig['uid'], $access_token);
}
}
return $access_token['access_token'];
}
/**
* 获取微信签名
* @date 2021-07-20
* @param array $data 需要生成签名数据
*/
public function getPaySign($data)
{
foreach ($data as $k => $v) {
if ($v) {
$Parameters[$k] = $v;
}
}
ksort($Parameters);
$String = '';
foreach ($Parameters as $k => $v) {
$String .= $k . "=" . $v . "&";
}
$String = $String . "key=" . $this->wxpayConfig['app_secret'];
$String = md5($String);
$result = strtoupper($String);
platformLog([$data, $this->wxpayConfig['app_secret']], $result, 'get_pay_sign');
return $result;
}
}