坑爹的微信支付v3,其实没有那么坑

http://www.cnblogs.com/zskbll/p/wxpay.htmlhtml

研究微信开发一年多了,每一个新接口,都会第一时间进行研究。微信支付开放好久,一直没机会接触到支付接口,等了很久终于从朋友那儿搞到了接口,今后开始了我两天多的支付接口的研究。ajax

 

拿到这个接口文档的第一个想法就是这也没什么难的嘛, 和支付宝、财付通、网银在线等一些传统接口的思路逻辑都是同样的,以为差很少最多一个下午就能够搞定,结果第一步调用统一支付接口就给来了个下马威,无论怎么改,就一直返回签名错误。第一次遇到签名错误,首先想到的是应该是没有正确理解签名的生成规则,又从头看了几回签名的生成规则,每次都是的理解都是同样的,试了改几回仍是不行。 这一次已经开始怀疑腾讯的文档写的有问题,一边找其余资料一边在内心骂腾讯写文档的做者。在园子里看到了处处都是坑的微信支付V3后,更加确认是微信的文档的问题。如今想一想当时的想法太幼稚了,大部分自信心爆棚的人,在遇到解决不了的问题时老是会怀疑是否是别人给的东西不对,而不会从自身找问题,一句话总结就是一到便秘就怪地球没引力。(各位看官请勿对号入座,纯属我的看法,勿喷)。api

如今说正题。。安全

从开始遇到错误到最后解决签名的问题,总结的问题就是我在生成签名的时候把参数进行了编码,而官方给的开发文档并无说要作url编码,另一个就是我进入了一个死胡同,总以为本身的理解与实现过程没有问题,但最后当我把以前写的代码彻底放弃,推倒重作后,问题终于解决。兴奋之极。下面从头说下个人理解与解决方法。微信

官方文档中接口调用规则:微信开发

�  认证方式:HTTPS 认证,退款和冲正接口调用须要商户证书(证书在审核邮件附件app

中)post

�  请求采用 POST 方式微信支付

�  提交和返回结果采用 XML 格式编码

�  字符集默认使用 UTF-8,请勿使用其它字符集

�  商户与微信之间的交互(特别是 Native 回调和支付通知回调),都须要验证签名

�  处理返回时先判断协议返回错误码,再判断业务返回错误码,最后判断交易状态

 

下面是官方的签名生成方法

a.对全部传入参数按照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值对的格式(即 key1=value1&key2=value2…)拼接成字符串 string1,注意:值为空的参数不参与签名

b. 在 string1 最 后 拼 接 上 key=Key( 商 户 支 付 密 钥 ) 得 到 stringSignTemp 字 符 串 , 并 对 stringSignTemp 进行 md5 运算,再将获得的字符串全部字符 转换为大写,获得 sign 值

下面是我所理解的签名生成规则:

1,全部的参数都是小写的

2,参数的值不须要作任何处理,包括url编码

3,确保必须的参数不能为空,且是正确无误的。

下面是示范过程:

要传入的参数分别为:appid,mch_id,nonce_str,body,attach,out_trade_no,total_fee,spbill_create_ip,notify_url,trade_type,openid(jsapi必须) ,product_id(native必须)。

首先将键值对存入 Dictionary<string,string>中,其次根据key值升序排序,代码以下:    var dictemp = dic.OrderBy(d => d.Key);

而后将键值对转换成url形式后,在末尾连接上key值,例如:appid=****&attach=****…………&key=******,最后进行md5加密并将加密后的字符串转换成大写。这里须要特别注意的是,md5加密是须要将字符集转换成utf-8,不然中文商品描述会出现乱码。

  md5加密

 

生成签名后将sign=签名  键值对添加到生成签名时生成的dictemp中,而后将dictemp转换成xml,post到https://api.mch.weixin.qq.com/pay/unifiedorder,返回值也是xml,最后对xml进行解析,为了保证安全性,需将解析后的键值对进行签名校验。

  正确的xml

校验签名无误后,下一步就是取出预支付id prepay_id,而后调用微信支付js,注意:调用微信支付js以前也须要将全部参与调用的参数进行签名,且这里的参与签名的参数须要验证遵照大小写(腾讯有的时候真的很脑残,一会全小写,一会有大写有小写)。生成签名后就能够调用微信支付js了,代码以下:

  微信支付js

为了方便调用,我将微信支付js写到了一个单独的js文件,而后在页面中载入,生成签名用ajax调用。调用代码以下:

  支付js调用

这里我只传入了一些和商品相关的参数,其余和商品没法的参数写到了后台代码中。后台收到请求后,将appid,mch_id等参数拼接成键值对进行进一步的处理,而后将处理后的结果返回给前台。

 

  获取js支付参数

下面是生成键值对的方法,因为请求支付的过程当中,处处须要生成签名,因此我将各个请求参数都写成了一个个类,而后使用泛型类和反射动态生成字典键值对,请求url和xml。代码以下:

  生成键值对,url,xml

  到这里应该就能够知足jsapi的需求了, 后期会将native和其余接口分享给你们。

 

 

 

 

若是你以为本文对你有帮助,请大方的扫下面的二维码悬赏一下吧。

新建了个微信支付及微信开发的QQ群,欢迎你们加入一块儿交流微信开发技术。C#微信开发交流

相关文章
相关标签/搜索