pay.ftl
<span style="white-space:pre"> </span><div class="orderMes">
<p>感谢您在本店购物!您的订单号已提交成功,请记住您的订单号:<span class="textRed">${order.orderno}</span></p>
<p>
您选定的配送方式为:<span class="textRed">顺丰</span>;
您选定的支付方式为:<span class="textRed">支付宝</span>;
您的应付款金额为:<span class="textRed">¥${order.total}</span>;
</p>
<span style="color:#ff0000;"> <a class="payBtn" href="${path}/alipay/gopay/${order.id}">立即支付 ></a></span>
<p>您可以返回<a class="textOrange" href="${path}/index">首页</a>或去<a class="textOrange" href="${path}/manage/order">用户中心</a></p>
</div>
AlipayApiController
@SuppressWarnings(value="all")
@Controller
@RequestMapping(value="/alipay")
public class AlipayApiController extends BaseController {
Logger logger = Logger.getLogger(AlipayApiController.class);
public static final String ALIPAY_GATEWAY_NEW = "https://mapi.alipay.com/gateway.do?";
@Autowired
private IOrderService orderService;
@Autowired
private ICorpPayaccountService accountService;
@Autowired
private InitService initService;
/*** 支付宝回调 url配置 */
public String Alipay_URL = "";
@ModelAttribute
public void init(ServletRequest req, ServletResponse resp) throws Exception{
Alipay_URL = initService.getPcpath();
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse) resp;
HttpSession session = request.getSession();
Long storeId=(Long) session.getAttribute("storeId");
// if(store.getPcurl().equals("rzh.ebiaoji.com")){
// Alipay_URL="http://"+store.getPcurl()+"/shop-pc";
// }else{
// Alipay_URL="http://"+store.getPcurl();
// }
}
<span style="color:#ff0000;">/**
* 功能: 前往支付宝支付页面
* 说明 : 订单创建后,生成支付链接,跳转到支付宝页面
* 日期 : 2015-09-10 by chan
*/
@RequestMapping(value="/gopay/{orderid}")
public String goodsid(ModelMap model,@PathVariable Long orderid)throws Exception{
//获取商家账号信息(支付宝支付=1)
</span><span style="color:#cc33cc;">PaymentAccount payaccount = accountService.findByCorpIdAndPaymode(corpid, PayTypeEnum.ALIPAY.getValue());
Order order = orderService.getOrder(orderid);</span><span style="color:#ff0000;">
if(null == payaccount){
logger.info("商家没有设置支付账号");
return "/system/500";
}else{
</span><span style="color:#cc33cc;">String sHtmlText = buildRequest(order, payaccount);
model.addAttribute("sHtmlText", sHtmlText);
//唤起收银支付页面
</span><span style="color:#009900;">return "/alipay/pay";</span><span style="color:#ff0000;">
}
}</span>
<span style="color:#cc33cc;"> /**
*功能:即时到账交易接口接入页
*版本:3.3
*日期:2012-08-14
*说明:
*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*************************注意*****************
*如果您在接口集成过程中遇到问题,可以按照下面的途径来解决
*1、商户服务中心(https://b.alipay.com/support/helperApply.htm?action=consultationApply),提交申请集成协助,我们会有专业的技术工程师主动联系您协助解决
*2、商户帮助中心(http://help.alipay.com/support/232511-16307/0-16307.htm?sh=Y&info_type=9)
*3、支付宝论坛(http://club.alipay.com/read-htm-tid-8681712.html)
*如果不想使用扩展功能请把扩展功能参数赋空值。
**********************************************
*/
private String buildRequest(Order order,PaymentAccount payaccount) throws Exception {
// 支付类型
// 必填,不能修改
String payment_type = "1";
// 服务器异步通知页面路径
// 需http://格式的完整路径,不能加?id=123这类自定义参数
String notify_url = Alipay_URL+"/alipay/notify_url/"+order.getId();
// 页面跳转同步通知页面路径
// 需http://格式的完整路径,不能加?id=123这类自定义参数,不能写成http://localhost/
String return_url = Alipay_URL+"/alipay/return_url/"+order.getId();
//商户订单号.商户网站订单系统中唯一订单号,必填
String out_trade_no = order.getOrderno() ;
//订单名称 必填
String subject = "商城订单支付";
//订单金额
String total_fee = order.getTotal().toString();
//订单描述
String body = "订单描述,共"+total_fee+"元";
Map<String, String> sParaTemp = new HashMap<String, String>();
sParaTemp.put("service", "create_direct_pay_by_user");//接口服务----即时到账
sParaTemp.put("partner", payaccount.getPartnerid());//支付宝PID
sParaTemp.put("seller_email", payaccount.getSellerid());//卖家支付宝账号
sParaTemp.put("_input_charset", AlipayConfig.input_charset);//统一编码
sParaTemp.put("payment_type", payment_type);//支付类型
sParaTemp.put("notify_url", notify_url);//异步通知页面
sParaTemp.put("return_url", return_url);//页面跳转同步通知页面
sParaTemp.put("out_trade_no", out_trade_no);//商品订单编号
sParaTemp.put("subject", subject);//商品名称
sParaTemp.put("total_fee", total_fee);//价格
sParaTemp.put("body", body);
//建立请求
String sHtmlText = AlipaySubmit.buildRequest(ALIPAY_GATEWAY_NEW, sParaTemp, "get", "确认",payaccount.getPayservice());
logger.info("生成链接"+sHtmlText);
return sHtmlText;
}
</span>
/**
* 功能 : 支付宝支付页面跳转异步通知页面路径 通知支付宝
* 说明 : 修改订单状态,减少库存数量
* 日期 : 2015-09-23 by chan
*/
@RequestMapping(value="/notify_url/{orderid}",method=RequestMethod.POST)
public void alipaytoNotify(ModelMap model,
@PathVariable java.lang.Long orderid,
HttpServletRequest request,
HttpServletResponse response)throws Exception
{
System.out.println("=============================alipay start notify..."+new Date());
//获取商家账号信息(支付宝支付=1)
PaymentAccount payaccount = accountService.findByCorpIdAndPaymode(corpid, PayTypeEnum.ALIPAY.getValue());
if(null == payaccount){
System.out.println("=============================商家没有设置支付账号...");
logger.info("商家没有设置支付账号");
}else{
//获取支付宝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);
}
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
//RSA签名解密
if(AlipayConfig.sign_type.equals("0001")) {
params = AlipayNotify.decrypt(params);
}
//System.out.println("支付宝支付 服务器异步通知页面路径:"+params);
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
//商户订单号
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");
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
String msg="";
if(AlipayNotify.verifyNotify(params,payaccount.getPartnerid(),payaccount.getPayservice())){//验证成功
//
//请在这里加上商户的业务逻辑程序代码
//——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
if(trade_status.equals("TRADE_FINISHED")){
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序
//注意:
//该种交易状态只在两种情况下出现
//1、开通了普通即时到账,买家付款成功后。
//2、开通了高级即时到账,从该笔交易成功时间算起,过了签约时的可退款时限(如:三个月以内可退款、一年以内可退款等)后。
msg="success";
//请不要修改或删除
} else if (trade_status.equals("TRADE_SUCCESS")){
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序
//注意:
//该种交易状态只在一种情况下出现——开通了高级即时到账,买家付款成功后。
msg="success";
}
//——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
//
}else{//验证失败
msg="fail";
}
//支付宝支付 服务器回调 服务器订单 查询
if(msg.equals("success")){
//支付宝支付 服务器回调 服务器订单 查询
Order order = orderService.getOrder(orderid);
//已经支付过的订单
Order payOrder = orderService.findByIdAndPaystatus(orderid, PayStatusEnum.YES.getValue());
if(null!=order && payOrder == null){
orderService.payOrder(order);
}
//请不要修改或删除
response.getWriter().println("success");
}else{
response.getWriter().println("fail");
}
System.out.println("支付宝支付 服务器异步通知页面路径:"+params);
System.out.println("支付宝支付 页面跳转异步通知页面路径:"+msg);
}
}
/**
* 功能 : 支付宝支付服务器同步通知页面路径
* 说明: 支付成功,返回本地订单列表
* 日期 : 2015-09-23 by chan
*/
@RequestMapping(value="/return_url/{orderid}")
public String alipaytoCallback(ModelMap model,
@PathVariable java.lang.Long orderid,HttpServletRequest request)throws Exception{
//获取商家账号信息(支付宝支付=1)
PaymentAccount payaccount = accountService.findByCorpIdAndPaymode(corpid, PayTypeEnum.ALIPAY.getValue());
if(null == payaccount){
logger.info("商家没有设置支付账号");
return "/system/500";
}else{
//获取支付宝GET过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map requestParams = request.getParameterMap();
System.out.println("请求参数:"+requestParams);
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"), "utf-8");
params.put(name, valueStr);
}
System.out.println("支付参数:"+params);
System.out.println("支付宝支付 服务器同步通知页面路径:"+params);
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
//商户订单号 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 result = new String(request.getParameter("result").getBytes("ISO-8859-1"),"UTF-8");
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
//计算得出通知验证结果
boolean verify_result = AlipayNotify.verifyNotify(params,payaccount.getPartnerid(),payaccount.getPayservice());
String msg="";
if(verify_result){//验证成功
//
//请在这里加上商户的业务逻辑程序代码
//——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
//该页面可做页面美工编辑
msg="验证成功<br />";
//——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
//支付宝支付 服务器回调 服务器订单 查询
Order order=orderService.getOrder(orderid);
//已经支付过的订单
Order payOrder = orderService.findByIdAndPaystatus(orderid, PayStatusEnum.YES.getValue());
if(null!=order && order.getStatus()!=1 && payOrder == null){
orderService.payOrder(order);
}
return "redirect:/manage/order";
}else{
//该页面可做页面美工编辑
msg="验证失败";
}
//支付宝支付 服务器异步通知页面路径
model.addAttribute("errormsg", "支付宝支付 服务器同步通知页面路径:"+msg);
return "/system/500";
}
}
/** 2014-10-13 add by wayne
* 支付宝支付 操作中断返回地址
* @param model
* @param request
* @return
* @throws Exception
*/
@RequestMapping(value="/error_url/{orderid}")
public String alipayerror(ModelMap model,@PathVariable java.lang.Long orderid,HttpServletRequest request) throws Exception{
System.out.println("支付宝支付操作中断返回地址:"+orderid);
Order order=orderService.getOrder(orderid);
if(null!=order){
model.addAttribute("errormsg", "订单支付错误");
return "redirect:"+Alipay_URL+"/manage/order/"+order.getId();
}else{
return "/system/500";
}
}
}
CorpPayaccountServiceImpl
@Component
public class CorpPayaccountServiceImpl extends BaseServiceImpl<PaymentAccount> implements ICorpPayaccountService{
@Autowired
private CorpPayaccountDao accountDao;
/** ------------------------------- 扩展 ------------------------------*/
<span style="color:#cc33cc;">/**
* 查询当前企业下支付方式,1:支付宝,2:微信支付,3:其他(免费)
*/
@Override
public PaymentAccount findByCorpIdAndPaymode(Long corpid,Integer paymode) throws Exception {
return accountDao.findByCorpIdAndPaymode(corpid,paymode);
}</span>
}
OrderServiceImpl
<pre name="code" class="java">@Component
public class OrderServiceImpl extends BaseServiceImpl<Order> implements
IOrderService {
@Autowired
private OrderDao orderDao;
@Autowired
private OrderHistoryDao orderHistoryDao;
@Autowired
private OrderItemDao orderItemDao;
@Autowired
private IGoodsService goodsService;
@Autowired
private IMemberService memberService;
@Autowired
private ICartService cartService;
@Autowired
private IMessageChannelService messageChannelService;
@Autowired
private IVoucherRecordService voucherRecordService;
/**
<span> </span><span style="color:#cc33cc;"> * 查询订单 单一
<span> </span> */
<span> </span>@Override
<span> </span>public Order getOrder(Long id) throws Exception {
<span> </span>return orderDao.findOne(id);
<span> </span>}</span>
}
pay.ftl
<!DOCTYPE html>
<html lang="zh">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta charset="utf-8">
<title></title>
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta name="format-detection" content="telephone=no">
</head>
<body>
<span style="color:#009900;">${sHtmlText}</span>
</body>
</html>