返回首页
专题
网络编程
ASPjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 .NETjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 PHPjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 JSPjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 C#jrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 Javajrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 Delphijrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 VBjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 C/C++jrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 Android开发 IOS开发 Windows Phone开发 Pythonjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 Rubyjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 移动开发 其他编程jrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播
网页制作
HTMLjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 CSSjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 Dreamweaverjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 FrontPagesjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 Javascriptjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 web前端
数据库
SqlServer MySql Oracle Access DB2 SQLite 其他数据库
图形设计
photoshopjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 Fireworksjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 CorelDrawjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 Illustratorjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 AutoCadjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 FLASHjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播
操作系统
Windows xpjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 Windows 7jrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 Windows 8jrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 Windows 2003jrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 Windows Server 2008jrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 Linuxjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 Windows 10
网站运营
建站经验 SEO优化 站长心得 网赚技巧 网站推广 站长故事
手机学院
手机速递 安卓jrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 iphonejrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 手机评测 手机技巧 手机知识 手机应用 手机游戏 手机导购
网店宝典
开店指导 开店经验 网店装修 网店推广 网店seo 网购技巧
软件jrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播
办公软件 系统工具 媒体工具 压缩工具 图文处理 文件管理
范文之家
自我介绍 自我鉴定 写作模板 合同范本 工作总结 贺词祝福语 演讲致辞 思想汇报 入党申请书 实习报告 心得体会 工作计划 简历模板 工作报告 导游词 评语寄语 口号大全 策划书范文
信息工程
软件工程 企业开发 系统运维 软件测试
移民之家
移民动态 移民政策 移民百科 移民生活 技术移民 投资移民
知识大全
母婴 数码 摄影 装修 美文 常识 时尚 婚嫁 美食 养生 旅游 兴趣 职场 教育 文学 健康
问答大全
电脑网络 手机数码 QQ专区 生活 游戏 体育运动 娱乐明星 休闲爱好 文化艺术 社会民生 教育科学 健康医疗 商业理财 情感家庭 地区问题 其他
编程问答
IOS Android .NET Java C/C++ Delphi VC/MFC 其他语言 PHP MSSQL MYSQL Oracle 其他数据库 Web开发 Windows Linux 硬件/嵌入开发 网络通信 移动开发 云计算 企业IT 游戏开发
笑话大全
幽默笑话 爱情笑话 成人笑话 校园笑话 爆笑笑话 综合笑话 古代笑话 现代笑话 国外笑话

微信支付JS-SDK最新版,从0开始

来源:互联网  时间:2015/2/3 13:56:36

前段时间微信发布JS-SDK接口,其中包括了微信支付,然后就勾起了我一个想法,那是不是我可以在微信上做个H5朋友给我转钱啊,后来才觉得这个想法有多煞笔。

好吧,言归正传,我也是从0开发,摸索了很多资料,网上的jrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播详细不详细,我不知道,反正没有我的详细


微信网页支付,ASP.NET开发,往下看吧。


首先我要先说一下我遇到的几个问题

1、修改测试目录失败,mch_id和appid没有关联关系。

2、签名错误。

3、公众号支付签名错误,无法发起该交易。


第一个错误,我无奈了1整天时间,各种百度,谷歌,都没有找到这样的错误,千万别问客服啊,她们只会让你看文档,后来是直接联系的一个微信支付技术人员把appid给他之后就解决了,如果你们也遇到这样的问题可以发邮件给wepayTS(微信支付技术支持) 

好,现在开始开发:

第一步:配置js-sdk配置信息

api:    微信JS-SDK说明文档

使用JS-SDK 必须引用微信js文件:

然后 配置config 权限验证:


 wx.config({
            debug: false, 
            appId: 'wxc94d5d50202f9dcf', // 必填,公众号的唯一标识
            timestamp: <%=wxconfig.timestamp%>,//时间戳
            nonceStr: "<%=wxconfig.nonceStr%>",//随机字符串
            signature: "<%=wxconfig.signature%>", //权限签名 与微信支付签名没有半毛钱关系
            jsApiList: [  // 必填,需要使用的JS接口列表
                'onMenuShareTimeline',
                'onMenuShareAppMessage',
                'getNetworkType',
                'chooseWXPay'
              ]
        });
所有的权限验证算吗 为了安全 需要在后台程序实现


这里的算法是用SHA1,字典排序,而微信支付全部用MD5,注意参数的大小写,url是当前请求网页的url 包括参数。#前面的所有。(需要去公众平台绑定安全域名否则会报invalid url domain 的错误


        /// 
        /// 获取JS-SDK签名包
        /// 
        /// 
        public wxHandleModel.wxJSconfig GetTicket(string url)
        {
            wxservice.wxSoapClient wxs = new wxservice.wxSoapClient();
            wxs.Get_access_token(appid);
            string ticket = wxs.Get_access_ticket(appid, false);   //验证算法签名的ticket,
            wxHandleModel.wxJSconfig wxconfig = new wxHandleModel.wxJSconfig();
            wxconfig.appId = appid;    
            wxconfig.nonceStr = GenerateCheckCode(16); //随机字符串
            wxconfig.timestamp = ConvertDateTimeInt(DateTime.Now);   //时间戳
            wxconfig.signature = SHA1("jsapi_ticket=" + ticket + "&noncestr=" + wxconfig.nonceStr + "×tamp=" + wxconfig.timestamp + "&url=" + url);
            return wxconfig;
        }


api文档中说的非常的清楚,生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次

数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket


wxservice 是我写的web service用来获取更新ticket的,这是看自己如何写方便,一定要缓存,ticket调取频率非常有限。


常见的错误:

invalid url domain   当前页面所在域名与使用的appid没有绑定

invalid signature     签名错误,可以在wx.error函数中 写一个ajax,更新ticket,刷新当前页,如果还是出现这个错误的,检查签名生成参数。

the permission value is offline verifying     这个错误是因为config没有正确执行,或者是调用的JSAPI没有传入config的jsApiList参数中

function not exist                      当前客户端版本不支持该接口,请升级到新版体验,好像是要6.01以上的版本

更多错误 看api吧。


签名写好之后,返回前台JS-sdk所有需要页面加载执行的函数需要写在微信加载事件中,wx.ready(function () {     });  


        document.querySelector('#payOK').onclick = function () {
             wx.chooseWXPay({
                timestamp: <%=wxpayconfig.timestamp%>, // 支付签名时间戳
                nonceStr: "<%=wxpayconfig.nonceStr%>", // 支付签名随机串
                package: "<%=wxpayconfig.package%>", // 统一支付接口返回的package包
                signType: "<%=wxpayconfig.signType%>", // 签名方式,'MD5'
                paySign: "<%=wxpayconfig.paySign %>", // 支付签名
                success: function (res) {
                   if(res.err_msg == "get_brand_wcpay_request:ok" )
                   {
                        alert("支付成功");
                   // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。 
                   }  
                }
            });
          };
这是微信支付点击支付执行的事件,当然支付签名和package包也要在后台实现



第二步:微信支付参数和签名

如果你没有遇到我上面说的第一个问题的话,那么你应该可以直接在微信支付的开发配置中设置 测试支付目录,ok,下面签名算法

使用微信支付前都是通过  统一下单  接口为当前设置一个预支付交易会话标识prepay_id,支付签名和package包都需要用到他。

请求参数并不是所有的都需要,如果你JSAPI支付的话那么openid必须有,如果是NATIVE那么商品ID必须有,文档写的很详细,我是JSAPI支付

        protected Hashtable Parameters = new Hashtable();  //请求参数集合
        string appid = ConfigurationManager.AppSettings["appid"]; //appid
        string appkey = ConfigurationManager.AppSettings["appkey"]; //商户密匙
        string mchid = ConfigurationManager.AppSettings["mchid"]; //商户号



这里appkey要说明一下,这是微信支付审核成功之后会收到一封邮件,邮件中有appid 商户号,商户后台登录上号和密码,登录到商户后台:账户设置-安全设置-切换到API安全,下载证书,下面有一个api密匙,进去填写一个字符串 ,保存,后续两次签名都会需要它


                //设置package订单参数
                SetParameter("appid", appid);		  //公众账号ID
                SetParameter("body", "gtsw-wxpaytest"); //商品描述
                SetParameter("mch_id", mchid);		  //商户号
                SetParameter("nonce_str", wxhand.GenerateCheckCode(16).ToLower());     //随机字符串
                SetParameter("notify_url", "http://***/wxpay/paycallback.aspx");		    //接收财付通通知的URL
                SetParameter("openid", openid);	                    //openid
                SetParameter("out_trade_no", wxhand.ConvertDateTimeInt(DateTime.Now) + wxhand.GenerateCheckCode(8));		//商家订单号
                SetParameter("spbill_create_ip", sIp);   //用户的公网ip,不是商户服务器IP
                SetParameter("total_fee", "1");			        //商品金额,以分为单位(money * 100).ToString()
                SetParameter("trade_type", "JSAPI");	                    //交易类型
                //签名,需要除sin以外所有的参数都得参与签名
                string sign = wxhand.getSin(Parameters, appkey);
                SetParameter("sign", sign);//签名
                string pkxml = wxhand.getDataXML(Parameters);
                //发送给微信支付统一下单接口
                string urlFormat = "https://api.mch.weixin.qq.com/pay/unifiedorder";
                var result = wxhand.GetPage(urlFormat, pkxml);
                //接收微信返回的xml数据
                var res = XDocument.Parse(result);



openid可以通过网页授权得到 传送门  ,这里我们只需要得到一个OPENID,所以授权类型为 scope=snsapi_base静默授权就好了。

setParameter方法是给Hash包里添加参数:

        /// 
        /// 设置发送数据包参数值
        /// 
        /// 
        /// 
        public void SetParameter(string parameter, string parameterValue)
        {
	   if (parameter != null && parameter != "")
            {
                if (Parameters.Contains(parameter))
                {
                    Parameters.Remove(parameter);
                }
		Parameters.Add(parameter, parameterValue);
            }
        }

sign是获取prepay_id的签名,参与签名的参数是:除了sign以外的所有参数。(!!!!!!!!MD5加密的结果要大写啊!!!!!!)
appkey是拼接在字符串的最后面 &key=appkey

        /// 
        /// 获取签名
        /// 
        /// sin签名
        public string getSin(Hashtable ParametersTosin,string appkey)
        {
            StringBuilder sb = new StringBuilder();
            ArrayList akeys = new ArrayList(ParametersTosin.Keys);
            akeys.Sort();
            foreach (string k in akeys)
            {
                string v = (string)ParametersTosin[k];
                if (null != v && "".CompareTo(v) != 0 && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0)
                {
                    sb.Append(k + "=" + v + "&");
                }
            }
            sb.Append("key=" + appkey);
            string sign = MD5(sb.ToString()).ToUpper();
            return sign;
        }



好的,如果你按照上面来的话,应该是无误的啦,那么把数据包发送给统一下单的接口之后,会收到返回的xml数据包

拿到最重要的prepay_id了,最后的支付签名需要用到它。


                   if (res.Element("xml").Element("return_code").Value == "SUCCESS")
                    {
                        //下单成功返回
                        string repayId = res.Element("xml").Element("prepay_id").Value;
                        wxpayconfig = new wxHandleModel.wxPayconfig();
                        wxpayconfig = wxhand.GetwxPay(repayId);
                    }
                    else
                    {
                        //下单失败返回
                        wxpayconfig = new wxHandleModel.wxPayconfig();
                        if (res.Element("xml").Element("return_msg").Value.Contains("openid"))
                        {
                            //如果错误信息为无效的openid,跳转到授权页面重新授权。
                            Response.Redirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxc94d5d50202f9dcf&redirect_uri=" + oauthurl + "&response_type=code&scope=snsapi_base&state=1#wechat_redirect");
                        }
                        else
                        {
                            //下单错误信息。
                            Response.Write("return_code:" + res.Element("xml").Element("return_code").Value + ",return_msg:" + res.Element("xml").Element("return_msg").Value);
                        }
                    }

最后就是要获取微信支付JS中需要的参数了 在 GetwxPay 方法中



        /// 
        /// 获取微信支付JS包
        /// 
        /// 预支付ID
        /// 
        public wxHandleModel.wxPayconfig GetwxPay(string repayId)
        {
            wxHandleModel.wxPayconfig wxpayconfig = new wxHandleModel.wxPayconfig();
            string package = string.Format("prepay_id={0}", repayId);   //package包
            wxpayconfig.package = package; 
            wxpayconfig.timestamp = ConvertDateTimeInt(DateTime.Now);   //时间戳
            string nostr = GenerateCheckCode(16);                       //随机串
            wxpayconfig.nonceStr = nostr;
            wxpayconfig.signType = "MD5";                               //加密方式
            string stringA = string.Format(@"appId={0}&nonceStr={1}&package={2}&signType={3}&timeStamp={4}&key={5}"
                , appid, wxpayconfig.nonceStr, wxpayconfig.package, wxpayconfig.signType, wxpayconfig.timestamp, appkey);
            wxpayconfig.paySign = MD5(stringA).ToUpper();                //微信支付签名
            return wxpayconfig;
        }

这是最后一步了,也是最终要的一步,随机串和时间戳没什么说的


package 一定要是package=‘wx12212vghdsad’ 这样的形式 , appkey密匙拼接在加密的字符串最后中

参与签名的参数大小写一定要注意,appId  不要写成 appid ,大小写加密出来的字符不同  最后转大写。


还记得请求参数里的回调URLnotify_url 吗,这个也非常重要,

他说:支付完成后,微信会把相关支付结果和用户信息发送给商户,商户需要接收处理,并返回应答。

所以  这是 paycallback.aspx 内的代码

            string postStr = "";
            /// 
            /// 微信支付回调 
            /// 
            /// 
            if (Request.HttpMethod.ToLower() == "post")
            {
                Stream s = System.Web.HttpContext.Current.Request.InputStream;
                byte[] b = new byte[s.Length];
                s.Read(b, 0, (int)s.Length);
                postStr = Encoding.UTF8.GetString(b);

                if (!string.IsNullOrEmpty(postStr))
                {
                    //封装请求类
                    var res = XDocument.Parse(postStr);
		  if (res.Element("xml").Element("return_code").Value == "SUCCESS")
                    {
                        WriteTxt(string.Format(@"商户订单号:{0},订单状态:{1},金额:{2},时间:{3},openid:{4}",
                            res.Element("xml").Element("out_trade_no").Value,
                            res.Element("xml").Element("result_code").Value,
                            res.Element("xml").Element("total_fee").Value,
                            res.Element("xml").Element("time_end").Value,
                            res.Element("xml").Element("openid").Value
                            ));
                        //保存订单信息,并返回微信应答
                        Response.Write(string.Format(@"
                               
                               
                            "));
                    }
                    else
                    {
                        WriteTxt(res.ToString());
                        Response.Write(string.Format(@"
                               
                               
                            ", "FAIL", res.Element("xml").Element("return_msg").Value));
                    }
                }
            }


因为是测试,我就把信息保存在了 记事本里,方便查看,一开始我只是接收了微信通知的信息,但是我没有回应 然后记事本里就会增加好多条同一个订单的信息

所以一定要回应微信,一定要以上面代码中 xml的形式,回复之后 你会收到微信支付公众号给你推送的一条消费消息。







上一篇C#实现异步消息队列
下一篇C#判断上传文件是否是图片以防止木马上传的方法
明星图片
相关文章
《微信支付JS-SDK最新版,从0开始》由码蚁之家搜集整理于网络,
联系邮箱:mxgf168#qq.com(#改为@)