(2018年5月18日测试可用)
1.进入微信商户平台查看统一下单接口文档。
在查看完统一下单文档后,能够看到需要传递给微信“统一下单接口”地址的参数有哪些
统一下单文档地址:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1
2.查看完下单接口之后,我们知道要传递过去的参数有,
Appid(在微信开放平台能够看到自己的appid);
mch_id(微信商户平台的id);
nonce_str(随机字符串,可自己生成,只要长度不超过32为就可以)
Body(商品描述,例:游戏币充值);
out_trade_no(商品订单号,可自己生成);
total_fee(商品价格,自己设置,100代表1元,因为微信默认是按分计算的);
spbill_create_ip(ip地址,也可以自己随便填写,不影响支付);
notify_url(通知地址,用户支付成功后,微信主动通知服务器,从而进行操作,测试时也可先随便填写一个)
trade_type(交易类型:App支付就填写APP)
交易类型:可到https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_2 这个地址去看下文档
sign(现在还差最重要,也是最容易出错的一个参数sign签名没有说到,sign签名其实就是将所有要传过去的参数拼接到一起,再拼接一个key=商户平台的密匙,再进行一个md5加密,后面我将会举出实例)
上面讲到的是集成微信支付,必须要传递过去的参数,下面将对这些参数中必须要自己写的参数给出实例,大家可以直接复制
3.参数实例
nonce_str随机字符串,自己生成的
function getNonceStr() {
$code = "";
for ($i=0; $i < 10; $i++) {
$code .= mt_rand(1000,2000); //获取随机数
}
$nonceStrTemp = md5($code);
$nonce_str = mb_substr($nonceStrTemp, 1,30); //MD5加密后截取30位字符
return $nonce_str;
}
$nonce_str=getNonceStr();
out_trade_no商户订单号
$out_trade_no =date('YmdHis').rand(10000000,99999999);
sign签名,自己参照微信文档,接口规则,安全文档拼接写
$str1="appid=$appid&body=$body&mch_id=$mch_id&nonce_str=$nonce_str¬ify_url=$notify_url&out_trade_no=$out_trade_no&spbill_create_ip=$spbill_create_ip&total_fee=$total_fee&trade_type=$trade_type&key=dsdsd3edwdwedewdcwededsdsdsdswdw";
$sign=strtoupper(md5($str1));//签名md5加密后,转换为大写
4.以上几步都弄完了之后,我们现在要将参数组成xml字符串,因为微信微信接收的参数和返回的参数都是xml的
拼接xml
$post_data =<<<xml
<xml>
<appid><![CDATA[自己填appid]]></appid>
<body><![CDATA[自己填商品介绍]]></body>
<mch_id><![CDATA[自己填商户id]]></mch_id>
<nonce_str><![CDATA[自己填随机字符串]]></nonce_str>
<notify_url><![CDATA[自己填回调地址]]></notify_url>
<out_trade_no><![CDATA[$out_trade_no]]></out_trade_no>
<spbill_create_ip><![CDATA[自己填ip地址]]></spbill_create_ip>
<total_fee><![CDATA[$total_fee]]></total_fee>
<trade_type><![CDATA[自己填支付类型,做app就填 app]]></trade_type>
<sign><![CDATA[填写签名,就是上面经过md5加密的]]></sign>
</xml>
xml;
5.拼接xml成功后,我们就可以通过post方式将数据发送给微信了
post方式将xml发送给微信
//初始化
$curl = curl_init();
//设置抓取的url
curl_setopt($curl, CURLOPT_URL, 'https://api.mch.weixin.qq.com/pay/unifiedorder');
//设置头文件的信息作为数据流输出
curl_setopt($curl, CURLOPT_HEADER, 0);
//设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
//设置post方式提交
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS,$post_data);
$data = curl_exec($curl);
//关闭URL请求
curl_close($curl);
$data就是微信返回过来的数据,用echo输出数据是什么也看不到的,这个问题我做的时候还找了一段时间的原因,因为微信返回过来的数据是一个xml,xml在浏览器就被解析了,中间的内容又是被注释的,
所以看页面上什么都没有,如果用echo输出的话,大家可以查看源文件就可以看到了
6.到了这里我们已经成功了一大半了,如果微信返回的数据没有问题,会返回一个prepay_id给我们
然后我们将微信返回过来的参数拼接一下发送给前端
我们查看微信调起支付接口文档,看看前端需要一些什么参数
前端需要的参数文档地址:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2
因为传递给前端的参数需要微信返回的数据,所以我们必须将微信返回过来的数据转换成数组,才能取出微信返回的参数
function Array1($xml)
{
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $values;
}
$ar=Array1($data);//将xml转换成数组的结果,执行这个函数就将微信返回的数据变成数组了
到这里的时候我们需要注意的是返回给前端的参数,同样有一个sign签名,所以我们这里又要签名一次,签名方法和上面说的一样,就是将需要传递的参数拼接成字符串,然后md5加密
7.二次签名和返回给前端数据的代码
//获取当前时间的时间戳
$time=intval(time());
//进行二次签名
$str2="appid=$ar[appid]&noncestr=$nonce_str&package=Sign=WXPay&partnerid=$mch_id&prepayid=$ar[prepay_id]×tamp=$time&key=dsdsd3edwdwedewdcwededsdsdsdswdw";
$sign1=strtoupper(md5($str2));//签名md5加密后,转换为大写
echo "{\"appid\":\"$ar[appid]\",\"noncestr\":\"$nonce_str\",\"package\":\"Sign=WXPay\",\"partnerid\":\"$mch_id\",\"prepayid\":\"$ar[prepay_id]\",\"timestamp\":$time,\"sign\":\"$sign1\"}";
8.整体代码,上面教程最好是一步一步看,下面我将整体代码贴出来,大家也可以直接使用,修改下统一下单的参数就可以了,如果有什么问题或者遇到什么特殊情况也可以加我QQ:407771144,现在时间还是比较多,一般马上就可以回复,帮助别人就是帮助自己
<?php
/**
* 发送post请求
* @param string $url 请求地址
* @param array $post_data post键值对数据
* @return string
*/
header("Content-Type: text/html; charset=utf-8");
header("Access-Control-Allow-Origin: *");
//使用方法
$appid="wxd1015a07771ea640";//微信appid,在开放平台看
$mch_id="1503938301";//商户平台id,在商户平台查看
//nonce_str随机字符串,自己生成的
function getNonceStr() {
$code = "";
for ($i=0; $i < 10; $i++) {
$code .= mt_rand(1000,2000); //获取随机数
}
$nonceStrTemp = md5($code);
$nonce_str = mb_substr($nonceStrTemp, 1,30); //MD5加密后截取30位字符
return $nonce_str;
}
$nonce_str=getNonceStr();
//商品描述
$body="微信测试";
//商户订单号
$out_trade_no = date('YmdHis').rand(10000000,99999999);
//总金额
$total_fee=10;
//终端ip
$spbill_create_ip='139.159.226.163';
//通知地址
$notify_url="https://www.baidu.com";
//交易类型
$trade_type="APP";
//签名,自己参照微信文档,接口规则,安全文档拼接写
$str1="appid=$appid&body=$body&mch_id=$mch_id&nonce_str=$nonce_str¬ify_url=$notify_url&out_trade_no=$out_trade_no&spbill_create_ip=$spbill_create_ip&total_fee=$total_fee&trade_type=$trade_type&key=dsdsd3edwdwedewdcwededsdsdsdswdw";
$sign=strtoupper(md5($str1));//签名md5加密后,转换为大写
//要传递给微信的数据
$post_data =<<<xml
<xml>
<appid><![CDATA[$appid]]></appid>
<body><![CDATA[$body]]></body>
<mch_id><![CDATA[$mch_id]]></mch_id>
<nonce_str><![CDATA[$nonce_str]]></nonce_str>
<notify_url><![CDATA[$notify_url]]></notify_url>
<out_trade_no><![CDATA[$out_trade_no]]></out_trade_no>
<spbill_create_ip><![CDATA[$spbill_create_ip]]></spbill_create_ip>
<total_fee><![CDATA[$total_fee]]></total_fee>
<trade_type><![CDATA[APP]]></trade_type>
<sign><![CDATA[$sign]]></sign>
</xml>
xml;
//初始化
$curl = curl_init();
//设置抓取的url
curl_setopt($curl, CURLOPT_URL, 'https://api.mch.weixin.qq.com/pay/unifiedorder');
//设置头文件的信息作为数据流输出
curl_setopt($curl, CURLOPT_HEADER, 0);
//设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
//设置post方式提交
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS,$post_data);
$data = curl_exec($curl);
//关闭URL请求
curl_close($curl);
//将微信返回过来的xml数据转换成数组
function xmlToArray($xml)
{
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $values;
}
$ar=xmlToArray($data);//将xml转换成数组的结果
//获取当前时间的时间戳
$time=intval(time());
//进行二次签名
$str2="appid=$ar[appid]&noncestr=$nonce_str&package=Sign=WXPay&partnerid=$mch_id&prepayid=$ar[prepay_id]×tamp=$time&key=dsdsd3edwdwedewdcwededsdsdsdswdw";
$sign1=strtoupper(md5($str2));//签名md5加密后,转换为大写
echo "{\"appid\":\"$ar[appid]\",\"noncestr\":\"$nonce_str\",\"package\":\"Sign=WXPay\",\"partnerid\":\"$mch_id\",\"prepayid\":\"$ar[prepay_id]\",\"timestamp\":$time,\"sign\":\"$sign1\"}";
?>