net.mingsoft.pay.aop.MPayNotifyLogAop Maven / Gradle / Ivy
The newest version!
/**
* Copyright (c) 2012-present 铭软科技(mingsoft.net)
* 本软件及相关文档文件(以下简称“软件”)的版权归 铭软科技 所有
* 遵循 铭软科技《服务协议》中的《保密条款》
*/
package net.mingsoft.pay.aop;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import net.mingsoft.mdiy.util.ConfigUtil;
import net.mingsoft.pay.constant.Const;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.util.AlipayNotify;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
import com.github.binarywang.wxpay.service.WxPayService;
import net.mingsoft.basic.aop.BaseAop;
import net.mingsoft.pay.action.web.WeixinPayAction;
import net.mingsoft.pay.bean.PayBean;
import net.mingsoft.pay.biz.IPayLogBiz;
import net.mingsoft.pay.entity.PayLogEntity;
import net.mingsoft.pay.entity.PayLogEntity.LogStatusEnum;
import net.mingsoft.pay.entity.PayLogEntity.LogTypeEnum;
/**
* 支付模块,交易日志业务处理
*
* @author 铭飞开发团队
* @version 版本号:100-000-000
* 创建日期:2018年4月19日
* 历史修订:
*/
@Component
@Aspect
public class MPayNotifyLogAop extends BaseAop {
/**
* 交易记录
*/
@Autowired
private IPayLogBiz payLogBiz;
@Pointcut("@annotation(net.mingsoft.pay.ann.MPayNotifyLogAnn)")
public void log() {
}
@Around("log()")
public Object log(ProceedingJoinPoint jp) throws Throwable {
//订单号
Object target = jp.proceed();
ShiroHttpServletRequest shiroHttpServletRequest = this.getType(jp, ShiroHttpServletRequest.class);
HttpServletRequest request = (HttpServletRequest) shiroHttpServletRequest.getRequest();
String alipayParam = request.getParameter("out_trade_no");
if(!StringUtils.isEmpty(alipayParam)){
// 获取支付宝POST过来反馈信息
Map params = new HashMap();
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 price = request.getParameter("total_amount");
String logTitle = request.getParameter("subject");
// 支付宝交易号
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");
// 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
LOG.debug("支付回调");
Map alipayConfig = ConfigUtil.getMap(Const.ALIPAY_PAY_CONFIG_NAME);
//app支付验证标记
boolean appFlag = false;
//网站支付验证标记
boolean flag = false;
if(!StringUtils.isEmpty(alipayConfig.get("payAlipayPublicKey"))){
try {
//app支付验证回调参数状态
appFlag = AlipaySignature.rsaCheckV1(params, alipayConfig.get("payAlipayPublicKey"), "UTF-8","RSA2");
} catch (AlipayApiException e) {
// TODO Auto-generated catch block
LOG.debug("app支付验证失败");
e.printStackTrace();
}
}
params.put("ckey", alipayConfig.get("payKey"));
params.put("cpartner", alipayConfig.get("payPartner"));
flag = AlipayNotify.verify(params);
if(flag || appFlag){
// 验证成功
// ////////////////////////////////////////////////////////////////////////////////////////
// 请在这里加上商户的业务逻辑程序代码
// ——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
LOG.debug("支付回调成功");
PayLogEntity payLog = new PayLogEntity();
payLog.setOrderNo(out_trade_no);
PayLogEntity newPayLog = (PayLogEntity) payLogBiz.getEntity(payLog);
//TRADE_SUCCESS :交易支付成功、TRADE_FINISHED :交易结束,不可退款
if ("TRADE_FINISHED".equals(trade_status) || "TRADE_SUCCESS".equals(trade_status)) {
// 判断该笔订单是否在商户网站中已经做过处理
// 如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
// 如果有做过处理,不执行商户的业务程序
LOG.debug("支付回调订单:" + out_trade_no);
//回写日志,修改支付状态
if (newPayLog == null) {
newPayLog = new PayLogEntity();
newPayLog.setOrderNo(out_trade_no);
newPayLog.setLogTransactionId(trade_no);
newPayLog.setLogMoney(Double.valueOf(price));
newPayLog.setLogTitle(logTitle);
newPayLog.setLogStatus(LogStatusEnum.PAY.toString());
newPayLog.setLogPayType(PayBean.Type.ALIPAY);
newPayLog.setLogDate(new Date());
newPayLog.setLogType(LogTypeEnum.OUTCOME.toString());
payLogBiz.saveEntity(newPayLog);
}else if(StringUtils.equals(newPayLog.getLogStatus(), LogStatusEnum.UN_PAY.toString())){
newPayLog.setLogStatus(LogStatusEnum.PAY.toString());
newPayLog.setLogPayType(PayBean.Type.ALIPAY);
newPayLog.setLogDate(new Date());
newPayLog.setLogTransactionId(trade_no);
newPayLog.setLogType(LogTypeEnum.OUTCOME.toString());
payLogBiz.updateEntity(newPayLog);
}
// 注意:
// 该种交易状态只在两种情况下出现
// 1、开通了普通即时到账,买家付款成功后。
// 2、开通了高级即时到账,从该笔交易成功时间算起,过了签约时的可退款时限(如:三个月以内可退款、一年以内可退款等)后。
}
LOG.debug("支付成功:");
} else {// 验证失败
LOG.debug("支付回调订单失败:");
}
}else{
//微信支付
// 获取支付实体
Map weixinPayConfig = ConfigUtil.getMap(Const.WEIXIN_PAY_CONFIG_NAME);
WxPayService payService = WeixinPayAction.buildPayService(weixinPayConfig,null);
try {
synchronized (this) {
String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
WxPayOrderNotifyResult result = payService.parseOrderNotifyResult(xmlResult);
// if (SignUtils.checkSign(result, null,
// pay.getWeixinPayMchId())) {
if (result.getResultCode().equalsIgnoreCase("SUCCESS")) { // 支付成功
String orderNo = result.getOutTradeNo().split("\\|")[0]; // 需要通过分割特殊符合还原原始订单号
String totalFee = BaseWxPayResult.fenToYuan(result.getTotalFee());
// 自己处理订单的业务逻辑,需要判断订单是否已经支付过,否则可能会重复调用
// 根据订单ID查询订单信息
PayLogEntity payLog = new PayLogEntity();
payLog.setOrderNo(orderNo);
PayLogEntity newPayLog = (PayLogEntity) payLogBiz.getEntity(payLog);
if (newPayLog != null) {
if (newPayLog.getLogStatus() == LogStatusEnum.UN_PAY.toString()
&& newPayLog.getLogMoney() == Double.parseDouble(totalFee)) { // 判断存在的订单是否已经支付成功,如果没有支付成功就进行支付操作
newPayLog.setLogStatus(LogStatusEnum.PAY.toString());
newPayLog.setLogPayType(PayBean.Type.WEIXIN);
newPayLog.setLogTransactionId(result.getTransactionId());
newPayLog.setLogDate(new Date());
newPayLog.setLogType(LogTypeEnum.OUTCOME.toString());
payLogBiz.updateEntity(newPayLog);
this.LOG.info("out_trade_no: " + result.getOutTradeNo() + " pay SUCCESS!");
}
}
}
// } else { // 支付失败
// response.getWriter().write(" ");
// this.LOG.error("out_trade_no: " + result.getOutTradeNo() + "
// check signature FAIL");
// }
}
} catch (Exception e) {
LOG.error("微信回调结果异常,异常原因{}," + e.getMessage());
// return WxPayNotifyResponse.fail(e.getMessage());
}
}
return jp.proceed();
}
}