原文:
http://www.cnblogs.com/phirothing/archive/2013/01/20/2868917.html
支付宝(各种版本:java,php...demo下载):
https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7386797.0.0.1AcL8O&treeId=193&articleId=105201&docType=1
支付宝接口调用顺序(个人理解,不懂得可以看作者原文,最好下载一个demo结合例子理解,最好有公司申请的appid ):
一 结构
1.接入部分:
接入部分即为传递参数等信息组合成超级链接,并用该链接来进行跳转
配置页面(alipay_Config),
方法详细页面(alipay/Alipay_Payto),
程序入口页面(index) ,
md5加密页面(alipayto/Alipay_md5)
2.通知返回部分
通知返回部分则是支付宝服务器对该笔订单处理完毕后,通知与返回该笔订单的详细信息到商户服 务器,商 户服务器接收到后,并对其进行数据处理。
方法详细页面(alipay/Alipay_Payto),
md5加密页面(alipayto/Alipay_md5),
支付完成后(支付宝处理完毕后)自动跳转回的自定义页面(return_Alipay_Notify
二 工作原理
1.选定参数
string service = "trade_create_by_buyer";
string seller_email = "
[email protected]";
string sign_type = "MD5";
string key = "********************************";
string partner = "2088************";
string _input_charset = "utf-8";
string show_url = "http://www.alipay.com/";
string out_trade_no = TxtOrderno.Text.Trim();
string subject = TxtSubject.Text.Trim();
string body = TxtBody.Text.Trim();
string price = TxtPrice.Text.Trim();
string quantity = TxtQua.Text.Trim();
string logistics_type = "POST";
string logistics_fee = TxtPost.Text.Trim();
string logistics_payment = "BUYER_PAY";
string notify_url = "http://www.xxx.com/swnet05utf8/Alipay_Notify.aspx";
string return_url = "http://www.xxx.com/swnet05utf8/Alipay_Return.aspx";
2.排序
拼接字符串,并按参数的变量名排序
3.加密
将参数用 & 并结成一个长的字符串(排除:string gateway = "https://www.alipay.com/cooperate/gateway.do?" ),之后将拼接的字符串加密,然后将加密后的字符串存储在sign这个参数中。
4.拼接URL
将网关(gaetway) 和加密的类型参数sign_type拼接进来
如:https://www.alipay.com/cooperate/gateway.do?s...3d199ba&sign_type=MD5
5.页面跳转
调用url,跳转到支付宝官方的收银页面
三 参数
1. service服务参数,这个是用来区别这个接口是用的什么接口,所以绝对不能修改。
2. partner合作身份者ID、key安全校验码或称私钥这一组参数是签约合同生效后才能拿的到 partner是来鉴别是哪个商家与支付宝签约,而这个Key它如同钥匙般相当重要。
3.seller_email收款人支付宝账号,支付宝中有手机类型、电子邮件类型的支付宝账号是都可 以用这个参数的。
4.subject在支付宝的收银台里是直接与商品名称关联在一起的,但是说的更准确些的话,这 个参数是这笔交易的名称,因为这笔交易不一定只买一件商品。它的作用不仅是在收银台 里可以清晰的显示出来,而且在支付宝的账
户的交易明细的列表里,它也是排在第一列,由此可推测出,它有财务对账、作为交易查询的筛选条件等诸多作用。非常重要。
5.out_trade_no技术文档中给出的是商户交易号(确保在商户系统中唯一),顾名思义这个就 是我们大家自己网站的订单系统里的唯一订单号,而非支付宝的。这里需要强调的,这个 订单号必须得是唯一的,如何唯一法?自己网站
6.price 总金额(算上运费)
7.payment_type 支付类型 :1
8.logistics_type、logistics_fee、logistics_payment这是一组物流信息
9._input_charset
当是UTF- 8的编码格式时必须得用到且不允许为空的,即_input_charset=”utf-8”
10. notify_url、return_url,return_url代表支付完毕后可以自动从支付宝的官方页面跳转 回来,notify_url这个是防止调单的首选最佳工具。
11. body,在支付宝收银台中的商品描述里显示,如果subject是订单名称的话,那么这个bod y则最准确的称之为订单描述,其实个人认为它作为备注之类的更为恰当。很多人都很郁 闷支付宝为何不能像其他公司
12. discount折扣,顾名思义如果小于0,则是用原金额Price*quantity+(discount),实际金额便比原总额小了。现在有些商户有支付宝的优惠卷,而优惠卷的用途也是在这个参数中体现,具体做法与前
面无异。
13. show_url商品展示地址,这个链接的作用是在支付宝收银台的商品链接旁边有个下划线“详情”的链接,而点链接弹出的一个新页面便是这个商品展示地址的页面。
14. 收货信息receive_name、receive_address、receive_zip、receive_phone、receive_mobile,这些信息若也设置为传递给支付宝的参数之一的话,那么在支付宝收银台点选下一步的时候,本该出现的填写收货信息页面不见踪影,而直接跳到了收货信息页面的下一个页面去了。很多商户在自己的网站的购物
流程中都有一个填写收货信息的选项卡,为了省去到支付宝收银台中还要填写一次收货信息的麻烦,那么这些收货信息的参数就派上用场了。值得注意的是,收货人姓名和地址是必填项,不然还是会出现收货信息填写页。
15. buyer_email买家支付宝账号,这个设置好后呈现的效果便是,原本是空的支付宝账号的输入框此时已经有个支付宝账号在里面放置。
c) 剩下的参数无需理会
四 通知返回
a)返回页
具备的属性:
1、支付接口中买家的购买流程已经走到支付宝里且支付宝提示支付成功时,页面会自动跳转回自身网站的这个页面里来。
2、同步的,无时差
3、获得参数的方法是用get方式获取。
4、不论跳转回来程序判断是真还是假(if(sign = mysign and responseTxt = true))只跳转回来一次,不重复。
5、这个并不是支付宝服务器调用了该页面,而是通过与组合拼接各参数形成的URL链接原理等同,拼接出来的URL链接,之后程序上做自动跳转。
6、基于5的原因,该页面的程序调试可不必在服务器上而是 本机 上调试、运行。
b)通知页
具备的属性:
1、这个通知页就是被支付宝调用才能启动的。
2、服务器间的互动,不像返回页肉眼可以看到,这个是看不到的。
3、获得参数的方法是用POST方式获取。
4、支付宝中的该笔交易存在,且该笔交易状态发生了变更,就会被调用。
5、被调用程序判断(if(sign = mysign and responseTxt = true)),若我们自己在该判断中有做程序编写,成功则不再被调用,不成功则会反复被调用。
6、异步的,第一次收到订单信息(以下都称之为“通知”)是与返回页近乎等同或等同的同步时间,在判断不成功的情况下,会收到第二次第三次等次数的通知,时间间隔从最先的一两分钟,到后面的几个小时。失效时间是4
8小时。
7、基于6的原因,该页面的程序调试必须在 服务器 上调试、运行。
8、程序编写时必须采用程序执行成功,才写页面response.Write(“success”);,不成功则写页面response.Write(“fail”); 支付宝根据success来判定是否要重新再次发送通知。
9、该页面的Html页面中必须是空白、无任何Html标签、无任何空格、不允许做页面跳转
几种状态:
if (mysign == sign && responseTxt == "true")
{
//判断支付状态_等待买家付款(文档中有枚举表可以参考)
if (Request.Form["trade_status"] == "WAIT_BUYER_PAY")
{
//更新自己数据库的订单语句,请自己填写一下
}
//判断支付状态_买家付款成功,等待卖家发货(文档中有枚举表可以参考)
else if (Request.Form["trade_status"] == "WAIT_SELLER_SEND_GOODS")
{
//更新自己数据库的订单语句,请自己填写一下
string strOrderNO = Request.Form["out_trade_no"];//订单号
string strPrice = Request.Form["price"];//金额
string sql = "update order_table set order_status = '买家已付款,等待卖家发货' where order_no = @out_trade_no";
Update(sql,para);
}
//判断支付状态_卖家已发货等待买家确认(文档中有枚举表可以参考)
else if (Request.Form["trade_status"] == "WAIT_BUYER_CONFIRM_GOODS")
{
//更新自己数据库的订单语句,请自己填写一下
string strOrderNO = Request.Form["out_trade_no"];//订单号
string strPrice = Request.Form["price"];//金额
string sql = "update order_table set order_status = '卖家已发货,等待买家确认收货' where order_no = @out_trade_no";
Update(sql, para);
}
// 判断支付状态_交易成功结束(文档中有枚举表可以参考)
else if (Request.Form["trade_status"] == "TRADE_FINISHED")
{
//更新自己数据库的订单语句,请自己填写一下
string strOrderNO = Request.Form["out_trade_no"];//订单号
string strPrice = Request.Form["price"];//金额
string sql = "update order_table set order_status = '交易成功' where order_no = @out_trade_no";
Update(sql, para);
}
else
{
//更新自己数据库的订单语句,请自己填写一下
}
Response.Write("success");
}
else
{
Response.Write("fail");
}
五 调试
注意事项:
1.页面设置 : 不能将支付宝的页面放在自己网站的框架下面
2.参数的传递方式 :post和get不能混用传递参数,统一用同一种方法传递参数
3.编码格式 : 最好统一采用utf-8