net.core 微信APP支付

前言:微信APP支付(两步操作1:唤醒。2:支付完成回调并返回)

微信支付申请:
1. 打开微信开发放平台 https://open.weixin.qq.com/
2. 进入 管理中心 / 创建移动应用 页面(这里的应用包名和签名是一定要写对的,修改正确之后还是错误是因为微信统一下单接口有缓存延迟,第二天重试即可)
3. 填写基本信息
4. 填写平台信息

申请成功之后需要与微信支付商户关联

1:参数配置  WeiXinPayConfig为微信支付参数

public static class WeiXinPayConfig
    {
        public static string NotifyUrl { get; set; }
        public static string APP_ID { get; set; }
        public static string MCHID { get; set; }
        public static string Key { get; set; }
    }

    public class WxPayModel
    {
        /// <summary>
        /// 应用ID
        /// </summary>
        public string appid { set; get; } = "";
        /// <summary>
        /// 商户号
        /// </summary>
        public string partnerid { set; get; } = "";
        /// <summary>
        /// 预支付交易会话ID
        /// </summary>
        public string prepayid { set; get; } = "";
        /// <summary>
        /// 扩展字段
        /// </summary>
        public string package { set; get; } = "Sign=WXPay";
        /// <summary>
        /// 随机字符串
        /// </summary>
        public string noncestr { set; get; } = "";
        /// <summary>
        /// 时间戳
        /// </summary>
        public string timestamp { set; get; } = "";

        /// <summary>
        /// 签名
        /// </summary>
        public string sign { set; get; } = "";
    }

2:微信唤醒  唤醒的时候需要注意的是sign签名是需要获取两次的

/// <summary>
        /// 微信APP唤醒
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<MessageModel<WxPayModel>> WeiXinPay(WeChatPayQuery query)
        {
            try
            {
                //特别注意****************************************
                var timeStamp = TimeUtil.GetCurrentTimestamp(false);
                string out_trade_no = query.CustomerId + DateTime.Now.ToString("yyyyMMddHHmmssfff");
                logger.LogInformation("微信唤醒开始" + out_trade_no);
                var guidstr = Guid.NewGuid().ToString().Replace("-", "");
                HttpClient httpClient = new HttpClient();//http对象  //表头参数
                httpClient.DefaultRequestHeaders.Accept.Clear();
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
                StringBuilder xml = new StringBuilder() { };
                xml.AppendFormat("<xml><appid>" + WeiXinPayConfig.APP_ID + "</appid>");//appid
                xml.AppendFormat("<attach>名称</attach>");//你要传送的额外信息,例如订单ID之类的
                xml.AppendFormat("<body>名称</body>");//产品描述,也就是支付事由
                xml.AppendFormat("<mch_id>" + WeiXinPayConfig.MCHID + "</mch_id>");//你的商户号,需要与open.weixin.qq.com上对应的APP绑定
                xml.AppendFormat("<nonce_str>" + guidstr + "</nonce_str>");//生成的随机字符串
                xml.AppendFormat("<notify_url>" + WeiXinPayConfig.NotifyUrl + "</notify_url>");//支付成功后通知处理Url,不能带参数
                xml.AppendFormat("<out_trade_no>" + out_trade_no + "</out_trade_no>");//订单号,不能重复
                xml.AppendFormat("<spbill_create_ip>" + PayInfoQuery.CreateIp + "</spbill_create_ip>");//.net core服务器IP
                xml.AppendFormat("<total_fee>" + query.Money * 100 + "</total_fee>");//金额单位是分  
                xml.AppendFormat("<trade_type>APP</trade_type>");//APP就填写APP
                StringBuilder str = new StringBuilder() { };
                str.AppendFormat(@"appid={0}&attach=名称&body=名称&mch_id={1}&nonce_str={2}&notify_url={3}&out_trade_no={4}&spbill_create_ip={5}&total_fee={6}&trade_type=APP&key={7}", WeiXinPayConfig.APP_ID, WeiXinPayConfig.MCHID, guidstr, WeiXinPayConfig.NotifyUrl, out_trade_no, PayInfoQuery.CreateIp, query.Money * 100, WeiXinPayConfig.Key);
                xml.AppendFormat("<sign>" + GetSign(str.ToString()) + "</sign></xml>");//生成的sign
                HttpContent httpContent = new StringContent(xml.ToString());//转为链接需要的格式
                //请求
                HttpResponseMessage response = httpClient.PostAsync("https://api.mch.weixin.qq.com/pay/unifiedorder", httpContent).Result;
                string result = "";
                //这里开始进入第3步了
                if (response.IsSuccessStatusCode)
                {
                    Task<string> t = response.Content.ReadAsStringAsync();
                    if (t != null)
                    {
                        result = t.Result;
                        WxPayModel model = new WxPayModel() { };
                        XmlDocument xmlDoc = new XmlDocument();
                        xmlDoc.LoadXml(result);
                        model.appid = xmlDoc.DocumentElement.GetElementsByTagName("appid")[0].InnerText;
                        model.noncestr = xmlDoc.DocumentElement.GetElementsByTagName("nonce_str")[0].InnerText;
                        model.partnerid = xmlDoc.DocumentElement.GetElementsByTagName("mch_id")[0].InnerText;
                        model.prepayid = xmlDoc.DocumentElement.GetElementsByTagName("prepay_id")[0].InnerText;
                        StringBuilder str2 = new StringBuilder() { };
                        str2.AppendFormat(@"appid={0}&noncestr={1}&package=Sign=WXPay&partnerid={2}&prepayid={3}&timestamp={4}&key={5}", WeiXinPayConfig.APP_ID, model.noncestr, model.partnerid, model.prepayid, timeStamp, WeiXinPayConfig.Key);

                        model.sign = GetSign(str2.ToString());
                        model.timestamp = timeStamp;
                        logger.LogInformation("微信唤醒成功" + out_trade_no);
                        _unitOfWork.BeginTran();
                       //可以添加自己的业务逻辑  
                        if (order > 0)
                        {
                            _unitOfWork.CommitTran();
                            return new MessageModel<WxPayModel>() { success = true, msg = "唤醒成功", response = model };
                        }
                    }
                }
                return new MessageModel<WxPayModel>() { success = false, msg = "操作失败" };
            }
            catch (Exception ex)
            {
                _unitOfWork.RollbackTran();
                logger.LogInformation("微信唤醒异常" + ex.ToString());
                return new MessageModel<WxPayModel>() { success = false, msg = "微信唤醒失败" };
            }
        }

3:获取签名的方法

 /// <summary>
        /// 生成签名
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public string GetSign(string str)
        {
            var md5 = MD5.Create();
            var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
            var sb = new StringBuilder();
            foreach (byte b in bs)
            {
                sb.Append(b.ToString("x2"));
            }
            //所有字符转为大写
            return sb.ToString().ToUpper();
        }

4:支付成功回调

 /// <summary>
        /// 微信回调
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> UnderWeiXinPay()
        {
            logger.LogInformation("开始回调(微信)");
            Stream stream = HttpContext.Request.Body;
            byte[] buffer = new byte[HttpContext.Request.ContentLength.Value];
            await stream.ReadAsync(buffer, 0, buffer.Length); //.net core 3.1需要用ReadAsync才不会出错
            string xml = System.Text.Encoding.UTF8.GetString(buffer);
            //上面几行是关键的获取POST过来的xml数据的代码
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(xml);
            logger.LogInformation("(微信)参数xml" + xmlDoc);
            if (xmlDoc.DocumentElement.GetElementsByTagName("return_code")[0].InnerText == "SUCCESS")
            {
                string Transaction_Id = xmlDoc.DocumentElement.GetElementsByTagName("transaction_id")[0].InnerText;
                string out_trade_no = xmlDoc.DocumentElement.GetElementsByTagName("out_trade_no")[0].InnerText;
                logger.LogInformation("参数Transaction_Id" + Transaction_Id);
                logger.LogInformation("参数out_trade_no" + out_trade_no);
                //获取指定节点内容
                //这里是进行各种逻辑代码,最好对sign进行下验证
                var result = //验证单号是否在苦中
                if (result == null)
                {
                    logger.LogInformation("Failure支付结果中微信订单号不存在" + out_trade_no);
                    return WeChatPayNotifyResult.Failure;
                }
                if (result != null && result.Status == EnumOrderType.payoff)
                {
                    logger.LogInformation("信回调SUCCESS:" + out_trade_no);
                    return WeChatPayNotifyResult.Success;
                }
                var payresult =//处理自己业务逻辑
                if (payresult.success == true)
                {
                    logger.LogInformation("微信回调SUCCESS:" + out_trade_no);
                    return WeChatPayNotifyResult.Success;
                }
                else
                {
                    return WeChatPayNotifyResult.Failure;
                }
            }
            else
            {
                return WeChatPayNotifyResult.Failure;
            }
        }

到这里你就可以放心的去给前端让其支付了

*下期更新苹果虚拟商品必须开启IPA支付

*

*

*

*

*

*

*

*

*

*

*

是不是惊奇的发现安卓唤起OK  但是ios唤不起来呢  报错签名错误

究极解决方案(关于这个问题呢是安卓和ios需求不同)上方时间戳那里生成的时候生成10位时间戳就可以了

下方附上时间戳生成方法

/// <summary>
        /// 获取当前时间戳
        /// </summary>
        /// <param name="millisecond">精度(毫秒)设置 true,则生成13位的时间戳;精度(秒)设置为 false,则生成10位的时间戳;默认为 true </param>
        /// <returns></returns>
        public static string GetCurrentTimestamp(bool millisecond = true)
        {
            return DateTime.Now.ToTimestamp(millisecond);
        }

        /// <summary>
        /// 转换指定时间得到对应的时间戳
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="millisecond">精度(毫秒)设置 true,则生成13位的时间戳;精度(秒)设置为 false,则生成10位的时间戳;默认为 true </param>
        /// <returns>返回对应的时间戳</returns>
        public static string ToTimestamp(this DateTime dateTime, bool millisecond = true)
        {
            return dateTime.ToTimestampLong(millisecond).ToString();
        }

        /// <summary>
        /// 转换指定时间得到对应的时间戳
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="millisecond">精度(毫秒)设置 true,则生成13位的时间戳;精度(秒)设置为 false,则生成10位的时间戳;默认为 true </param>
        /// <returns>返回对应的时间戳</returns>
        public static long ToTimestampLong(this DateTime dateTime, bool millisecond = true)
        {
            var ts = dateTime.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return millisecond ? Convert.ToInt64(ts.TotalMilliseconds) : Convert.ToInt64(ts.TotalSeconds);
        }

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会飞的黄金鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值