如何对 微信支付签名验证工具 结果通知的内容做 签名验证

Pages: 1/2
主题 : 微信支付怎么在前端签名
级别: 侠客
可可豆: 302 CB
威望: 302 点
在线时间: 227(时)
发自: Web Page
来源于&&分类
微信支付怎么在前端签名&&&
微信支付签名怎么在前端生成????PayReq *request = [[PayReq alloc] init];&&&&/** 商家向财付通申请的商家id */&&&&request.partnerId = @&&;&&&&/** 预支付订单这个是后台跟微信服务器交互后,微信服务器传给你们服务器的,你们服务器再传给你 */&&&&request.prepayId= @&c4c063c30&;&&&&/** 这个比较特殊,是固定的,只能是即request.package = Sign=WXPay */&&&&request.package = @&Sign=WXPay&;&&&&/** // 随机编码,为了防止重复的,在后台生成 */&&&&request.nonceStr= @&lUu5qloVJV7rrJlr&;&&&&/** 这个是时间戳,也是在后台生成的,为了验证支付的 */&&&&NSString * stamp = @&&;&&&&request.timeStamp = stamp.intV&&&&/** 商家根据微信开放平台文档对数据做的签名 */&&&&request.sign= @&b640c1a6f4d34b8a9e&;&&&&[WXApi sendReq: request];
级别: 侠客
可可豆: 135 CB
威望: 134 点
在线时间: 304(时)
发自: Web Page
回 楼主(源于舞客) 的帖子
最好放到后台来做,demo中有详细的签名方法
级别: 新手上路
UID: 535961
可可豆: 208 CB
威望: 157 点
在线时间: 179(时)
发自: Web Page
回 楼主(源于舞客) 的帖子
如果后台返给你的签名没有经过二次加密,你需要将你所有的信息再加一次密,将得到的加密信息赋给request.sign,然后发起支付
图片:粘贴图片.png
级别: 新手上路
UID: 535961
可可豆: 208 CB
威望: 157 点
在线时间: 179(时)
发自: Web Page
这个做过很久了,不知道现在微信有没有对这个更改过
级别: 侠客
UID: 525976
可可豆: 162 CB
威望: 151 点
在线时间: 176(时)
发自: Web Page
楼主怎么做的,求分享
级别: 新手上路
可可豆: 66 CB
威望: 66 点
在线时间: 523(时)
发自: Web Page
可以的,自己生成一些模拟数据,用postman调用接口,模拟后台就行。关键是获得 partnerId。
级别: 骑士
UID: 543193
可可豆: 443 CB
威望: 443 点
在线时间: 297(时)
发自: Web Page
前端不安全,交给后台,方便自己。
级别: 侠客
可可豆: 302 CB
威望: 302 点
在线时间: 227(时)
发自: Web Page
-(void)touchPlayWXChat:(NSDictionary *)dict{&&&&//传额外字符串attach&&&&WXpayRequsestHandler *handle = [[WXpayRequsestHandler alloc]init];&&&&if ( [handle&&init:@&wx*****& mch_id:@&******&]) {&&&&&&&&NSLog(@&初始化成功&);&&&&}&&&&//设置商户密钥&&&&[handle setKey:@&*******&];&&&&//提交预支付,获得prepape_id&&&&NSString *order_name = dict[@&title&];&& //订单标题&&&&NSString * priceStr = [NSString stringWithFormat:@&%f&,[dict[@&cost&] floatValue]*100];&&&&NSString *order_price = [NSString stringWithFormat:@&%d&,[priceStr intValue]];//测试价格 分为单位&&&&NSString *nocify_URL = @&http://。。。。。。。&;&&&&//回调借口&&&&NSString *noncestr&&= [NSString stringWithFormat:@&%d&, rand()]; //随机串&&&&NSString *orderno&& = [NSString stringWithFormat:@&%@&,dict[@&order_num&]];&&&&NSMutableDictionary *params = [@{@&appid&:@&wx*****&,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& @&mch_id&:@&*****&,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& @&device_info&:[[[UIDevice currentDevice] identifierForVendor] UUIDString],&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& @&nonce_str&:noncestr,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& @&trade_type&:@&APP&,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& @&body&:order_name,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& @&notify_url&:nocify_URL,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& @&out_trade_no&:orderno,//商户订单号:这个必须用后台的订单号&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& @&spbill_create_ip&:@&8.8.8.8&,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& @&attach&:@&running&,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& @&total_fee&:order_price}mutableCopy];&&&&&&&&//提交预支付两次签名得到预支付订单的id(每次的请求得到的预支付订单id都不同)&&&&NSString *prepate_id = [handle sendPrepay:params];&&&&if (prepate_id != nil)&&&&{&&&&&&&&PayReq *request = [[PayReq alloc] init];&&&&&&&&/** 商家向财付通申请的商家id */&&&&&&&&request.partnerId = @&*****&;&&&&&&&&/** 预支付订单这个是后台跟微信服务器交互后,微信服务器传给你们服务器的,你们服务器再传给你 */&&&&&&&&request.prepayId= prepate_&&&&&&&&/** 这个比较特殊,是固定的,只能是即request.package = Sign=WXPay */&&&&&&&&request.package = @&Sign=WXPay&;&&&&&&&&/** // 随机编码,为了防止重复的,在后台生成 */&&&&&&&&request.nonceStr=&&&&&&&&/** 这个是时间戳,也是在后台生成的,为了验证支付的 */&&&&&&&&request.timeStamp = (UInt32)[[NSDate date] timeIntervalSince1970];&&&&&&&&/** 商家根据微信开放平台文档对数据做的签名wx***** */&&&&&&&&request.sign = [self createMD5SingForPay:@&wx****& partnerid:@&****& prepayid:request.prepayId package:@&Sign=WXPay& noncestr:request.nonceStr timestamp:(UInt32)[[NSDate date] timeIntervalSince1970]];&&&&&&&&/*! @brief 发送请求到微信,等待微信返回onResp&&&&&&&& *&&&&&&&& * 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。支持以下类型&&&&&&&& * SendAuthReq、SendMessageToWXReq、PayReq等。&&&&&&&& * @param req 具体的发送请求,在调用函数后,请自己释放。&&&&&&&& * @return 成功返回YES,失败返回NO。&&&&&&&& */&&&&&&&&//带起微信支付&&&&&&&&if ([WXApi sendReq:request]) {&&&&&&&&&&&&&&&&&&&&}else{&&&&&&&&&&&&//NSLog(@&走之类&);&&&&&&&&&&&&//未安装微信客户端&&&&&&&&&&&&[[[UIAlertView alloc]initWithTitle:@&微信支付& message:@&微信支付出错& delegate:nil cancelButtonTitle:@&知道了& otherButtonTitles:nil, nil]show];&&&&&&&&}&&&&}&&&&else&&&&{&&&&&&&&[OMGToast showWithText:@&该订单过期,请重新下单& bottomOffset:3 duration:2];&&&&}}#pragma mark -&&微信支付本地签名-(NSString *)createMD5SingForPay:(NSString *)appid_key partnerid:(NSString *)partnerid_key prepayid:(NSString *)prepayid_key package:(NSString *)package_key noncestr:(NSString *)noncestr_key timestamp:(UInt32)timestamp_key{&&&&NSMutableDictionary *signParams = [NSMutableDictionary dictionary];&&&&[signParams setObject:appid_key forKey:@&appid&];&&&&[signParams setObject:noncestr_key forKey:@&noncestr&];&&&&[signParams setObject:package_key forKey:@&package&];&&&&[signParams setObject:partnerid_key forKey:@&partnerid&];&&&&[signParams setObject:prepayid_key forKey:@&prepayid&];&&&&[signParams setObject:[NSString stringWithFormat:@&%u&,(unsigned int)timestamp_key] forKey:@&timestamp&];&&&&NSMutableString *contentString&&=[NSMutableString string];&&&&NSArray *keys = [signParams allKeys];&&&&//按字母顺序排序&&&&NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {&&&&&&&&return [obj1 compare:obj2 options:NSNumericSearch];&&&&}];&&&&//拼接字符串&&&&for (NSString *categoryId in sortedArray) {&&&&&&&&if (&& ![[signParams objectForKey:categoryId] isEqualToString:@&&]&&&&&&&&&&&&&& ![[signParams objectForKey:categoryId] isEqualToString:@&sign&]&&&&&&&&&&&&&& ![[signParams objectForKey:categoryId] isEqualToString:@&key&]&&&&&&&&&&&&)&&&&&&&&{&&&&&&&&&&&&[contentString appendFormat:@&%@=%@&&, categoryId, [signParams objectForKey:categoryId]];&&&&&&&&}&&&&}&&&&//添加商户密钥key字段&&&&[contentString appendFormat:@&key=%@&,@&*************&];&&&&NSString *result = [self md5:contentString];&&&&&&&&}//创建发起支付时的sige签名-(NSString *)md5:(NSString *)str{&&&&const char *cStr = [str UTF8String];&&&&unsigned char result[16]= &abcdef&;&&&&CC_MD5(cStr, (CC_LONG)strlen(cStr), result);&&&&//这里的x是小写则产生的md5也是小写,x是大写则md5是大写,这里只能用大写,微信的大小写验证很逗&&&&return [NSString stringWithFormat:&&&&&&&&&&&&@&%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X&,&&&&&&&&&&&&result[0], result[1], result[2], result[3],&&&&&&&&&&&&result[4], result[5], result[6], result[7],&&&&&&&&&&&&result[8], result[9], result[10], result[11],&&&&&&&&&&&&result[12], result[13], result[14], result[15]&&&&&&&&&&&&];}//MD5 加密
级别: 侠客
可可豆: 302 CB
威望: 302 点
在线时间: 227(时)
发自: Web Page
代码在这,可以正常支付,好像订单会过期,今天订单不支付,明天支付好像支付不了!&&如果下单过几个小时还可以支付
级别: 新手上路
UID: 578325
可可豆: 103 CB
威望: 71 点
在线时间: 126(时)
发自: Web Page
直接谷歌一下不就知道了。我也是菜鸟,但是有谷歌什么都不怕。我当时就先在我这边加密的签名,测试成功了。后来还是在后台加密了。这篇文章讲的不错,还有Demo:
Pages: 1/2
关注本帖(如果有新回复会站内信通知您)
苹果公司现任CEO是谁?2字 正确答案:库克
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版开发过程中可能遇到 异步通知页面签名无法通过;那么原因何在呢?
我直说我碰到的这个
  先看我错误时候微信回馈的xml
&xml&&appid&&![CDATA[wx3a542a6f]]&&/appid&
&bank_type&&![CDATA[CFT]]&&/bank_type&
&cash_fee&&![CDATA[1]]&&/cash_fee&
&fee_type&&![CDATA[CNY]]&&/fee_type&
&is_subscribe&&![CDATA[Y]]&&/is_subscribe&
&mch_id&&![CDATA[]]&&/mch_id&
&nonce_str&&![CDATA[m8iidgrc2ng2hd25xh3uywhzdtlimt8b]]&&/nonce_str&
&openid&&![CDATA[oc8rujitiX4ghHtvP57WvQQW4-UA]]&&/openid&
&out_trade_no&&![CDATA[wx3a542a6f]]&&/out_trade_no&
&result_code&&![CDATA[SUCCESS]]&&/result_code&
&return_code&&![CDATA[SUCCESS]]&&/return_code&
&sign&&![CDATA[EACCCADF43AB0F16C711C]]&&/sign&
&time_end&&![CDATA[25]]&&/time_end&
&token&&![CDATA[oksiyy]]&&/token&
&total_fee&1&/total_fee&
&trade_type&&![CDATA[JSAPI]]&&/trade_type&
&transaction_id&&![CDATA[2510]]&&/transaction_id&
正确时候的:
&xml&&appid&&![CDATA[wx3a542a6f]]&&/appid&
&bank_type&&![CDATA[CFT]]&&/bank_type&
&cash_fee&&![CDATA[1]]&&/cash_fee&
&fee_type&&![CDATA[CNY]]&&/fee_type&
&is_subscribe&&![CDATA[Y]]&&/is_subscribe&
&mch_id&&![CDATA[]]&&/mch_id&
&nonce_str&&![CDATA[e824na6v3q0zobi92ahjxwcrfbfzu7fs]]&&/nonce_str&
&openid&&![CDATA[oc8rujitiX4ghHtvP57WvQQW4-UA]]&&/openid&
&out_trade_no&&![CDATA[wx3a542a6f]]&&/out_trade_no&
&result_code&&![CDATA[SUCCESS]]&&/result_code&
&return_code&&![CDATA[SUCCESS]]&&/return_code&
&sign&&![CDATA[EA530F09FF5]]&&/sign&
&time_end&&![CDATA[39]]&&/time_end&
&total_fee&1&/total_fee&
&trade_type&&![CDATA[JSAPI]]&&/trade_type&
&transaction_id&&![CDATA[4065]]&&/transaction_id&
其实最后问题的关键就在于那个token 参数;
问题就出在:回调连接带了个参数;
$unifiedOrder-&setParameter("notify_url","/wxpay/pay/utils/notify_url.php?token=$token");//通知地址
我带了个参数;结果微信就把他好好的放在了xml中;但是签名就是随你怎么走都无法通过。
所以请保证回调参数不要加上任何参数;
阅读(...) 评论()其他回答(3)
园豆:2762
你咋解决的 我也遇见这问题了 &统一下下单成功 然后提交订单 先提示支付成功 然后又提示 支付验证签名失败
亲, 你怎么解决, chooseWXPay中的paySign到底是怎么个签名, 求指教
&&&您需要以后才能回答,未注册用户请先。坑你没商量之c#微信回调中核实订单的签名验证 - 博客频道 - CSDN.NET
阿灿的专栏
未来,是做出来的,不是说出来的
分类:MVCasp/.net
&&&&&&& 最近公司app项目的开发,有幸参与到该项目中,并且由我独立负责服务端的开发。本文主要讲下在微信回调开发遇到的问题以及解决方案!而在前端开发方面都是由另外一位同事主导,我只负责返回请求参数,因此这里不做讨论。说到这里不得不吐槽下微信文档的说明,大部分都是云里雾里的。
&&&&& 首先从官方开放平台下载服务端c#开发sdk文件。然后找到里头一个 “支付结果通知回调处理类” ResultNotify.cs文件。主要处理流程都在下面这个方法里头。从这个方法里头衍生出其他的方法来。
&&&&& 本来只有一个应用的话,也是不必要在来发文章讨论的,直接跟着sdk写好的方法走就成,但是我们项目最终是要有两个app的,也因此申请了两个微信移动应用,充值分别充入对应的商户里头。官方文档表明了 “通知url必须为直接可访问的url,不能携带参数。示例:notify_url:“https://pay./wxpay/pay.action”” 因此这导致回调都是分开的。一开始我想要直接使用一个配置文件【config.cs】,但是验证一直通不过。最后没办法,只得分开了两份代码,都具备各自的配置文件和其他方法。
&&& 后来实在想不通,既然他的config.cs可以通过WxPayData进行重新赋值,没道理需要分开写。因此为了测试,我把以前充值的单号找出来,重新写了两个查询订单的方法,反复写测试返回参数比对查看。最终才发现问题的关键。
&&&&& 1、首先不得不说下官方封装的HttpService.Post(xml, url, false, timeOut)//调用HTTP通信接口提交数据
&&&&&&&&&&&&&&&&&&&&&&& 图片1 config.cs
&&&&&&&&&&&&&&&&&&&&&&&&&& 图片2 HttpService.cs
你说你这里晓得传递一个证书验证启用开关,怎么代理服务器的设置,就不晓得也整个开关,让我们自由选择呢。
结果我每次运行这个方法就提示超时。刚开始也没明白怎么整,直接找到config.cs的PROXY_URL端口配置为自己项目的服务器端口【/*默认IP和端口号分别为0.0.0.0和0,此时不开启代理(如有需要才设置)*/官方文档里头的注释,关键你这里写不开启,可是怎么到了方法里头默认的竟然是开启的,而且一点说明都木有!!】还是不行,都要疯了,大量查阅资料,终于找到有网友提出的解决方案,直接把这几行代码注释掉。
&&&&& 2、是在验证签名过程,这还在自己本身,文档没有阅读仔细,
一开始以为签名都只需要【appid、mch_id、nonce_str、transaction_id+key】的,然后我在MakeSign()方法里头直接封装str参数串,在运行,返回的还是签名错误。
没办法只得在重写下几个用到的方法,然后到处打印出字符串,最后才发现在我们从远程获取到正确的数据后,是整个对象里头的参数都又进行了签名的。【appid、bank_type、cash_fee、fee_type......transaction_id+key】,然后又回头去看官网,文档里头提示 “微信接口可能增加字段,验证签名时必须支持增加的扩展字段”。果然文档提示的都要小心要注意!!
&&&&& 最后,我想到的方案是修改MakeSign(string key)增加个key秘钥的传递。因为远程返回的xml里头都有appid和mch_id,因此只要稍微调整几个方法即可。完整代码如下:
//回调方法
public string Wx_Notify_url()
string logid = Guid.NewGuid().ToString();
const string key=&......&;//(获取商户api秘钥 )//////重点是这里这里这里,两个回调这里的key对应的是商户里头设置的秘钥 这里是常量常量常量
//对返回的支付结果通知的内容做签名验证
WxPayAPI.WxPayData notifyData = GetNotifyData(key);
//检查支付结果中transaction_id是否存在
if (!notifyData.IsSet(&transaction_id&))
//若transaction_id不存在,则立即返回结果给微信支付后台
WxPayAPI.WxPayData res = new WxPayAPI.WxPayData();
res.SetValue(&return_code&, &FAIL&);
res.SetValue(&return_msg&, &支付结果中微信订单号不存在&);
//Log.Error(this.GetType().ToString(), &The Pay result is error : & + res.ToXml());
return res.ToXml();
string transaction_id = notifyData.GetValue(&transaction_id&).ToString();
//先写入记事本对账
if (transaction_id != &&) {
//写入记事本
DbHelperSQL.ExecuteSql(&insert into [log] values('& + logid + &', 'transaction_id: & + transaction_id + &, 订单号:& + notifyData.GetValue(&out_trade_no&).ToString() + &', getdate(), 'wx')&);
//支付结果中查询订单,判断订单真实性
判断条件!QueryOrder(transaction_id)
不判断transaction_id == &&
if (!QueryOrder(transaction_id, notifyData, key))
//若订单查询失败,则立即返回结果给微信支付后台
WxPayAPI.WxPayData res = new WxPayAPI.WxPayData();
res.SetValue(&return_code&, &FAIL&);
res.SetValue(&return_msg&, &订单查询失败&);
return res.ToXml();
//查询订单成功
//业务逻辑处理start...
//////////////////////////////////////////////////////////////
//更改订单状态
if(.....){
//插入币值记录
/////////////////////////////////////////////////////////////
//业务逻辑处理end...
WxPayAPI.WxPayData res = new WxPayAPI.WxPayData();
res.SetValue(&return_code&, &SUCCESS&);
res.SetValue(&return_msg&, &OK&);
return res.ToXml();
/// &summary&
/// 接收从微信支付后台发送过来的数据并验证签名
/// &/summary&
/// &returns&微信支付后台返回的数据&/returns&
private WxPayAPI.WxPayData GetNotifyData(string KEY)
//接收从微信后台POST过来的数据
System.IO.Stream s = Request.InputS
int count = 0;
byte[] buffer = new byte[1024];
StringBuilder builder = new StringBuilder();
while ((count = s.Read(buffer, 0, 1024)) & 0)
builder.Append(Encoding.UTF8.GetString(buffer, 0, count));
s.Flush();
s.Close();
s.Dispose();
//(this.GetType().ToString(), &Receive data from WeChat : & + builder.ToString());
//转换数据格式并验证签名
WxPayAPI.WxPayData data = new WxPayAPI.WxPayData();
data.FromXml(builder.ToString(), KEY);
catch (WxPayAPI.WxPayException ex)
//若签名错误,则立即返回结果给微信支付后台
WxPayAPI.WxPayData res = new WxPayAPI.WxPayData();
res.SetValue(&return_code&, &FAIL&);
res.SetValue(&return_msg&, ex.Message);
//Log.Error(this.GetType().ToString(), &Sign check error : & + res.ToXml());
Response.Write(res.ToXml());
//(this.GetType().ToString(), &Check sign success&);
//查询订单
这里我重写了下,把远程返回的data和加密key直接传入
public bool QueryOrder(string transaction_id, WxPayData inputObj, string key)
WxPayAPI.WxPayData req = new WxPayAPI.WxPayData();
//增加对req进行赋值//////////////////////////////////////
req.SetValue(&appid&, inputObj.GetValue(&appid&));
req.SetValue(&mch_id&, inputObj.GetValue(&mch_id&));
req.SetValue(&key&, key);
////////////////////////////////////////////////////////
req.SetValue(&transaction_id&, transaction_id);
WxPayAPI.WxPayData res = WxPayAPI.WxPayApi.OrderQuery(req);
if (res.GetValue(&return_code&).ToString() == &FAIL&)
if (res.GetValue(&return_code&).ToString() == &SUCCESS& &&
res.GetValue(&result_code&).ToString() == &SUCCESS&)
&&&& 然后,在QueryOrder()方法里头进行一些列sign验证,只要把这几个方法在重新调整下,即可!修改WxPayApi文件:
using System.Collections.G
using System.W
using System.N
using System.IO;
using System.T
namespace WxPayAPI
public class WxPayApi
* 查询订单
* @param WxPayData inputObj 提交给查询订单API的参数
* @param int timeOut 超时时间
* @throws WxPayException
* @return 成功时返回订单查询结果,其他抛异常
public static WxPayData OrderQuery(WxPayData inputObj, int timeOut = 6)
string url = &https://api.mch./pay/orderquery&;
//检测必填参数
if (!inputObj.IsSet(&out_trade_no&) && !inputObj.IsSet(&transaction_id&))
throw new WxPayException(&订单查询接口中,out_trade_no、transaction_id至少填一个!&);
//1、我这里定义了临时WxPayData对象,因为inputObj把key也装进去了,而这里签名并不需要key,不然会出错,而且这个key是要到处使用的,
//2、另外的解决方法就是string key = inputObj.GetValue(&KEY&).ToString();
然后移除key值,不过微信 WxPayData对象并没有封装这个方法,Directory字典有内部方法可以使用【m_values.Remove(&key&);//这里就可以直接根据他们文档来写个方法了】,偷懒了下,我选择方案1
WxPayData tmp = new WxPayData();
tmp.SetValue(&transaction_id&, inputObj.GetValue(&transaction_id&));
tmp.SetValue(&appid&, inputObj.GetValue(&appid&));//公众账号ID
tmp.SetValue(&mch_id&, inputObj.GetValue(&mch_id&));//商户号
tmp.SetValue(&nonce_str&, WxPayApi.GenerateNonceStr());//随机字符串
tmp.SetValue(&sign&, tmp.MakeSign(inputObj.GetValue(&key&).ToString()));//签名
string xml = tmp.ToXml();
var start = DateTime.N
Log.Debug(&WxPayApi&, &OrderQuery request : & + xml);
string response = HttpService.Post(xml, url, false, timeOut);//调用HTTP通信接口提交数据
Log.Debug(&WxPayApi&, &OrderQuery response : & + response);
var end = DateTime.N
int timeCost = (int)((end - start).TotalMilliseconds);//获得接口耗时
//将xml格式的数据转化为对象以返回
WxPayData result = new WxPayData();
result.FromXml(response, inputObj.GetValue(&key&).ToString());//这里增加传递秘钥key
ReportCostTime(url, timeCost, result, inputObj.GetValue(&key&).ToString());//测速上报
//不知道这个注销有没有影响,这个倒是没测
* 测速上报
* @param string interface_url 接口URL
* @param int timeCost 接口耗时
* @param WxPayData inputObj参数数组
private static void ReportCostTime(string interface_url, int timeCost, WxPayData inputObj, string key)
//如果不需要进行上报
if(WxPayConfig3.REPORT_LEVENL == 0)
//如果仅失败上报
if(WxPayConfig3.REPORT_LEVENL == 1 && inputObj.IsSet(&return_code&) && inputObj.GetValue(&return_code&).ToString() == &SUCCESS& &&
inputObj.IsSet(&result_code&) && inputObj.GetValue(&result_code&).ToString() == &SUCCESS&)
//上报逻辑
WxPayData3 data = new WxPayData3();
data.SetValue(&interface_url&,interface_url);
data.SetValue(&execute_time_&,timeCost);
//返回状态码
if(inputObj.IsSet(&return_code&))
data.SetValue(&return_code&,inputObj.GetValue(&return_code&));
//返回信息
if(inputObj.IsSet(&return_msg&))
data.SetValue(&return_msg&,inputObj.GetValue(&return_msg&));
//业务结果
if(inputObj.IsSet(&result_code&))
data.SetValue(&result_code&,inputObj.GetValue(&result_code&));
//错误代码
if(inputObj.IsSet(&err_code&))
data.SetValue(&err_code&,inputObj.GetValue(&err_code&));
//错误代码描述
if(inputObj.IsSet(&err_code_des&))
data.SetValue(&err_code_des&,inputObj.GetValue(&err_code_des&));
//商户订单号
if(inputObj.IsSet(&out_trade_no&))
data.SetValue(&out_trade_no&,inputObj.GetValue(&out_trade_no&));
if(inputObj.IsSet(&device_info&))
data.SetValue(&device_info&,inputObj.GetValue(&device_info&));
Report(data, key);///增加key值
catch (WxPayException ex)
//不做任何处理
* 测速上报接口实现
* @param WxPayData inputObj 提交给测速上报接口的参数
* @param int timeOut 测速上报接口超时时间
* @throws WxPayException
* @return 成功时返回测速上报接口返回的结果,其他抛异常
public static WxPayData Report(WxPayData inputObj, string key, int timeOut = 1)
string url = &https://api.mch./payitil/report&;
//检测必填参数
if(!inputObj.IsSet(&interface_url&))
throw new WxPayException(&接口URL,缺少必填参数interface_url!&);
if(!inputObj.IsSet(&return_code&))
throw new WxPayException(&返回状态码,缺少必填参数return_code!&);
if(!inputObj.IsSet(&result_code&))
throw new WxPayException(&业务结果,缺少必填参数result_code!&);
if(!inputObj.IsSet(&user_ip&))
throw new WxPayException(&访问接口IP,缺少必填参数user_ip!&);
if(!inputObj.IsSet(&execute_time_&))
throw new WxPayException(&接口耗时,缺少必填参数execute_time_!&);
inputObj.SetValue(&appid&,WxPayConfig3.APPID);//公众账号ID
inputObj.SetValue(&mch_id&,WxPayConfig3.MCHID);//商户号
inputObj.SetValue(&user_ip&,WxPayConfig3.IP);//终端ip
inputObj.SetValue(&time&,DateTime.Now.ToString(&yyyyMMddHHmmss&));//商户上报时间
inputObj.SetValue(&nonce_str&,GenerateNonceStr());//随机字符串
inputObj.SetValue(&sign&, inputObj.MakeSign(key));//签名
string xml = inputObj.ToXml();
(&WxPayApi&, &Report request : & + xml);
string response = HttpService.Post(xml, url, false, timeOut);
(&WxPayApi&, &Report response : & + response);
WxPayData result = new WxPayData();
result.FromXml(response, key);///增加key值
&&& 然后,修改Data.cs文件:
* @将xml转为WxPayData对象并返回对象内部的数据
* @param string 待转换的xml串
* @return 经转换得到的Dictionary
* @throws WxPayException
public SortedDictionary&string, object& FromXml(string xml, string key/*传递秘钥*/)
if (string.IsNullOrEmpty(xml))
Log.Error(this.GetType().ToString(), &将空的xml串转换为WxPayData不合法!&);
throw new WxPayException(&将空的xml串转换为WxPayData不合法!&);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
XmlNode xmlNode = xmlDoc.FirstC//获取到根节点&xml&
XmlNodeList nodes = xmlNode.ChildN
foreach (XmlNode xn in nodes)
XmlElement xe = (XmlElement)
m_values[xe.Name] = xe.InnerT//获取xml的键值对到WxPayData内部的数据中
// 错误是没有签名
if (m_values[&return_code&].ToString() != &SUCCESS&)
CheckSign(key);//验证签名,不通过会抛异常
//在把秘钥传入验证签名的方法里头
catch (WxPayException ex)
throw new WxPayException(ex.Message);
        *
        * 检测签名是否正确
        * 正确返回true,错误抛异常
        */
        public bool CheckSign(string key)
        {
            //如果没有设置签名,则跳过检测
            if (!IsSet(&sign&))
            {
               Log.Error(this.GetType().ToString(), &WxPayData签名存在但不合法!&);
               throw new WxPayException(&WxPayData签名存在但不合法!&);
            }
            //如果设置了签名但是签名为空,则抛异常
            else if(GetValue(&sign&) == null || GetValue(&sign&).ToString() == &&)
            {
                Log.Error(this.GetType().ToString(), &WxPayData签名存在但不合法!&);
                throw new WxPayException(&WxPayData签名存在但不合法!&);
            }
            //获取接收到的签名
            string return_sign = GetValue(&sign&).ToString();
            //在本地计算新的签名
            string cal_sign = MakeSign(key);//生成sign直接使用传入的key值,而不是config.cs配置好的默认的key值
            if (cal_sign == return_sign)
            {
               
            }
            Log.Error(this.GetType().ToString(), &WxPayData签名验证错误!&);
            throw new WxPayException(&WxPayData签名验证错误!&);
        }
        * @生成签名,详见签名生成算法
        * @return 签名, sign字段不参加签名
        */
        public string MakeSign(string key)
        {
            //转url格式
            string str = ToUrl();
            //在string后加入API KEY
            //str += &&key=& + WxPayConfig.KEY;//不适用写好的方法
            str += &&key=& +
            //MD5加密
            var md5 = MD5.Create();
            var bs = puteHash(Encoding.UTF8.GetBytes(str));
            var sb = new StringBuilder();
            foreach (byte b in bs)
            {
                sb.Append(b.ToString(&x2&));
            }
            //所有字符转为大写
            return sb.ToString().ToUpper();
        }
&&&&& 最后,补充下上面OrderQuery()说的方案二删除key的方法,已经测试过,有效!!
//这个是WxPayApi.cs的调整
string key = inputObj.GetValue(&KEY&).ToString();
inputObj.RemoveTkey(&KEY&);
//Data.cs文件增加方法RemoveTkey
       
* 根据字段名删除某个字段的值
       
* @param key 字段名
         * @return key对应的字段值
    
    */
       
public bool RemoveTkey(string Tkey)
       
           
bool e = m_values.Remove(Tkey);
           
        }
&&&&&&& 经测试,返回参数如下:
排名:千里之外
(42)(21)(3)(3)(3)(1)(16)(6)(2)}

我要回帖

更多关于 微信支付验证签名错误 的文章

更多推荐

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

点击添加站长微信