• Asp.Net Core3.0 微信退款


    参考文档:

    微信支付申请退款API文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_8_11.shtml   (最新更新时间:2022.01.05)

    注意:
    1、交易时间超过一年的订单无法提交退款
    
    2、微信支付退款支持单笔交易分多次退款(不超50次),多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。申请退款总金额不能超过订单金额。 一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号
    
    3、错误或无效请求频率限制:6qps,即每秒钟异常或错误的退款申请请求不超过6次
    
    4、每个支付订单的部分退款次数不能超过50次
    
    5、如果同一个用户有多笔退款,建议分不同批次进行退款,避免并发退款导致退款失败
    
    6、申请退款接口的返回仅代表业务的受理情况,具体退款是否成功,需要通过退款查询接口获取结果
    
    7、一个月之前的订单申请退款频率限制为:5000/min
    
    8、同一笔订单多次退款的请求需相隔1分钟

    环境

    相关工具:VS2019 SQLServer2019

    服务器软件:.net core 3.0

    面向对象:NetCore初学者代码只是简单实现退款功能,仅供参考,请勿在生产环境中使用,否则可能造成资金风险

    1.申请退款V3

    请求URL:https://api.mch.weixin.qq.com/v3/refund/domestic/refunds

    请求方式:POST

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

            //微信退款
    public async Task Refund() { //微信退费操作 var url = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds"; int money = 0; var retParamar = new { //transaction_id = "", out_trade_no = "", out_refund_no = "", reason = "客户申请提现,小程序退款", amount = new { refund = money, total = money, currency = "CNY" }, notify_url = "http://api.xxxx.com/api/pay/RefundNotifyUrl" //回调地址 }; var reqJson = JsonConvert.SerializeObject(retParamar); var httpHandler = new HttpHandler(_mchid, _serialNo); HttpClient client = new HttpClient(httpHandler); var bodyJson = new StringContent(reqJson, Encoding.UTF8, "application/json"); var response = await client.PostAsync(url, bodyJson); var respStr = await response.Content.ReadAsStringAsync(); var respResult = JsonConvert.DeserializeObject<dynamic>(respStr);
          
    //处理自己业务逻辑
          //TODO...
    }

    2.退款回调V3

    通知规则

    商户退款完成后,微信会把相关退款结果和用户信息发送给清算机构,清算机构需要接收处理后返回应答成功,然后继续给异步通知到下游从业机构。

    参数解密

    下面详细描述对通知数据进行解密的流程:

    1、用商户平台上设置的APIv3密钥 【微信商户平台—>账户设置—>API安全—>设置APIv3密钥】 ,记为key;

    2、针对resource.algorithm中描述的算法(目前为AEAD_AES_256_GCM),取得对应的参数nonce和associated_data;

    3、使用key、nonce和associated_data,对数据密文resource.ciphertext进行解密,得到JSON形式的资源对象。

    注: AEAD_AES_256_GCM算法的接口细节,请参考rfc5116。微信支付使用的密钥key长度为32个字节,随机串nonce长度12个字节,associated_data长度小于16个字节并可能为空字符串。

            public dynamic RefundNotifyUrl(NotifyDto ret)
            {
                WxPayAPI.WxPayData res = new WxPayAPI.WxPayData();
                res.SetValue("return_code", "FAIL");
                res.SetValue("return_msg", "失败");
                try
                {
                    if (ret.Event_type == "REFUND.SUCCESS")//成功
                    {
                        //解密数据报文
                        var dataJson = AesGcmHelper.AesGcmDecryptFromBase64(_key, ret.Resource.Nonce, ret.Resource.Ciphertext, ret.Resource.Associated_data);
                        //转换对象接受
                        var data = JsonConvert.DeserializeObject<RefundCipherText>(dataJson);
                       //处理自己逻辑
                //TODO...
    res.SetValue("return_code", "SUCCESS"); res.SetValue("return_msg", "成功"); return Content(res.ToXml()); } else { _log.WriteLog("NotifyFaile:" + JsonConvert.SerializeObject(ret)); } return Content(res.ToXml()); } catch (Exception ex) { _log.WriteLog(ex.ToString()); return Content(res.ToXml()); } }

    /// <summary>
    /// 退款resource
    /// </summary>
    public class RefundCipherText
    {
      public string mchid { get; set; }
      public WxRefundAmountModel amount { get; set; }
      public string out_trade_no { get; set; }
      public string transaction_id { get; set; }
      public string refund_id { get; set; }
      public string refund_status { get; set; }
      public string user_received_account { get; set; }
      public string success_time { get; set; }

    }

  • 相关阅读:
    javascript类继承系列一
    Update Statistics用法
    FOR XML PATH
    SQL Server 中WITH (NOLOCK)
    ROW_NUMBER () 与 PARTITION组合拳
    sql脚本的格式
    存储过程
    动态sql
    尽量不要用select into 复制表
    杂谈
  • 原文地址:https://www.cnblogs.com/nowar/p/16090644.html
Copyright © 2020-2023  润新知