微信支付签名验证失败 jsapi支付验证签名是什么机制

微信支付-加密、解密参数。验证签名方法。
时间: 10:54:21
&&&& 阅读:2675
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&微信并没有给ASP.net用户提供一个很好的实例,只好苦心研究,经过一个下午的努力和N次测试,终于知道如何解密和验签nofify的数据了,以下是我实现的代码,好东西需分享给各位朋友:(以下的商户编号我已经修改过,所以没有返回true,请根据自己的实际数据测试)
using&System.Collections.G
using&System.L
using&System.W
using&System.D
using&System.Drawing.I
using&System.IO;
using&System.Drawing.Drawing2D;
using&Ganxike.B
using&Ganxike.E
using&System.T
using&System.Security.C
namespace&Ganxike.Front
&&&&public&partial&class&Test : System.Web.UI.Page
&&&&&&&&protected&void&Page_Load(object&sender, EventArgs e)
&&&&&&&&&&&&//bank_billno:057579
&&&&&&&&&&&&//bank_type:2011 //付款银行代号
&&&&&&&&&&&&//discount:0 //折扣价格(如果有)
&&&&&&&&&&&&//fee_type:1 //币种
&&&&&&&&&&&&//input_charset:GBK //编码字符
&&&&&&&&&&&&//notify_id:cEBCIhJpi4A6JrwjzYjarrY4-y04msE2T7Ixq0U19wcntbPlOXrtshGlKcEhGsN-uC78fnIcPi6mIFpl2UfDxW3R1yPv7yRQ //通知ID
&&&&&&&&&&&&//out_trade_no: //商户订单号
&&&&&&&&&&&&//partner: //商户号
&&&&&&&&&&&&//product_fee:1 //物品费用(分)
&&&&&&&&&&&&//sign:E59DC7FA49FEC3CE0D1C3 //签名
&&&&&&&&&&&&//sign_type:MD5 //签名方式
&&&&&&&&&&&&//time_end:33 //支付完成时间
&&&&&&&&&&&&//total_fee:1 //总金额(分)
&&&&&&&&&&&&//trade_mode:1 //交易模式(1即时到帐)
&&&&&&&&&&&&//trade_state:0 //交易状态(0成功)
&&&&&&&&&&&&//transaction_id:5338 //订单号
&&&&&&&&&&&&//transport_fee:0 //物流费用
&&&&&&&&&&&&Dictionary&string,&string& parameters =&new&Dictionary&string,&string&();
&&&&&&&&&&&&parameters.Add("bank_billno",&"057579");
&&&&&&&&&&&&parameters.Add("bank_type",&"2011");
&&&&&&&&&&&&parameters.Add("discount",&"0");
&&&&&&&&&&&&parameters.Add("fee_type",&"1");
&&&&&&&&&&&&parameters.Add("input_charset",&"GBK");
&&&&&&&&&&&&parameters.Add("notify_id",&"cEBCIhJpi4A6JrwjzYjarrY4-y04msE2T7Ixq0U19wcntbPlOXrtshGlKcEhGsN-uC78fnIcPi6mIFpl2UfDxW3R1yPv7yRQ");
&&&&&&&&&&&&parameters.Add("out_trade_no",&"");
&&&&&&&&&&&&parameters.Add("partner",&"");
&&&&&&&&&&&&parameters.Add("product_fee",&"1");
&&&&&&&&&&&&parameters.Add("sign_type",&"MD5");
&&&&&&&&&&&&parameters.Add("time_end",&"33");
&&&&&&&&&&&&parameters.Add("total_fee",&"1");
&&&&&&&&&&&&parameters.Add("trade_mode",&"1");
&&&&&&&&&&&&parameters.Add("trade_state",&"0");
&&&&&&&&&&&&parameters.Add("transaction_id",&"5338");
&&&&&&&&&&&&parameters.Add("transport_fee",&"0");
&&&&&&&&&&&&//将所有参数按Key字母排序
&&&&&&&&&&&&string&content = GetSignContent(parameters);
&&&&&&&&&&&&Response.Write(VerifySignature(content,&"BABCDC7FA49DECE0D1C3",&"20a1cb292"));
&&&&&&&&/// &summary&
&&&&&&&&/// 验证签名
&&&&&&&&/// &/summary&
&&&&&&&&/// &param name="content"&排序后的所有参数(不包括sign参数)&/param&
&&&&&&&&/// &param name="sign"&合作商传过来的sign签名(对参数加密后的MD5)&/param&
&&&&&&&&/// &param name="ourKey"&我们用于签名的密钥(用于解密的一串字符)&/param&
&&&&&&&&/// &returns&&/returns&
&&&&&&&&public&static&bool&VerifySignature(String content, String sign, String ourKey)
&&&&&&&&&&&&string&signResult = WXPayMD5(content +&"&key="&+ ourKey).ToUpper();
&&&&&&&&&&&&return&(sign == signResult);
&&&&&&&&/// &summary&
&&&&&&&&/// MD5加密
&&&&&&&&/// &/summary&
&&&&&&&&/// &param name="s"&需加密的字符&/param&
&&&&&&&&/// &returns&&/returns&
&&&&&&&&public&static&String WXPayMD5(String s)
&&&&&&&&&&&&char[] hexDigits = {&‘0‘,&‘1‘,&‘2‘,&‘3‘,&‘4‘,&‘5‘,&‘6‘,&‘7‘,&‘8‘,&‘9‘,
‘A‘,&‘B‘,&‘C‘,&‘D‘,&‘E‘,&‘F‘&};
&&&&&&&&&&&&try
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&byte[] btInput = System.Text.Encoding.Default.GetBytes(s);
&&&&&&&&&&&&&&&&// 获得MD5摘要算法的 MessageDigest 对象
&&&&&&&&&&&&&&&&MD5 mdInst = System.Security.Cryptography.MD5.Create();
&&&&&&&&&&&&&&&&// 使用指定的字节更新摘要
&&&&&&&&&&&&&&&&puteHash(btInput);
&&&&&&&&&&&&&&&&// 获得密文
&&&&&&&&&&&&&&&&byte[] md = mdInst.H
&&&&&&&&&&&&&&&&// 把密文转换成十六进制的字符串形式
&&&&&&&&&&&&&&&&int&j = md.L
&&&&&&&&&&&&&&&&char[] str =&new&char[j * 2];
&&&&&&&&&&&&&&&&int&k = 0;
&&&&&&&&&&&&&&&&for&(int&i = 0; i & i++)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&byte&byte0 = md[i];
&&&&&&&&&&&&&&&&&&&&str[k++] = hexDigits[(int)(((byte)byte0) && 4) & 0xf];
&&&&&&&&&&&&&&&&&&&&str[k++] = hexDigits[byte0 & 0xf];
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&return&new&string(str);
&&&&&&&&&&&&}
&&&&&&&&&&&&catch&(Exception e)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&Console.Error.WriteLine(e.StackTrace);
&&&&&&&&&&&&&&&&return&
&&&&&&&&&&&&}
&&&&&&&&/// &summary&
&&&&&&&&/// 将字典所有值按Key字母顺序合并成字符串
&&&&&&&&/// &/summary&
&&&&&&&&/// &param name="parameters"&字典类&/param&
&&&&&&&&/// &returns&字符串&/returns&
&&&&&&&&public&static&string&GetSignContent(IDictionary&string,&string& parameters)
&&&&&&&&&&&&// 第一步:把字典按Key的字母顺序排序
&&&&&&&&&&&&IDictionary&string,&string& sortedParams =&new&SortedDictionary&string,&string&(parameters);
&&&&&&&&&&&&IEnumerator&KeyValuePair&string,&string&& dem = sortedParams.GetEnumerator();
&&&&&&&&&&&&// 第二步:把所有参数名和参数值串在一起
&&&&&&&&&&&&StringBuilder query =&new&StringBuilder("");
&&&&&&&&&&&&while&(dem.MoveNext())
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&string&key = dem.Current.K
&&&&&&&&&&&&&&&&string&value = dem.Current.V
&&&&&&&&&&&&&&&&if&(!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&query.Append(key).Append("=").Append(value).Append("&");
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&string&content = query.ToString().Substring(0, query.Length - 1);
&&&&&&&&&&&&return&
}标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:/boldiy/p/4177632.html
教程昨日排行
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!微信支付jsapi在ios下无法发起,提示签名无效
我开发一直用的安卓手机测试,今天准备发布时,测试人员发现用ios手机无法发起微信支付,求解,安卓下可以完成整个流程?
签名无效invalid signature签名错误。建议按如下顺序检查:确认签名算法正确,可用&http://mp./debug/cgi-bin/sandbox?t=jsapisign&页面工具进行校验。确认config中nonceStr(js中驼峰标准大写S), timestamp与用以签名中的对应noncestr, timestamp一致。确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)://'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。确保一定缓存access_token和jsapi_ticket。确保你获取用来签名的url是动态获取的,动态页面可参见实例代码中php的实现方式。如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,而且需要encodeURIComponent),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。
还没有登录帐号?首先介绍一下我在调用微信支付接口使用的是&weixin.senparc SDK,非常方便好用开源的一个微信开发SDK。
weixin.senparc SDK&官网:/
先去下载下来Senparc.Weixin SDK。
在调起支付接口之前,需要先要调用统一下单接口,商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再在APP里面调起支付。
&微信&JsApi支付 在这个目录下&Senparc.Weixin.MP.Sample.Controllers 找到JsApi支付。
public ActionResult JsApi(string code, string state)
if (string.IsNullOrEmpty(code))
return Content("您拒绝了授权!");
if (!state.Contains("|"))
//这里的state其实是会暴露给客户端的,验证能力很弱,这里只是演示一下
//实际上可以存任何想传递的数据,比如用户ID,并且需要结合例如下面的Session["OAuthAccessToken"]进行验证
return Content("验证失败!请从正规途径进入!1001");
//获取产品信息
var stateData = state.Split('|');
int productId = <span style="color: #;
ProductModel product = null;
if (int.TryParse(stateData[<span style="color: #], out productId))
int hc = <span style="color: #;
if (int.TryParse(stateData[<span style="color: #], out hc))
var products = ProductModel.GetFakeProductList();
product = products.FirstOrDefault(z =& z.Id == productId);
if (product == null || product.GetHashCode() != hc)
return Content("商品信息不存在,或非法进入!1002");
ViewData["product"] =
//通过,用code换取access_token
var openIdResult = OAuthApi.GetAccessToken(TenPayV3Info.AppId, TenPayV3Info.AppSecret, code);
if (openIdResult.errcode != ReturnCode.请求成功)
return Content("错误:" + openIdResult.errmsg);
string sp_billno = Request["order_no"];
if (string.IsNullOrEmpty(sp_billno))
//生成订单10位序列号,此处用时间和随机数生成,商户根据自己调整,保证唯一
sp_billno = string.Format("{0}{1}{2}", TenPayV3Info.MchId, DateTime.Now.ToString("yyyyMMdd"),
TenPayV3Util.BuildRandomStr(<span style="color: #));
sp_billno = Request["order_no"];
var timeStamp = TenPayV3Util.GetTimestamp();
var nonceStr = TenPayV3Util.GetNoncestr();
var body = product == null ? "test" : product.N
var price = product == null ? <span style="color: #0 : product.Price * <span style="color: #0;
var xmlDataInfo = new TenPayV3UnifiedorderRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, body, sp_billno, price, Request.UserHostAddress, TenPayV3Info.TenPayV3Notify, TenPayV3Type.JSAPI, openIdResult.openid, TenPayV3Info.Key, nonceStr);
var result = TenPayV3.Unifiedorder(xmlDataInfo);//调用统一订单接口
//JsSdkUiPackage jsPackage = new JsSdkUiPackage(TenPayV3Info.AppId, timeStamp, nonceStr,);
var package = string.Format("prepay_id={0}", result.prepay_id);
ViewData["appId"] = TenPayV3Info.AppId;
ViewData["timeStamp"] = timeS
ViewData["nonceStr"] = nonceS
ViewData["package"] =
ViewData["paySign"] = TenPayV3.GetJsPaySign(TenPayV3Info.AppId, timeStamp, nonceStr, package, TenPayV3Info.Key);
return View();
catch (Exception ex)
var msg = ex.M
msg += "&br&" + ex.StackT
msg += "&br&==Source==&br&" + ex.S
if (ex.InnerException != null)
msg += "&br&===InnerException===&br&" + ex.InnerException.M
return Content(msg);
先在微信服务后台生成预支付交易单,获得预支付订单号。
先说说在统一下单这里遇到的坑。
1.在统一下单的时候解析返回结果,一直出现以下问题:您没有JSAPI支付权限
&return_code&&![CDATA[FAIL]]&&/return_code&
&return_msg&&![CDATA[您没有JSAPI支付权限]]&&/return_msg&&/xml&
1)先看看你的公众号微信支付设置是否正确。
关于如何配置微信支付:可以参考这个&/article/77b8dc7fef360d6174eab690.html
2)检查你的授权目录是否正确,格式要这样,后面记得别漏了一个/ & 例如:/u/
3)检查需要传过去的账户参数,上公众号还有商户号检查你的账户参数是否正确。我在开发当中就出现,微信公众号商户号,appid 是分别不同两个公众号的,坑啊,找了好久,觉得不对劲,原来是给的配置参数密钥不对。
&这里详细说一下对应的参数:
MCHID:商户号(必须配置,开户邮件中可查看),商户申请微信支付后,由微信支付分配的商户收款账号。
APPID:微信开放平台审核通过的应用APPID,appid是微信公众账号或开放平台APP的唯一标识,在公众平台申请公众账号或者在开放平台申请APP账号后,微信会自动分配对应的appid用于标识该应用。可在微信公众平台--&开发者中心查看,商户的微信支付审核通过邮件中也会包含该字段值.
KEY:商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置),交易过程生成签名的密钥,仅保留在商户系统和微信支付后台,不会在网络中传播。商户妥善保管该Key,切勿在网络中传输,不能在其他客户端中存储,保证key不会被泄漏。商户可根据邮件提示登录微信商户平台进行设置。也可按一下路径设置:微信商户平台(pay.)--&账户设置--&API安全--&密钥设置.APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置, 登录公众平台,进入开发者中心可设置)
2.在统一下单,解析返回来的结果我出现了商户号mch_id与appid不匹配这个问题
&return_code&&![CDATA[FAIL]]&&/return_code&
&return_msg&&![CDATA[商户号mch_id与appid不匹配]]&&/return_msg&&/xml&
原因是我拿到的商户号不是这个公众号的。一定要检查是不是这个公众号的商户号。
3.在统一下单,解析返回来的结果出现&appid and openid not match,appid和openid不匹配。
&return_code&&![CDATA[FAIL]]&&/return_code&
&return_msg&&![CDATA[appid and openid not match]]&&/return_msg&&/xml&
原因是我这个用户的openid 不是这个公众号的
3.在统一下单,解析返回来的结果出现&CDATA[openid is invalid],openid无效
&return_code&&![CDATA[FAIL]]&&/return_code&
&return_msg&&![CDATA[openid is invalid]]&&/return_msg&&/xml&
原因是,传过去不是有效的opendid。不小心看错了,把用户id 当做openid传过去了。
当统一下单成功,会返回以下格式的参数
&xml&&&&&return_code&&![CDATA[SUCCESS]]&&/return_code&&&&&return_msg&&![CDATA[OK]]&&/return_msg&&&&&appid&&![CDATA[wx0ec43b]]&&/appid&&&&&mch_id&&![CDATA[]]&&/mch_id&&&&&nonce_str&&![CDATA[IITRi8Iabbblz1Jc]]&&/nonce_str&&&&&sign&&![CDATA[EB8ED0CED72F]]&&/sign&&&&&result_code&&![CDATA[SUCCESS]]&&/result_code&&&&&prepay_id&&![CDATA[wx507cbf6ffd8b]]&&/prepay_id&&&&&trade_type&&![CDATA[APP]]&&/trade_type&&/xml&
解析获得预支付单号:
string prepayId = res.Element("xml").Element("prepay_id").V //获取预支付订单号
给页面对应地参数
ViewData["appId"] = TenPayV3Info.AppId;
ViewData["timeStamp"] = timeS
ViewData["nonceStr"] = nonceS
ViewData["package"] =
ViewData["paySign"] = TenPayV3.GetJsPaySign(TenPayV3Info.AppId, timeStamp, nonceStr, package, TenPayV3Info.Key);
静态页面js调用:
wx.chooseWXPay({
timestamp: 0, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: '', // 支付签名随机串,不长于 32 位
package: '', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
signType: '', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: '', // 支付签名
success: function (res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {//支付成功
//支付失败
// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
阅读(...) 评论()

我要回帖

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

 

随机推荐