记录最近调通微信公众号支付的过程

写这篇文章记录最近一次接入微信公众号支付的一些思路。

       首先无论是支付宝还是微信用h5编写的代码想获取微信的授权都必须发一个get请求给https://open.weixin.qq.com/connect/oauth2/authorize,后面的参数省略,其中有一个参数redirect_uri很重要这个是授权返回的你本地程序的url你可以在这个返回的过程中带几个自己的参数。

       

[HttpGet]
        public ActionResult McrMsgOAuth(string OrganizationId,string WId)
        {
            string RootUrl = GlobalContext.WeChatPay.WebSevRootUrl;
            WxModel model = new WxModel();
            model.WxOAuthUrl = string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope={2}&state={3}##wechat_redirect", GlobalContext.WeChatPay.AppId, WebHelper.HtmlEncode(string.Format("{0}/ParkingLotManage/KadPay/McrMsgOAuthReCall?WId="+WId, RootUrl)), "snsapi_userinfo", OrganizationId);
            return View(model);
        }

       授权的过程需要取一次token,顺便把openid取到,当然你可以利用现有的信息取到一些个人资料。下面的代码就是取token的方法。

public static PayAccess GetPayAccessToken(string code) {

            string ApiUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";
            string RequestParameter = string.Format("appid={0}&secret={1}&code={2}&grant_type={3}", GlobalContext.WeChatPay.AppId, GlobalContext.WeChatPay.AppSecret, code, "authorization_code");
            string WxData = WebHelper.UseGetPushApi(ApiUrl, RequestParameter, Encoding.UTF8);
            //log.AppendAndSave("WeiXinAccount_GetPayAccessToken", string.Format("WxData:{0}", WxData));

            PayAccess access = null;
            if (!string.IsNullOrWhiteSpace(WxData) && WxData.IndexOf("errcode") < 0)
            {//请求成功
                try
                {
                    access = JsonConvert.DeserializeObject<PayAccess>(WxData);
                    
                }
                catch (Exception ex)
                {
                
                }
            }
            return access;
        }

      取到的信息可以缓存起来或者组织存成数据库信息。很多过程视业务而定,在整个支付过程中需要用cookie缓存一个个人用户信息来避免反复授权。其次要缓存整个交易过程中的一些信息,并不是所有信息都要通过url传递的这点大家都应该了解。

[HttpGet]
        public async Task<ActionResult> McrMsgOAuthReCall(string code, string state,string WId)
        {
            LogHelper.Write("McrMsgOAuthReCall!! code:" + code + ",state:" + state + ",WId:" + WId);
            //state是组织机构id
            
            PayAccess access =  WebHelper.GetPayAccessToken(code);

            //WebHelper.GetWxUserInfo(access.access_token, access.openid);
            
            var UserId = IdGeneratorHelper.Instance.GetId();
            MembersEntity entity = new MembersEntity();
            entity.OpenId = access.openid;
            entity.Id = UserId;
            entity.OrganizationId = long.Parse(state);
            entity.RegisterTime = DateTime.Now;
            CarModel model = new CarModel();
            model.OrganizationId = long.Parse(state);
            model.UserId = UserId + "";
            model.PayMethod = 1;
            model.OpenId = access.openid;
            model.WId = WId;
            CacheFactory.Cache.SetCache<CarModel>(UserId+"", model);
            LogHelper.Write("openid:" + access.openid + ",userId:" + UserId + ",OrganizationId:" + state);
            TData<string> obj  = await membersBLL.AddForm(entity);
            if (obj.Tag == 1) {
                _httpContextAccessor.HttpContext.Response.Cookies.Append(GlobalContext.WeChatPay.McrMsgUserCookieKey + state, UserId+"");

            }
            //授权完userid openid 组织机构id存到数据库
            //存cookie

            return this.RedirectToRoute(new { controller = "KadPay", action = "McrMsgConfirmOrder", Dsn="", WId=WId, UserId = UserId });
        }

       最近是为了测试支付,通过授权之后直接到订单页面支付了。订单的一些信息是通过service取到的,现在是测试机器不可能一直联通所以为了方便就直接new一个对象把值都构建出来。

[HttpGet]
        public ActionResult McrMsgConfirmOrder(string WId, string Dsn, string UserId,string CarNumber) {

            ViewBag.flag = false;
            LogHelper.Write("McrMsgConfirmOrder:WId:" + WId + ",Dsn:" + Dsn + ",UserId:" +UserId);
            //Payment payment = ParkingTcpService.Instance().GetUnpaidParkingFee(int.Parse(WId), "", Dsn);
            Payment payment = new Payment();
            payment.PlateNO = "闽DXC921";
            payment.ParkingName = "科安达停车场";
            payment.EntTime = DateTime.Now;
            payment.ParkingTime = 40;
            payment.TotalAmount = 0.01;

            OrdersEntity entity = new OrdersEntity();
            entity.OrderNo = IdGeneratorHelper.Instance.GetId() + "";
            entity.PayUserId = long.Parse(UserId);
            LogHelper.Write("McrMsgConfirmOrder:UserId" + UserId + "");
            LogHelper.Write((payment!=null) +"");

            if (payment != null)
            {
                entity.LicencePlateNo = payment.PlateNO;
                entity.ParkingLotName = payment.ParkingName;
                entity.TimeIn = payment.EntTime;
                entity.TimeOut = ((DateTime)payment.EntTime).AddSeconds(payment.ParkingTime * 60);
                entity.ParkingTime = payment.ParkingTime + "";
                entity.TotalFee = payment.TotalAmount*100;
            }
            LogHelper.Write("WeChatPay:TotalFee" + entity.TotalFee + "");
            LogHelper.Write("WeChatPay:UserId" + entity.PayUserId);
            ActionResult result = new ViewResult();
            CarModel cache = CacheFactory.Cache.GetCache<CarModel>(entity.PayUserId + "");
            WxPayData data = new WxPayData();
            data.SetValue("body", string.Format("{0}停车缴费", entity.LicencePlateNo));
            data.SetValue("attach", string.Format(""));
            data.SetValue("out_trade_no", entity.OrderNo);
            //data.SetValue("total_fee", re.Price.ToString());//支付金额 /分
            data.SetValue("total_fee", entity.TotalFee + "");
            var timeStamp = DateTime.Now.ToString("yyyyMMddHHmmss");
            data.SetValue("time_start", timeStamp);
            data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));
            //data.SetValue("goods_tag", "test");//订单优惠标记
            data.SetValue("trade_type", "JSAPI");//交易类型
            data.SetValue("openid", cache.OpenId);
            LogHelper.Write("WeChatPay:OpenId" + cache.OpenId + "");
            data.SetValue("notify_url", GlobalContext.WeChatPay.NOTIFY_URL);
            string IPAddress = _httpContextAccessor.HttpContext.Connection.LocalIpAddress.ToString();
            WxPayData wxdata = WxUtil.UnifiedOrder(data, IPAddress);
            if (!wxdata.IsSet("appid") || !wxdata.IsSet("prepay_id") || wxdata.GetValue("prepay_id").ToString() == "")
            {

                return result;
            }

            string ViewStr = WxUtil.GetJsApiParameters(wxdata, timeStamp);
            LogHelper.Write(ViewStr);
            //ViewBag.wxJsApiParam = ViewStr;
            ViewData["wxJsApiParam"] = ViewStr;
            return View(entity);
        }

返回来的值可以构成一串json字符串,传递到前端配合一些js就可以唤起支付了。其他有些部分的代码就在微信提供的demo里面。我不知道是不是大家都这样,代码中用到linq,但是打开编译环境确实.net framework 2.0,需要手工把编译环境改成.net framework 4.0。

       最后附上前端调用的js

<script type="text/javascript">
        //调用微信JS api 支付
        function jsApiCall() {
            //alert("jsApiCall");
            WeixinJSBridge.invoke(
                'getBrandWCPayRequest', @Html.Raw(ViewData["wxJsApiParam"]),//josn串/**/
                function (res) {
                    WeixinJSBridge.log(res.err_msg);
                    //alert(res.err_code + res.err_desc + res.err_msg);
                    if (res.err_msg == "get_brand_wcpay_request:ok") {
                        // 使用以上方式判断前端返回,微信团队郑重提示:
                        //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
                        location.href = "McrMsgPayOK";
                    } 
                }
            );
        }

        function callpay() {
            //alert(typeof WeixinJSBridge);
            if (typeof WeixinJSBridge == "undefined") {
                if (document.addEventListener) {
                    document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
                }
                else if (document.attachEvent) {
                    document.attachEvent('WeixinJSBridgeReady', jsApiCall);
                    document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
                }
            }
            else {
                jsApiCall();
            }
        }
        
    </script>

        文章就写到这里了希望对大家有所帮助

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值