C#(文章随着实现而持续更新,各种产生都是个人遇到并且解决记录,有误地方请告示)
微信支付:
注意:
MD5加密注意编码方式,默认使用GBK(“GB2312”),因此MD5加密时,需要指定编码(“UTF-8”,网站使用的编码格式(charset)),否则签名会一直出错。支付宝支付:
(担保交易)疑问:(结果在尾)
Alipay只支持(暂时?)Form方式,虽然Document写着”推荐使用Form方式”,而且Demo有其他方式(Post写入流)但是,使用起来,相同的参数,相同的签名,只有Form成功,而(参数正确)其他都会一直提示:
/gateway.do?
签名失败(“ILLEGAL_SIGN”)
/gateway.do?_input_charset=utf-8
抱歉,由于网络系统的原因,您暂时无法使用当前的服务,请稍候再使用。
到这里大概想到为什么需要用“Form方式”,然后针对这两点使用“Form方式”进行测试:(“Form方式”带不带参数都能正常发出包)
action=/gateway.do?_input_charset=utf-8
结果:成功
action=/gateway.do?
结果:签名失败
–Query String Parameters 为空
编码的时候,要使用网站使用的编码格式来加密,虽然知道加密方式为MD5但是不知道使用“UTF-8”格式编码(c#(system)默认GBK),因此在支付宝接口那里进行签名对比,就会一直不同,导致一直提示“签名失败”。
因为要带”?_input_charset=utf-8”,在使用Post写入流的方式下:
#. 带参数:“抱歉,由于网络系统的原因,您暂时无法使用当前的服务,请稍候再使用。”,#. 不带参数:“ILLEGAL_SIGN ”(签名不正确),不知道加密的编码方式。
其他Document说明里也说了,URL后面要加上加上编码,所以因为要带”?_input_charset=utf-8”,而Post不能带,否则出现第一种提示,如果不带可以,但是没有签名失败。
而Form行,所以暂时只支持“Form方式”,不然获取不到。为什么会出现第一种,暂时没找到答案。
疑问 ——:
1. 使用默认MD5默认加密编码(GBK)不就行了么?
2. 用浏览器模拟Get方式(直接组装到URL里) – OK,但是使用c# WebClient/HttpWebRequest/……来GET,一样出现问题1
带着这两个问题,继续测试,结果让我否定上面几乎所有的“问”:
用Form成功之后会保存一个cookie(“ALIPAYJSESSIONID”),如果自己删了,就会出现问题1。
那么为什么浏览器可以,用后台不行,原来是c#默认没有给它写入的,需要创建CookieContainer类:
HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strUrl);myReq.Method = "post";myReq.ContentType = "application/x-www-form-urlencoded";myReq.CookieContainer = new CookieContainer();
这样就有定义了CookieContainer对象并且写入Cookie,返回给网页,而浏览器返回的包,如果看过,会发现Set_Cookie这个字段,返回时写入(当然,不知道如何说明)。
如果Cookie有“ALIPAYJSESSIONID”,Post写入流还是其他方式都能正常运行,URL(/gateway.do?_input_charset=utf-8)带参数本来就是没问题。
到这里为止,另外说下,我去Alipay问他们技术人员:“所有Alipay接口都只是接受:“Form方式””,所以我上面才那样说的……