支付宝的接口调用很不方便,刚做好一个封装,实现了虚拟交易和实物交易。
解决方案中有三个项目以及ndoc生成的文档,简单的序列图:commonalipay,封装的支付宝接口。
testali,asp.net的测试项目
testcommonalipay,nunit的测试项目。
调用方法:
1、引入commonalipay.dll
2、实现支付宝服务接口的方法调用方式:
alipay ap = new alipay();
string key = "";//填写自己的key
string partner = "";//填写自己的partner
standardgoods bp = new standardgoods("trade_create_by_buyer", partner, key, "md5", "卡2", guid.newguid().tostring(), 2.551m, 1, "[email protected]", "[email protected]"
, "ems", 25.00m, "buyer_pay","1");
bp.notify_url = "http://203.86.79.185/ali/notify.aspx";
ap.createstandardtrade("https://www.alipay.com/cooperate/gateway.do", bp, this);上面是通用的调用方式。
下面是只支持虚拟货物的方式:
string key = "";//填写自己的key
string partner = "";//填写自己的partner
alipay ap = new alipay();
digitalgoods bp = new digitalgoods("create_digital_goods_trade_p", partner, key, "md5", "卡2", guid.newguid().tostring(), 2.551m, 1, "[email protected]", "[email protected]");
bp.notify_url = "http://203.86.79.185/ali/notify.aspx";
ap.createdigitaltrade("https://www.alipay.com/cooperate/gateway.do", bp, this);3、实现支付宝通知接口方法的调用(支持虚拟和实物):
protected void page_load(object sender, eventargs e)
{
string key = "";//填写自己的key
string partner = "";//填写自己的partner
alipay ap = new alipay();
string notifyid = request.form["notify_id"];
verify v = new verify("notify_verify", partner, notifyid);
ap.waitsellersendgoods+=new alipay.processnotifyeventhandler(ap_waitsellersendgoods);
ap.waitbuyerpay += new alipay.processnotifyeventhandler(ap_waitbuyerpay);
ap.processnotify(this, "https://www.alipay.com/cooperate/gateway.do",key,v, "utf-8");
}
void ap_waitbuyerpay(object sender, notifyeventargs e)
{
// //加入自己的处理逻辑
log4net.log.error("wait buyer pay fire");
}
private void ap_waitsellersendgoods(object sender, notifyeventargs e)
{
//加入自己的处理逻辑
log4net.log.error("waitsellersendgoods fire");
}支付宝的交易状态都被定义成了类似名称的事件。
部分源代码解析:
1、解析forms集合到notifyeventargs类,因为后面此类的数据要用来做md5sign,所以所有值类型,不能存在初始值,如:int的0等。因此用nullable范型。
private notifyeventargs parsenotify(namevaluecollection nv, object obj)
{
propertyinfo[] propertyinfos = obj.gettype().getproperties(bindingflags.public | bindingflags.instance);
foreach (propertyinfo pi in propertyinfos)
{
string v = nv.get(pi.name.tolower());
if (v != null)
{
if (pi.propertytype == typeof(string))
{
pi.setvalue(obj, v, null);
}
else if (pi.propertytype == typeof(int?))
{
pi.setvalue(obj, int.parse(v), null);
}
else if (pi.propertytype == typeof(decimal?))
{
pi.setvalue(obj, decimal.parse(v), null);
}
else if (pi.propertytype == typeof(datetime?))
{
pi.setvalue(obj, datetime.parse(v), null);
}
else if (pi.propertytype == typeof(bool))
{
pi.setvalue(obj, bool.parse(v), null);
}
else
{
//转型失败会抛出异常
pi.setvalue(obj, v, null);
}
}
}
return (notifyeventargs)obj;
}
2、从类型中获取排序后的参数
/**//// <summary>
/// 获取排序后的参数
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
private sortedlist<string,string> getparam(object obj)
{
propertyinfo[] propertyinfos = obj.gettype().getproperties(bindingflags.public|bindingflags.instance);
sortedlist<string, string> sortedlist = new sortedlist<string, string>(stringcomparer.currentcultureignorecase);
foreach (propertyinfo pi in propertyinfos)
{
if (pi.getvalue(obj, null) != null)
{
if (pi.name == "sign" || pi.name == "sign_type")
{
continue;
}
sortedlist.add(pi.name.tolower(), pi.getvalue(obj, null).tostring());
}
}
return sortedlist;
}3、从sortedlist中产生参数
private string geturlparam(sortedlist<string, string> sortedlist,bool isencode)
{
stringbuilder param = new stringbuilder();
stringbuilder encodeparam = new stringbuilder();
if (isencode == false)
{
foreach (keyvaluepair<string, string> kvp in sortedlist)
{
string t = string.format("{0}={1}", kvp.key, kvp.value);
param.append(t + "&");
}
return param.tostring().trimend('&');
}
else
{
foreach (keyvaluepair<string, string> kvp in sortedlist)
{
string et = string.format("{0}={1}", httputility.urlencode(kvp.key), httputility.urlencode(kvp.value));
encodeparam.append(et + "&");
}
return encodeparam.tostring().trimend('&');
}
}
新闻热点
疑难解答