如何正确的处理支付回调
2020-12-16 本文已影响0人
大风过岗
下面以处理微信支付的回调为例
完整代码
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.util.*;
/**
* @Author: chihaojie
* @Date: 2020/12/7 16:26
* @Version 1.0
* @Note
*/
@Service
public class WXCallbackServiceImpl implements WXCallbackService {
private static final String CLASS_NAME = WXCallbackServiceImpl.class.getName();
private static final Logger infoLogger = BatteryCabinetLoggerFactory.getServerInfoLogger(WXCallbackServiceImpl.class);
private static final Logger errorLogger = BatteryCabinetLoggerFactory.getServerErrorLogger(WXCallbackServiceImpl.class);
private static final Object concurrentNotifyLock = new Object();
private static final String resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
@Autowired
private RentOrderMapper rentOrderMapper;
@Transactional
@Override
public void wxPaySuccessNotify(HttpServletRequest request, HttpServletResponse response) throws BatteryException {
final String methodName = "wxPaySuccessNotify";
Date now = new Date();
PrintWriter out = null;
String respWX = resXml;
String orderNum = null;
SortedMap<String, String> callbackParam = null;
try{
out = response.getWriter();
callbackParam = getWechatCallbackSortedMap(request);
infoLogger.info("[微信回调的内容为: {}]",JSONObject.toJSONString(callbackParam));
String result_code = callbackParam.get("result_code");
orderNum = callbackParam.get("out_trade_no");
String orderType = callbackParam.get("attach");
BigDecimal totalFee = new BigDecimal(callbackParam.get("total_fee"));
//校验签名
if (!WXPayUtil.isSignatureValid(callbackParam, WXPayConfig.KEY)) {
errorLogger.error("微信回调异常发生-回调签名错误: [ className: {},methodName: {},methodParam: {},]",CLASS_NAME,methodName,new String[]{JSONObject.toJSONString(callbackParam)});
}
synchronized (concurrentNotifyLock){
//在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。
//校验订单状态
RentOrderEntity rentOrder = rentOrderMapper.selectOrderByOrderNum(orderNum);
if(!ObjectUtils.isEmpty(rentOrder) ){
Boolean isEqual = rentOrder.getPayMoney().compareTo(totalFee) == 0;
//校验 支付状态 和订单金额
if( !SystemConstant.PAY_STATUS_NOTPAY.equals(rentOrder.getIsPayed()) && isEqual){
//执行相关的业务逻辑处理
//......修改订单支付状态
//....... 其他业务逻辑处理
}
}else errorLogger.error("微信回调异常发生-回调订单中错误: 订单不存在, 回调参数为:{}",callbackParam);
out.println(respWX);
out.flush();
out.close();
}
}catch (Exception e){
errorLogger.error("微信回调异常发生: [ className: {},methodName: {},callbackParam: {},orderNum: {}, ex: {}]",CLASS_NAME,methodName,JSONObject.toJSONString(callbackParam),orderNum, ExceptionUtils.formatExceptionStack(e));
respWX = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
+ "<return_msg><![CDATA[处理失败]]></return_msg>" + "</xml> ";
out.println(respWX);
out.flush();
out.close();
}
}
private SortedMap<String, String> getWechatCallbackSortedMap(HttpServletRequest request) throws BatteryException {
final String methodName = "getWechatCallbackSortedMap";
try{
//读取参数
StringBuffer sb = new StringBuffer();
InputStream inputStream = request.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String s;
while ((s = in.readLine()) != null) {
sb.append(s);
}
in.close();
inputStream.close();
//解析xml成map;
Map<String, String> xmlToMap = WXPayUtil.xmlToMap(sb.toString());
if (null == xmlToMap) {
throw new BatteryException(ErrorCodeEnum.ERROR_CODE_WECHAT_PAY_CALLBACK_EXCEPTION);
}
//过滤空 设置 TreeMap
SortedMap<String, String> callbackParam = new TreeMap<>();
Iterator it = xmlToMap.keySet().iterator();
while (it.hasNext()) {
String parameter = (String) it.next();
String parameterValue = xmlToMap.get(parameter);
String v = "";
if (null != parameterValue) {
v = parameterValue.trim();
}
callbackParam.put(parameter, v);
}
return callbackParam;
}catch (Exception e){
errorLogger.error("微信回调异常发生: [ className: {},methodName: {},methodParam: {},orderNum: {}, ex: {}]",CLASS_NAME,methodName,new String[]{"nothing"}, ExceptionUtils.formatExceptionStack(e));
throw new BatteryException(e.getCause());
}
}
}