NopCommerce 4.2 小程序微信支付

大兔子大兔子 提交于 2019-12-05 04:30:42

今天写小程序的支付接口,参照的当然是微信支付API了

有那么多时间写文字,不如多写点代码~😄

 

下面只想记录下实现的过程及最重要的代码处理。

 

 步骤一:小程序获取,opendid与orderid,传入下面第二部的“统一下单接口”中

 

 

 

 

接口:统一下单接口

 

        //接口部分,怎么组装你自己想咯,太懒是不行的
        public APIResult<UnifiedOrderResult> Prepay(PrepayParam prepayParam)
        {
            string openId = CryptoProvider.NetDecrypt(prepayParam.openId, LiteMallDefaults.Key);//此设备号是由小程序OpenId加密而成的

            var order = _orderService.GetOrderById(prepayParam.orderId);

            var key = _weiXinPaySettings.KEY;//商户后台API安全的KEY值(手动设定的)
            var appid = _weiXinPaySettings.APPID;//微信支付分配的小程序ID
            var mch_id = _weiXinPaySettings.MCHID;//微信支付分配的商户号
            var nonce_str = Guid.NewGuid().ToString().Replace("-", "");// 随机字符串,长度要求在32位以内
            var body = _storeContext.CurrentStore.Name;//商品简单描述,该字段请按照规范传递,具体请见参数规定
            var attach = order.Id.ToString();//附加数据(这里传递订单号,以便后续异步通知同步商户信息)
            var out_trade_no = order.CustomOrderNumber;//商户系统内部订单号,要求32个字符内、且在同一个商户号下唯一。 
            //var total_fee = Math.Round(order.OrderTotal * 100, 0).ToString();
            var total_fee = 1;
            var spbill_create_ip = "8.8.8.8";//DEMO 默认值,不能为空
            if (!string.IsNullOrEmpty(_weiXinPaySettings.IP))
            {
                spbill_create_ip = _weiXinPaySettings.IP;
            }
            var time_start = DateTime.Now.ToString("yyyyMMddHHmmss");// 订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
            var time_expire = DateTime.Now.AddMinutes(30).ToString("yyyyMMddHHmmss");//订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见
            var trade_type = "JSAPI"; //固定值
            var product_id = order.Id.ToString();//商品ID
            var notify_url = _storeContext.CurrentStore.Url + "Plugins/PaymentWeiXinPay/PayNotify";//回调地址(请按照路由的设定填写,请确保路径正确)

            //参数
            //特别说明:SortedDictionary自身就会自动排除,所以后续就没有在手动进行排序操作
            //否则的话,你可能需要手动按照规则进行排序哦!
            SortedDictionary<string, object> para = new SortedDictionary<string, object>();
            para.Add("appid", appid);
            para.Add("mch_id", mch_id);
            para.Add("nonce_str", nonce_str);
            para.Add("body", body);
            para.Add("attach", attach);
            para.Add("out_trade_no", out_trade_no);
            para.Add("openid", openId);
            para.Add("total_fee", total_fee);
            para.Add("spbill_create_ip", spbill_create_ip);
            para.Add("time_start", time_start);
            para.Add("time_expire", time_expire);
            para.Add("trade_type", trade_type);
            para.Add("product_id", product_id);
            para.Add("notify_url", notify_url);
            //获取签名:参数 + key 值
            var sign = WeChatHelper.MakeSign(para, key);
            //将签名加入集合中
            para.Add("sign", sign);
            //重新排序并生成接口需要的XML格式数据
            string xml = WeChatHelper.ToXml(para);
            //调用统一下单接口
            var post = new RemotePostXml
            {
                FormName = "weixinpaysubmit",
                Url = "https://api.mch.weixin.qq.com/pay/unifiedorder",
                Method = "POST",
                XmlParamsString = xml
            };
            var postResult = post.Post();
            //接收微信服务器返回的XML数据,并转成字典方便操作
            SortedDictionary<string, object> resultSorteDictioinary = WeChatHelper.FromXml(postResult, para);

            //为支付接口准备数据
            string AppId = appid;
            string TimeStamp = WeChatHelper.GetTimeStamp();//获取时间戳
            string nonceStr = Guid.NewGuid().ToString().Replace("-", "");
            string prepayid = WeChatHelper.GetValue(resultSorteDictioinary, "prepay_id").ToString();
            string package = "prepay_id=" + prepayid;
            string signType = "MD5";

            //sign签名需要的数据
            SortedDictionary<string, object> pay_sign_para = new SortedDictionary<string, object>();
            pay_sign_para.Add("appId", appid);
            pay_sign_para.Add("timeStamp", TimeStamp);
            pay_sign_para.Add("nonceStr", nonceStr);
            pay_sign_para.Add("package", package);
            pay_sign_para.Add("signType", signType);
            //var pay_sign = WeChatHelper.GetMD5(WeChatHelper.ToUrl(pay_sign_para) + "&" + key);
            var pay_sign = WeChatHelper.MakeSign(pay_sign_para, key);
            pay_sign_para.Add("sign", pay_sign);

            UnifiedOrderResult unifiedOrderResult = new UnifiedOrderResult()
            {
                timeStamp = TimeStamp,
                nonceStr = nonceStr,
                packageValue = package,
                signType = signType,
                paySign = pay_sign
            };

            return Success(unifiedOrderResult, "");
        }

 

到这里,就会弹出支付窗体啦!完成支付后,你不是要点击“完成支付”吗?这个动作还要对应一个回调地址来处理系统的订单,例如:标记为已经完成支付

 

  /// <summary>
        /// 微信支付通知 
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        public ActionResult PayNotify()
        {

            //获取微信返回的xml字符串数据
            Stream stream = HttpContext.Request.Body;
            byte[] buffer = new byte[HttpContext.Request.ContentLength.Value];
            stream.Read(buffer, 0, buffer.Length);
            string contentXml = Encoding.UTF8.GetString(buffer);//格式:xml字符串
            _logger.InsertLog(LogLevel.Debug, "异步结果通知:" + contentXml);
            //将XML数据转为字典(方便操作)
            SortedDictionary<string, object> data = new SortedDictionary<string, object>();
            data = FromXml(contentXml.ToString(), data);
            var return_code = GetValue(data, "return_code");
            var return_msg = GetValue(data, "return_msg");
            //异常时结果集合:更多可能的异常,补充处理
            SortedDictionary<string, object> resultDict = new SortedDictionary<string, object>();
            if (return_code != null)
                resultDict.Add("return_code", return_code);
            if (return_msg != null)
                resultDict.Add("return_msg", return_msg);
            if (return_code != null && return_code.ToString().ToUpper() != "SUCCESS")
            {
                _logger.InsertLog(LogLevel.Debug, "异步结果通知:失败");
                //失败的情况
                return Content(ToXml(resultDict));
            }

            #region 自身系统订单处理

            //交易号transaction_id订单查询
            SortedDictionary<string, object> orderQueryRequest = new SortedDictionary<string, object>();
            var transactionId = GetValue(data, "transaction_id");
            if (transactionId != null)
            {
                orderQueryRequest.Add("transaction_id", transactionId);
            }
            //查询微信订单
            var orderQueryResult = OrderQuery(orderQueryRequest);

            //根据微信订单状态判断
            if (GetValue(data, "return_code") != null &&
                GetValue(data, "result_code") != null &&
                GetValue(data, "return_code").ToString() == "SUCCESS" &&
                GetValue(data, "result_code").ToString() == "SUCCESS")
            {

                _logger.InsertLog(LogLevel.Debug, "异步结果通知:已查询到微信支付订单信息");

                #region 订单操作

                //获取交易号
                var strOrderCustomNumber = GetValue(data, "out_trade_no");//这里下单时传递的是订单的GUID号,不是订单ID编号

                if (strOrderCustomNumber != null)
                {
                 
                    if (!string.IsNullOrEmpty(strOrderCustomNumber.ToString()))
                    {
                        _logger.InsertLog(LogLevel.Debug, "异步结果通知:订单获取成功,准备修改订单信息:自定义的订单号:"+ strOrderCustomNumber);
                        //获取订单信息

                        var order = _orderService.GetOrderByGuid(new Guid(strOrderCustomNumber.ToString()));

                        //设定订单为已经支付
                        if (order == null)
                        {
                            _logger.InsertLog(LogLevel.Debug, "异步结果通知==订单状态修改失败,没有获取到系统的订单信息");

                            return Content(ToXml(resultDict));
                        }
                        else if (order != null)
                        {
                            if (_orderProcessingService.CanMarkOrderAsPaid(order))
                            {
                                _logger.InsertLog(LogLevel.Debug, "允许修改订单为已经支付");
                                _orderProcessingService.MarkOrderAsPaid(order);
                                _logger.InsertLog(LogLevel.Debug, "异步结果通知==订单状态已修改为【已支付】");
                            }
                            else
                            {
                                _logger.InsertLog(LogLevel.Debug, "允许修改订单为已经支付");
                            }
                          
                        }
                        
                        //_logger.InsertLog(LogLevel.Debug, "异步结果通知==修改订单时,出现其他未知情况");
                    }
                    else
                    {
                        _logger.InsertLog(LogLevel.Debug, "异步结果通知==订单号异常");
                    }
                }
                else
                {
                    _logger.InsertLog(LogLevel.Debug, "异步结果通知==订单号异常");
                }

                #endregion
            }
            else
            {
                //若订单查询失败

                resultDict.Add("return_code", "FAIL");
                resultDict.Add("return_msg", "FAIL");
                return Content(ToXml(resultDict));

            }
            #endregion

            _logger.InsertLog(LogLevel.Debug, "反馈的结果:"+ ToXml(resultDict));
            return Content(ToXml(resultDict));

        }

 

 就此,微信支付及系统订单的处理过程就完成了。

 

 不要问我要完整的代码了(实在不会,找我是会帮忙的,免费是不可能滴,( ̄▽ ̄)")

 

NopCommerce3.x以上版本处理方式一毛一样。不会有太大区别

=============================================================

找我吗

 

QQ:64664795 (备注:博客园)

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!