//微信APP支付 一定要先仔细阅读微信的官方文档,统一下单接口
// 调取微信APP支付必须先开通商户后台的微信APP支付
// 注意:开通微信APP支付会发邮件到你们邮箱,下面的商户号和appid还有key密钥,都必须是开通后的。说这些主要是提醒,有些商户是多个商户后台的,所以就有多个商户id和商户appid和商户key,必须匹配,不然获取不到预支付id,也就是prepay_id的。
// header("Content-type: text/xml"); // 支付出问题时,方便查看xml格式数据,放开可以查看传送的xml字符串 xml要用 echo输出 不要var_dump()
echo weChatPay('订单号','价格'); //直接输出json给前台APP
//入口函数
function weChatPay($order_num,$price){
$json = array();
//生成预支付交易单的必选参数:
$newPara = array();
//应用ID
$newPara["appid"] = "商户appid";
//商户号
$newPara["mch_id"] = "商户id";
//设备号
$newPara["device_info"] = "WEB";
//随机字符串,这里推荐使用函数生成
$newPara["nonce_str"] = createNoncestr();
//商品描述
$newPara["body"] = "APP支付";
//商户订单号,这里是商户自己的内部的订单号
$newPara["out_trade_no"] = $order_num;
//总金额
$newPara["total_fee"] = $price*100;
//终端IP
$newPara["spbill_create_ip"] = $_SERVER["REMOTE_ADDR"];
//通知地址,注意,这里的url里面不要加参数
$newPara["notify_url"] = "支付成功后的回调地址";
//交易类型
$newPara["trade_type"] = "APP";
$key = "密钥:在商户后台个人安全中心设置";
//第一次签名
$newPara["sign"] = appgetSign($newPara,$key);
//把数组转化成xml格式
$xmlData = arrayToXml($newPara);
$get_data = sendPrePayCurl($xmlData);
//返回的结果进行判断。
if($get_data['return_code'] == "SUCCESS" && $get_data['result_code'] == "SUCCESS"){
//根据微信支付返回的结果进行二次签名
//二次签名所需的随机字符串
$newPara["nonce_str"] = createNoncestr();
//二次签名所需的时间戳
$newPara['timeStamp'] = time()."";
//二次签名剩余参数的补充
$secondSignArray = array(
"appid"=>$newPara['appid'],
"noncestr"=>$newPara['nonce_str'],
"package"=>"Sign=WXPay",
"prepayid"=>$get_data['prepay_id'],
"partnerid"=>$newPara['mch_id'],
"timestamp"=>$newPara['timeStamp'],
);
$json['success'] = 1;
$json['ordersn'] = $newPara["out_trade_no"]; //订单号
$json['order_arr'] = $secondSignArray; //返给前台APP的预支付订单信息
$json['order_arr']['sign'] = appgetSign($secondSignArray,$key); //预支付订单签名
$json['data'] = "预支付完成";
//预支付完成,在下方进行自己内部的业务逻辑
/*****************************/
return json_encode($json);
}
else{
$json['success'] = 0;
$json['error'] = $get_data['return_msg'];
return json_encode($json);
}
}
//将数组转换为xml格式
function arrayToXml($arr)
{
$xml = "";
foreach ($arr as $key=>$val)
{
if (is_numeric($val))
{
$xml.="".$val."".$key.">";
}
else
$xml.="".$key.">";
}
$xml.="";
return $xml;
}
//发送请求
function sendPrePayCurl($xml,$second=30)
{
$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
$ch = curl_init();
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
$data = curl_exec($ch);
curl_close($ch);
$data_xml_arr =XMLDataParse($data);
if($data_xml_arr)
{
return $data_xml_arr;
}
else
{
$error = curl_errno($ch);
echo "curl出错,错误码:$error"."
";
echo "错误原因查询";
curl_close($ch);
return false;
}
}
//xml格式数据解析函数
function XMLDataParse($data){
$xml = simplexml_load_string($data,NULL,LIBXML_NOCDATA);
$array=json_decode(json_encode($xml),true);
return $array;
}
//随机字符串
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;
}
/*
* 格式化参数格式化成url参数 生成签名sign
*/
function appgetSign($Obj,$appwxpay_key)
{
foreach ($Obj as $k => $v)
{
$Parameters[$k] = $v;
}
//签名步骤一:按字典序排序参数
ksort($Parameters);
$String = formatBizQueryParaMap($Parameters, false);
//echo '【string1】'.$String.'';
//签名步骤二:在string后加入KEY
if($appwxpay_key){
$String = $String."&key=".$appwxpay_key;
}
//echo "【string2】".$String."";
//签名步骤三:MD5加密
$String = md5($String);
//echo "【string3】 ".$String."";
//签名步骤四:所有字符转为大写
$result_ = strtoupper($String);
//echo "【result】 ".$result_."";
return $result_;
}
//按字典序排序参数
function formatBizQueryParaMap($paraMap, $urlencode)
{
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v)
{
if($urlencode)
{
$v = urlencode($v);
}
//$buff .= strtolower($k) . "=" . $v . "&";
$buff .= $k . "=" . $v . "&";
}
$reqPar;
if (strlen($buff) > 0)
{
$reqPar = substr($buff, 0, strlen($buff)-1);
}
return $reqPar;
}