侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

.NET Core 微信小程序退款步骤――(统一退款)

微信(小程序)  /  管理员 发布于 5年前   717

继上一篇".NET Core 微信小程序支付――(统一下单)后",本文将实现统一退款功能,能支付就应该能退款嘛,一般涉及到钱的东西都会比较敏感,所以在设计退款流程时一定要严谨,不能出一点差错,否则你将会面临自己掏腰包的可能,下面我们来讲一讲退款的实现步骤。

退款应该场景及规则

当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后,按照退款规则将支付款按原路退到买家帐号上。

规则

1、交易时间超过一年的订单无法提交退款;

2、微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。申请退款总金额不能超过订单金额。 一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号。

3、请求频率限制:150qps,即每秒钟正常的申请退款请求次数不超过150次

    错误或无效请求频率限制:6qps,即每秒钟异常或错误的退款申请请求不超过6次

4、每个支付订单的部分退款次数不能超过50次

接口地址

接口链接:https://api.mch.weixin.qq.com/secapi/pay/refund

相关参数

官方退款文档

文档地址:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_4&index=6

实现统一退款流程

如果业务有多处退款流程,可以将退款流程进行封装,方便多位置调用;如果公司有同主体下的不同小程序,都需要退款功能,也是可以进行封装,针对不同的小程序进行退款。

去商户后台先下载证书,退款时需要,下图是商户后台下载证书的界面:

引用包:

Senparc.Weixin.WxOpen

Senparc.Weixin.TenPay

注册公众号,小程序信息

services.AddSenparcGlobalServices(Configuration).AddSenparcWeixinServices(Configuration);IRegisterService register = RegisterService.Start(env, senparcSetting.Value).UseSenparcGlobal(false, null);register.UseSenparcWeixin(senparcWeixinSetting.Value, senparcSetting.Value) .RegisterTenpayV3(senparcWeixinSetting.Value, "appid"); 

统一退款代码实现

publicbool RefundProduct(OrdOrderProduct ordOrderProduct, PayOrderMstParam payOrderMstParam, OrdOrderPayItem ordOrderPayItem, string appID, DateTime thisTime, ref string errMsg){ try { OrdOrderPayMst refPay = null; if (!PayOrderManager.CreatePayOrderMST(payOrderMstParam, thisTime, ref refPay, ref errMsg)) {  errMsg = "生成退款单出错!" + errMsg;  return false; } var PayInfo = Senparc.Weixin.Config.SenparcWeixinSetting.Items[appID]; string AppID = PayInfo.WxOpenAppId; string AppSecret = PayInfo.WxOpenAppSecret; string Mch_id = PayInfo.TenPayV3_MchId;//商户号 string Mch_key = PayInfo.TenPayV3_Key;//商户密钥 string notifyUrl = string.Format(PayInfo.TenPayV3_TenpayNotify, "RefundNotifyUrl"); var timeStamp = TenPayV3Util.GetTimestamp(); var nonceStr = TenPayV3Util.GetNoncestr(); //支付源单号 string outTradeNo = ordOrderPayItem.PayNo;//商户订单号/支付单号 refPay.PayNoSource = ordOrderPayItem.PayNo; //退款单号 string outRefundNo = refPay.PayNo;//新退款单号 //支付时的总金额 int totalFee = (int)(ordOrderPayItem.PayPrice * 100); //退款金额 int refundFee = (int)(refPay.PayPrice * 100); string opUserId = PayInfo.TenPayV3_MchId; var dataInfo = new TenPayV3RefundRequestData(AppID, Mch_id, Mch_key,  null, nonceStr, null, outTradeNo, outRefundNo, totalFee, refundFee, opUserId, null, notifyUrl: notifyUrl); //Logger.Info($"PayInfo={PayInfo.SerializeObject()}"); //Logger.Info($"dataInfo={dataInfo.SerializeObject()}"); //var basePath = AppContext.BaseDirectory; //var certPath = Path.Combine(basePath, "Config/apiclient_cert.p12"); //var cert = @"D:\projects\orderapi.trydou.com\Config\apiclient_cert.p12";//根据自己的证书位置修改 //var password = Mch_id;//默认为商户号,建议修改 //配置好证书地址,V3自动识别 var result = TenPayV3.Refund(dataInfo); refPay.PayResult = result.SerializeObject(); //Logger.Info("提交退款申请:" + refPay.PayResult); if (result.return_code.ToUpper() == "SUCCESS" && result.result_code.ToUpper() == "SUCCESS") {  using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))  {  //业务处理  //提交事务  scope.Complete();  }  return true; } else {  errMsg = result.err_code_des;  Logger.Error(string.Format("提交退款失败,退款单号={0},关联订单号={1},关联产品={2},退款result={3}",  refPay.PayNo, refPay.RelationNo, refPay.RelationNos, refPay.PayResult)); } } catch (Exception ex) { errMsg = ex.Message; Logger.Error(string.Format("提交退款异常:Message={0},StackTrace={1}", ex.Message, ex.StackTrace));  }  return false; }

注:注意退款接口的参数,如:金额,退款地址等,确保参数正确,一般微信会收到退款的请求指令,微信处理成功后,会异步回调退款的接口给服务器。

退款统一回调处理

直接上代码如下:

/// <summary>/// 退款回调/// </summary>[HttpPost("RefundNotifyUrl")]public ActionResult RefundNotifyUrl(){ ResponseResult result = new ResponseResult(); ResponseHandler resHandler = new ResponseHandler(HttpContext); string return_code = resHandler.GetParameter("return_code"); string return_msg = resHandler.GetParameter("return_msg"); try { var mch_key = Senparc.Weixin.Config.SenparcWeixinSetting.TenPayV3_Key; if (return_code.ToUpper() == "SUCCESS") {  //string result_code = resHandler.GetParameter("result_code");  //string appId = resHandler.GetParameter("appid");  //string mch_id = resHandler.GetParameter("mch_id");  //string nonce_str = resHandler.GetParameter("nonce_str");  string req_info = resHandler.GetParameter("req_info");  var decodeReqInfo = TenPayV3Util.DecodeRefundReqInfo(req_info, mch_key);  var decodeDoc = XDocument.Parse(decodeReqInfo);  var refundNotifyXml = decodeDoc.SerializeObject();  //获取接口中需要用到的信息  string out_trade_no = decodeDoc.Root.Element("out_trade_no").Value;  string out_refund_no = decodeDoc.Root.Element("out_refund_no").Value;  string transaction_id = decodeDoc.Root.Element("transaction_id").Value;  string refund_id = decodeDoc.Root.Element("refund_id").Value;  int total_fee = int.Parse(decodeDoc.Root.Element("total_fee").Value);  int refund_fee = int.Parse(decodeDoc.Root.Element("refund_fee").Value);  RefundNotifyParam param = new RefundNotifyParam()  {  PayNo = out_trade_no,//商户订单号  PayPrice = ((float)refund_fee.ToInt() / 100).ToDecimal(),//退款金额  Out_refund_no = out_refund_no,//商户退款单号   TransactionNo = transaction_id,//微信订单号  Refund_id = refund_id, //微信退款单号   };  Logger.Info(string.Format("退款回调参数,return_code={0},return_msg={1},refundNotifyXml={2}", return_code, return_msg, refundNotifyXml));  result = Service.RefundNotifyUrl(param);  if (result.errno != 0)  {  //回调处理逻辑失败  Logger.Error(string.Format("退款回调业务处理失败:退款单号{0},{1}", param.Out_refund_no, result.errmsg));  }  else  {  Logger.Info(string.Format("退款回调业务处理成功,退款单号:{0}", param.Out_refund_no));  string xml = string.Format(@"<xml>    <return_code><![CDATA[{0}]]></return_code>    <return_msg><![CDATA[{1}]]></return_msg>    </xml>", return_code, return_msg);  return Content(xml, "text/xml");  } } else {  //错误的订单处理  Logger.Error(string.Format("退款回调失败,return_code={0},return_msg={1}", return_code, return_msg)); } } catch (Exception ex) { Logger.Error(string.Format("退款回调异常:Message={0},StackTrace={1}", ex.Message, ex.StackTrace)); } return Content("fail", "text/xml");}

注:如果业务处理退款成功后,请返回结果告诉微信SUCCESS,否则微信也会按规则不停发送退款回调给服务器,直到次数用完为止,具体查看上面规则文档。

总结

以上所述是小编给大家介绍的.NET Core 微信小程序退款步骤――(统一退款),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!


  • 上一条:
    Laravel5.5+框架中配置自定义404错误页面流程步骤
    下一条:
    小程序实现长按保存图片的方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 微信模板消息改版后发送规则记录(微信订阅消息参数值内容限制说明)(1个评论)
    • 微信支付v3对接所需工具及命令(0个评论)
    • 2023年9月1日起:微信小程序必须备案才能上线运营(0个评论)
    • 腾讯官方客服回应了:微信好友上限约10000个!(1个评论)
    • 2023年做微信小程序的老铁注意:新增收费项、微信小程序获取手机号也收费了(2个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2017-10
    • 2018-01
    • 2020-03
    • 2021-06
    • 2021-10
    • 2022-03
    • 2023-02
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-10
    • 2023-11
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客