微信app服务端php,微信APP支付服务端PHP完整代码

//微信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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
微信 支付这 官方文档 很乱 写的 也不是很清楚,测试时 一定要与安卓 或 苹果端 一起测试。 否则 根本找不到问题。 废话 不过说 先 说说 几大坑的地方。我也是 借鉴 别人的 博客 才测试成功调起支付。文章后 直接上代码 代码 绝对能调起 微信 测试过的! 第一步,生成prepayid,这一步,只要你的appid,mch_id,key没写错,那么99%以上都能获取到prepayid,如果失败,那肯定是几个ID和key有问题,仔细检查,包括编码等,仔细仔细仔细检查。 问题来了,第二步,对获取到的prepayid进行二次签名,官方文档的坑来了,官方并没有详细说明这一步骤,一切的一切只能靠自己摸索,爬坑。 首先第一坑:参数顺序,我这里用了SortedMap,自动对参数进行asc编码顺序,一劳永逸,当然,也可以用其他map,但一定要注意参数顺序,必须是asc编码顺序。 第二坑:参数package的Sign=WXPay中=的编码问题,转码即可,小坑。 第三坑:苹果系统的timestamp位数,统一成10位即可,小坑。 第四坑:次级大坑,注意,官方文档说到的参与二次签名的参数,prepayId,appId,timeStamp等,如果你用他们的驼峰进行大写,那么你就完了。一定要小写,小写,小写。 第五坑:最大坑,一样,官方文档并没有对于二次签名有过多赘述,如果你上面几个坑完美出坑,那么,你获取到的签名sign跟官方验证的sign绝对是一样的,然而,将这些玩意丢回给APPAPP调起支付,大大的几个字出现了,验证签名失败!WTF!不要急,我已折腾了好几天,终于发现坑在哪里,那就是noncestr随机字符串,参与二次签名的随机字符串不能再次生成,注意,不能再次生成,一定要用第一步中获取prepayid时的那串字符串,一定要用第一步中获取prepayid时的那串字符串,一定要用第一步中获取prepayid时的那串字符串。 第六坑:经历了上述5坑,相信你已经有想干死人的冲动,那么你以为这就结束了吗,还有最后一坑,那就是APP签名已经包名,一定要与开放平台中的一致,然而,即使一致了你以为又结束了吗,NO,如果你更改过开放平台中的签名,并且,在更改前调用过APP微信支付,那么一定一定一定一定记得清除微信缓存。 至此,所有坑都成功出坑,终于出现了支付页面,举国欢腾,微信去年买了个表。最后附上MD5签名类
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值