QQ小程序微信H5支付
1、先看文档
//uniapp支付接口文档,支持QQ支付,微信H5支付
文档地址:https://q.qq.com/wiki/develop/miniprogram/API/open_port/port_pay.html
//微信H5支付
qq.requestWxPayment({
url: "",
referer: "",
success(res) { },
fail(res) { }
})
后端下单接口
https://q.qq.com/wiki/develop/miniprogram/server/virtual-payment/wx_pay.html
H5支付统一下单,有V2版,v3版 H5支付,区别如下:
V2版中的参数有
AppID
AppSecret
支付专用签名串PaySignKey
商户号PartnerID
初始密钥PartnerKey
并且包含一个证书文件: 安全证书
同时,V2版需要缴纳保证金
V3版中的参数有
AppID
AppSecret
商户号PartnerID
初始密钥PartnerKey
商户号MCHID
申请编号
商户平台登录帐号
商户平台登录密码
包含5个证书文件(证书pkcs12格式、证书pem格式、证书密钥pem格式、CA证书, 安全证书)
V3不再需要缴纳保证金。
V3是一个新版本,基本上微信包含微信支付的新产品,具体情况可选择V3版支付下单接口
微信H5支付下单接口
private function transactions_v2() {
$parameters = array(
'appid' => $appid, //小程序ID
'body' => $body,//商品描述
'mch_id' => $mch_id, //商户号
'nonce_str' => $this->createNoncestr(), //随机字符串
'notify_url' => "https://api.q.qq.com/wxpay/notify", //
'out_trade_no'=> $out_trade_no,//商户订单号
'spbill_create_ip' => $_SERVER['REMOTE_ADDR'], //终端IP
'total_fee' => $total_fee*100, //总金额
'trade_type' => "MWEB", //交易类型
);
$parameters['scene_info'] = '{"h5_info": {"type":"Wap","wap_url":$wap_url,"wap_name":$wap_name}}';
//签名
$parameters['sign'] = $this->MakeSign($parameters);
$xmlData = $this->data_to_xml($parameters);
//获取access_token
$access_token_arr = $this->curlGetWithWx("https://api.q.qq.com/api/getToken?grant_type=client_credential&appid=".$this->qq_appid."&secret=".$this->qq_secret);
$url_qq = "https://api.q.qq.com/wxpay/unifiedorder?appid=".$this->qq_appid."&access_token=".$access_token_arr['access_token'].'&&real_notify_url='.$notify_url;
$return = $this->xml_to_data($this->postXmlCurl($xmlData, $url_qq, 60));
if( !empty($result['result_code']) && !empty($result['err_code']) ){
//支付失败处理
}
return $return;
}
//作用:产生随机字符串,不长于32位
private function createNoncestr($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
/**
* 生成签名
* @return 签名
*/
public function MakeSign( $params ){
//签名步骤一:按字典序排序数组参数
ksort($params);
$string = $this->ToUrlParams($params);
//签名步骤二:在string后加入KEY
$string = $string . "&key=".$this->key;
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
/**
* 将参数拼接为url: key=value&key=value
* @param $params
* @return string
*/
public function ToUrlParams( $params ){
$string = '';
if( !empty($params) ){
$array = array();
foreach( $params as $key => $value ){
$array[] = $key.'='.$value;
}
$string = implode("&",$array);
}
return $string;
}
/**
* 输出xml字符
* @param $params 参数名称
* return string 返回组装的xml
**/
public function data_to_xml( $params ){
if(!is_array($params)|| count($params) <= 0)
{
return false;
}
$xml = "<xml>";
foreach ($params as $key=>$val)
{
if (is_numeric($val)){
$xml.="<".$key.">".$val."</".$key.">";
}else{
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml.="</xml>";
return $xml;
}
/**
* 将xml转为array
* @param string $xml
* return array
*/
public function xml_to_data($xml){
if(!$xml){
return false;
}
//将XML转为array
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $data;
}
/**
* get请求
* @param $url
* @param $authorization
* @return mixed
*/
function curlGetWithWx($url)
{
// 初始化curl
$ch = curl_init();
// 设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
// 运行curl,结果以jason形式返回
$res = curl_exec($ch);
curl_close($ch);
// 取出数据
$data = json_decode($res, true);
//返回
return $data;
}
private static function postXmlCurl($xml, $url, $second = 30)
{
$headers = [
'Content-Type: application/json; charset=utf-8',
'Content-Length: ' . strlen($xml),
'Authorization: ' . "WECHATPAY2-SHA256-RSA2048 ",
'Accept: application/json',
'User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'
];
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($ch, CURLOPT_TIMEOUT, 40);
set_time_limit(0);
//运行curl
$data = curl_exec($ch);
//返回结果
if ($data) {
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
return "curl出错,错误码:$error";
}
}
获取接口调用凭证access_token
https://q.qq.com/wiki/develop/game/server/open-port/getAccessToken.html