微信支付接口之心酸
发布日期:2022-03-13 05:36:11 浏览次数:16 分类:技术文章

本文共 11046 字,大约阅读时间需要 36 分钟。

微信接口,对于某些人来说,很容易,宝宝自己尝试了一下,瞬间感觉泪奔呀,唉。

首先,统一下单接口

[HttpPost]        [Route("~/api/WXPay/UnifiedOrder")]        public HttpResponseMessage UnifiedOrder()        {            try            {                NameValueCollection param = Request.Content.ReadAsFormDataAsync().Result;                string body = param["body"].ToString();//简单描述                string out_trade_no = param["out_trade_no"].ToString();                string total_fee = param["total_fee"].ToString();                string spbill_create_ip = param["spbill_create_ip"].ToString();                var stringADict = new Dictionary
(); stringADict.Add("appid", "这里是公众号ID"); stringADict.Add("mch_id", "商户号"); stringADict.Add("device_info", device_info); stringADict.Add("nonce_str", CreateNonce_str()); stringADict.Add("body", body); stringADict.Add("out_trade_no", out_trade_no); stringADict.Add("total_fee", total_fee); stringADict.Add("spbill_create_ip", spbill_create_ip); stringADict.Add("notify_url", "回调函数"); stringADict.Add("trade_type", "APP"); var sign = Sign(stringADict, "签名字符串");//生成签名字符串 var postdata = GeneralPostdata(stringADict, sign); var url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; var client = new HttpClient(); var result = client.PostAsync(url, new StringContent(postdata)).Result; if (!result.IsSuccessStatusCode) return null; dynamic doc = new DynamicXml(result.Content.ReadAsStringAsync().Result); JObject obj = new JObject(); var a = doc.return_code.Value; var c = doc.return_msg.Value; if (doc.return_code.Value == "SUCCESS" && doc.result_code.Value == "SUCCESS") { obj.Add("prepay_id", doc.prepay_id.Value); obj.Add("trade_type", doc.trade_type.Value); obj.Add("sign", doc.sign.Value); obj.Add("nonce_str", doc.nonce_str.Value); obj.Add("result_code", doc.result_code.Value); obj.Add("return_code", doc.return_code.Value); obj.Add("return_msg", doc.return_msg.Value); obj.Add("RetCode", 0); obj.Add("RetMsg", ""); } else { obj.Add("RetCode", -1); obj.Add("doc", doc.return_code.ToString() + doc.return_msg.ToString()); } return Request.CreateResponse(obj); } catch (Exception e) { JObject obj = new JObject(); obj.Add("RetCode", "-1"); obj.Add("ErrorDescription", e.ToString()); obj.Add("RetMsg", "错误代码:" + Guid.NewGuid().ToString()); return Request.CreateResponse(obj); } }

  在这里,必须要说明的是DynamicXml,在这个动态读取XML的时候,可坑死宝宝了。

public class DynamicXml : DynamicObject, IEnumerable    {        private readonly List
_elements; public DynamicXml(string text) { var doc = XDocument.Parse(text); _elements = new List
{ doc.Root }; } protected DynamicXml(XElement element) { _elements = new List
{ element }; } protected DynamicXml(IEnumerable
elements) { _elements = new List
(elements); } public override bool TryGetMember(GetMemberBinder binder, out object result) { result = null; if (binder.Name == "Value") result = _elements[0].Value; else if (binder.Name == "Count") result = _elements.Count; else { var attr = _elements[0].Attribute(XName.Get(binder.Name)); if (attr != null) result = attr; else { var items = _elements.Descendants(XName.Get(binder.Name)); if (items == null || items.Count() == 0) return false; result = new DynamicXml(items); } } return true; } public IEnumerator GetEnumerator() { foreach (var element in _elements) yield return new DynamicXml(element); } ///
/// /// ///
///
///
///
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) { int ndx = (int)indexes[0]; result = new DynamicXml(_elements[ndx]); return true; } ///
/// /// ///
public override string ToString() { StringWriter message = new StringWriter(); foreach (var item in _elements) message.WriteLine("{0}:\t{1}", item.Document, item.Value); return message.ToString(); } }

  因为刚开始没有加上ToString和TryGetIndex的重写,然后呢,解析了一天,都不知道哪里的错。唉

OK,微信回调接口

[HttpPost]        [Route("~/api/WXPay/Notify")]        public HttpResponseMessage Notify()        {            try            {                byte[] a = Request.Content.ReadAsByteArrayAsync().Result;                string b = Encoding.UTF8.GetString(a);                var sParam = GetRequestPost(b);                if (sParam.Count <= 0)                {                    throw new ArgumentNullException();                }                JObject obj = new JObject();                obj.Add("RetCode", 0);                obj.Add("RetMsg", "");                if (sParam["return_code"] == "SUCCESS" && sParam["result_code"] == "SUCCESS")                {                    var sign = sParam["sign"];                    var signValue = Sign(sParam, "签名字符串");                    bool isVerify = sign == signValue;                    if (isVerify)                    {                        var out_trade_no = sParam["out_trade_no"];                        //具体的后期业务操作                    }                    obj.Add("return_code", "success");                }                else                {                    obj.Add("return_code", "fail");                }                return Request.CreateResponse(HttpStatusCode.OK, obj);            }            catch (ArgumentNullException e)            {                JObject obj = new JObject();                obj.Add("RetCode", "-1");                obj.Add("RequestMsg", "暂无参数!");                return Request.CreateResponse(obj);            }            catch (Exception e)            {                JObject obj = new JObject();                obj.Add("RetCode", "-1");                obj.Add("ErrorDescription", e.ToString());                obj.Add("RetMsg", "错误代码:" + Guid.NewGuid().ToString());                return Request.CreateResponse(obj);            }        }

  对于这里的GetRequestPost方法,其实就是组合生成一个标准的xml字符串。

private SortedDictionary
GetRequestPost(string xml) { SortedDictionary
sArray = new SortedDictionary
(); dynamic resultXml = new DynamicXml(xml); sArray.Add("appid", resultXml.appid.Value); sArray.Add("bank_type", resultXml.bank_type.Value); sArray.Add("cash_fee", resultXml.cash_fee.Value); sArray.Add("fee_type", resultXml.fee_type.Value); sArray.Add("is_subscribe", resultXml.is_subscribe.Value); sArray.Add("mch_id", resultXml.mch_id.Value); sArray.Add("nonce_str", resultXml.nonce_str.Value); sArray.Add("openid", resultXml.openid.Value); sArray.Add("out_trade_no", resultXml.out_trade_no.Value); sArray.Add("time_end", resultXml.time_end.Value); sArray.Add("total_fee", resultXml.total_fee.Value); sArray.Add("transaction_id", resultXml.transaction_id.Value); sArray.Add("trade_type", resultXml.trade_type.Value); sArray.Add("sign", resultXml.sign.Value); sArray.Add("result_code", resultXml.result_code.Value); sArray.Add("return_code", resultXml.return_code.Value); return sArray; }

  附,后面的辅助方法,包含签名生成工具等。

public static string GeneralPostdata(IDictionary
postdataDict, string sign) { var sb2 = new StringBuilder(); sb2.Append("
"); foreach (var sA in postdataDict.OrderBy(x => x.Key)) { sb2.Append("<" + sA.Key + ">") .Append(Transfer(sA.Value)) .Append("
"); } sb2.Append("
").Append(sign).Append("
"); sb2.Append("
"); return sb2.ToString(); } public static string Transfer(string instr) { if (instr == null) return ""; return instr.Replace("&", "&").Replace("<", "<") .Replace(">", ">").Replace("\"", """); } ///
/// 生成签名 /// 签名在线验证工具: /// http://mch.weixin.qq.com/wiki/tools/signverify/ /// ///
参与签名生成的参数列表 ///
商家私钥 ///
public static string Sign(IDictionary
stringADict, string partnerKey) { var sb = new StringBuilder(); foreach (var sA in stringADict.OrderBy(x => x.Key)) { if (string.IsNullOrEmpty(sA.Value)) continue; if (string.Compare(sA.Key, "sign", true) == 0) continue; sb.Append(sA.Key).Append("=").Append(sA.Value).Append("&"); } var string1 = sb.ToString(); sb.Append("key=").Append(partnerKey); var stringSignTemp = sb.ToString(); var sign = MD5(stringSignTemp, "UTF-8").ToUpper(); return sign; } public static string MD5(string encypStr, string charset = "UTF-8") { string retStr; MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider(); byte[] inputBye; byte[] outputBye; try { inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr); } catch { inputBye = Encoding.GetEncoding("GB2312").GetBytes(encypStr); } outputBye = m5.ComputeHash(inputBye); retStr = System.BitConverter.ToString(outputBye); retStr = retStr.Replace("-", "").ToUpper(); return retStr; }

  OK,只是一个简单的记录,可以直接套用的,当然,对于.net来说,特别注意的就是那个DynamicXML那个类,太尼玛坑爹了,百毒了半天,然后看了半天,终于晓得问题了,唉。不喜勿喷。谢谢

      其中,很多包含借鉴网上的东西,如有版权牵扯,请及时联系本人,谢谢。

转载于:https://www.cnblogs.com/JeffController/p/5531494.html

转载地址:https://blog.csdn.net/weixin_30323961/article/details/98220692 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:【转】VMware 11安装Mac OS X 10.10 及安装Mac Vmware Tools.
下一篇:lintcode-212. 空格替换 java

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月20日 19时17分59秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

Vue事件处理_vue的事件处理超级方便_功能强大---vue工作笔记0011 2019-04-26
Vue表单数据自动收集---vue工作笔记0012 2019-04-26
Vue生命周期---vue工作笔记0013 2019-04-26
ES6-ES11新特性_ECMAScript_简单介绍---JavaScript_ECMAScript工作笔记001 2019-04-26
ES6-ES11新特性_ECMAScript相关名词介绍_---JavaScript_ECMAScript工作笔记002 2019-04-26
ES6新特性_let变量声明以及声明特性---JavaScript_ECMAScript_ES6-ES11新特性工作笔记003 2019-04-26
Sharding-Sphere,Sharding-JDBC_介绍_Sharding-Sphere,Sharding-JDBC分布式_分库分表工作笔记001 2019-04-26
Sharding-Sphere,Sharding-JDBC_分库分表介绍_Sharding-Sphere,Sharding-JDBC分布式_分库分表工作笔记002 2019-04-26
C++_类和对象_对象特性_构造函数的分类以及调用---C++语言工作笔记041 2019-04-26
C++_类和对象_对象特性_拷贝构造函数调用时机---C++语言工作笔记042 2019-04-26
C++_类和对象_对象特性_构造函数调用规则---C++语言工作笔记043 2019-04-26
C++_类和对象_对象特性_深拷贝与浅拷贝---C++语言工作笔记044 2019-04-26
AndroidStudio_java.util.ConcurrentModificationException---Android原生开发工作笔记237 2019-04-26
AndroidStudio_android中实现对properties文件的读写操作_不把properties文件放在assets文件夹中_支持读写---Android原生开发工作笔记238 2019-04-26
弹框没反应使用Looper解决_the caller should invoke Looper.prepare() and Looper.loop()---Android原生开发工作笔记239 2019-04-26
Command line is too long. Shorten command line for Application---微服务升级_SpringCloud Alibaba工作笔记0067 2019-04-26
AndroidStudio_android实现双击_3击_监听实现---Android原生开发工作笔记240 2019-04-26
C++_类和对象_对象特性_初始化列表---C++语言工作笔记045 2019-04-26
AndroidStudio安卓原生开发_UI高级_DrawerLayout_侧滑菜单控件---Android原生开发工作笔记120 2019-04-26
AndroidStudio安卓原生开发_UI高级_Shape的使用_虚线_直线_矩形_渐变_径向渐变_线性渐变_扫描渐变---Android原生开发工作笔记122 2019-04-26