【.net core】微信公众号JSAPI支付--退款成功回调

前期的一些说明

接上篇文章申请退款,这里主要是退款成功后的回调、
项目结构的一些基本说明以及微信公众号支付的准备工作统一下单那篇已经说明
回调中用到的WxPayData也请参考统一下单那篇
链接:https://www.cnblogs.com/sylvia-/p/12771241.html

准备工作及遇到的一些坑

退款成功的回调拿到的xml中返回的req_info 是需要进行解密的
微信官方提供的SDK中并没有提供解密的方法
微信的官方文档中有说明如何进行解密,详细可以去看下官方文档
解密后可以拿到退款单号啥的,然后就可以处理具体的业务逻辑了

上代码

Controller

    [HttpPost("TestRefundCallBack")]
    public void TestRefundCallBack()
    {
        _ticketRepository.TestRefundCallBack(HttpContext);
    }

Interface

    (bool result, string msg) TestRefundCallBack(HttpContext context);

业务仓储

    public (bool result,string msg) TestRefundCallBack(HttpContext context)
    {
        _logger.LogWarning($"TestRefundCallBack comming");
        var result = _wxHelper.RefundCallBack(context);
        //这里处理您的业务逻辑
        return (true, "success");
    }

帮助方法

    public string RefundCallBack(HttpContext context)
    {
        string out_refund_no = "";

        #region 
        //.net core 3.0以后需加下边这段,否则Stream会报错
        var syncIOFeature = context.Features.Get<IHttpBodyControlFeature>();
        if (syncIOFeature != null)
        {
            syncIOFeature.AllowSynchronousIO = true;
        }
        #endregion

        //接收从微信后台POST过来的数据
        System.IO.Stream s = context.Request.Body;
        int count = 0;
        byte[] buffer = new byte[1024];
        StringBuilder builder = new StringBuilder();
        while ((count = s.Read(buffer, 0, 1024)) > 0)
        {
            builder.Append(Encoding.UTF8.GetString(buffer, 0, count));
        }
        s.Flush();
        s.Close();
        s.Dispose();
        _logger.LogWarning($"GetNotifyData Receive data from WeChat :{builder.ToString()}");

        //转换数据格式并验证签名
        WxPayData notifyData = new WxPayData();
        notifyData.NoSignFromXml(builder.ToString());

        if (notifyData.GetValue("return_code").ToString() == "SUCCESS")
        {
            WxPayData res = new WxPayData();
            res.SetValue("return_code", "SUCCESS");
            res.SetValue("return_msg", "OK");
            context.Response.WriteAsync(res.ToXml());

            string req_info = notifyData.GetValue("req_info").ToString();
            string key = Encrypt.GetStrMD5("xxx").ToLower();     //xxx是微信商户key
            req_info = WxPayData.DecodeAES256ECB(req_info, key);

            WxPayData data = new WxPayData();
            data.NoSignFromXml(req_info);

            if (data.GetValue("refund_status").ToString() == "SUCCESS")
            {
                out_refund_no = data.GetValue("out_refund_no").ToString();
            }
        }
        return out_refund_no;
    }

WxPayData 中的方法

    public static string DecodeAES256ECB(string s, string key)
    {
        string r = null;
        try
        {
            byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
            byte[] toEncryptArray = Convert.FromBase64String(s);
            RijndaelManaged rDel = new RijndaelManaged();
            rDel.Key = keyArray;
            rDel.Mode = CipherMode.ECB;
            rDel.Padding = PaddingMode.PKCS7;
            ICryptoTransform cTransform = rDel.CreateDecryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
            r = UTF8Encoding.UTF8.GetString(resultArray);
        }
        catch { }
        return r;
    }
posted @ 2020-04-25 17:19  游牧人生  阅读(687)  评论(0)    收藏  举报