首先要了解第三方支付的处理流程(已支付宝为例:)
页面效果:
一.选择支付方式提交
struts文件配置:
<action name="buttTestEpay" class="payAction" method="executeEpay">
</action>
action:
/**
* 支付链接
*/
public String executeEpay() throws Exception {
String userId = (String) this.getSession().get(Constants.SESSION_USER_ID);
this.payService.savePayMent(payInfo, userId);
HttpServletResponse response = ServletActionContext.getResponse();
response.setContentType("text/html; charset=utf-8");
PrintWriter p=response.getWriter();
if(StringUtils.equals(payInfo.getPayMode(), "1")){
//支付宝
p.println(this.payService.setAlipay(payInfo));
}else if(StringUtils.equals(payInfo.getPayMode(), "2")){
//民生e付宝
p.println(GenerateDirectPayServiceUrl.main(payInfo));
}else{
//网银支付(支付宝代理)
p.println(this.payService.setAlipay(payInfo));
}
return null;
}
Service实现类:
1.支付宝支付、网银支付:
/**
* 支付宝数据设置
*/
public String setAlipay(PayInfo payInfo){
Map<String, String> sParaTemp = new HashMap<String, String>();
sParaTemp.put("service", "create_direct_pay_by_user");
sParaTemp.put("partner", AlipayConfig.partner);
sParaTemp.put("seller_id", AlipayConfig.partner);
sParaTemp.put("_input_charset", AlipayConfig.input_charset);
sParaTemp.put("payment_type", "1");
sParaTemp.put("notify_url", Constants.BASE_URL+"/jsp/pay/notify_url.jsp");
sParaTemp.put("return_url", Constants.BASE_URL+"/jsp/pay/return_url.jsp");
sParaTemp.put("out_trade_no", payInfo.getPayId());
sParaTemp.put("subject", payInfo.getPayName());
sParaTemp.put("total_fee", payInfo.getPayMoeny().toString());
sParaTemp.put("body", "");
sParaTemp.put("show_url", "");
sParaTemp.put("anti_phishing_key", "");
sParaTemp.put("exter_invoke_ip", "");
//网银支付
if(!StringUtils.equals(payInfo.getPayMode(), "1")){
sParaTemp.put("paymethod", "bankPay");
sParaTemp.put("defaultbank", payInfo.getPayMode());
}
//建立请求(调用支付宝demo文档中的数据处理,加密方式为:MD5)
String sHtmlText = AlipaySubmit.buildRequest(sParaTemp,"get","确认");
return sHtmlText;
}
2.民生e支付直接调用的demo文档和支付宝业务处理相似!
二.支付成功后的业务处理(异步处理为例):
异步处理页面(根据demo页面修改),根据返回的数据进行所需的业务处理:
<%@page import="com.traymarket.utils.enums.PayMode"%>
<%@page import="com.traymarket.utils.SpringContextHolder"%>
<%
/* *
功能:支付宝服务器异步通知页面
版本:3.3
日期:2012-08-17
说明:
以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
//***********页面功能说明***********
创建该页面文件时,请留心该页面文件中无任何HTML代码及空格。
该页面不能在本机电脑测试,请到服务器上做测试。请确保外部可以访问该页面。
该页面调试工具请使用写文本函数logResult,该函数在com.alipay.util文件夹的AlipayNotify.java类文件中
如果没有收到该页面返回的 success 信息,支付宝会在24小时内按一定的时间策略重发通知
//********************************
* */
%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<%@ page import="com.traymarket.pay.alipay.util.*"%>
<%@ page import="com.traymarket.pay.alipay.config.*"%>
<%@page import="org.springframework.context.ApplicationContext"%>
<%@page import="com.traymarket.main.service.PayService"%>
<%
//获取支付宝POST过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map requestParams = request.getParameterMap();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i]
: valueStr + values[i] + ",";
}
//乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
params.put(name, valueStr);
}
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
//商户订单号
String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
//支付宝交易号
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
//交易状态
String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
if(AlipayNotify.verify(params)){//验证成功
//
//请在这里加上商户的业务逻辑程序代码
//——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
if(trade_status.equals("TRADE_FINISHED")){
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序
//注意:
//退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
} else if (trade_status.equals("TRADE_SUCCESS")){
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序
ApplicationContext applicationContext = SpringContextHolder.getApplicationContext();
PayService payService=(PayService)applicationContext.getBean("payService");
payService.updatePayment(out_trade_no,trade_no,PayMode.ALIPAY.getValue());
//注意:
//付款完成后,支付宝系统发送该交易状态通知
}
//——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
out.println("success"); //请不要修改或删除
//
}else{//验证失败
out.println("fail");
}
%>
民生异步处理页面最后返回消息方法:
//
...............
ServletOutputStream out1 = response.getOutputStream();
//成功<pre name="code" class="html"> //out1.write(new String("true").getBytes());
//失败
out1.write(new String("false").getBytes()); }finally{ out.clear(); out = pageContext.pushBody(); }
三,支付宝文档代码:
/**
* 建立请求,以表单HTML形式构造(默认)
* @param sParaTemp 请求参数数组
* @param strMethod 提交方式。两个值可选:post、get
* @param strButtonName 确认按钮显示文字
* @return 提交表单HTML文本
*/
public static String buildRequest(Map<String, String> sParaTemp, String strMethod, String strButtonName) {
//待请求参数数组
Map<String, String> sPara = buildRequestPara(sParaTemp);
List<String> keys = new ArrayList<String>(sPara.keySet());
StringBuffer sbHtml = new StringBuffer();
sbHtml.append("<form id=\"alipaysubmit\" name=\"alipaysubmit\" action=\"" + ALIPAY_GATEWAY_NEW
+ "_input_charset=" + AlipayConfig.input_charset + "\" method=\"" + strMethod
+ "\">");
for (int i = 0; i < keys.size(); i++) {
String name = (String) keys.get(i);
String value = (String) sPara.get(name);
sbHtml.append("<input type=\"hidden\" name=\"" + name + "\" value=\"" + value + "\"/>");
}
//submit按钮控件请不要含有name属性
sbHtml.append("<input type=\"submit\" value=\"" + strButtonName + "\" style=\"display:none;\"></form>");
sbHtml.append("<script>document.forms['alipaysubmit'].submit();</script>");
return sbHtml.toString();
}
四 总结:
1.第三方支付中支付宝技术文档写得比较完整,容易看懂,可能出现的问题总结得比较齐全。
2.个人觉得民生e支付业务处理完全和支付宝相似,且民生技术文档遗漏问题较多,如果不是先前做了支付宝支付,做民生e支付可能花的时间会更多(文档写得太水了)。
3.支付宝退款,支付宝商户批量支付接口和支付宝支付接口相似,按照接口文档提交数据到对应接口就行了!