微支付你“接”了么?

发送到手机
使用"扫一扫"即可发送至手机

随着现企业越来越喜欢在微信有想法时,相对微支付的需求越来越多,最近刚接到一个需要微支付的微信小游戏项目,拿到最新的微信支付接口文档(3.3.6)就开始研究微信支付。鉴于网上分享的大都是2.X的版本,方法跟当前版本差异较多,这里分享给为微信支付苦恼的小伙伴们。

首先我们需要了解微信支付的整体流程,微信分为JSAPI支付和Native支付,两者区别简单来说就是JSAPI是可以再网页直接发起支付,Native则是生成一个链接让用户可以通过扫二维码或者直接点击一个链接就进行支付。不管需要调用哪种支付,我们都必须先实现统一支付接口

一、统一支付接口:

统一支付接口的实现需要参照接口文档请求参数给必要的参数赋值然后以XML的方式传入,然后微信会根据我们传入的参数进行处理并以XML的形式返回相应的参数。需要注意的是参数名一定要参照ASCII码从小到大排序,参数为空的就不参与签名。这里我刚开始是手动排序的,这就导致我一直出现签名错误的问题。因此后面我采用了建立一个Dictionary<string, string> sign = new Dictionary<string, string>();然后在把每条参数和值添加进去在通过LINQ排序,这样能完美解决问题。需要注意的就是key值不能加进去,必须最后MD5加密前写在末尾。代码参考:

Dictionary<string, string> sine = new Dictionary<string, string>();
            sine.Add("appid", appid);
            sine.Add("mch_id", mch_id);
            sine.Add("nonce_str", nonce_str);
            sine.Add("body", body);
            sine.Add("total_fee", total_fee);
            sine.Add("out_trade_no", out_trade_no);
            sine.Add("spbill_create_ip", spbill_create_ip);
            sine.Add("notify_url", notify_url);
            sine.Add("trade_type", trade_type);
            sine.Add("openid", openid);
            var md5 = EncryptUtil.MD5(WeChatUtil.FormatBizQueryParaMap(sine, false) + "&key=" + key);
            string sign = md5.ToUpper();
            string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
            string xml = string.Format(@"<xml>
<appid>{0}</appid>
<body><![CDATA[{1}]]></body>
<mch_id>{2}</mch_id>
<nonce_str>{3}</nonce_str>
<notify_url><![CDATA[{8}]]></notify_url>
<openid><![CDATA[{10}]]></openid>
<out_trade_no>{4}</out_trade_no>
<spbill_create_ip>{5}</spbill_create_ip>
<trade_type><![CDATA[{9}]]></trade_type>
<total_fee>{6}</total_fee>
<sign><![CDATA[{7}]]></sign>
</xml>", appid, body, mch_id, nonce_str, out_trade_no, spbill_create_ip, total_fee, sign, notify_url, trade_type, openid);
            string sHtmlText = WeChatUtil.GetPage(url, xml);

二、JSAPI支付:

     我们通过统一支付接口成功后会返回预支付ID(prepay_id),然后调用JSAPI方法时需要用到的参数paySign的签名是需要重新按照签名生成方法重新生成的,切勿使用统一接口的Sign,然后这里不能按照Dictionary方法,JSAPI的参数名首字母会有大写,这个必须一样,前面字典加入进去会把参数名全部变成小写,这里参数是固定的,因此建议直接string.Format("appId={0}&nonceStr={1}&package={2}&signType={3}&timeStamp={4}&key={5}", appid, nonce_str, package, "MD5", time, key) 这样写比较好。

代码参考:

 var pay = WeChatUtil.XmlToEntity(new PayModel(), sHtmlText) as PayModel;
            var time = DateTimeUtil.ConvertDateTimeInt(DateTime.Now).ToString();
            var package = string.Format("prepay_id={0}", pay.prepay_id);
            string paySign = EncryptUtil.MD5(string.Format("appId={0}&nonceStr={1}&package={2}&signType={3}&timeStamp={4}&key={5}", appid, nonce_str, package, "MD5", time, key));
            StateUtil.SetSessionValue(_paySignKey,paySign);
            StateUtil.SetSessionValue(paySign,order);
            return Json(new { appId = pay.appid, timeStamp = time, nonceStr = nonce_str,
                package = string.Format("prepay_id={0}", pay.prepay_id), signType = "MD5", paySign = paySign.ToUpper() });


备注:Native支付基本上只要实现统一接口就基本完成了,这里就不在做介绍了。

三、支付宝vs微支付

现阶段的微支付如同一个刚懂事的小孩,官方没有demo,第一次实现起来比较麻烦,并且实现接口都需要签名一次,比较繁琐。而现阶段的支付宝要做的事情官方demo都已经做好并且有多个版本,我们所需要做的就是把参数依次填入就可以了。

我们拿都是网页支付的方法做比较,一下是支付宝实现的代码:

    SortedDictionary<string, string> sParaTemp = new SortedDictionary<string, string>();
    sParaTemp.Add("partner", Config.Partner);
    sParaTemp.Add("_input_charset", Config.Input_charset.ToLower());
    sParaTemp.Add("service", "create_direct_pay_by_user");
    sParaTemp.Add("payment_type", payment_type);
    sParaTemp.Add("notify_url", notify_url);
    sParaTemp.Add("return_url", return_url);
    sParaTemp.Add("seller_email", seller_email);
    sParaTemp.Add("out_trade_no", out_trade_no);
    sParaTemp.Add("subject", subject);
    sParaTemp.Add("total_fee", total_fee);
    sParaTemp.Add("body", body);
    sParaTemp.Add("anti_phishing_key", anti_phishing_key);
    sParaTemp.Add("exter_invoke_ip", exter_invoke_ip);
    //建立请求
    string sHtmlText = Submit.BuildRequest(sParaTemp, "get", "确认");
    return Content(sHtmlText);


其中Submit.BuildRequest方法是官方自带的,我们只需要这样就能给支付宝发出请求,然后就是等用户付款就可以做下一步操作了。

     在做微支付的时候查看了网上的资料,因此看到了以前2.X版本的微支付,跟现在的微支付方法变了不少,因为微信支付还处于不稳定的阶段很有可能在下一个大版本更新后方法又改变了,这样很有可能会影响到以前做的项目。所以很希望微信官方跟支付宝一样,不管你怎么变化,只要你提供一个方法“Subit.BuildRequest”不变就好了,这样也能方便我们调用。

 


微支付你“接”了么?

微支付你“接”了么?

分享: