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

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

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

现在说正题。。

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

官方文档中接口调用规则:

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

中)

�  请求采用 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群,欢迎大家加入一起交流微信开发技术。

坑爹的微信支付v3,其实没有那么坑的更多相关文章

  1. 到处都是坑的微信支付V3

    业务需要一个在微信上能付款的功能,于是乎想到了最普遍的支付宝,坑爹的是T与A是水火不容啊,默默的还是接微信支付吧,没想到从此掉进了连环坑…… 网上写微信支付接口的还是很多,PHP官方有(鄙视源码作者, ...

  2. 到处都是坑的微信支付V3之 微信支付回调页面

    据上次 到处都是坑的微信支付V3 后很多园友在被虐了千百遍后终于跳转到了亲切的微信支付界面,但输入密码支付后却不知道怎么处理了,接下来补上支付后的处理流程. 1. html中根据前台支付后反馈信息成功 ...

  3. 微信支付v3发布到iis时的证书问题(转)

    本文纯粹转载(原地址:微信支付v3发布到iis时的证书问题 ) 一开始报“出现了内部错误” 解决方法是 方法一 var cer = new X509Certificate(certpath, pass ...

  4. 微信支付[v3]

    原文:微信支付[v3] V2升级V3 顺便记录一下 ,文档: http://pay.weixin.qq.com/wiki/doc/api/index.html !!! 支付授权目录与测试人的微信帐号白 ...

  5. 微信支付v3开发(5) 扫码并输入金额支付

    关键字:微信支付 微信支付v3 动态native支付 统一支付 Native支付 prepay_id 作者:方倍工作室 本文介绍微信支付下的扫描二维码并输入自定义金额的支付的开发过程. 注意 微信支付 ...

  6. 为了Java微信支付V3开发包,我找出了微信支付文档至少六个错误

    1. 前言 最近忙的一批,难得今天有喘气的机会就赶紧把最近在开发中的一些成果分享出来.前几日分享了自己写的一个微信支付V3的开发包payment-spring-boot-starter,就忙里偷闲完善 ...

  7. 如何在Spring Boot项目中集成微信支付V3

    Payment Spring Boot 是微信支付V3的Java实现,仅仅依赖Spring内置的一些类库.配置简单方便,可以让开发者快速为Spring Boot应用接入微信支付. 演示例子: paym ...

  8. Payment Spring Boot 1.0.4.RELEASE 发布,最易用的微信支付 V3 实现

    Payment Spring Boot 是微信支付V3的Java实现,仅仅依赖Spring内置的一些类库.配置简单方便,可以让开发者快速为Spring Boot应用接入微信支付. 欢迎ISSUE,欢迎 ...

  9. 微信支付V3 SDK Payment Spring Boot 1.0.6 发布,实现留守红包,助力抗疫

    春节将至,为防控疫情,多地政府提倡员工.外来务工者留守本地过年,并鼓励企业向员工发放"留守红包".为此,微信支付推出"春节留守红包"能力,希望可以协助有发放需求 ...

随机推荐

  1. EF里的默认映射以及如何使用Data Annotations和Fluent API配置数据库的映射

    I.EF里的默认映射 上篇文章演示的通过定义实体类就可以自动生成数据库,并且EF自动设置了数据库的主键.外键以及表名和字段的类型等,这就是EF里的默认映射.具体分为: 数据库映射:Code First ...

  2. [LeetCode] Kth Largest Element in an Array 数组中第k大的数字

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  3. 外网访问内网工具ngrok tunnel 使用总结

    需求分析 在软件开发测试过程中,我们会经常遇到需要网站部署测试.给客户演示.APP开发的调试这样的需求.通常的做法是申请一个域名和空间,将网站放到外网上给客户演示. 这种方法确实可行不过会有两点不好, ...

  4. 修改 jquery.validate.js 支持非form标签

    尝试使用markdown来写一篇blog,啦啦啦 源代码传送门:github 在特殊情况下我们使用jquery.validate.js对用户输入的内容做验证的时候,表单并不是一定包含在form之中,有 ...

  5. php代码小实例

    php多图上传 <html> <meta http-equiv="Content-Type" content="text/html; charset=u ...

  6. css-css权威指南学习笔记6

    第八章 padding/border/margin 1.对于只包含文本的行,能改变行间距里的属性只有line-height/font-size/vertical-align. 2.对行内非替换元素应用 ...

  7. NOIP2016滚粗记

    想了好久还是决定要写... Day0 Day-5得感冒一直没好,连磕5天药丸. 早晨得知爸妈都要上班并不能送我到校的消息,于是计划10:30集合,定表8:45准备自己走去学校. 然后平常睡得有点晚,结 ...

  8. Nginx配置SSL证书部署HTTPS网站

    1.购买ssl证书 购买网站:沃通 2.上传证书到nginx服务器,然后进行解压. 解压后的的效果: [root@bubidev-ng3 nginx]# pwd/etc/nginx [root@bub ...

  9. ZKW线段树

    简介 zkw线段树虽然是线段树的另一种写法,但是本质上已经和普通的递归版线段树不一样了,是一种介于树状数组和线段树中间的存在,一些功能上的实现比树状数组多,而且比线段树好写且常数小. 普通线段树采用从 ...

  10. JS 小数的常用处理方法

    1.丢弃小数部分,保留整数部分 parseInt(5/2) 2.向上取整,有小数就整数部分加1 Math.ceil(5/2) 3,四舍五入. Math.round(5/2) 4,向下取整 Math.f ...