净核心之微信支付之公众号、H5支付详解
前言
本篇主要记录微信支付中公众号及H5支付全过程。
准备篇
公众号或者服务号(并开通微信支付功能)、商户平台中开通支付插件支付、H5支付。
配置篇
公众号或者服务号中-开发-开发者工具-网络开发者工具-绑定为开发者
公众号或者服务号中-公众号设置-功能设置:填写业务域名、JS安全域名、网页授权域名示例:pay.one.com
商户平台中-产品中心-开发配置- JSAPI支付授权目录填写:http://支付。一个。com/http://pay . one.com/微信公众号/PubPay/-H5支付填写:pay.one.com
若对配置还有疑问,可参考官方文档:
https://mp.weixin.qq.com/wiki?t=资源/RES _ mainid=MP 1421140842
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?章节=7 _ 7索引=6
开发篇
支付插件支付
本演示是基于支付的软件开发工具包(软件开发工具包)开发。具体详情可参考:https://github.com/essisoft/Payment
首先使用框架安装付款:
安装包:本质软件AspNetCore。付款。微信-版本2.3.2
建一个模型:微信公众号
公共类微信公众号视图模型{[必选][显示(名称='out_trade_no')]公共字符串OutTradeNo { get设置;}[必选][显示(名称='body')]公共字符串Body { get设置;}[必选][显示(名称=' total _ fee ')]public int TotalFee { get;设置;}[必选][显示(名称='spbill_create_ip')]公共字符串SpbillCreateIp { get设置;}[必需][显示(名称='notify_url')]公共字符串NotifyUrl { get设置;}[必选][显示(名称='trade_type')]公共字符串TradeType { get设置;}[必选][显示(名称='openid')]公共字符串OpenId { get设置;} }微信支付控制器:
//微信支付请求客户端(用于处理请求与响应)private readonly IWeChatPayClient _ client;private readonly ilogegwicatpaycontroller _ logger;private IHttpContextAccessor _ accessor;公众的微信公众号控制器(IWeChatPayClient客户端,IHttpContextAccessor访问器,ILoggerWeChatPayController记录器){ _ client=client_访问者=访问者;_ logger=logger }////摘要///公众号支付////summary////returns/returns[HttpGet]public IActionResult PubPay(){ 0微信公众号payPubPayViewMoDEL=new微信公众号payModel='微信公众号支付测试,输出日期=日期时间.现在。ToString(' yyymmdhmmssfff '),TotalFee=1,//分单位SpbillCreateIp='127.0.0.1 ',NotifyUrl=' http://pay。一个。com/notify/微信公众号/unifiedorder ',TradeType='JSAPI ',OpenId='' //此处需进行授权获取OpenId };返回视图(支付模型);} ///摘要///公众号支付////summary////param name=' viewModel '/param///returns/returns[Httpset]public async taskictionresult PubPay(微信公众号)viewModel) { if(字符串IsNullOrEmpty(视图模型.OpenId)) { ViewData['response']='请返回上级重新进入此页面以获取最新数据;返回视图();} var请求=新微信payunified order request { Body=viewModel .车身,输出编号=视图模型.OutTradeNo,TotalFee=viewModel .TotalFee,SpbillCreateIp=viewModel .SpbillCreateIp,NotifyUrl=viewModel .NotifyUrl,TradeType=viewModel .TradeType,OpenId=viewModel .OpenId //此处需进行授权获取OpenId };定义变量响应=await _ client .ExecuteAsync(请求);如果(响应ReturnCode=='SUCCESS '响应结果代码==' SUCCESS '){ var req=new微信支付H5 callpaymentrequest { Package='预付费_id='响应。预付费id };定义变量参数=等待客户端ExecuteAsync(请求);//将参数(参数)给公众号前端让他在微信内H5调起支付(https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?章节=7 _ 7索引=6)查看数据['参数']=JsonConvert .SerializeObject(参数);ViewData['response']=响应。身体;返回视图();} ViewData['response']=response .身体;返回视图();}注意:公众号或者微信内支付,需要授权获取到用户的OpenId。所以,此处我们还需要进行微信授权,而授权方式有两种,一种是静默授权、一种是需要用户同意,区别是静默授权只能拿到Openid,而经用户同意后可拿到微信头像、昵称、性别等其他信息。
具体可参阅文档:https://mp.weixin.qq.com/wiki?t=资源/RES _ mainid=MP 1421140842
页面:
@使用牛顿英尺.Json@model微信公众号视图模型@{视图数据['Title']='公众号支付-统一下单;} nav aria-label=' bread ' ol class=' bread ' Li class=' bread-item ' a ASP-controller='微信公众号asp-action=“索引”微信支付/a/Li Li class='面包屑-活动项目' aria-current=' page ' @ ViewData[' Title ']/Li/ol/nav br/div class=' card ' div class=' card-body ' form ASP-controller='微信pay ' ASP-action=' PubPay ' div ASP-validation-summary=' All ' class=' text-danger '/div class=' form-group '标签ASP-for=' outradon '/标签输入类型=' text ' class=' form-control ' ASP-for=' .outradeno//div class=' form-group '标签ASP-for=' Body '/标签输入类型=' text ' class=' form-control ' ASP-for=' Body '值=' @模型?body '/div div class=' form-group '标签ASP-for=' TotalFee '/标签输入类型=' text ' class=' form-control ' ASP-for=' TotalFee '值=' @模型?totalFee '/div div class=' form-group '标签ASP-for=' SpbillCreateIp '/标签输入类型=' text ' class=' form-control ' ASP-for=' SpbillCreateIp '值=' @模型?SpbillCreateIp '/div class=' form-group '标签ASP-for=' NotifyUrl '/标签输入类型=' text '类=' form-control ' ASP-for=' NotifyUrl '值=' @模型?通知网址'/div class='表单组'标签ASP-for=' trade type '/标签输入类型=' text ' class=' form-control ' ASP-for=' trade type ' value=' @ Model?交易类型'/div div class='表单-组'标签ASP-for=' OpenId '/标签输入类型=' text ' class=' form-control ' ASP-for=' OpenID '值=' @模型?OpenId//div按钮类型='submit' class='btn btn-primary '提交请求/button button type=' button ' class=' BTNBTN-success ' id=' PayNow '立即支付/button/form HR/form class=' form-horizontal ' div class=' form-group ' label response :/label text area class=' form-control ' row=' 10 ' @ view data[' response ']/text area/div class=' form-group ' label parameter :/label text area class=' form-control ' row=' 3 ' @ view data[' parameter ']/text area/div/form/div @ section Scripts { @ { wait Html .RenderPartialAsync(' _ validationscriptpartial ');} }脚本src=' http : ~/lib/jquery/dist/jquery。量滴js '/script脚本类型=' text/JavaScript ' $(function(){ $(' # PayNow ')).on('click ',function(){ const local=' http://pay。一个。com/微信公众号/RETURn/';窗户。位置。href=' https://打开。微信。QQ。com/connect/oauth 2/authorize?[电子邮件保护]redirect _ uri=' encodeURIComponent(本地)' response _ type=codescope=snsapi _ base state=a #微信_重定向';});});/script此时:报复行动如下:
[HttpGet]公共异步任务结果回收(){ var代码=请求.查询['代码'];变量状态=请求。查询['状态'];oauthttoken令牌模型=new oauthttoken();//通过密码换取令牌if(!字符串IsNullOrEmpty(代码)){ _logger .日志警告('授权成功');视图包代码=代码令牌模型=OauthApi .GetAuthToken(代码,微信公众号);} var请求=新的微信统一订单请求{ Body='微信公众号支付测试,输出日期=日期时间.现在。ToString(' yyymmdhmmssfff '),TotalFee=1,//分单位SpbillCreateIp='127.0.0.1 ',notify URL=' http://pay。一个。com/notify/微信pay/unifiedorder ',TradeType='JSAPI ',OpenId=tokenModel .Openid //此处需进行授权获取OpenId };定义变量响应=await _ client .ExecuteAsync(请求);_记录器.日志警告($ '统一下单接口返回:{回应.返回代码} ');如果(响应ReturnCode=='SUCCESS '响应结果代码==' SUCCESS '){ var req=new微信支付H5 callpaymentrequest { Package='预付费_id='响应。预付费id };定义变量参数=等待客户端ExecuteAsync(请求);//将参数(参数)给公众号前端让他在微信内H5调起支付(https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?章节=7 _ 7索引=6)查看数据['参数']=JsonConvert .SerializeObject(参数);_记录器.日志警告($ '统一下单成功,即将调起微信支付:{ViewData['参数']。ToString()} ');ViewData['response']=响应。身体;返回视图();} ViewData['response']=response .身体;返回视图();}其中:OAuthToken是网页授权返回的实体:
///获取网页授权代币时,返回的实体////摘要公共类oauthttoken : BaseRes {///摘要///网页授权接口调用凭证。注意:此访问令牌与基础支持的访问令牌不同////摘要[JsonProperty('access_token')]公共字符串AccessToken { get设置;} private int _ expire resin//摘要///access_token接口调用凭证超时时间,单位(秒)////summary[JsonProperty(' expires _ in ')]public int expire resin { get { return _ expire resin;}设置{ ExpiresTime=DateTime .现在。添加秒(值);_ expiresIn树脂=值;} } ///摘要///用于刷新access _ token////summary[JsonProperty(' refresh _ token ')]公共字符串RefreshToken { get设置;} ///摘要///用户唯一标识。请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的open id////summary[JsonProperty(' Openid ')]公共字符串Openid { get设置;} ///摘要///用户授权的作用域,使用逗号(,)分隔////摘要[JsonProperty(' Scope ')]公共字符串范围{ get设置;}[JsonProperty(' expires _ time ')]公共DateTime过期时间{ get设置;} ///摘要///只有在用户将公众号绑定到微信开放平台账号后,才会出现该字段////摘要[JsonProperty(' union id ')]公共字符串Unionid { get设置;} }最后贴一下支付成功后的回调函数:
[路由('通知/微信支付')]公共类微信通知控制器:控制器{ private readonly iwechatpaynotifyiclient _ client;private readonly ilogeggwechatpaynotifycontroller _ logger;公众的微信支付通知控制器(IWeChatPayNotifyClient客户端,ilogeg微信paynotifycontroller记录器){ _ client=client _ logger=logger }///摘要///统一下单支付结果通知////summary///returns/returns[Route('统一顺序')][httpset]public async TaskIActionResult统一顺序(){ try { _ logger .日志警告($ '进入回调');var payconfig=OpenApi .GetPayConfig();var notify=await _ client .executeasyncc微信executeasyncc微信ExecuteAsyncWeChatPayUnifiedOrderNotify(请求);_记录器.日志警告($ '返回状态码:{通知.返回代码} ');如果(通知ReturnCode=='SUCCESS') { _logger .日志警告($ '业务结果码:{通知.结果代码} ');如果(通知结果代码=='SUCCESS') { _logger .日志警告($ '支付方式:{通知.trade type } ');_记录器.日志警告($ '商户订单号:{通知.outredeno } ');_记录器.日志警告($ '微信支付订单号:{通知.事务id } ');_记录器.日志警告($ '支付金额:{通知.totalFee } ');返回微信日历结果。成功;} }返回no content();} catch(Exception ex) { _logger .日志警告($ '回调失败:{ex .message } ');返回无内容();} }}然后测试一下支付,查看服务器原木如下:
H5支付
H5支付是指再除开微信浏览器以外的移动端浏览器上进行微信回复操作。
和上面步骤大体一致,有几个地方需要注意
1:客户端互联网协议(互联网协议)问题:H5支付的时候,微信支付系统会根据客户端调起的当前互联网协议(互联网协议的缩写)作为支付Ip,若发现发起支付请求时,ip有问题,则会支付失败,或者提示系统繁忙。这里贴一下我获取互联网协议(互联网协议)的代码:
Utils .GetUserIp(_)访问器. HttpContext);//页面上调用///摘要///穿过代理服务器获取真实IP///summary///返回/返回公共静态字符串GetUserIp(此上下文对象上下文){ var ip=context .请求。标题[' X-转发-用于']。first ordefault();如果(字符串IsNullOrEmpty(ip)) { ip=context .连接。远程IP地址。tostring();}返回知识产权;} 2:雷达类型类型应该是:MWEB
3:若调起微信支付成功后,默认回调到支付首页,若需要设置回调页面,则可以再全球资源定位器(统一资源定位符)中拼接:
///摘要///H5支付////summary////param name=' viewModel '/param///returns/returns[Httpset]public async tasiactionresult H5Pay(微信付费H5 payviewmodel viewModel){ var request=new微信支付统一订单请求{ Body=viewModel .车身,输出编号=视图模型.OutTradeNo,TotalFee=viewModel .TotalFee,SpbillCreateIp=viewModel .SpbillCreateIp,NotifyUrl=viewModel .NotifyUrl,TradeType=viewModel .交易类型};定义变量响应=await _ client .ExecuteAsync(请求);//mweb_url为拉起微信支付收银台的中间页面,可通过访问该全球资源定位器(统一资源定位符)来拉起微信客户端,完成支付,mweb_url的有效期为5分钟如果(回应MwebUrl==null){ view data[' response ']=response .返回消息返回视图();}返回重定向(响应MwebUrl);}
更多详细可参考文档:https://pay.weixin.qq.com/wiki/doc/api/H5.php?章节=15_4
4:支付结果通知:
注意:
1、同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。
2.在后台通知交互中,如果微信收到不符合规范或超时的商家响应,将确定本次通知失败,重新发送通知,直至成功(通知不成功的情况下,微信共发起10次通知,通知频率为15s/15s/30s/3m/10m/24h 4m/30m/30m/60m/3h/3h/3h/3h)
3.如果订单状态不明或未收到微信支付结果通知,建议商家拨打微信支付【查询订单API】确认订单状态。
特别提醒:
1.商户系统必须对支付结果通知的内容进行签字验证,验证退回的订单金额是否与商户端订单金额一致,防止因数据泄露导致“误通知”,造成资金损失。
2.收到通知进行处理时,首先检查相应业务数据的状态,判断通知是否已处理;如果它还没有被处理,那么处理它;如果已经处理,直接成功返回结果。在检查和处理业务数据的状态之前,应该使用数据锁进行并发控制,以避免由于函数重新进入而导致的数据混乱。
最后,您可以测试H5支付并检查返回的日志:
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。
版权声明:净核心之微信支付之公众号、H5支付详解是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。