吐槽: 微信支付的 SDK(.Net) 可能是实习生写的

版权声明:所有博客文章除特殊声明外均为原创,允许转载,但要求注明出处。

最近在作一个接入支付的项目,支付类型包括支付宝和微信支付。我是一个懒人,写代码的原则是:只要官方有 SDK 可用的话就尽量用官方的,除非万不得已不要自己写。微信支付当然也是有 SDK 的(地址在这里)。但是打开以后想要引用的时候,我有点被其不专业程度 shock 到了。按照道理,像支付这样涉及钱包问题的接口,即便不包含任何服务器逻辑,也应该作得比较严谨和正规吧,但微信支付的 SDK(.Net版) 却只能算新手级别的。这样的 SDK 微信你好意思拿出来让客户用吗?

问题之一:根本不算 SDK

下载的程序严格来说根本算不上SDK,而是一个基于 WebForm 的示例网站。虽然接口代码放在了和页面不同的命名空间中,然而有好几个接口类直接引用 System.Web.UI.Controls。这种代码已经绑死在 WebForm 上了,如果要在 MVC 项目中使用就要去修改很多代码——实际上 Page 参数是可以用 HttpContext 代替的(虽然也算不上非常好,但耦合会减少很多),但看来作者根本就没有这个意识。

问题之二:重要参数硬编码

在看接口调用的时候就发现程序没有设置两个重要的参数 appid/mch_id。再往下查找,才知道这些参数原来都作为常量定义在 WxPayConfig 里面。真正的程序是绝对不应该把这些参数硬编码在源文件里的,作者对此也同样毫无认识。这也意味着我必须为大多数接口增加额外的参数,从外部传入,否则这个接口对我而言是无法使用的。

问题之三:返回没有检查

下面是从 SDK 摘抄的源码:

WxPayData data = new WxPayData();
data.SetValue("body", "test");//商品描述
data.SetValue("attach", "test");//附加数据
data.SetValue("out_trade_no", WxPayApi.GenerateOutTradeNo());//随机字符串
data.SetValue("total_fee", 1);//总金额
data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));//交易起始时间
data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));//交易结束时间
data.SetValue("goods_tag", "jjj");//商品标记
data.SetValue("trade_type", "NATIVE");//交易类型
data.SetValue("product_id", productId);//商品ID
WxPayData result = WxPayApi.UnifiedOrder(data);//调用统一下单接口
string url = result.GetValue("code_url").ToString();//获得统一下单接口返回的二维码链接

这段代码是作为封装的函数提供的,但程序中却没有检查调用的返回结果是否正确,就直接 GetValue 了。实际上,如果传递的参数有问题,那么 result 应该包含 return_msg, 而不检查就取结果会直接导致 NPE,原本应该保留的错误信息也丢失了。这样的封装有何意义?

其他的小问题就不再一一列举了。我实在很难相信微信团队是这样对待支付这样一个重要产品的,又下载了它的 Java SDK 看看,对比一下就能看出,Java SDK 比 .Net SDK 写的专业多了:

  • 接口没有绑定到 Servlet,可以作为纯粹的类库调用;
  • WXPayConfig 是作为参数传递的,接口参数方法可以重载;
  • 对于接口返回结果有专门的函数处理错误信息。

由此大概可以得出结论:微信支付的 .Net 团队比 Java 团队水平差多了。也可能不是水平的问题,而是根本不重视 .Net 版本,随便找了个实习生来糊弄一下吧。我记得前段时间还有腾讯员工专门写文章记录他们是如何在公司内部推行 .Net 的,看来他们的工作成果也没有影响到微信的团队。希望微信支付的 .Net 程序员继续努力吧。