前两天开始做移动端APP的微信支付,过程中遇到了一些问题,比如支付的过程中返回值总是:-1 {status:false},这些问题已经得到了解决。前人栽树,后人尽管乘凉,那么分享一下整个支付过程(wxPay 方案一):
1、申请微信开发平台的账号、创建移动应用、申请开发者资质认证(整个过程APICLOUD官方网站已经给出了相当明确的操作步骤,与实际操作没有差异,按照文档一步一步来,是没有问题的),附带链接地址:http://docs.apicloud.com/Others/Open-SDK-Integration-Guide/weChat
2、配置移动应用中 config.xml 文件
复制代码
配置获取方式说明以及截图:从微信开发平台获取,登录微信开发平台 —>管理中心—>移动应用—>查看(urlScheme的值和apiKey相同)(微信开发平台链接:https://open.weixin.qq.com/)
3、getOrderId(),将获取预支付订单号,建议将获取预支付订单号放置服务器端执行。(服务端代码如下:)
$dataArr = array(
'appid' => $appId, 'mch_id' => $mchId, 'nonce_str' => getNonceStr(), 'body' => $body, 'attach' => $attach, 'out_trade_no' => getNonceStr(), 'total_fee' => $totalFee, 'spbill_create_ip' => $cIp, 'notify_url' => $url, 'trade_type' => 'APP'
12345678910111213141516171819);
//转XML格式
function createXML($rootNode, $arr)
{
//创建一个文档,文档时xml的,版本号为1.0,编码格式utf-8 $xmlObj = new DOMDocument('1.0', 'UTF-8'); //创建根节点 $Node = $xmlObj->createElement($rootNode); //把创建好的节点加到文档中 $root = $xmlObj->appendChild($Node); //开始把数组中的数据加入文档 foreach ($arr as $key => $value) { //如果是$value是一个数组 if (is_array($value)) { //先创建一个节点 $childNode = $xmlObj->createElement($key); //将节点添加到$root中 $root->appendChild($childNode); //循环添加数据 foreach ($value as $key2 => $val2) { //创建节点的同时添加数据 $childNode2 = $xmlObj->createElement($key2, $val2); //将节点添加到$childNode $childNode->appendChild($childNode2); } } else { //创建一个节点,根据键和值 $childNode = $xmlObj->createElement($key, $value); //把节点加到根节点 $root->appendChild($childNode); } } //把创建好的xml保存到本地 $xmlObj->save('xml/log.xml'); $str = $xmlObj->saveXML();
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061// echo $str;
//返回xml字符串 return $str; 123
}
//封装签名算法
function MakeSign($arr)
{
//签名步骤一:按字典序排序参数 ksort($arr); $string = ToUrlParams($arr); //签名步骤二:在string后加入KEY $string = $string . "&key=" . $key; //签名步骤三:MD5加密 $string = md5($string); //签名步骤四:所有字符转为大写 $result = strtoupper($string); return $result;
12345678910111213141516171819}
/**
格式化参数格式化成url参数*/
function ToUrlParams($arr)
{
$buff = ""; foreach ($arr as $k => $v) { if ($k != "sign" && $v != "" && !is_array($v)) { $buff .= $k . "=" . $v . "&"; } } $buff = trim($buff, "&"); return $buff;
1234567891011121314151617}
//随机字符串(不长于32位)
function getNonceStr($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str = ""; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; 1234567891011
}
function curl($url, $post_data)
{
$headerArray = array( 'Accept:application/json, text/javascript, */*', 'Content-Type:application/x-www-form-urlencoded', 'Referer:https://mp.weixin.qq.com/' ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); // 对认证证书来源的检查,0表示阻止对证书的合法性的检查。 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 从证书中检查SSL加密算法是否存在 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//关闭直接输出 curl_setopt($ch, CURLOPT_POST, 1);//使用post提交数据 curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);//设置 post提交的数据 curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.69 Safari/537.36');//设置用户代理 curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArray);//设置头信息 $loginData = curl_exec($ch);//这里会返回token,需要处理一下。 return $loginData; $token = array_pop($token); curl_close($ch);
123456789101112131415161718192021222324252627282930313233343536373839}
/**
解析xml文档,转化为对象
@param String $xmlStr xml文档
@return Object 返回Obj对象
*/
function xmlToObject($xmlStr)
{
if (!is_string($xmlStr) || empty($xmlStr)) { return false; } // 由于解析xml的时候,即使被解析的变量为空,依然不会报错,会返回一个空的对象,所以,我们这里做了处理,当被解析的变量不是字符串,或者该变量为空,直接返回false libxml_disable_entity_loader(true); $postObj = json_decode(json_encode(simplexml_load_string($xmlStr, 'SimpleXMLElement', LIBXML_NOCDATA)), true); //将xml数据转换成对象返回 return $postObj; 123456789101112131415
}
//=执行===
s i g n = M a k e S i g n ( sign = MakeSign( sign=MakeSign(dataArr);//签名生成
$dataArr[‘sign’] = $sign;
$xmlStr = createXML(‘xml’, $dataArr);//统一下单xml数据生成
$reArr = explode(’?>’, $xmlStr);
r e A r r = e n d ( reArr = end( reArr=end(reArr);
$xml = curl(‘https://api.mch.weixin.qq.com/pay/unifiedorder’, $reArr);//发送请求 统一下单数据
//解析返回的xml字符串
r e = x m l T o O b j e c t ( re = xmlToObject( re=xmlToObject(xml);
//判断统一下单是否成功
if ($re[‘result_code’] == ‘SUCCESS’) {
//支付请求数据 $payData = array( 'appid' => $re['appid'], 'partnerid' => $re['mch_id'], 'prepayid' => $re['prepay_id'], 'noncestr' => getNonceStr(), 'package' => 'Sign=WXPay', 'timestamp' => time() ); //生成支付请求的签名 $paySign = MakeSign($payData); $payData['sign'] = $paySign; //拼接成APICLOUD所需要支付数据请求 $payDatas = array( 'apiKey' => $re['appid'], 'orderId' => $re['prepay_id'], 'mchId' => $re['mch_id'], 'nonceStr' => $payData['noncestr'], 'package' => 'Sign=WXPay', 'timeStamp' => $payData['timestamp'], 'sign' => $paySign ); //返回支付请求数据 echo json_encode($payDatas);
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152} else {
$re['payData'] = "error"; echo json_encode($re); 123
}
复制代码
4、预支付下单成功后,将拼接好的支付请求数据返回,也就是上述代码中数组$payDatas(注意:第二次参与签名的字段是:appid、partnerid、prepayid、noncestr、package、timestamp),app端代码如下:
$.ajax({
url:url, data:{ body:body, attach:attach, total_fee:total_fee }, dataType:"json", type:"post", success:function(data){ if(data.payData != "error"){ var wxPay = api.require('wxPay'); wxPay.payOrder(data, function(ret, err) { if (ret.status) { //支付成功 alert('支付成功'); } } else { alert(err.code);
12345678910111213141516171819202122232425262728293031323334353637复制代码
5、以上描述,已经亲测没有问题,如果代码或叙述有问题的,欢迎各位大神指教批评;如果有帮到各位初学者的不胜荣幸;另外说下我之前遇到过支付过程中返回-1的问题:参与第二次支付签名的参数是:appid、partnerid、prepayid、noncestr、package、timestamp,生成签名后,需要将payOrder()所需要的参数一一对应重新填写(appKeyappid、orderIdprepayid、mchIdpartnerid、nonceStrnoncestr、packagepackage、timeStamptimestamp)。
相关知识
移动APP 微信支付完整过程(wxPay 方案一)
微信支付
担忧微信支付安全性 险企不敢冒进
微信支付境外文档
微信营销活动方案10篇
宠物电商app开发方案及宠物电商app功能
宠物店微信小程序全面解析:功能、优点及使用攻略
微信社群建设方案
app营销推广方案模板(10篇)
8个月以上成年犬不听话的完整训练方案
网址: 移动APP 微信支付完整过程(wxPay 方案一) https://m.mcbbbk.com/newsview319671.html
上一篇: 附件1: 参赛作品规范 (一)内 |
下一篇: 婚前性行为=婚前试爱?你怎么看? |