支付寶的接口調用很不方便,剛做好一個封裝,實現了虛擬交易和實物交易。
解決方案中有三個項目以及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('&');
}
}
新聞熱點
疑難解答