前段时间做了一个微信支付的网页版,遇到了很多问题,但最终还是解决了。现在我就把开发过程和说明记录在这里,给其他人一些参考。
一、准备工作
首先要先打开微信支付功能。我们开通微信支付之前不需要3万元的押金,所以就做了这个功能。
开发微信支付,需要在微信官方账号和微信商家后台进行相关设置。
1.开发目录配置
微信支付需要在微信官方账号后台进行配置(微信支付=“开发配置”)。这里的授权目录需要是一个在线地址,也就是可以通过互联网访问的地址,微信支付系统需要能够通过互联网访问你的地址。
微信授权目录需要精确到二级或三级目录。示例:如果发起支付的链接是http://www.hxfspace.net/weixin/WeXinPay/WeXinPayChoose,那么配置的目录应该是http://www.hxfspace.net/weixin/WeXinPay/,其中http://www.hxfspace.net是域名微信,虚拟目录是WeXinPay,也就是说,与控制器相关的支付请求都在WeXinPay中进行。
2.OAuth2.0网页授权域名设置
微信支付时会回拨支付请求获取授权码,因此需要在这里设置授权域名。当然,这里的域名和支付授权目录中的域名是一样的。别忘了设置这个。只是当时忘了设置,然后找了半天理由,哭死了。
3.相关参数的准备
要调用微信支付,需要通过脚本向微信支付系统发送支付请求。参数描述见微信官网支付平台https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?章节=7_7index=6
套餐和paySign的生成需要开发者密钥AppSecret、微信商户号和微信支付密钥。这些参数的获取和设置可以在本文//www . JB 51 . net/soft JC/346871 . html中找到。
二、发展历程
废话不多说,只谈整理后的流程:
1.通过微信授权回拨获取授权码
2.交换网页授权访问的授权码_token和openid
3.调用统一订购界面获取预付费id
4.建立jsapi微信支付请求参数,发起支付
5.接收微信支付回拨进行后续操作
三、具体开发(代码)
微信支付只能在线上环境下进行,模式非常不方便,所以最好在开发之初就把好每一个关键位置的日志。
1.通过微信授权回拨获取授权码
首先,将发起支付地址及相关参数发送到微信支付界面。微信支付验证成功后,您将重新请求您的支付地址并携带授权码。
像我一样
//判断网页是否授权,获取授权码,如果没有授权,构建网页获取授权码。并重新请求if(字符串。isnullrempty(请求。query string[' code ']){ string redirecturl=_微信payserevce . getauthorizeurl(account。appid,帐户。redquest URL,' state'' #微信_ redirect ',' snsapi _ base ');返回重定向(redirectUrl);}拼接微信网页授权Url的方法
公共字符串GetAuthorizeUrl(字符串appId,字符串redirectUrl,字符串状态,字符串范围){字符串url=字符串。格式(' https://打开。微信。QQ。com/connect/oauth 2/authorize?appid={ 0 } redirect _ uri={ 1 } response _ type=code scope={ 2 } state={ 3 } ',appId,HttpUtility .UrlEncode(redirectUrl),作用域,状态);/* 这一步发送之后,客户会得到授权页面,无论同意或拒绝,都会返回重定向全球资源定位器(Uniform Resource Locator)页面。 * 如果用户同意授权,页面将跳转至重定向_uri/?代码=代码状态=状态。这里的密码用于换取access_token(和通用接口的访问令牌不通用) * 若用户禁止授权,则重定向后不会带上密码参数,仅会带上状态参数重定向尤里。state=STATE */AppLog .写('获取到授权url: ',AppLog .日志消息类型。调试);返回url}2、通过授权密码来换取网页授权访问令牌和openid
从第一步中获取到授权密码之后,组合网页授权请求url,来获取访问令牌和openid
public Tuplestring,string GetOpenidAndAccessTokenFromCode(字符串appId,字符串代码,字符串appSecret){ tuplesting,字符串元组=null请尝试{字符串url=字符串. format(' https://API。微信。QQ。com/SNS/oauth 2/access _ token?appid={ 0 } secret={ 1 } code={ 2 } grant _ type=authorization _ code ',appId,appSecret,code);字符串结果=微信助手获取(网址);AppLog .写('微信支付-获取openid和访问令牌请求URL :“URL”结果:结果,AppLog .日志消息类型。调试);if(!字符串IsNullOrEmpty(result)){ var JD=Newtonsoft .Json。JsonConvert。反序列化ObjectDictionarystring,string(结果);tuple=new Tuplestring,string(jd['openid'],JD[' access _ token ']);AppLog .写('微信支付-获取openid和访问令牌成功,AppLog .日志消息类型。调试);} } catch (Exception ex) { AppLog .写('微信支付:获取openid和访问_令牌异常,AppLog .调试,例如);}返回元组;}3、调用统一下单接口获取预支付预付身份
这里RequestHandler是用的网上别人封装好的dll,帮你封装好了签名的生成以及一些验证请求dll。可以在这他们官网下载http://weixin.senparc.com/
//吴康伯鲁伯鲁伯鲁伯鲁伯request handler package req handler=new request handler(null);//哎哎哎哎哎packageReqHandler(软件包请求处理程序)。init();//阿云哥时间戳字符串=辅助样式get time tamp();//李亚明(音译)字符串nonceStr=行辅助样式getnoncestr();//沙吾提包包包包包包包包包包包包包包包包包包包包包包包包包包包包包吴亚玲阿金准备好了吗阿金曰包请求处理程序id .设定参数(“appid”,帐户)。appid/云娥包请求处理程序id .设置参数(“mch_id”,帐户)。合作伙伴Id://唉呀呀呀packageReqHandler(软件包请求处理程序)。设定参数(“nonce_str”,non estr);//李亚明(音译)packageReqHandler(软件包请求处理程序)。设定参数(“身体”,账户).体;packageReqHandler(软件包请求处理程序)。设置参数(“out_trade_no”,帐户)。订单序列化程序;//哎哎哎哎packageReqHandler(软件包请求处理程序)。设置参数('总费用',帐户)。总额;//哎哎哎哎,云娥(货币* 100)。ToString() packageReqHandler .设置参数(' sp bill _ create _ IP ',帐户。申请人;//王佳芝(音译)ip地址,吴经盛?吴经盛IP数据包请求处理程序.设置参数(' notify _ URL ',帐户NotifyUrl://韩升洙韩升洙包请求处理程序网址.设定参数(“trade_type”、“jsapi”;//魏冄packageReqHandler(软件包请求处理程序)。设置参数(“openid”,帐户)。openid//你好吗OpenID字符串符号=包请求处理程序.CreateMd5Sign('密钥,帐户).paysignkeypackageReqHandler(软件包请求处理程序)。设定参数(‘签’,签);//你好字符串预付id=字符串。空的;尝试{ string data=package request handler .解析XML();var结果=tenpayv 3 .统一订单(日期);邮件帮助发送邮件('贺盛瑞?贺盛瑞,何忍-结果诶哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟*日期:var res=xdocument .分析(结果):prierid=RES . element(' XML ').元素(“预付费_id”).价值;掌声鼓励。写入('范思哲?范思哲?范思哲准备好了吗阿灵顿是,长官日志消息类型。调试:} catch(异常)。写入('哎哎哎openid(开放id)你好access_tokenu-什么是,长官日志消息类型。调试,例如:邮件帮助发送邮件('范思哲?范思哲?范思哲准备好了吗-什么*前:返回null:}4优哉jsapi(jsapi)菲兰达菲兰达,阿童木(音译)
阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆阿列姆,朱塞佩朱塞佩联署材料东奔西跑
//阿金jsapi(jsapi)request handler paysign req handler=new request handler(null);paySignReqHandler(付款处理程序)。设定参数(' appId ',帐户)。appidpaySignReqHandler(付款处理程序)。设定参数(' timeStamp ',timeStamp):paySignReqHandler(付款处理程序)。设定参数(' non estr ',non cestr);paySignReqHandler(付款处理程序)。设置参数(“包”,字符串).格式(“预付费_id={0},‘预付费id’);paySignReqHandler(付款处理程序)。设定参数(“signType”、“MD5”);字符串付款标志=付款标志请求处理程序.CreateMd5Sign('密钥,帐户).paysignkeywexiatjspayrequestmodel结果模型=new微信jspayrequestmodel { appid=account .AppId、NonceStr=nonceStr、时间戳=时间戳、包=字符串。格式('预付费_id={0},'预付费id ',PaySign=paySign,Sign类型=' MD5 ' };绿筠小姐
私有字符串CreateWeixinJs(微信jspayrequestmodel){ string js=@ ' script type=' text/JavaScript ' callpay();函数JSapiCall(){ Weinjbridge。调用(' GetBrandwcpayrequest ',{ requestParam },函数(RES){ if(RES . err _ msg==' get _ brand _ wcpay _ request : ok '){ window。位置。href=' SuccessURl} else { window。位置。href=' FailURl} } );}函数callpay() { if(类型为weixin bridge==' undefined '){ if(document。addeventlistener){ document。addeventlistener(' weixinsbridgeready ',jsApiCall,false);} else if(文档。attachevent){ document。attach event(' weixinsbridgeready ',JSapicall);文件。attach event(' on weixinsbridgeready ',JSapicall);} } else { JSapiCall();} }/script ';字符串requestParam=字符串.格式(“@”AppID“:“{ 0 }”、“TiMer”:“{ 1 }”、“NoStr”:“{ 2 }”、“package”:“{ 3 }”、“SignType”:“{ 4 }”、“PaySign”:“{ 5 }”、型号。AppId,模型。时间戳,模型。非库存,型号。包装,模型签名类型,型号PaySign);js=js .替换(“请求参数”,请求参数).替换(“成功Url”,模型跳转网址“结果=1”).替换(“failUrl”,模型跳转URl“结果=0”);AppLog .写('生成可执行脚本成功,AppLog .日志消息类型。调试);返回js;}5、接收微信支付回调进行后续操作
回调的时候首先需要验证签名是否正确,保证安全性,签名验证通过之后再进行后续的操作,订单状态、通知啥的。
响应句柄=新的响应句柄(系统网络。httpcontext。电流);bool isSuccess=_微信支付服务processNotify(Reshandler);if(issuence ss){ string result=@ ' XML return _ code![CData[SUCCESS]]/return _ code return _ msg![CDATA[支付成功]]/return _ msg/XML ';HttpContext .回应。写(结果);HttpContext .响应。end();}返回新的EmptyResult();这里有一点需要注意,就是微信支付回调的时候微信会通知八次,好像是这个数吧,所以你需要在第一次收到通知之后,把收到请求这个状态以可扩展标记语言的格式响应给微信支付接口。当然你不进行这个操作也是可以的,再回调的时候每次去判断该订单是否已经回调成功,回调成功则不进行处理就可以了。
原文链接:http://www .cn博客。com/mines nil-forfaith/p/4976006。超文本标记语言
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。