微信支付所需参数
openId? ? ? ? ?//微信用户ID? 登录授权时获取
appid? ? ? ? ? ?//公众号appid? 微信公众号获取
appSecret? ? //公众号appkey? 微信公众号后台获取??
mch_id? ? ? ? ?//商户号mechid? ?微信商户号后台获取
mchsecret? ? //商户api秘钥? 微信商户号后台获取
//控制器操作
public function Pay(){
$fee = '0.01'; //支付金额
$body = '微信支付测试'; //交易描述
$openid =''; 发起支付的用户openid
$data = ['body' => $body , 'fee' => $fee , 'openId' => $openid];
$data['out_trade_no'] = '65461348974616'; //支付订单号
$result = $this -> toPay($data);
if($result['return_code'] == "SUCCESS" && $result['result_code'] == "SUCCESS"){
return json($this->returnData('99','支付成功',$result));
}else{
$data['RETURN_CODE'] = $result['RETURN_CODE'];
$data['RETURN_MSG'] = $result['RETURN_MSG'];
return json($this -> returnData(1, '未知错误',$data));
}
}
public function toPay($param)
{
$resData = [];
$body = empty($param['body']) ? '' : $param['body']; //描述
$orderSn = $param['out_trade_no']; //订单号
$totalFee = empty($param['fee']) ? 0.01 : $param['fee']; //金额
$openId = empty($param['openId']) ? '' : $param['openId']; //用户openId
//统一下单参数构造
$unifiedOrder = array(
'appid' => $this ->AppID, //公众号appid
'mch_id' => $this ->MchId, //商户号mchid
'nonce_str' => $this->getNonceStr(), //随机字符串
'body' => $body, //支付描述
'out_trade_no' => $orderSn, //订单号
'total_fee' => $totalFee*100, //支付金额
'spbill_create_ip' => $this->getIp(), //获取本地id
'notify_url' => $this->_payCfg['notify_url'],//todo 你的支付回调url
'trade_type' => 'JSAPI', //支付类型
'openid' => $openId //支付用户openid
);
$unifiedOrder['sign'] = $this->makeSign($unifiedOrder);
//请求数据,统一下单
$xmlData = $this->toxml($unifiedOrder);
$res = $this->postxmlCurl($this->_payCfg['request_url'], $xmlData);
$content = $this->toArr($res);
$res = self::xmlToArray($res);
$res['pay'] = $unifiedOrder;
return $res;
}
/**
* 生成签名
* @param $unifiedOrder
* @param $mchSecret
* @return string
*/
public function makeSign($unifiedOrder)
{
//签名步骤一:按字典序排序参数
ksort($unifiedOrder);
$string = $this->toUrlParams($unifiedOrder);
//签名步骤二:在string后加入KEY
$string = $string . "&key=" . $this -> MchSecret;
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
/**
* 格式化参数格式化成url参数
* @param $unifiedOrder
* @return string
* @internal param $unifiedOrder
*/
public function toUrlParams($unifiedOrder)
{
$buff = "";
foreach ($unifiedOrder as $k => $v) {
if ($k != "sign" && $v != "" && !is_array($v)) {
buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}
/**
* 输出xml字符
* @param $unifiedOrder
* @return string
*/
public function toxml($unifiedOrder)
{
if (!is_array($unifiedOrder) || count($unifiedOrder) <= 0) exit('数组异常');
$xml = "<xml>";
foreach ($unifiedOrder as $key => $val) {
if (is_numeric($val)) {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else {
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
}
}
$xml .= "</xml>";
return $xml;
}
/**
* auth: bruce
* 以post方式提交xml到对应的接口url
* 2021/3/23
* @param $url
* @param $xml
* @param int $time_out
* @param bool $cert
* @return bool|string
*/
public function postxmlCurl($url, $xml, $time_out = 30)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_TIMEOUT, $time_out);
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_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
$data = curl_exec($ch);
if ($data) {
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
exit("curl出错,错误码:$error");
}
}
/**
* 将xml转为array
* @param $xml
* @return mixed
*/
public function toArr($xml){
//将xml转为array,禁止引用外部xml实体
libxml_disable_entity_loader(true);
$values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $values;
}
/**
* XML 转数组
* @param $xml
* @return mixed
*/
private function xmlToArray($xml)
{
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $values;
}
|