公众号支付有2种支付方式:

JS API 支付:是指用户打开图文消息或者扫描二维码,在微信内置浏览器打开网页进行的支付。商户网页前端通过使用微信提供的 JS API,调用微信支付模块。这种方式,适合
需要在商户网页进行选购下单的购买流程。
  Native(原生)支付:是指商户组成符合 Native(原生)支付规则的 URL 链接,用户可通过点击该链接或者扫描对应的二维码直接进入微信支付模块(微信客户端界面),即可
进行支付。这种方式,适合无需选购直接支付的购买流程。

以上两种方式最大的区别是:是否需要经过网页调用!

交互原理:

客户是想做一个手机端的商城,所以选择JS API支付,通过网页调取微信支付。。

楼主第一次看过文档后,什么“支付签名(paySign)”啊,什么“package包”啊等等一些参数,反正似懂非懂的样子。楼主这人比较懒,不然也不会注册3年了,也就写了这么篇不入流的文章,楼主想啊像这些个大公司开放个啥接口的肯定会有demo。楼主的运气还真不错(PS:楼主可是为福利事业贡献了不少哦,咋就没这运气?),还真让楼主找到了,那心情肯定是比不上中500W的,嘿嘿。

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>公众号支付测试网页</title>
  5. <script language="javascript" src="http://res.mail.qq.com/mmr/static/lib/js/jquery.js"></script>
  6. <script language="javascript" src="http://res.mail.qq.com/mmr/static/lib/js/lazyloadv3.js"></script>
  7. <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/md5.js"></script>
  8. <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha1.js"></script>
  9. <script Language="javascript">
  10. //辅助函数
  11. function Trim(str,is_global)
  12. {
  13. var result;
  14. result = str.replace(/(^\s+)|(\s+$)/g,"");
  15. if(is_global.toLowerCase()=="g") result = result.replace(/\s/g,"");
  16. return result;
  17. }
  18. function clearBr(key)
  19. {
  20. key = Trim(key,"g");
  21. key = key.replace(/<\/?.+?>/g,"");
  22. key = key.replace(/[\r\n]/g, "");
  23. return key;
  24. }
  25.  
  26. //获取随机数
  27. function getANumber()
  28. {
  29. var date = new Date();
  30. var times1970 = date.getTime();
  31. var times = date.getDate() + "" + date.getHours() + "" + date.getMinutes() + "" + date.getSeconds();
  32. var encrypt = times * times1970;
  33. if(arguments.length == ){
  34. return arguments[] + encrypt;
  35. }else{
  36. return encrypt;
  37. }
  38.  
  39. }
  40.  
  41. //以下是package组包过程:
  42.  
  43. var oldPackageString;//记住package,方便最后进行整体签名时取用
  44.  
  45. function getPartnerId()
  46. {
  47. return document.form1.partnerId.value;
  48. }
  49.  
  50. function getPartnerKey()
  51. {
  52. return "8934e7d15453e97507ef794cf7b0519d";
  53. }
  54.  
  55. function getPackage()
  56. {
  57. var banktype = "WX";
  58. var body = document.form1.body.value;//商品名称信息,这里由测试网页填入。
  59. var fee_type = "";//费用类型,这里1为默认的人民币
  60. var input_charset = "GBK";//字符集,这里将统一使用GBK
  61. var notify_url = "http://www.qq.com";//支付成功后将通知该地址
  62. var out_trade_no = ""+getANumber();//订单号,商户需要保证该字段对于本商户的唯一性
  63. var partner = getPartnerId();//测试商户号
  64. var spbill_create_ip = "127.0.0.1";//用户浏览器的ip,这个需要在前端获取。这里使用127.0.0.1测试值
  65. var total_fee = document.form1.totalFee.value;//总金额。
  66. var partnerKey = getPartnerKey();//这个值和以上其他值不一样是:签名需要它,而最后组成的传输字符串不能含有它。这个key是需要商户好好保存的。
  67.  
  68. //首先第一步:对原串进行签名,注意这里不要对任何字段进行编码。这里是将参数按照key=value进行字典排序后组成下面的字符串,在这个字符串最后拼接上key=XXXX。由于这里的字段固定,因此只需要按照这个顺序进行排序即可。
  69. var signString = "bank_type="+banktype+"&body="+body+"&fee_type="+fee_type+"&input_charset="+input_charset+"&notify_url="+notify_url+"&out_trade_no="+out_trade_no+"&partner="+partner+"&spbill_create_ip="+spbill_create_ip+"&total_fee="+total_fee+"&key="+partnerKey;
  70.  
  71. var md5SignValue = ("" + CryptoJS.MD5(signString)).toUpperCase();
  72. //然后第二步,对每个参数进行url转码,如果您的程序是用js,那么需要使用encodeURIComponent函数进行编码。
  73.  
  74. banktype = encodeURIComponent(banktype);
  75. body=encodeURIComponent(body);
  76. fee_type=encodeURIComponent(fee_type);
  77. input_charset = encodeURIComponent(input_charset);
  78. notify_url = encodeURIComponent(notify_url);
  79. out_trade_no = encodeURIComponent(out_trade_no);
  80. partner = encodeURIComponent(partner);
  81. spbill_create_ip = encodeURIComponent(spbill_create_ip);
  82. total_fee = encodeURIComponent(total_fee);
  83.  
  84. //然后进行最后一步,这里按照key=value除了sign外进行字典序排序后组成下列的字符串,最后再串接sign=value
  85. var completeString = "bank_type="+banktype+"&body="+body+"&fee_type="+fee_type+"&input_charset="+input_charset+"&notify_url="+notify_url+"&out_trade_no="+out_trade_no+"&partner="+partner+"&spbill_create_ip="+spbill_create_ip+"&total_fee="+total_fee;
  86. completeString = completeString + "&sign="+md5SignValue;
  87.  
  88. oldPackageString = completeString;//记住package,方便最后进行整体签名时取用
  89.  
  90. return completeString;
  91. }
  92.  
  93. //下面是app进行签名的操作:
  94.  
  95. var oldTimeStamp ;//记住timestamp,避免签名时的timestamp与传入的timestamp时不一致
  96. var oldNonceStr ; //记住nonceStr,避免签名时的nonceStr与传入的nonceStr不一致
  97.  
  98. function getAppId()
  99. {
  100. return document.form1.appId.value;
  101. }
  102.  
  103. function getAppKey()
  104. {
  105. return "2Wozy2aksie1puXUBpWD8oZxiD1DfQuEaiC7KcRATv1Ino3mdopKaPGQQ7TtkNySuAmCaDCrw4xhPY5qKTBl7Fzm0RgR3c0WaVYIXZARsxzHV2x7iwPPzOz94dnwPWSn";
  106. }
  107.  
  108. function getTimeStamp()
  109. {
  110. var timestamp=new Date().getTime();
  111. var timestampstring = timestamp.toString();//一定要转换字符串
  112. oldTimeStamp = timestampstring;
  113. return timestampstring;
  114. }
  115.  
  116. function getNonceStr()
  117. {
  118. var $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  119. var maxPos = $chars.length;
  120. var noceStr = "";
  121. for (i = ; i < ; i++) {
  122. noceStr += $chars.charAt(Math.floor(Math.random() * maxPos));
  123. }
  124. oldNonceStr = noceStr;
  125. return noceStr;
  126. }
  127.  
  128. function getSignType()
  129. {
  130. return "SHA1";
  131. }
  132.  
  133. function getSign()
  134. {
  135. var app_id = getAppId().toString();
  136. var app_key = getAppKey().toString();
  137. var nonce_str = oldNonceStr;
  138. var package_string = oldPackageString;
  139. var time_stamp = oldTimeStamp;
  140. //第一步,对所有需要传入的参数加上appkey作一次key=value字典序的排序
  141. var keyvaluestring = "appid="+app_id+"&appkey="+app_key+"&noncestr="+nonce_str+"&package="+package_string+"&timestamp="+time_stamp;
  142. sign = CryptoJS.SHA1(keyvaluestring).toString();
  143. return sign;
  144. }
  145.  
  146. </script>
  147. <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
  148. <meta id="viewport" name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1; user-scalable=no;" />
  149.  
  150. <style>
  151.  
  152. body { margin:;padding:;background:#eae9e6; }
  153. body,p,table,td,th { font-size:14px;font-family:helvetica,Arial,Tahoma; }
  154. h1 { font-family:Baskerville,HelveticaNeue-Bold,helvetica,Arial,Tahoma; }
  155. a { text-decoration:none;color:#;}
  156.  
  157. .container { }
  158. .title { }
  159. #content {padding:30px 20px 20px;color:#;box-shadow: 1px 4px #ccc; background:#f7f2ed; }
  160. .seeAlso { padding:15px 20px 30px; }
  161.  
  162. .headpic div { margin:20px ;}
  163. .headpic img { display:block;}
  164.  
  165. .title h1 { font-size:22px;font-weight:bold;padding:;margin:;line-height:1.2;color:#1f1f1f; }
  166. .title p { color:#aaa;font-size:12px;margin:5px ;padding:;font-weight:bold;}
  167. .pic { margin:20px ; }
  168. .articlecontent img { display:block;clear:both;box-shadow:0px 1px 3px #; margin:5px auto;}
  169. .articlecontent p { text-indent: 2em; font-family:Georgia,helvetica,Arial,Tahoma;line-height:1.4; font-size:16px; margin:20px ; }
  170.  
  171. .seeAlso h3 { font-size:16px;color:#a5a5a5;}
  172. .seeAlso ul { margin:;padding:; }
  173. .seeAlso li { font-size:16px;list-style-type:none;border-top:1px solid #ccc;padding:2px ;}
  174. .seeAlso li a { border-bottom:none;display:block;line-height:1.1; padding:13px ; }
  175.  
  176. .clr{ clear:both;height:1px;overflow:hidden;}
  177.  
  178. .fontSize1 .title h1 { font-size:20px; }
  179. .fontSize1 .articlecontent p { font-size:14px; }
  180. .fontSize1 .weibo .nickname,.fontSize1 .weibo .comment { font-size:11px; }
  181. .fontSize1 .moreOperator { font-size:14px; }
  182.  
  183. .fontSize2 .title h1 { font-size:22px; }
  184. .fontSize2 .articlecontent p { font-size:16px; }
  185. .fontSize2 .weibo .nickname,.fontSize2 .weibo .comment { font-size:13px; }
  186. .fontSize2 .moreOperator { font-size:16px; }
  187.  
  188. .fontSize3 .title h1 { font-size:24px; }
  189. .fontSize3 .articlecontent p { font-size:18px; }
  190. .fontSize3 .weibo .nickname,.fontSize3 .weibo .comment { font-size:15px; }
  191. .fontSize3 .moreOperator { font-size:18px; }
  192.  
  193. .fontSize4 .title h1 { font-size:26px; }
  194. .fontSize4 .articlecontent p { font-size:20px; }
  195. .fontSize4 .weibo .nickname,.fontSize4 .weibo .comment { font-size:16px; }
  196. .fontSize4 .moreOperator { font-size:20px; }
  197.  
  198. .jumptoorg { display:block;margin:16px 16px; }
  199. .jumptoorg a { }
  200.  
  201. .moreOperator a { color:#; }
  202.  
  203. .moreOperator .share{ border-top:1px solid #ddd; }
  204.  
  205. .moreOperator .share a{ display:block;border:1px solid #ccc;border-radius:4px;margin:20px ;border-bottom-style:solid;background:#f8f7f1;color:#; }
  206.  
  207. .moreOperator .share a span{ display:block;padding:10px 10px;border-radius:4px;text-align:center;border-top:1px solid #eee;border-bottom:1px solid #eae9e3;font-weight:bold; }
  208.  
  209. .moreOperator .share a:hover,
  210. .moreOperator .share a:active { background:#efedea; }
  211. @media only screen and (-webkit-min-device-pixel-ratio: ) {
  212. }
  213. </style>
  214. <script language="javascript">
  215. function auto_remove(img){
  216. div=img.parentNode.parentNode;div.parentNode.removeChild(div);
  217. img.onerror="";
  218. return true;
  219. }
  220.  
  221. function changefont(fontsize){
  222. if(fontsize < || fontsize > )return;
  223. $('#content').removeClass().addClass('fontSize' + fontsize);
  224. }
  225.  
  226. // 当微信内置浏览器完成内部初始化后会触发WeixinJSBridgeReady事件。
  227. document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {
  228. //公众号支付
  229. jQuery('a#getBrandWCPayRequest').click(function(e){
  230. WeixinJSBridge.invoke('getBrandWCPayRequest',{
  231. "appId" : getAppId(), //公众号名称,由商户传入
  232. "timeStamp" : getTimeStamp(), //时间戳
  233. "nonceStr" : getNonceStr(), //随机串
  234. "package" : getPackage(),//扩展包
  235. "signType" : getSignType(), //微信签名方式:1.sha1
  236. "paySign" : getSign() //微信签名
  237. },function(res){
  238. if(res.err_msg == "get_brand_wcpay_request:ok" ) {}
  239. // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
  240. //因此微信团队建议,当收到ok返回时,向商户后台询问是否收到交易成功的通知,若收到通知,前端展示交易成功的界面;若此时未收到通知,商户后台主动调用查询订单接口,查询订单的当前状态,并反馈给前端展示相应的界面。
  241. });
  242.  
  243. });
  244.  
  245. WeixinJSBridge.log('yo~ ready.');
  246.  
  247. }, false)
  248.  
  249. if(jQuery){
  250. jQuery(function(){
  251.  
  252. var width = jQuery('body').width() * 0.87;
  253. jQuery('img').error(function(){
  254. var self = jQuery(this);
  255. var org = self.attr('data-original1');
  256. self.attr("src", org);
  257. self.error(function(){
  258. auto_remove(this);
  259. });
  260. });
  261. jQuery('img').each(function(){
  262. var self = jQuery(this);
  263. var w = self.css('width');
  264. var h = self.css('height');
  265. w = w.replace('px', '');
  266. h = h.replace('px', '');
  267. if(w <= width){
  268. return;
  269. }
  270. var new_w = width;
  271. var new_h = Math.round(h * width / w);
  272. self.css({'width' : new_w + 'px', 'height' : new_h + 'px'});
  273. self.parents('div.pic').css({'width' : new_w + 'px', 'height' : new_h + 'px'});
  274. });
  275. });
  276. }
  277. </script>
  278. </head>
  279. <body>
  280.  
  281. <form name="form1" target="_blank">
  282. <table border="">
  283. <TR><th>公众号ID</th> <th><INPUT value="wxf8b4f85f3a794e77" name="appId" id=""></th>
  284. <tr><th>商户ID</th><th><INPUT value="" name="partnerId" id=""></th>
  285. <TR><th>总金额</th><th><INPUT value= name="totalFee" id=""></th>
  286. <TR><th>商品名</th><th><INPUT value="江诗丹顿" name="body" id=""></th>
  287. </table>
  288. </form>
  289. <div class="WCPay">
  290. <a id="getBrandWCPayRequest" href="javascript:void(0);"><h1 class="title">提交</h1></a>
  291. </div>
  292.  
  293. </body>
  294. </html>
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>公众号支付测试网页</title>
  5. <script language="javascript" src="http://res.mail.qq.com/mmr/static/lib/js/jquery.js"></script>
  6. <script language="javascript" src="http://res.mail.qq.com/mmr/static/lib/js/lazyloadv3.js"></script>
  7. <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/md5.js"></script>
  8. <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha1.js"></script>
  9. <script Language="javascript">
  10. //辅助函数
  11. function Trim(str,is_global)
  12. {
  13. var result;
  14. result = str.replace(/(^\s+)|(\s+$)/g,"");
  15. if(is_global.toLowerCase()=="g") result = result.replace(/\s/g,"");
  16. return result;
  17. }
  18. function clearBr(key)
  19. {
  20. key = Trim(key,"g");
  21. key = key.replace(/<\/?.+?>/g,"");
  22. key = key.replace(/[\r\n]/g, "");
  23. return key;
  24. }
  25.  
  26. //获取随机数
  27. function getANumber()
  28. {
  29. var date = new Date();
  30. var times1970 = date.getTime();
  31. var times = date.getDate() + "" + date.getHours() + "" + date.getMinutes() + "" + date.getSeconds();
  32. var encrypt = times * times1970;
  33. if(arguments.length == 1){
  34. return arguments[0] + encrypt;
  35. }else{
  36. return encrypt;
  37. }
  38.  
  39. }
  40.  
  41. //以下是package组包过程:
  42.  
  43. var oldPackageString;//记住package,方便最后进行整体签名时取用
  44.  
  45. function getPartnerId()
  46. {
  47. return document.form1.partnerId.value;
  48. }
  49.  
  50. function getPartnerKey()
  51. {
  52. return "8934e7d15453e97507ef794cf7b0519d";
  53. }
  54.  
  55. function getPackage()
  56. {
  57. var banktype = "WX";
  58. var body = document.form1.body.value;//商品名称信息,这里由测试网页填入。
  59. var fee_type = "1";//费用类型,这里1为默认的人民币
  60. var input_charset = "GBK";//字符集,这里将统一使用GBK
  61. var notify_url = "http://www.qq.com";//支付成功后将通知该地址
  62. var out_trade_no = ""+getANumber();//订单号,商户需要保证该字段对于本商户的唯一性
  63. var partner = getPartnerId();//测试商户号
  64. var spbill_create_ip = "127.0.0.1";//用户浏览器的ip,这个需要在前端获取。这里使用127.0.0.1测试值
  65. var total_fee = document.form1.totalFee.value;//总金额。
  66. var partnerKey = getPartnerKey();//这个值和以上其他值不一样是:签名需要它,而最后组成的传输字符串不能含有它。这个key是需要商户好好保存的。
  67.  
  68. //首先第一步:对原串进行签名,注意这里不要对任何字段进行编码。这里是将参数按照key=value进行字典排序后组成下面的字符串,在这个字符串最后拼接上key=XXXX。由于这里的字段固定,因此只需要按照这个顺序进行排序即可。
  69. var signString = "bank_type="+banktype+"&body="+body+"&fee_type="+fee_type+"&input_charset="+input_charset+"&notify_url="+notify_url+"&out_trade_no="+out_trade_no+"&partner="+partner+"&spbill_create_ip="+spbill_create_ip+"&total_fee="+total_fee+"&key="+partnerKey;
  70.  
  71. var md5SignValue = ("" + CryptoJS.MD5(signString)).toUpperCase();
  72. //然后第二步,对每个参数进行url转码,如果您的程序是用js,那么需要使用encodeURIComponent函数进行编码。
  73.  
  74. banktype = encodeURIComponent(banktype);
  75. body=encodeURIComponent(body);
  76. fee_type=encodeURIComponent(fee_type);
  77. input_charset = encodeURIComponent(input_charset);
  78. notify_url = encodeURIComponent(notify_url);
  79. out_trade_no = encodeURIComponent(out_trade_no);
  80. partner = encodeURIComponent(partner);
  81. spbill_create_ip = encodeURIComponent(spbill_create_ip);
  82. total_fee = encodeURIComponent(total_fee);
  83.  
  84. //然后进行最后一步,这里按照key=value除了sign外进行字典序排序后组成下列的字符串,最后再串接sign=value
  85. var completeString = "bank_type="+banktype+"&body="+body+"&fee_type="+fee_type+"&input_charset="+input_charset+"&notify_url="+notify_url+"&out_trade_no="+out_trade_no+"&partner="+partner+"&spbill_create_ip="+spbill_create_ip+"&total_fee="+total_fee;
  86. completeString = completeString + "&sign="+md5SignValue;
  87.  
  88. oldPackageString = completeString;//记住package,方便最后进行整体签名时取用
  89.  
  90. return completeString;
  91. }
  92.  
  93. //下面是app进行签名的操作:
  94.  
  95. var oldTimeStamp ;//记住timestamp,避免签名时的timestamp与传入的timestamp时不一致
  96. var oldNonceStr ; //记住nonceStr,避免签名时的nonceStr与传入的nonceStr不一致
  97.  
  98. function getAppId()
  99. {
  100. return document.form1.appId.value;
  101. }
  102.  
  103. function getAppKey()
  104. {
  105. return "2Wozy2aksie1puXUBpWD8oZxiD1DfQuEaiC7KcRATv1Ino3mdopKaPGQQ7TtkNySuAmCaDCrw4xhPY5qKTBl7Fzm0RgR3c0WaVYIXZARsxzHV2x7iwPPzOz94dnwPWSn";
  106. }
  107.  
  108. function getTimeStamp()
  109. {
  110. var timestamp=new Date().getTime();
  111. var timestampstring = timestamp.toString();//一定要转换字符串
  112. oldTimeStamp = timestampstring;
  113. return timestampstring;
  114. }
  115.  
  116. function getNonceStr()
  117. {
  118. var $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  119. var maxPos = $chars.length;
  120. var noceStr = "";
  121. for (i = 0; i < 32; i++) {
  122. noceStr += $chars.charAt(Math.floor(Math.random() * maxPos));
  123. }
  124. oldNonceStr = noceStr;
  125. return noceStr;
  126. }
  127.  
  128. function getSignType()
  129. {
  130. return "SHA1";
  131. }
  132.  
  133. function getSign()
  134. {
  135. var app_id = getAppId().toString();
  136. var app_key = getAppKey().toString();
  137. var nonce_str = oldNonceStr;
  138. var package_string = oldPackageString;
  139. var time_stamp = oldTimeStamp;
  140. //第一步,对所有需要传入的参数加上appkey作一次key=value字典序的排序
  141. var keyvaluestring = "appid="+app_id+"&appkey="+app_key+"&noncestr="+nonce_str+"&package="+package_string+"&timestamp="+time_stamp;
  142. sign = CryptoJS.SHA1(keyvaluestring).toString();
  143. return sign;
  144. }
  145.  
  146. </script>
  147. <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
  148. <meta id="viewport" name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1; user-scalable=no;" />
  149.  
  150. <style>
  151.  
  152. body { margin:0;padding:0;background:#eae9e6; }
  153. body,p,table,td,th { font-size:14px;font-family:helvetica,Arial,Tahoma; }
  154. h1 { font-family:Baskerville,HelveticaNeue-Bold,helvetica,Arial,Tahoma; }
  155. a { text-decoration:none;color:#385487;}
  156.  
  157. .container { }
  158. .title { }
  159. #content {padding:30px 20px 20px;color:#111;box-shadow:0 1px 4px #ccc; background:#f7f2ed; }
  160. .seeAlso { padding:15px 20px 30px; }
  161.  
  162. .headpic div { margin:20px 0 0;}
  163. .headpic img { display:block;}
  164.  
  165. .title h1 { font-size:22px;font-weight:bold;padding:0;margin:0;line-height:1.2;color:#1f1f1f; }
  166. .title p { color:#aaa;font-size:12px;margin:5px 0 0;padding:0;font-weight:bold;}
  167. .pic { margin:20px 0; }
  168. .articlecontent img { display:block;clear:both;box-shadow:0px 1px 3px #999; margin:5px auto;}
  169. .articlecontent p { text-indent: 2em; font-family:Georgia,helvetica,Arial,Tahoma;line-height:1.4; font-size:16px; margin:20px 0; }
  170.  
  171. .seeAlso h3 { font-size:16px;color:#a5a5a5;}
  172. .seeAlso ul { margin:0;padding:0; }
  173. .seeAlso li { font-size:16px;list-style-type:none;border-top:1px solid #ccc;padding:2px 0;}
  174. .seeAlso li a { border-bottom:none;display:block;line-height:1.1; padding:13px 0; }
  175.  
  176. .clr{ clear:both;height:1px;overflow:hidden;}
  177.  
  178. .fontSize1 .title h1 { font-size:20px; }
  179. .fontSize1 .articlecontent p { font-size:14px; }
  180. .fontSize1 .weibo .nickname,.fontSize1 .weibo .comment { font-size:11px; }
  181. .fontSize1 .moreOperator { font-size:14px; }
  182.  
  183. .fontSize2 .title h1 { font-size:22px; }
  184. .fontSize2 .articlecontent p { font-size:16px; }
  185. .fontSize2 .weibo .nickname,.fontSize2 .weibo .comment { font-size:13px; }
  186. .fontSize2 .moreOperator { font-size:16px; }
  187.  
  188. .fontSize3 .title h1 { font-size:24px; }
  189. .fontSize3 .articlecontent p { font-size:18px; }
  190. .fontSize3 .weibo .nickname,.fontSize3 .weibo .comment { font-size:15px; }
  191. .fontSize3 .moreOperator { font-size:18px; }
  192.  
  193. .fontSize4 .title h1 { font-size:26px; }
  194. .fontSize4 .articlecontent p { font-size:20px; }
  195. .fontSize4 .weibo .nickname,.fontSize4 .weibo .comment { font-size:16px; }
  196. .fontSize4 .moreOperator { font-size:20px; }
  197.  
  198. .jumptoorg { display:block;margin:16px 0 16px; }
  199. .jumptoorg a { }
  200.  
  201. .moreOperator a { color:#385487; }
  202.  
  203. .moreOperator .share{ border-top:1px solid #ddd; }
  204.  
  205. .moreOperator .share a{ display:block;border:1px solid #ccc;border-radius:4px;margin:20px 0;border-bottom-style:solid;background:#f8f7f1;color:#000; }
  206.  
  207. .moreOperator .share a span{ display:block;padding:10px 10px;border-radius:4px;text-align:center;border-top:1px solid #eee;border-bottom:1px solid #eae9e3;font-weight:bold; }
  208.  
  209. .moreOperator .share a:hover,
  210. .moreOperator .share a:active { background:#efedea; }
  211. @media only screen and (-webkit-min-device-pixel-ratio: 2) {
  212. }
  213. </style>
  214. <script language="javascript">
  215. function auto_remove(img){
  216. div=img.parentNode.parentNode;div.parentNode.removeChild(div);
  217. img.onerror="";
  218. return true;
  219. }
  220.  
  221. function changefont(fontsize){
  222. if(fontsize < 1 || fontsize > 4)return;
  223. $('#content').removeClass().addClass('fontSize' + fontsize);
  224. }
  225.  
  226. // 当微信内置浏览器完成内部初始化后会触发WeixinJSBridgeReady事件。
  227. document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {
  228. //公众号支付
  229. jQuery('a#getBrandWCPayRequest').click(function(e){
  230. WeixinJSBridge.invoke('getBrandWCPayRequest',{
  231. "appId" : getAppId(), //公众号名称,由商户传入
  232. "timeStamp" : getTimeStamp(), //时间戳
  233. "nonceStr" : getNonceStr(), //随机串
  234. "package" : getPackage(),//扩展包
  235. "signType" : getSignType(), //微信签名方式:1.sha1
  236. "paySign" : getSign() //微信签名
  237. },function(res){
  238. if(res.err_msg == "get_brand_wcpay_request:ok" ) {}
  239. // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
  240. //因此微信团队建议,当收到ok返回时,向商户后台询问是否收到交易成功的通知,若收到通知,前端展示交易成功的界面;若此时未收到通知,商户后台主动调用查询订单接口,查询订单的当前状态,并反馈给前端展示相应的界面。
  241. });
  242.  
  243. });
  244.  
  245. WeixinJSBridge.log('yo~ ready.');
  246.  
  247. }, false)
  248.  
  249. if(jQuery){
  250. jQuery(function(){
  251.  
  252. var width = jQuery('body').width() * 0.87;
  253. jQuery('img').error(function(){
  254. var self = jQuery(this);
  255. var org = self.attr('data-original1');
  256. self.attr("src", org);
  257. self.error(function(){
  258. auto_remove(this);
  259. });
  260. });
  261. jQuery('img').each(function(){
  262. var self = jQuery(this);
  263. var w = self.css('width');
  264. var h = self.css('height');
  265. w = w.replace('px', '');
  266. h = h.replace('px', '');
  267. if(w <= width){
  268. return;
  269. }
  270. var new_w = width;
  271. var new_h = Math.round(h * width / w);
  272. self.css({'width' : new_w + 'px', 'height' : new_h + 'px'});
  273. self.parents('div.pic').css({'width' : new_w + 'px', 'height' : new_h + 'px'});
  274. });
  275. });
  276. }
  277. </script>
  278. </head>
  279. <body>
  280.  
  281. <form name="form1" target="_blank">
  282. <table border="1">
  283. <TR><th>公众号ID</th> <th><INPUT value="wxf8b4f85f3a794e77" name="appId" id="1"></th>
  284. <tr><th>商户ID</th><th><INPUT value="1900000109" name="partnerId" id="2"></th>
  285. <TR><th>总金额</th><th><INPUT value=1 name="totalFee" id="3"></th>
  286. <TR><th>商品名</th><th><INPUT value="江诗丹顿" name="body" id="4"></th>
  287. </table>
  288. </form>
  289. <div class="WCPay">
  290. <a id="getBrandWCPayRequest" href="javascript:void(0);"><h1 class="title">提交</h1></a>
  291. </div>
  292.  
  293. </body>
  294. </html>

打开一看(楼主心里想TX你是多缺美工!),“提交”两字这么大,点一下试试,没反应?这不科学啊!立马找原因,当看到这句:“微信支付,是基于微信客户端提供的支付服务功能” ,楼主**(已和谐)了!放网站上用微信打开,这次有反应了!微信友情的提示我:“功能未授权”。。 这次知道是啥原因了,找客户沟通,原来合同快递还没到,保证金5W没交(现在只要2W了)。。

N天之后。。。。

这下测试能成功了,该怎么跟网站结合呢?不会直接把参数改了,然后让客户点提交吧?楼主想想这用户体验也太差了吧,客户肯定不认同。这问题纠结了楼主几天,百撕不得骑姐。有一天突然企业QQ一个讨论组的图标老闪,我就纳闷我没加过讨论组啊,打开正想喷(实际也真没喷过,能拉进讨论组都是好友,不过问题解不出来的时候确实很烦)的时候,人物列表那个头像怎么那么熟呢?那不我客户吗?瞬间一盆凉水从头到脚彻底没脾气了!A(TX商务人员):“你们的微信支付做好了没?”,我:“还没呢。”,A:"有什么困难吗?",我:“有,有一些地方不明白。”,A:"我帮你安排个技术支持吧?",楼主欣喜若狂啊,从看到这行信息到打出“好的”发出去绝对是没有超过1秒。。

之后楼主一帆风顺了,如鱼得水了,同事妹纸也变的水灵多了。。

<-------------------------------------------------------------------吐槽结束,华丽的分割线----------------------------------------------------------------->

以下是.NET版本的微信支付:

MD5Util类:

  1. using System;
  2. using System.Security.Cryptography;
  3. using System.Text;
  4.  
  5. namespace tenpayApp
  6. {
  7. /// <summary>
  8. /// MD5Util 的摘要说明。
  9. /// </summary>
  10. public class MD5Util
  11. {
  12. public MD5Util()
  13. {
  14. //
  15. // TODO: 在此处添加构造函数逻辑
  16. //
  17. }
  18.  
  19. /** 获取大写的MD5签名结果 */
  20. public static string GetMD5(string encypStr, string charset)
  21. {
  22. string retStr;
  23. MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider();
  24.  
  25. //创建md5对象
  26. byte[] inputBye;
  27. byte[] outputBye;
  28.  
  29. //使用GB2312编码方式把字符串转化为字节数组.
  30. try
  31. {
  32. inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr);
  33. }
  34. catch (Exception ex)
  35. {
  36. inputBye = Encoding.GetEncoding("GB2312").GetBytes(encypStr);
  37. }
  38. outputBye = m5.ComputeHash(inputBye);
  39.  
  40. retStr = System.BitConverter.ToString(outputBye);
  41. retStr = retStr.Replace("-", "").ToUpper();
  42. return retStr;
  43. }
  44. }
  45. }

RequestHandler类:

  1. using System;
  2. using System.Collections;
  3. using System.Text;
  4. using System.Web;
  5. using System.Xml;
  6. using System.Security.Cryptography;
  7. using System.Collections.Generic;
  8. using System.Text.RegularExpressions;
  9. namespace tenpayApp
  10. {
  11. /**
  12. '签名工具类
  13. ============================================================================/// <summary>
  14. 'api说明:
  15. 'init();
  16. '初始化函数,默认给一些参数赋值。
  17. 'setKey(key_)'设置商户密钥
  18. 'createMd5Sign(signParams);字典生成Md5签名
  19. 'genPackage(packageParams);获取package包
  20. 'createSHA1Sign(signParams);创建签名SHA1
  21. 'parseXML();输出xml
  22. 'getDebugInfo(),获取debug信息
  23. *
  24. * ============================================================================
  25. */
  26. public class RequestHandler
  27. {
  28.  
  29. public RequestHandler(HttpContext httpContext)
  30. {
  31. parameters = new Hashtable();
  32.  
  33. this.httpContext = httpContext;
  34.  
  35. }
  36. /** 密钥 */
  37. private string key;
  38.  
  39. protected HttpContext httpContext;
  40.  
  41. /** 请求的参数 */
  42. protected Hashtable parameters;
  43.  
  44. /** debug信息 */
  45. private string debugInfo;
  46.  
  47. /** 初始化函数 */
  48. public virtual void init()
  49. {
  50. }
  51. /** 获取debug信息 */
  52. public String getDebugInfo()
  53. {
  54. return debugInfo;
  55. }
  56. /** 获取密钥 */
  57. public String getKey()
  58. {
  59. return key;
  60. }
  61.  
  62. /** 设置密钥 */
  63. public void setKey(string key)
  64. {
  65. this.key = key;
  66. }
  67.  
  68. /** 设置参数值 */
  69. public void setParameter(string parameter, string parameterValue)
  70. {
  71. if (parameter != null && parameter != "")
  72. {
  73. if (parameters.Contains(parameter))
  74. {
  75. parameters.Remove(parameter);
  76. }
  77.  
  78. parameters.Add(parameter, parameterValue);
  79. }
  80. }
  81.  
  82. //获取package带参数的签名包
  83. public string getRequestURL()
  84. {
  85. this.createSign();
  86. StringBuilder sb = new StringBuilder();
  87. ArrayList akeys=new ArrayList(parameters.Keys);
  88. akeys.Sort();
  89. foreach(string k in akeys)
  90. {
  91. string v = (string)parameters[k];
  92. if(null != v && "key".CompareTo(k) != )
  93. {
  94. sb.Append(k + "=" + TenpayUtil.UrlEncode(v, getCharset()) + "&");
  95. }
  96. }
  97.  
  98. //去掉最后一个&
  99. if(sb.Length > )
  100. {
  101. sb.Remove(sb.Length-, );
  102. }
  103.  
  104. return sb.ToString();
  105.  
  106. }
  107.  
  108. //创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
  109.  
  110. protected virtual void createSign()
  111. {
  112. StringBuilder sb = new StringBuilder();
  113.  
  114. ArrayList akeys=new ArrayList(parameters.Keys);
  115. akeys.Sort();
  116.  
  117. foreach(string k in akeys)
  118. {
  119. string v = (string)parameters[k];
  120. if(null != v && "".CompareTo(v) !=
  121. && "sign".CompareTo(k) != && "key".CompareTo(k) != )
  122. {
  123. sb.Append(k + "=" + v + "&");
  124. }
  125. }
  126.  
  127. sb.Append("key=" + this.getKey());
  128. string sign = MD5Util.GetMD5(sb.ToString(), getCharset()).ToUpper();
  129.  
  130. this.setParameter("sign", sign);
  131.  
  132. //debug信息
  133. this.setDebugInfo(sb.ToString() + " => sign:" + sign);
  134. }
  135.  
  136. //创建package签名
  137. public virtual string createMd5Sign()
  138. {
  139. StringBuilder sb = new StringBuilder();
  140. ArrayList akeys=new ArrayList(parameters.Keys);
  141. akeys.Sort();
  142.  
  143. foreach(string k in akeys)
  144. {
  145. string v = (string)parameters[k];
  146. if(null != v && "".CompareTo(v) !=
  147. && "sign".CompareTo(k) != && "".CompareTo(v) != )
  148. {
  149. sb.Append(k + "=" + v + "&");
  150. }
  151. }
  152. string sign = MD5Util.GetMD5(sb.ToString(), getCharset()).ToLower();
  153.  
  154. this.setParameter("sign", sign);
  155. return sign;
  156. }
  157.  
  158. //创建sha1签名
  159. public string createSHA1Sign()
  160. {
  161. StringBuilder sb = new StringBuilder();
  162. ArrayList akeys = new ArrayList(parameters.Keys);
  163. akeys.Sort();
  164.  
  165. foreach (string k in akeys)
  166. {
  167. string v = (string)parameters[k];
  168. if (null != v && "".CompareTo(v) !=
  169. && "sign".CompareTo(k) != && "key".CompareTo(k) != )
  170. {
  171. if(sb.Length==)
  172. {
  173. sb.Append(k + "=" + v);
  174. }
  175. else{
  176. sb.Append("&" + k + "=" + v);
  177. }
  178. }
  179. }
  180. string paySign = SHA1Util.getSha1(sb.ToString()).ToString().ToLower();
  181.  
  182. //debug信息
  183. this.setDebugInfo(sb.ToString() + " => sign:" + paySign);
  184. return paySign;
  185. }
  186.  
  187. //输出XML
  188. public string parseXML()
  189. {
  190. StringBuilder sb = new StringBuilder();
  191. sb.Append("<xml>");
  192. foreach (string k in parameters.Keys)
  193. {
  194. string v = (string)parameters[k];
  195. if (Regex.IsMatch(v, @"^[0-9.]$"))
  196. {
  197.  
  198. sb.Append("<" + k + ">" + v + "</" + k + ">");
  199. }
  200. else
  201. {
  202. sb.Append("<" + k + "><![CDATA[" + v + "]]></" + k + ">");
  203. }
  204.  
  205. }
  206. sb.Append("</xml>");
  207. return sb.ToString();
  208. }
  209.  
  210. /** 设置debug信息 */
  211. public void setDebugInfo(String debugInfo)
  212. {
  213. this.debugInfo = debugInfo;
  214. }
  215.  
  216. public Hashtable getAllParameters()
  217. {
  218. return this.parameters;
  219. }
  220.  
  221. protected virtual string getCharset()
  222. {
  223. return this.httpContext.Request.ContentEncoding.BodyName;
  224. }
  225. }
  226. }

ResponseHandler类:

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Specialized;
  4. using System.Text;
  5. using System.Web;
  6. using System.Xml;
  7.  
  8. namespace tenpayApp
  9. {
  10.  
  11. /**
  12. '============================================================================
  13. 'api说明:
  14. 'getKey()/setKey(),获取/设置密钥
  15. 'getParameter()/setParameter(),获取/设置参数值
  16. 'getAllParameters(),获取所有参数
  17. 'isTenpaySign(),是否正确的签名,true:是 false:否
  18. 'isWXsign(),是否正确的签名,true:是 false:否
  19. ' * isWXsignfeedback判断微信维权签名
  20. ' *getDebugInfo(),获取debug信息
  21. '============================================================================
  22. */
  23.  
  24. public class ResponseHandler
  25. {
  26. // 密钥
  27. private string key;
  28.  
  29. // appkey
  30. private string appkey;
  31.  
  32. //xmlMap
  33. private Hashtable xmlMap;
  34.  
  35. // 应答的参数
  36. protected Hashtable parameters;
  37.  
  38. //debug信息
  39. private string debugInfo;
  40. //原始内容
  41. protected string content;
  42.  
  43. private string charset = "gb2312";
  44.  
  45. //参与签名的参数列表
  46. private static string SignField = "appid,appkey,timestamp,openid,noncestr,issubscribe";
  47.  
  48. protected HttpContext httpContext;
  49.  
  50. //初始化函数
  51. public virtual void init()
  52. {
  53. }
  54.  
  55. //获取页面提交的get和post参数
  56. public ResponseHandler(HttpContext httpContext)
  57. {
  58. parameters = new Hashtable();
  59. xmlMap = new Hashtable();
  60.  
  61. this.httpContext = httpContext;
  62. NameValueCollection collection;
  63. //post data
  64. if (this.httpContext.Request.HttpMethod == "POST")
  65. {
  66. collection = this.httpContext.Request.Form;
  67. foreach (string k in collection)
  68. {
  69. string v = (string)collection[k];
  70. this.setParameter(k, v);
  71. }
  72. }
  73. //query string
  74. collection = this.httpContext.Request.QueryString;
  75. foreach (string k in collection)
  76. {
  77. string v = (string)collection[k];
  78. this.setParameter(k, v);
  79. }
  80. if (this.httpContext.Request.InputStream.Length > )
  81. {
  82. XmlDocument xmlDoc = new XmlDocument();
  83. xmlDoc.Load(this.httpContext.Request.InputStream);
  84. XmlNode root = xmlDoc.SelectSingleNode("xml");
  85. XmlNodeList xnl = root.ChildNodes;
  86.  
  87. foreach (XmlNode xnf in xnl)
  88. {
  89. xmlMap.Add(xnf.Name, xnf.InnerText);
  90. }
  91. }
  92. }
  93.  
  94. /** 获取密钥 */
  95. public string getKey()
  96. { return key;}
  97.  
  98. /** 设置密钥 */
  99. public void setKey(string key, string appkey)
  100. {
  101. this.key = key;
  102. this.appkey = appkey;
  103. }
  104.  
  105. /** 获取参数值 */
  106. public string getParameter(string parameter)
  107. {
  108. string s = (string)parameters[parameter];
  109. return (null == s) ? "" : s;
  110. }
  111.  
  112. /** 设置参数值 */
  113. public void setParameter(string parameter,string parameterValue)
  114. {
  115. if(parameter != null && parameter != "")
  116. {
  117. if(parameters.Contains(parameter))
  118. {
  119. parameters.Remove(parameter);
  120. }
  121.  
  122. parameters.Add(parameter,parameterValue);
  123. }
  124. }
  125.  
  126. /** 是否财付通签名,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
  127. * @return boolean */
  128. public virtual Boolean isTenpaySign()
  129. {
  130. StringBuilder sb = new StringBuilder();
  131.  
  132. ArrayList akeys=new ArrayList(parameters.Keys);
  133. akeys.Sort();
  134.  
  135. foreach(string k in akeys)
  136. {
  137. string v = (string)parameters[k];
  138. if(null != v && "".CompareTo(v) !=
  139. && "sign".CompareTo(k) != && "key".CompareTo(k) != )
  140. {
  141. sb.Append(k + "=" + v + "&");
  142. }
  143. }
  144.  
  145. sb.Append("key=" + this.getKey());
  146. string sign = MD5Util.GetMD5(sb.ToString(), getCharset()).ToLower();
  147. this.setDebugInfo(sb.ToString() + " => sign:" + sign);
  148. //debug信息
  149. return getParameter("sign").ToLower().Equals(sign);
  150. }
  151.  
  152. //判断微信签名
  153. public virtual Boolean isWXsign()
  154. {
  155. StringBuilder sb = new StringBuilder();
  156. Hashtable signMap = new Hashtable();
  157.  
  158. foreach (string k in xmlMap.Keys)
  159. {
  160. if (k != "SignMethod" && k != "AppSignature")
  161. {
  162. signMap.Add(k.ToLower(), xmlMap[k]);
  163. }
  164. }
  165. signMap.Add("appkey", this.appkey);
  166.  
  167. ArrayList akeys = new ArrayList(signMap.Keys);
  168. akeys.Sort();
  169.  
  170. foreach (string k in akeys)
  171. {
  172. string v = (string)signMap[k];
  173. if (sb.Length == )
  174. {
  175. sb.Append(k + "=" + v);
  176. }
  177. else
  178. {
  179. sb.Append("&" + k + "=" + v);
  180. }
  181. }
  182.  
  183. string sign = SHA1Util.getSha1(sb.ToString()).ToString().ToLower();
  184.  
  185. this.setDebugInfo(sb.ToString() + " => SHA1 sign:" + sign);
  186.  
  187. return sign.Equals(xmlMap["AppSignature"]);
  188.  
  189. }
  190.  
  191. //判断微信维权签名
  192. public virtual Boolean isWXsignfeedback()
  193. {
  194. StringBuilder sb = new StringBuilder();
  195. Hashtable signMap = new Hashtable();
  196.  
  197. foreach (string k in xmlMap.Keys)
  198. {
  199. if (SignField.IndexOf(k.ToLower()) != -)
  200. {
  201. signMap.Add(k.ToLower(), xmlMap[k]);
  202. }
  203. }
  204. signMap.Add("appkey", this.appkey);
  205.  
  206. ArrayList akeys = new ArrayList(signMap.Keys);
  207. akeys.Sort();
  208.  
  209. foreach (string k in akeys)
  210. {
  211. string v = (string)signMap[k];
  212. if ( sb.Length == )
  213. {
  214. sb.Append(k + "=" + v);
  215. }
  216. else
  217. {
  218. sb.Append("&" + k + "=" + v);
  219. }
  220. }
  221.  
  222. string sign = SHA1Util.getSha1(sb.ToString()).ToString().ToLower();
  223.  
  224. this.setDebugInfo(sb.ToString() + " => SHA1 sign:" + sign);
  225.  
  226. return sign.Equals( xmlMap["AppSignature"] );
  227.  
  228. }
  229.  
  230. /** 获取debug信息 */
  231. public string getDebugInfo()
  232. { return debugInfo;}
  233.  
  234. /** 设置debug信息 */
  235. protected void setDebugInfo(String debugInfo)
  236. { this.debugInfo = debugInfo;}
  237.  
  238. protected virtual string getCharset()
  239. {
  240. return this.httpContext.Request.ContentEncoding.BodyName;
  241.  
  242. }
  243.  
  244. }
  245. }

SHA1Util:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Security.Cryptography;
  5.  
  6. namespace tenpayApp
  7. {
  8. class SHA1Util
  9. {
  10. public static String getSha1(String str)
  11. {
  12. //建立SHA1对象
  13. SHA1 sha = new SHA1CryptoServiceProvider();
  14. //将mystr转换成byte[]
  15. ASCIIEncoding enc = new ASCIIEncoding();
  16. byte[] dataToHash = enc.GetBytes(str);
  17. //Hash运算
  18. byte[] dataHashed = sha.ComputeHash(dataToHash);
  19. //将运算结果转换成string
  20. string hash = BitConverter.ToString(dataHashed).Replace("-", "");
  21. return hash;
  22. }
  23. }
  24. }

TenpayUtil:

  1. using System;
  2. using System.Text;
  3. using System.Web;
  4. namespace tenpayApp
  5. {
  6. /// <summary>
  7. /// TenpayUtil 的摘要说明。
  8. /// 配置文件
  9. /// </summary>
  10. public class TenpayUtil
  11. {
  12. public static string tenpay = "";
  13. public static string partner = ""; //商户号
  14. public static string key = ""; //密钥
  15. public static string appid = "";//appid
  16. public static string appkey = "";//paysignkey(非appkey)
  17. public static string tenpay_notify = "http://localhost/payNotifyUrl.aspx"; //支付完成后的回调处理页面,*替换成notify_url.asp所在路径
  18.  
  19. public TenpayUtil()
  20. {
  21.  
  22. }
  23. public static string getNoncestr()
  24. {
  25. Random random = new Random();
  26. return MD5Util.GetMD5(random.Next().ToString(), "GBK");
  27. }
  28.  
  29. public static string getTimestamp()
  30. {
  31. TimeSpan ts = DateTime.UtcNow - new DateTime(, , , , , , );
  32. return Convert.ToInt64(ts.TotalSeconds).ToString();
  33. }
  34.  
  35. /** 对字符串进行URL编码 */
  36. public static string UrlEncode(string instr, string charset)
  37. {
  38. //return instr;
  39. if(instr == null || instr.Trim() == "")
  40. return "";
  41. else
  42. {
  43. string res;
  44.  
  45. try
  46. {
  47. res = HttpUtility.UrlEncode(instr,Encoding.GetEncoding(charset));
  48.  
  49. }
  50. catch (Exception ex)
  51. {
  52. res = HttpUtility.UrlEncode(instr,Encoding.GetEncoding("GB2312"));
  53. }
  54.  
  55. return res;
  56. }
  57. }
  58.  
  59. /** 对字符串进行URL解码 */
  60. public static string UrlDecode(string instr, string charset)
  61. {
  62. if(instr == null || instr.Trim() == "")
  63. return "";
  64. else
  65. {
  66. string res;
  67.  
  68. try
  69. {
  70. res = HttpUtility.UrlDecode(instr,Encoding.GetEncoding(charset));
  71.  
  72. }
  73. catch (Exception ex)
  74. {
  75. res = HttpUtility.UrlDecode(instr,Encoding.GetEncoding("GB2312"));
  76. }
  77.  
  78. return res;
  79.  
  80. }
  81. }
  82.  
  83. /** 取时间戳生成随即数,替换交易单号中的后10位流水号 */
  84. public static UInt32 UnixStamp()
  85. {
  86. TimeSpan ts = DateTime.Now - TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(, , ));
  87. return Convert.ToUInt32(ts.TotalSeconds);
  88. }
  89. /** 取随机数 */
  90. public static string BuildRandomStr(int length)
  91. {
  92. Random rand = new Random();
  93.  
  94. int num = rand.Next();
  95.  
  96. string str = num.ToString();
  97.  
  98. if(str.Length > length)
  99. {
  100. str = str.Substring(,length);
  101. }
  102. else if(str.Length < length)
  103. {
  104. int n = length - str.Length;
  105. while(n > )
  106. {
  107. str.Insert(, "");
  108. n--;
  109. }
  110. }
  111.  
  112. return str;
  113. }
  114.  
  115. }
  116. }

页面代码:

  1. using System;
  2. using System.Data;
  3. using System.Configuration;
  4. using System.Web;
  5. using System.Web.Security;
  6. using System.Web.UI;
  7. using System.Web.UI.WebControls;
  8. using System.Web.UI.WebControls.WebParts;
  9. using System.Web.UI.HtmlControls;
  10. using System.Collections;
  11. using tenpayApp;
  12. //=================================
  13. //JSAPI支付
  14. //=================================
  15. public partial class _Default : System.Web.UI.Page
  16. {
  17. public String appId = TenpayUtil.appid;
  18. public String timeStamp = "";
  19. public String nonceStr = "";
  20. public String packageValue = "";
  21. public String paySign = "";
  22.  
  23. protected void Page_Load(object sender, EventArgs e)
  24. {
  25. string sp_billno = Request["order_no"];
  26. //当前时间 yyyyMMdd
  27. string date = DateTime.Now.ToString("yyyyMMdd");
  28.  
  29. if (null == sp_billno)
  30. {
  31. //生成订单10位序列号,此处用时间和随机数生成,商户根据自己调整,保证唯一
  32. sp_billno = DateTime.Now.ToString("HHmmss") + TenpayUtil.BuildRandomStr();
  33. }
  34. else
  35. {
  36. sp_billno = Request["order_no"].ToString();
  37. }
  38.  
  39. sp_billno = TenpayUtil.partner + sp_billno;
  40.  
  41. //创建支付应答对象
  42. RequestHandler packageReqHandler = new RequestHandler(Context);
  43. //初始化
  44. packageReqHandler.init();
  45.  
  46. //设置package订单参数
  47. packageReqHandler.setParameter("partner", TenpayUtil.partner); //商户号
  48. packageReqHandler.setParameter("fee_type", ""); //币种,1人民币
  49. packageReqHandler.setParameter("input_charset", "GBK");
  50. packageReqHandler.setParameter("out_trade_no", sp_billno); //商家订单号
  51. packageReqHandler.setParameter("total_fee", ""); //商品金额,以分为单位(money * 100).ToString()
  52. packageReqHandler.setParameter("notify_url", TenpayUtil.tenpay_notify); //接收财付通通知的URL
  53. packageReqHandler.setParameter("body", "JSAPIdemo"); //商品描述
  54. packageReqHandler.setParameter("spbill_create_ip", Page.Request.UserHostAddress); //用户的公网ip,不是商户服务器IP
  55.  
  56. //获取package包
  57. packageValue = packageReqHandler.getRequestURL();
  58.  
  59. //调起微信支付签名
  60. timeStamp = TenpayUtil.getTimestamp();
  61. nonceStr = TenpayUtil.getNoncestr();
  62.  
  63. //设置支付参数
  64. RequestHandler paySignReqHandler = new RequestHandler(Context);
  65. paySignReqHandler.setParameter("appid", appId);
  66. paySignReqHandler.setParameter("appkey", TenpayUtil.appkey);
  67. paySignReqHandler.setParameter("noncestr", nonceStr);
  68. paySignReqHandler.setParameter("timestamp", timeStamp);
  69. paySignReqHandler.setParameter("package", packageValue);
  70. paySign = paySignReqHandler.createSHA1Sign();
  71.  
  72. //获取debug信息,建议把请求和debug信息写入日志,方便定位问题
  73. //string pakcageDebuginfo = packageReqHandler.getDebugInfo();
  74. //Response.Write("<br/>pakcageDebuginfo:" + pakcageDebuginfo + "<br/>");
  75. //string paySignDebuginfo = paySignReqHandler.getDebugInfo();
  76. //Response.Write("<br/>paySignDebuginfo:" + paySignDebuginfo + "<br/>");
  77.  
  78. }
  79. }

微信支付http://www.cnblogs.com/True_to_me/p/3565039.html的更多相关文章

  1. app使用微信支付成功后,点击返回到该app却跳到另外一个app去了

    刚接手了公司iOS的两个APP, 现在碰到了这样一个问题: 有一台iPhone在一个APP中使用了微信支付,支付成功后,点击返回到该APP,结果却跳到了另外一个APP去了. 这两个APP都是公司开发的 ...

  2. 企业号微信支付 公众号支付 H5调起支付API示例代码 JSSDK C# .NET

    先看效果 1.本文演示的是微信[企业号]的H5页面微信支付 2.本项目基于开源微信框架WeiXinMPSDK开发:https://github.com/JeffreySu/WeiXinMPSDK 感谢 ...

  3. 微信支付(.NET版)

    前段时间做了网页版微信支付,遇到很多问题,不过最终还是解决了,现在在这里记录下开发流程以及说明,给其他人一些参考. 一.准备工作     首先肯定得先要开通微信支付功能,之前开通微信支付需要三万的押金 ...

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

    http://www.cnblogs.com/zskbll/p/wxpay.html 研究微信开发一年多了,每个新接口,都会第一时间进行研究.微信支付开放很久,一直没机会接触到支付接口,等了好久终于从 ...

  5. ***CodeIgniter集成微信支付(转)

    微信支付Native扫码支付模式二之CodeIgniter集成篇  http://www.cnblogs.com/24la/p/wxpay-native-qrcode-codeigniter.html ...

  6. iOS之微信支付

    前言:下面介绍微信支付的开发流程的细节,图文并茂,你可以按照我的随笔流程过一遍代码.包你也学会了微信支付.而且支付也是面试常问的内容. 正文: 1.首先在开始使用微信支付之前,有一些东西是开发者必须要 ...

  7. 微信支付开发(1) JS API支付

    关键字:微信支付 微信支付v3 jsapi支付 统一支付 Native支付 prepay_id 作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/wxpayv3 ...

  8. 微信支付开发(7) H5支付

    关键字:微信支付 微信支付v3 H5支付 wap支付 prepay_id 作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/wxpayv3_h5.html 本文 ...

  9. Atitit 微信支付 支付结果通用通知

    Atitit 微信支付 支付结果通用通知 Wechat hto sh ma  返回页面return_url - 熊佳佳的博客 d ,only notyfi url-... 接口链接 该链接是通过[统一 ...

随机推荐

  1. css字体图标的制作和使用。

    css字体图标的制作和使用. 在项目开发的过程中,我们会经常用到一些图标.但是我们在使用这些图标时,往往会遇到失真的情况,而且图片数量很多的话,页面加载就越慢.所以,我们可以使用字体图标的方式来显示图 ...

  2. 功能规格说明书Version2

    此功能规格说明书是Week8 功能规格说明书的第二个版本, 版本1地址:http://www.cnblogs.com/Z-XML/p/3407687.html 此功能规格说明书是面向用户的,所以作者将 ...

  3. java获取本机器的IP(linux和windows)

    目录 描述 方案描述 获取Windows下的IP 获取linux下的IP 判断操作系统的类型 最后将上面三个方法进行整合 参考 描述 由于项目是部署在集群上的,需要项目能够自动采集各机器的信息.jav ...

  4. iMuseum

    iMuseum 每日环球展览 iMuseum https://itunes.apple.com/cn/app/%E6%AF%8F%E6%97%A5%E7%8E%AF%E7%90%83%E5%B1%95 ...

  5. node和gulp实现前端工程自动化(附:gulp常用插件)

    /** * 1. LESS编译 压缩 合并 * 2. JS合并 压缩 混淆 * 3. img复制 * 4. html压缩 */ // 在gulpfile中先载入gulp包,因为这个包提供了一些APIv ...

  6. 从CUBIC/BBR的TCP ACK失速说起

    上周有同事问,延迟ACK到底对应用层会产生什么后果,我也不知道该如何作答,于是丢了一个链接: TCP之Delay ACK在Linux和Windows上实现的异同-Linux的自适应ACK: 是的,这是 ...

  7. 【ZJ选讲·字符串折叠】

    给一个字符串(len<=100) 把这个字符串折叠(就是压缩) 记 X(子串) 表示重复 X次该子串 比如 3(orz)  orzorzorz  来点神奇例子: AAAAAAAAAA ...

  8. 假的kd-tree小结

    至今还不是很体会kd-tree这种东西,只不过体会了一种解决某些枚举问题的方法,就是当我们有一群元素,我们要到一个答案,答案在这些元素中的某个或某几个中,我们就会枚举他们,然而我们发现这样做十分低效, ...

  9. malloc calloc realloc

    三个函数的申明分别是: void* realloc(void* ptr, unsigned newsize); void* malloc(unsigned size); void* calloc(si ...

  10. Active Directory Domain Services in Windows Server 2016/2012

    Applies To: Windows Server 2016, Windows Server 2012 R2, Windows Server 2012 You will find links to ...