移动APP 微信支付完整过程(wxPay 方案一)
apicloud、weixinpay官方提供了两种方案。
本模块封装了两套支付方案: 方案一:开发者通过 getOrderId、payOrder 自己处理签名过程(微信开放平台建议把 getOrderId 放在服务器端执行); 方案二:通过 config 接口和 pay 接口把签名过程交予模块内部处理。config 接口的参数可通过 key.xml 文件配置。
(本支付方案用于开发阶段测试验证账号的正确性,正式发版时请使用支付方案一)
方案二、属于本地测试账号是否完整的流程,正式使用的话使用方案一。
方案一、微信支付流程为:
、获取与支付订单。(这个订单号是微信生成的)。
、调用微信支付。
完整的方案一支付流程为:
1、申请微信开发平台的账号、创建移动应用、申请开发者资质认证(整个过程APICLOUD官方网站已经给出了相当明确的操作步骤,与实际操作没有差异,按照文档一步一步来,是没有问题的),附带链接地址:http://docs.apicloud.com/Others/Open-SDK-Integration-Guide/weChat
2、配置移动应用中 config.xml 文件
<feature name="wxPay">
<param name="urlScheme" value="wxd0d84bbf23b4a0e4"/>
<param name="apiKey" value="wxd0d84bbf23b4a0e4"/>
<param name="apiSecret" value="a354f72aa1b4c2b8eaad137ac81434cd"/>
</feature>
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'
); //转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();
// echo $str;
//返回xml字符串
return $str;
} //封装签名算法
function MakeSign($arr) {
//签名步骤一:按字典序排序参数
ksort($arr);
$string = ToUrlParams($arr);
//签名步骤二:在string后加入KEY
$string = $string.
"&key=".$key;
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
} /**
* 格式化参数格式化成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;
} //随机字符串(不长于32位)
function getNonceStr($length = ) {
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = ; $i < $length; $i++) {
$str. = substr($chars, mt_rand(, strlen($chars) - ), );
}
return $str;
} 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, ); //关闭直接输出
curl_setopt($ch, CURLOPT_POST, ); //使用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);
} /**
* 解析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;
}
//=====================执行=======================
$sign = MakeSign($dataArr);//签名生成
$dataArr['sign'] = $sign; $xmlStr = createXML('xml', $dataArr);//统一下单xml数据生成
$reArr = explode('?>', $xmlStr);
$reArr = end($reArr); $xml = curl('https://api.mch.weixin.qq.com/pay/unifiedorder', $reArr);//发送请求 统一下单数据 //解析返回的xml字符串
$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);
} else {
$re['payData'] = "error";
echo json_encode($re);
}
4、预支付下单成功后,将拼接好的支付请求数据返回,也就是上述代码中数组$payDatas(注意:第二次参与签名的字段是:appid、partnerid、prepayid、noncestr、package、timestamp),app端代码如下:
api.ajax({
url: baseUrl +'/api/v1/mallOrder/toPay?memberId=' +memberId+ '&orderId=' +orderId,
timeout: ,
dataType: 'json',
method: 'get'
}, function(ret, err) {
api.hideProgress();
/*** 登录异常 ***/
if (err) {
api.toast({
msg:'网络异常,请稍后重试',
duration: '',
localtion: 'middle'
});
return;
}
var wxPay = api.require('wxPay');
var data = ret.data;
wxPay.payOrder(data, function(ret, err) {
var statue = false;
if (ret.status) {
statue = true;
openPayResult(statue);
} else {
statue = false;
openPayResult(statue);
}
}); });
5、以上描述,已经亲测没有问题,如果代码或叙述有问题的,欢迎各位大神指教批评;如果有帮到各位初学者的不胜荣幸;另外说下我之前遇到过支付过程中返回-1的问题:这个问题不得不说APICLOUD官网有那么一点点的坑,官网上面payOrder()的参数为:appKey、orderId、mchId、nonceStr、timeStamp、package,就会以为参与第二次支付签名的参数是这些,但其实并不是,那么参与第二次支付签名的参数是:appid、partnerid、prepayid、noncestr、package、timestamp,生成签名后,需要将payOrder()所需要的参数一一对应重新填写(appKey==appid、orderId==prepayid、mchId==partnerid、nonceStr==noncestr、package==package、timeStamp==timestamp)。
移动APP 微信支付完整过程(wxPay 方案一)的更多相关文章
- 微信公众号支付|微信H5支付|微信扫码支付|小程序支付|APP微信支付解决方案总结
最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付.APP微信支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存. 先说注意 ...
- ThinkPHP5.0 实现 app微信支付功能
相对于之前随笔写的<ThinkPHP5.0实现app支付宝支付功能>来说,php对接app微信支付功能就相对简单的多了,最近有加我的朋友问到app微信支付,所以我把app微信支付的demo ...
- app微信支付
<?php namespace app\api\controller\v1; use think\Request; use app\api\exception\weappay\lib\WxPay ...
- APP微信支付报错《商户号该产品权限未开通,请前往商户平台>产品中心检查后重试》
问题 最近项目使用MUI,HBuilder.开发打包H5的app 在开发H5 plus支付的时候,遇到以下问题: App微信支付调官方的统一下单接口返回错误信息 {return_msg=商户号该产品权 ...
- thinkPHP实现APP微信支付
控制器 class Pay extends Controller { const WX_PAY_URL = "https://api.mch.weixin.qq.com/pay/unifie ...
- app微信支付-java服务端接口 支付-查询-退款
个人不怎么看得懂微信的文档,看了很多前辈的写法,终于调通了,在这里做一下记录. 首先来定义各种处理类(微信支付不需要特殊jar包,很多处理需要自己封装,当然也可以自己写完打个jar包) 参数要用jdo ...
- APP微信支付Java后台的实现(springmvc)
第一次做微信支付,阅读完开发文档后,下了个官方demo,摸索了好久,期间也出现了好多问题,终于是实现生成预支付订单以及支付成功后接收微信服务器通知,不多说了,直接上代码: 一.工具类 Constant ...
- java中微信统一下单采坑(app微信支付)
app支付前java后台统一下单文档:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1 微信支付接口签名校验工具:https ...
- APIcloud制作APP 微信支付与支付宝支付
首先要在云端绑定相应模块如alipay和wxpay其次编写代码. 配置区域 var cfg = { webName:'',//APP名字 payDebug:true, isUseWxPay:true, ...
随机推荐
- Spring——BeanFactory
Spring容器 什么是Spring容器 Spring容器是Spring的核心,它可以创建对象,把他们关联在一起,配置各个对象,并管理每个对象的整个生命周期.Spring容器使用依赖注入(DI)来管理 ...
- Spring MVC-集成(Integration)-生成XML示例(转载实践)
以下内容翻译自:https://www.tutorialspoint.com/springmvc/springmvc_xml.htm 说明:示例基于Spring MVC 4.1.6. 以下示例说明如何 ...
- 前端页面a标签嵌套a标签效果的两种解决方案
这是由工作中的一个小改动需求得到的这个解决方案的:那个需求是这样的,如图: 需求原来是球队名字没有点击功能的,而蓝色方框两队之间的比赛点击的时候会跳转到比赛文字直播页面.现在需要要求点击球队名字要跳转 ...
- Ubuntu下终端Vim编写C语言程序 AAAAA
我是开虚拟机下的Ubuntu,装双系统又卸了,Ubuntu默认是不包含编辑器vim和编译器gcc.如果你是刚安装好的Ubuntu电脑,下面我们将来实现自己的第一个程序. 1.准备工作 首先进入root ...
- hdu 1075(字典树)
What Are You Talking About Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/204800 K ...
- 认证与授权协议对比:OAuth2、OpenID、SMAL
认证授权是目前大多数系统都必须要实现都功能,认证就是验证用户都身份,授权就是验证身份后对受限资源的访问控制.最开始是单个平台要做,后来在互联网时代到来,一个账户可登陆多个平台,然后是各种开放平台账户共 ...
- bzoj 4318 OSU! —— 期望DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4318 期望DP,因为平方的期望不等于期望的平方,所以用公式递推: 第一次推错了囧,还是看这位 ...
- 3.4 存储简单数据的利器——Preferences
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="ht ...
- java jdk 管理工具
官网:http://www.jenv.be/ 安装: Linux / OS X $ git clone https://github.com/gcuisinier/jenv.git ~/.jenv M ...
- PCB LDI文件 自动化输出(改造)实现思路
由于工厂采用Liunxs系统输出LDI文件,由于我们数据库是用的Windows Server,编程语言是.net 无法与Liunxs系统进行有效对接, 所以造成才会造成LDI 资料输效率极低,人员工作 ...