androidios 微信支付成功回调ios的支付成功了,android端成功不了,会是后台生成的sign有问题吗

博客分类:
j界面调用支付ajax 通过xml格式向微信调起支付密码窗
// 微信支付
type: "POST",
url: path + "/wxpay/getPrepayId.do",
dataType: "json",
totalFee : payCost,
out_trade_no : orderNum,
success: function(data) {
wx.chooseWXPay({
appId: data.appId,
timestamp: data.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: data.nonceStr, // 支付签名随机串,不长于 32 位
package: data.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
signType: data.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: data.paySign, // 支付签名
success: function (res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
myLoading();
queryOrder(0);
if (res.errMsg == "chooseWXPay:ok") {
myLoading();
queryOrder(0);
error: function(res) {
myAlert("请求超时,请重试");
complete: function() {
myLoadingClose();
getPrepayId 方法:
@Action(value = "getPrepayId")
public String getPrepayId() throws Exception {
ProjSession ps = this.getSession();
// 商品描述,根据提交上来的ID来获取商品名称
String body = "服务";
String totalFeeStr = this.getRequest().getParameter("totalFee");
String out_trade_no = this.getRequest().getParameter("out_trade_no");
// 本次订单的金额,单位为分
Double d = Double.parseDouble(totalFeeStr) * 100;
int totalFee = Integer.parseInt(new java.text.DecimalFormat("0").format(d));
// 向微信发送的内容
UnifiedorderReqData xmlObj = new UnifiedorderReqData(body, out_trade_no, totalFee, this.getRequest().getRemoteAddr(), ps.getOpenid());
// 向微信发送接口数据
String result = WeixinUtil.weixinPostXml(Configure.UNIFIEDORDER, xmlObj);
// 微信返回的数据
UnifiedorderRespData retModel = (UnifiedorderRespData) Util.getObjectFromXML(result, UnifiedorderRespData.class);
Map&String, Object& returnMap = new HashMap&String, Object&();
if (ObjUtil.isNullOrEmpty(retModel)) {
// 支付请求失败
returnMap.put("success", false);
returnMap.put("msg", "支付请求失败");
this.doResponseWithJson(returnMap);
return NONE;
if (!"SUCCESS".equals(retModel.getReturn_code().toUpperCase())) {
// 支付请求失败
returnMap.put("success", false);
returnMap.put("msg", retModel.getReturn_msg());
this.doResponseWithJson(returnMap);
return NONE;
if (!retModel.getResult_code().toUpperCase().equals("SUCCESS")) {
returnMap.put("success", false);
returnMap.put("msg", retModel.getErr_code_des());
this.doResponseWithJson(returnMap);
return NONE;
//判断是否有预支付订单
OrderModel smodel=new OrderModel();
smodel.setOpenId(model.getOpenId());
smodel.setOrderStatus(Constants.ORDER_STATUS_2);
List&OrderModel& olist =this.getDao().selectForList("order.getOpenIdStatus", smodel);
if(ObjUtil.isNullOrEmpty(olist)){
// 插入dd_order表
model.setOrderStatus(Constants.ORDER_STATUS_2);
model.setOrderWebStatus(Constants.ORDER_STATUS_2);
this.getDao().insertSql("order.add_order", model);
model.setId(olist.get(0).getId());
model.setOrderStatus(Constants.ORDER_STATUS_2);
model.setOrderWebStatus(Constants.ORDER_STATUS_2);
this.getDao().updateSql("order.upt_order_openId", model);
returnMap.put("appId", Constants.APPID);
returnMap.put("timeStamp", Long.toString(System.currentTimeMillis() / 1000));
returnMap.put("nonceStr", RandomStringGenerator.getRandomStringByLength(32));
returnMap.put("package", "prepay_id="+retModel.getPrepay_id());
returnMap.put("signType", "MD5");
returnMap.put("paySign", Signature.getSign(returnMap));
this.doResponseWithJson(returnMap);
return NONE;
如果调用支付窗口成功,输入密码成功。
先调用WxNotifyAction.java
@Namespace("/notify")
public class WxNotifyAction extends BaseAction {
private static final long serialVersionUID = 1L;
private TradeService tradeService = new TradeServiceImpl();
@Action(value = "notify")
public String notification() throws Exception {
System.out.println("!!!!!!!!!!!into notify");
HttpServletRequest req = this.getRequest();
HttpServletResponse resp = this.getResponse();
req.setCharacterEncoding("utf-8");
InputStream reqBody = req.getInputStream();
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/ charset=utf-8");
String receiveXml = Util.inputStreamToString(reqBody);
System.out.println(receiveXml);
Notice retModel = (Notice) Util.getObjectFromXML(receiveXml, Notice.class);
PrintWriter out = resp.getWriter();
if (ObjUtil.isNullOrEmpty(retModel)) {
out.print("&xml&&return_code&FAIL&/return_code&&return_msg&NO_HANDLER_REPORTED&/return_msg&&/xml&");
return NONE;
if (!"SUCCESS".equals(retModel.getReturn_code().toUpperCase())) {
out.print("&xml&&return_code&FAIL&/return_code&&return_msg&NO_HANDLER_REPORTED&/return_msg&&/xml&");
return NONE;
if (!"SUCCESS".equals(retModel.getResult_code().toUpperCase())) {
out.print("&xml&&return_code&FAIL&/return_code&&return_msg&NO_HANDLER_REPORTED&/return_msg&&/xml&");
return NONE;
// 调用成功,插入数据库
boolean flag = tradeService.wxPayTrade(retModel);
System.out.println("--------------"+flag+"---------------");
if (flag) {
out.print("&xml&&return_code&SUCCESS&/return_code&&/xml&");
out.print("&xml&&return_code&FAIL&/return_code&&return_msg&NO_HANDLER_REPORTED&/return_msg&&/xml&");
return NONE;
然后调用js判断是否支付成功,wxpay表是否有数据插入
function queryOrder(requestTimes) {
type : "POST",
url : path + "/wxpay/orderQuery.do",
data : { orderNum : orderNum},
dataType : "json",
success : function(data) {
if (!data.success) {
if (requestTimes & 3) {
requestTimes = requestTimes + 1;
setTimeout(function(){queryOrder(requestTimes);}, 1000);
myAlert("请求超时,请核对订单列表,确定是否成功下单");
myLoadingClose();
successPng();
orderQuery
@Action(value = "orderQuery")
public String orderQuery() throws Exception {
Map&String, Object& returnMap = new HashMap&String, Object&();
ProjSession ps = this.getSession();
OrderModel o = new OrderModel();
// 页面需要把订单编号告诉我
String orderNum = this.getRequest().getParameter("orderNum");
o.setOrderNum(orderNum);
o.setPayType(Constants.wxpay);
o.setOpenId(ps.getOpenid());
o.setOrderStatus(Constants.ORDER_STATUS_1);
List&OrderModel& list = this.getDao().selectForList("wxpay.checkStatus", o);
if (!ObjUtil.isNullOrEmpty(list)) {
// 交易已经成功
System.out.println("++++++交易已经成功");
returnMap.put("success", true);
this.doResponseWithJson(returnMap);
// 交易未完成
// 向微信服务器查询订单是否完成
System.out.println("++++++交易未成功");
OrderqueryReqData xmlObj = new OrderqueryReqData(orderNum);
String result = WeixinUtil.weixinPostXml(Configure.ORDERQUERY, xmlObj);
OrderqueryRespData retModel = (OrderqueryRespData)Util.getObjectFromXML(result, OrderqueryRespData.class);
if (ObjUtil.isNullOrEmpty(retModel)) {
// 支付请求失败
returnMap.put("success", false);
this.doResponseWithJson(returnMap);
if (!"SUCCESS".equals(retModel.getReturn_code().toUpperCase())) {
// 支付请求失败
returnMap.put("success", false);
this.doResponseWithJson(returnMap);
if (!"SUCCESS".equals(retModel.getResult_code().toUpperCase())) {
returnMap.put("success", false);
this.doResponseWithJson(returnMap);
Notice n = new Notice();
BeanUtils.copyProperties(n, retModel);
boolean flag = tradeService.wxPayTrade(n);
returnMap.put("success", flag);
this.doResponseWithJson(returnMap);
return NONE;
浏览: 13333 次
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'iOS微信支付步骤以及出现的问题总结(二) - 简书
iOS微信支付步骤以及出现的问题总结(二)
前提是已经创建完应用了在微信的官网上。根据上一篇的微信获得支付能力的步骤,这一篇主要制作微信支付的demo。回顾上一篇内容请看查看下一篇 。往往回忆就是痛苦的因为记不住曾经的经历,还是喜欢简单粗暴。1.微信支付的demo与SDK。2.下载完之后,里面有好多的没用的文件,包括登录,分享,等等。(看到这里好恶心,为啥不单独做一个demo呢,哎,还能不能愉快的玩耍了)。如下 的文件夹目录的内容:
3.创建一个wxDemo工程。4.查看微信的官方文档。5.因为现在 的工程是iOS9 ,所以需要配置网址与白名单。
配置网址与白名单
6.改变bitcode设置为NO。
改变bitcode为NO
7.添加URL Types,如下。
添加URL Schemes
8.添加微信SDK到wxDemo里面。9.添加框架,用来安装应用。 。需要添加以下库:
SystemConfiguration.framework,
libz.dylib,
libsqlite3.0.dylib,
libc++.dylib
添加依赖库
10.在Appdelegate.m里面添加如下代码://注册微信支付[WXApi
registerApp:@"wxXXXXXXXXXX"]; 此时运行编译,快捷键commd+b 运行程序会出现以下错误,以下是错误的信息:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_CTTelephonyNetworkInfo", referenced from:
objc-class-ref in libWeChatSDK.a(MTAHelper.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
错误的图片:
错误信息的展示
11.修改错误操作,由于缺少一个依赖库:添加一个CoreTelephony.frame 依赖库,就可以解决了。
添加依赖库
12.根据微信里面的demo,添加需要的代码。以下是文件目录的一些解释:里面主要的方法就是支付的网络请求以及调用微信客户端的代码。
13.添加一个按钮的方法,实现支付。说明:支付目前来说有两种实现方式,一种是本地的app直接实现跳转进行支付;另一种方式是通过后台服务器进行网络请求。下面的这一种是通过服务器进行支付的跳转。
- (void)WXPay {
NSString*urlString=@"http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php?plat=ios";
//解析服务端返回json数据
//加载一个NSURL对象
NSURLRequest*request = [NSURLRequestrequestWithURL:[NSURLURLWithString:urlString]];
//将请求的url数据放到NSData对象中
NSData*response = [NSURLConnectionsendSynchronousRequest:requestreturningResponse:nilerror:nil];
if(response !=nil) {
NSMutableDictionary*dict =NULL;
//IOS5自带解析类NSJSONSerialization从response中解析出数据放到字典中
dict = [NSJSONSerializationJSONObjectWithData:responseoptions:NSJSONReadingMutableLeaveserror:&error];
NSLog(@"********url:%@",urlString);
if(dict !=nil){
NSMutableString*retcode = [dictobjectForKey:@"retcode"];
if(retcode.intValue==0){
NSMutableString*stamp= [dictobjectForKey:@"timestamp"];
//调起微信支付
//注意:此处的key一定要与demo中的key的字符一致,一个也不能少,一个也不能错。
PayReq* req= [[PayReqalloc]init];
req.partnerId= [dictobjectForKey:@"partnerid"];
req.prepayId= [dictobjectForKey:@"prepayid"];
req.nonceStr= [dictobjectForKey:@"noncestr"];
req.timeStamp= stamp.intV
req.package= [dictobjectForKey:@"package"];
req.sign= [dictobjectForKey:@"sign"];
[WXApisendReq:req];
//日志输出
NSLog(@"appid=%@\npartid=%@\nprepayid=%@\nnoncestr=%@\ntimestamp=%ld\npackage=%@\nsign=%@",[dictobjectForKey:@"appid"],req.partnerId,req.prepayId,req.nonceStr,(long)req.timeStamp,req.package,req.sign);
NSLog(@"%@",[dictobjectForKey:@"retmsg"]);
NSLog(@"服务器返回错误,未获取json对象");
NSLog(@"服务器返回错误");
14.在完成此处之后,点击支付按钮会出现下面的问题:在跳转到支付界面之后,仅仅会出现一个“确定”的白色按钮。如下图:
支付出现问题
通过查找信息,是由于配置的参数问题。因此我们不用服务器端进行网络请求直接用自己生成这些参数,然后就可以实现支付功能了。15.下面是获取参数的解释。参数解释:partnerId: 商家向财付通申请的商家id(就是自己的id,也就是在你申请开发者资质认证之后,有一个商户平台,这个平台对应的id,就是你自己的id。好像还没有说明白。)获取方式:打开链接,直接将微信发送给你的邮件里面的内容登陆商户平台,就找到了partnerid了。
prepayId: 预支付订单(需要向微信服务器提交申请后返回的一个支付交易ID)获取方式:这个一般情况下是服务器端已经申请好的,客户端直接调用。a、微信的服务端返回的参数的说明:。(看着很乱,可是呢,还是太乱)b、还要生成一个签名,这个官方文档也是写了。(虽然看着很简单,但是还是搞不定,坑太多,哎,没办法就是这么坑,多看几遍就好了)根据微信的接口,返回的xml的数据参数。将数据解析之后,就能获得prepayid。nonceStr: 随机串,防重发(随机字符串,不长于32位)获取方式:
注意:#pragma mark-
需要引入依赖库libcommonCrypto.tbd并且引入头文件#import &CommonCrypto/CommonGigest.h&
char*str = [input
UTF8String];
result[CC_MD5_DIGEST_LENGTH];
CC_MD5(str,strlen(str),result);
NSMutableString*
ret = [NSMutableString
stringWithCapacity:CC_MD5_DIGEST_LENGTH*2];
for(int i = 0 ;i &CC_MD5_DIGEST_LENGTH;i++) {
[ret appendFormat:@"%02X",result[i]];
NSLog(@"%@",[ret
uppercaseString]);
注意:就是一个随机数。noncestr就是在第一次生成签名的时候的那个随机数,不要再次生成。timeStamp:时间戳,防重发(标准北京时间,时区为东八区,自日 0点0分0秒以来的秒数)获取方式:NSString* timeString = [NSString
stringWithFormat:@"%.0f"[[NSDate date]timeIntervalSince1970]];由于:@property(nonatomic,assign)UInt32
timeS所以在提交的时候需要转换成对应的格式,UInt32 格式。sign:商家根据微信开放平台文档对数据做的签名,这里的签名不同于你第一次申请的prepayid的签名,这里的签名的参数是appid,prepayid,partnerid,timestamp,noncestr,package
这几个排序后再拼接的key最后生成一个sign。上面这些只是介绍了这些参数如何获取,在下面一篇文章中,开始仔细介绍,最后一步的支付流程,也就是配置参数、服务器相关的一些配置。参考资源:1.2.
做一个有艺术气息的技术大牛--SeanFrank
一. 支付准备工作 1. 微信相关准备工作 (1) 向微信官方开通支付功能. 这个不是前端的工作. (2) 导入官方下载的微信支付SDK包. 我用的是微信开放平台下载的最新SDK (3) 导入必要的库文件 SystemConfiguration.framework, lib...
前言:本篇文章目的在于梳理知识,巩固思想,学习总结。有什么好的建议,都可以留言。互相促进!总观,微信支付,也没心思,好好看文档。文档微微有些乱。感觉,微信demo,内部功能都集成到一块了,不好查找。终于,在各种坑下,仔细看了一遍文档,默默的弄完了。会用到的网址如下:微信开放...
银联支付,支付宝支付,微信支付的三大总结,之前也有写过两篇。 微信支付,支付宝支付,银联支付——三大支付总结: http://blog.csdn.net/androidstarjack/article/details/ 支付宝植入总结: android 支付...
目前项目里有微信支付的需求,调研过一段时间后,发现其实并没有想象中的那么困难。如果你只是想实现该功能,一个方法足以,但是若你想深入了解实现原理。就需要花费更多的功夫了。目前我只清楚微信支付需要做签名,一种是在后台签名,一种是自己在前端签名。其实这对前端来说代码量并没有多大的...
一.微信支付 前提:在微信开发者平台注册APP这样的事一般的是经理给你做好的,这个可以忽略,如果需要做的话,可以参考别人的这篇文章,微信支付没有想象的那么困难,下面我会写两种:一种在客户端(app)完成,一种在后台完成 1.开发前你需要看看微信开发的文档和微信的app开发步...
一直以来都挺喜欢画画的,但人又懒,迟迟不怎么动手。因为没有基础,没学过,这其中多少带着一点逃避的态度,越逃避越不会画。。对我自己无语了。 最近《深夜食堂》挺火的,当然,这不,我也在追!!追吧追吧,抛开对这部戏的评价,个人挺喜欢黄磊的。再来说说这部戏,我喜欢赵又延和戚薇那个故...
说明下,自己和这文章的作者思路一样,位置都一样,不过就是不想重复造轮子,所以才搬运过来了,自己通过当前类的方法重新加载图标的。已经实现了才发现此博客的 (本文转自:http://blog.csdn.net/u/article/details/5025052...
前言 不管开发什么游戏,游戏存档是个必不可少的功能,你可能需要保存玩家的一些信息,比如身上穿戴的装备,玩家角色所处的场景等各种信息,对于存档功能(数据持久化),Unity提供了原生技术Playerprefs,它的优点是理解和使用起来十分简单,缺点是对于大型数据存储时会力不从...
我们总是从各种人,各种书上看到或听到很多经验之谈!但是自己的生活依旧就像大家所说“道理我们都懂,但还是过不好自己的人生”
随着年龄的增长,其实你越来越会感觉到“人生最大的敌人就是自己”,我们不断的用自己的经历证明着前人告诉我们的道理的正确性。
我不能轻易...
主题:教练能力的提升--如何透过学员的打卡,找出问题并引导下一步 汤雪老师:首次海外授课,悉尼之行已结束,收获良多。一方面与国内氛围不同,家长和学生们更为放松;另一方面也要感谢各位现场支持的教练,大家付出良多,非常辛苦。 丫丫老师:
本次教练会参加人员明显减少,也许是因...71796人阅读
Android开发(1047)
首先我们先看一个android微信支付时遇到的一个错误提示:onPayFinish, errCode = -1 当你参数签名都没有问题的时候,出现这个提示,请按照如下操作:在你的项目测试android微信的组件(微信分享、微信支付等)的时候,一定要用你自己的keystore签名出来测试,如果用debug.keystore肯定是不成功的!1,在微信开放平台申请app_id,app_key我就不在这里叙述了,稍后我会把开发文档一并上传的,你也可以去微信开放平台自行查看(差不多一个周才会通过审核) 2,下面我就来说一说微信支付开发时需要注意的地方:2.1 首先来看一下,微信支付的架构和流程图
3.2 再来看一下成功调起微信支付的界面
3下面开始讲解配置工程3.1 这里必须要有wxapi这个包名,同时必须有WXPayEntryActivity这个类名,否则无法调起微信支付,(开发文档没有标注,废了好大周章) 3.2 支付成功通知:在WXPayEntryActivity的OnResp中处理,不能以微信返回的通知界面为准(我遇到的情况,网络不稳定的时候,微信返回界面提示支付失败,但是收到微信通知其实已经支付成功了),必须要去自己的服务器查询支付状态,这里微信建议用轮循机制去查询(最好听微信劝,O(∩_∩)O哈哈~) @Override
public void onResp(BaseResp resp) {
Log.d(TAG, "onPayFinish, errCode = " + resp.errCode);
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.app_tip);
builder.setMessage(getString(R.string.pay_result_callback_msg, resp.errStr +";code=" + String.valueOf(resp.errCode)));
builder.show();
}3.3 生成prepay_id,在服务器完成,由服务器去跟微信服务器交互,客户端不需要参与 /**
* 获取预支付订单号:
* prepay_id(服务器完成)!!!
* 注意:如果服务端开发文档跟客户端demo里的参数不一样,以demo里的参数为准,
* 否则服务器传过来的参数无法调起微信支付!!!
private String genProductArgs() {
StringBuffer xml = new StringBuffer();
nonceStr = genNonceStr();
xml.append("&/xml&");
List&NameValuePair& packageParams = new LinkedList&NameValuePair&();
packageParams.add(new BasicNameValuePair("appid", Constants.APP_ID));
packageParams.add(new BasicNameValuePair("body", "APP pay test"));
/**这里用的是mach_id,跟sign签名时参数名不同,一定要注意*/
packageParams.add(new BasicNameValuePair("mch_id", Constants.MCH_ID));
packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));
packageParams.add(new BasicNameValuePair("notify_url", "http://121.40.35.3/test"));
packageParams.add(new BasicNameValuePair("out_trade_no",genOutTradNo()));
packageParams.add(new BasicNameValuePair("spbill_create_ip","127.0.0.1"));
packageParams.add(new BasicNameValuePair("total_fee", "1"));
packageParams.add(new BasicNameValuePair("trade_type", "APP"));
String sign = genPackageSign(packageParams);
packageParams.add(new BasicNameValuePair("sign", sign));
String xmlstring =toXml(packageParams);
} catch (Exception e) {
Log.e(TAG, "genProductArgs fail, ex = " + e.getMessage());
}3.4 获取二次签名signprivate void genPayReq() {
req.appId = Constants.APP_ID;
req.partnerId = Constants.MCH_ID;
req.prepayId = resultunifiedorder.get("prepay_id");
req.packageValue = "prepay_id="+resultunifiedorder.get("prepay_id");
req.packageValue = "Sign=WXPay";
req.nonceStr = genNonceStr();
req.timeStamp = String.valueOf(genTimeStamp());
List&NameValuePair& signParams = new LinkedList&NameValuePair&();
signParams.add(new BasicNameValuePair("appid", req.appId));
signParams.add(new BasicNameValuePair("noncestr", req.nonceStr));
* 这里的package参数值必须是Sign=WXPay,否则IOS端调不起微信支付,
* (参数值是"prepay_id="+resultunifiedorder.get("prepay_id")的时候Android可以,IOS不可以)
signParams.add(new BasicNameValuePair("package", req.packageValue));
/**注意二次签名这里不再是mch_id,变成了*/
signParams.add(new BasicNameValuePair("partnerid", req.partnerId));
signParams.add(new BasicNameValuePair("prepayid", req.prepayId));
signParams.add(new BasicNameValuePair("timestamp", req.timeStamp));
req.sign = genAppSign(signParams);
sb.append("sign\n"+req.sign+"\n\n");
show.setText(sb.toString());
Log.e("orion", signParams.toString());
}3.5 起调微信支付private void sendPayReq() {
msgApi.registerApp(Constants.APP_ID);
msgApi.sendReq(req);
}3.6 配置Manifest.xml,权限什么的按照文档的配置就行了 &activity
android:name=".PayActivity"
android:label="@string/app_name"
android:exported="true"
android:launchMode="singleTop"&
&intent-filter&
&action android:name="android.intent.action.MAIN" /&
&category android:name="android.intent.category.LAUNCHER" /&
&/intent-filter&
&!--这个intent-filter不要忘了--&
&intent-filter&
&action android:name="android.intent.action.VIEW"/&
&category android:name="android.intent.category.DEFAULT"/&
&data android:scheme="wxd930ea5d5a258f4f"/&
&/intent-filter&
&/activity&4,支付通知接口和退款接口按照开发文档即可,这里不再赘述5, 在你的项目测试微信支付的时候,一定要用你自己的keystore签名出来测试,如果用debug.keystore肯定是不成功的,切记,切记,不要闹乌龙!!!好了,就写这么多吧,以此文来祭奠我和同事被腾讯坑死的那几天,如果有不懂的童鞋可以给我留言,或者QQ:联系我,大家可以去这个地址下载微信支付v3.0版本的开发文档和demo,以及一个成功的微信支付demo app,轮询事件大家可以参考我的下一篇blog,从别人那里转来的,写的挺详细的 补充问题:微信支付v3 body中文无法支付问题String nonceStr = genNonceStr();xml.append("&/xml&");// Yuebai Steam Car Wash Service List&NameValuePair& packageParams = new LinkedList&NameValuePair&();packageParams.add(new BasicNameValuePair("appid", Constants.APP_ID));packageParams.add(new BasicNameValuePair("body", "月白洗车"));// 这个一改就无法支付packageParams.add(new BasicNameValuePair("mch_id", Constants.MCH_ID));packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));packageParams.add(new BasicNameValuePair("notify_url", HttpConstant.wxapi));packageParams.add(new BasicNameValuePair("out_trade_no", orderid));packageParams.add(new BasicNameValuePair("spbill_create_ip", "127.0.0.1"));int a = (int) (Integer.parseInt(m) * 100);packageParams.add(new BasicNameValuePair("total_fee", a + ""));packageParams.add(new BasicNameValuePair("trade_type", "APP"));String sign = genPackageSign(packageParams);packageParams.add(new BasicNameValuePair("sign", sign));String xmlstring = toXml(packageParams); return new String(xmlstring.toString().getBytes(), "ISO8859-1");//这句加上就可以了吧xml转码下 另外说明的是,如果想增加参数,请先看看下面的内容。签名算法签名生成的通用步骤如下:第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。特别注意以下重要规则:◆ 参数名ASCII码从小到大排序(字典序);◆ 如果参数的值为空不参与签名;◆ 参数名区分大小写;◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。key设置路径:微信商户平台(pay.weixin.qq.com)--&账户设置--&API安全--&密钥设置举例:假设传送的参数如下:appid: wxd930ea5d5a258f4fmch_id: device_info: 1000body: testnonce_str: ibuaiVcKdpRxkhJA第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下:stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=&nonce_str=ibuaiVcKdpRxkhJA";第二步:拼接API密钥:stringSignTemp="stringA&key=c09247ec02edce69f6a2d"sign=MD5(stringSignTemp).toUpperCase()="9A0AA9CF3B7"最终得到最终发送的数据:&xml&&appid&wxd930ea5d5a258f4f&/appid&&mch_id&&/mch_id&&device_info&1000&device_info&&body&test&/body&&nonce_str&ibuaiVcKdpRxkhJA&/nonce_str&&sign&9A0AA9CF3B7&/sign&&xml&微信提供相关接口在线签名验证工具:。
所以,如果我们增加两个参数:attach、device_info就必须根据参数名ASCII字典序增加,如下图位置。如果将参数attach放在trade_type之后肯定就会报签名错误。List&NameValuePair& packageParams = new LinkedList&NameValuePair&();
packageParams.add(new BasicNameValuePair("appid", Constant.weixin_appID));
packageParams.add(new BasicNameValuePair("attach", mOrderNo));
packageParams.add(new BasicNameValuePair("body", "订单-" + mOrderNo)); //商品描述
packageParams.add(new BasicNameValuePair("device_info", "ANDROID"));
packageParams.add(new BasicNameValuePair("mch_id", Constant.MCH_ID));
packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));
packageParams.add(new BasicNameValuePair("notify_url", "http://wap.baidu.com/wechat_notify.php"));
packageParams.add(new BasicNameValuePair("out_trade_no",genOutTradNo()));
packageParams.add(new BasicNameValuePair("spbill_create_ip", "127.0.0.1"));
packageParams.add(new BasicNameValuePair("total_fee", String.valueOf((int) (mMoney * <span style="color:#))));//商品金额,以分为单位
packageParams.add(new BasicNameValuePair("trade_type", "APP")); 最后再为大家分享点干货。在计算订单总价的时候,有时会出现***.99998的现象,这个是浮点数计算出现的问题,得需要 BigDecimal解决高精度计算。下面是我的解决方法,大家有更好的可以分享下。/*
* 总订单的价格(不包含运费)
public double calculatingTotalPriceNoFreight() {
double total = 0.00;
for (ShopCartItem cartItem : getDataList()) {
double orderPrice = calculatingOrderPrice(cartItem);
total += orderP
//double值保留 2 位小数,使用银行家舍入法
return MathUtil.round(total, 2, BigDecimal.ROUND_HALF_EVEN) ;
}MathUtil.javapackage com.haier.cabinet.customer.
import java.math.BigD
public class MathUtil {
* 对double数据进行取精度.
* @param value
double数据.
* @param scale
精度位数(保留的小数位数).
* @param roundingMode
精度取值方式.
* @return 精度计算后的数据.
public static double round(double value, int scale,
int roundingMode) {
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(scale, roundingMode);
double d = bd.doubleValue();
* double 相加
* @param d1
* @param d2
public static double sum(double d1,double d2){
BigDecimal bd1 = new BigDecimal(Double.toString(d1));
BigDecimal bd2 = new BigDecimal(Double.toString(d2));
return bd1.add(bd2).doubleValue();
* double 相减
* @param d1
* @param d2
public static double sub(double d1,double d2){
BigDecimal bd1 = new BigDecimal(Double.toString(d1));
BigDecimal bd2 = new BigDecimal(Double.toString(d2));
return bd1.subtract(bd2).doubleValue();
* double 乘法
* @param d1
* @param d2
public static double mul(double d1,double d2){
BigDecimal bd1 = new BigDecimal(Double.toString(d1));
BigDecimal bd2 = new BigDecimal(Double.toString(d2));
return bd1.multiply(bd2).doubleValue();
* double 乘法
* @param n
* @param d2
public static double mul(int n,double d2){
BigDecimal bd1 = new BigDecimal(Integer.toString(n));
BigDecimal bd2 = new BigDecimal(Double.toString(d2));
return bd1.multiply(bd2).doubleValue();
* double 除法
* @param d1
* @param d2
* @param scale 四舍五入 小数点位数
public static double div(double d1,double d2,int scale){
当然在此之前,你要判断分母是否为0,
为0你可以根据实际需求做相应的处理
BigDecimal bd1 = new BigDecimal(Double.toString(d1));
BigDecimal bd2 = new BigDecimal(Double.toString(d2));
return bd1.divide
(bd2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
* 将double类型数据转为字符串
* @param d
public static String double2String(double d){
BigDecimal bg = new BigDecimal(d * 100);
double doubleValue = bg.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
String.valueOf((int)doubleValue);
补充:微信官网上对于支付返回-1是
我犯的错和他描述的都不一样。1、新建一个微信支付demo的工程,将包名和签名上传给微信。并保证apk是通过keystore方式打了签名的,用官方的工具做签名。2、将官方的demo示例参考一下,权限部分:&!-- WeixinPay --&
&uses-permission android:name="android.permission.INTERNET" /&
&uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/&
&uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
&activity android:name=".MainActivity"
android:exported="true"&
&intent-filter&
&action android:name="android.intent.action.MAIN" /&
&category android:name="android.intent.category.LAUNCHER" /&
&/intent-filter&
&intent-filter&
&action android:name="android.intent.action.VIEW"/&
&category android:name="android.intent.category.DEFAULT"/&
&data android:scheme="wxd31ef1f4dd******"/&
&/intent-filter&
&/activity&
&activity android:name=".AlipayH5Activity"&&/activity&
&activity android:name="com.*******.paydemo.wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop"&
&/activity&&/span&Activity部分的逻辑代码:IWXAPI api = WXAPIFactory.createWXAPI(MainActivity.this, null);//通过工厂创建对象
api.registerApp(ConstUtil.APP_ID);
PayReq request = new PayReq();
request.appId = ConstUtil.APP_ID;
request.partnerId = ConstUtil.PARTNER_ID;
request.prepayId = wxPrepayEntity.getPrepay_id();
request.nonceStr = wxPrepayEntity.getReq_noncestr();
request.timeStamp = wxPrepayEntity.getReq_timestamp();
request.packageValue = wxPrepayEntity.getReq_package();
request.sign = wxPrepayEntity.getReq_sign();
request.extData = "app data"; // optional
// 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信
api.sendReq(request);每一个参数都很关键的,如果签名和包名确定都没有问题,那么基本上是传递的参数有问题。最好跟做后台的同事一起看看就能解决问题。比如partnerId传错了就会出现签名错误,再比如timeStamp,你用了自定义的时间戳与服务器的不一致,也会出现错误。排查错误最好把sign这个字段的值打印出来,与服务器生成的信息做比较,参数值没有问题才会不出问题!1.第一种原因就是上边的这些参数有问题。一般都是秘钥有问题。需自己登陆商家版后台修改
2.需要知道支付是需要打包才能运行。这也是蛋疼的一点,测试只能通过log和Toast来推断。掉不起来可以去微信开放平台看自己配置的参数是否正确。3.微信支付跟支付宝支付不一样。微信支付同一订单不会第二次跳到支付页面 提示支付失败,同一订单第二次支付的时候直接在请求遇支付订单的时候就会返回preayid为空。所以童鞋们应该在吊起支付这一步判断一下 ,比较服务器很容易出错导致订单状态没有改,让用户一直付款。4.无法接受回调结果是因为微信规定接受支付那个类的必须在manifest里配置的包名+.wxapi里
所以这也是比较蛋疼的一点。5.微信支付支付过的订单再次获取prepare_id为null 无法掉起支付。6. 微信支付同一订单只能绑定一个价格 列如:
33订单最初的价格为1,这是获取prepareid可以获取到值,如果对33的价格进行修改,如果没有生成过预支付订单可以获取,如果已经生成过则获取到的prepareid为null
不可以调起支付Android快速实现微信支付如果你已经成功集成了微信登录和分享,那么此文将助你快速集成微信支付,此文基于微信支付SDK3.1.1,也就是目前为止最新的SDK资源下载不过我相信,即便你看了微信的官方文档,你依然不知道微信支付怎么集成,因为微信支付的官方文档简直太.....如果你已经准备好了资源包,接下来正式开始集成我们需要的资源其实有以下几样,在开始前,就这些转备好吧1)微信支付的APPID2)微信支付依赖包 &&& libammsdk.jar3)一个Activity类 &&& WXPayEntryActivity.java这里需要特别说明一下,这个Activity类,直接从上下载到的范例代码中copy到自己的工程中即可,这个页面是在你调起微信支付完成支付(或取消或失败)后,再回到你的App时会调用的一个页面。页面的布局可以是你自定义的布局,直接放图讲解:先说一下这个类的路径,网上也有一大堆介绍了,我直接放图,路径一定,而且必须是这样的:WXPayEntryActivity 的路径在这个类中需要注意的地方有两个:1、这个类中的布局是可以自定义的,如果你不需要展示什么布局,而是要跳转页面,把这段代码删除即可回调页面的布局2、回调结果的处理,下面是官方的处理方式,直接给了一个dialog,很多人会摸不着头脑,如果你不需要这个dialog,直接删除就好了,不需要把官方demo中的布局和资源都复制过来官方的处理方式下面是我自定义的处理方式,比较简单,就是土司显示了一下支付结果,如果你需要支付成功后跳转,那么直接在这里startActivity即可,别忘记最后要将这个页面finish()自定义的处理方式这个类中的其余的回调方法,我们都不需要去操作然后我们就可以开始支付了,支付很简单,真的很简单参数列表这是微信支付需要我们携带的参数,对于新人来说,可能比较困惑的是我怎么生成这些参数呢?其实这些参数都是服务器返回给我们的,APPID我们可以自己保存在本地一份,其余的都是服务器返回给我们的,大概介绍一下流程:发起支付的流程,提交订单的时候的参数根据项目需要配置最后,服务器返回给我们微信支付的参数后,我们就可以愉快的支付了,这里是关键一步,注意!!发起支付的关键步骤至此我们已经可以调起微信支付页面来支付了最后还有一个需要注意的是,很多人被这一步坑了,就是关于微信开放平台签名的问题。其实只要你手机上的程序的签名和你在微信平台登记的签名一致即可,无论是debug版本,还是release版本参考文章:http://www.jianshu.com/p/ce
文章:68篇
阅读:652202
文章:28篇
阅读:127363}

我要回帖

更多关于 android 微信支付 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信