🐛 Fixing a bug.支付宝异步回调 不修改支付状态

This commit is contained in:
冷冷 committed 2019-07-12 15:23:52 +08:00
1 parent 86b0cd228e
commit ad83a4f870
11 files changed
+183 -61

No files matched your search

@@ -1,3 +1,20 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.pay.handler;
/**
@@ -1,31 +0,0 @@
package com.pig4cloud.pigx.pay.handler;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.time.Duration;
/**
* @author lengleng
* @date 2019-06-14
* <p>
* 消息去重
*/
@Service
@AllArgsConstructor
public class MessageRedisDuplicateCheckerHandler implements MessageDuplicateCheckerHandler {
private final RedisTemplate redisTemplate;
/**
* 判断回调消息是否重复.
*
* @param messageId messageId需要根据上面讲的方式构造
* @return 如果是重复消息,返回false,否则返回true
*/
@Override
public boolean isDuplicate(String messageId) {
return redisTemplate.opsForValue()
.setIfAbsent(messageId, messageId, Duration.ofSeconds(10L));
}
}
@@ -15,8 +15,14 @@
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.pay.handler;
package com.pig4cloud.pigx.pay.handler.impl;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.pig4cloud.pigx.pay.entity.PayNotifyRecord;
import com.pig4cloud.pigx.pay.handler.PayNotifyCallbakHandler;
import com.pig4cloud.pigx.pay.service.PayNotifyRecordService;
import com.pig4cloud.pigx.pay.utils.PayConstants;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
@@ -54,4 +60,22 @@ public abstract class AbstractPayNotifyCallbakHandler implements PayNotifyCallba
saveNotifyRecord(params, result);
return result;
}
/**
* 保存记录
* @param params
* @param result
* @param record
* @param notifyId
* @param recordService
*/
public void saveRecord(Map<String, String> params, String result, PayNotifyRecord record, String notifyId
, PayNotifyRecordService recordService) {
record.setNotifyId(notifyId);
String orderNo = params.get(PayConstants.OUT_TRADE_NO);
record.setOrderNo(orderNo);
record.setRequest(MapUtil.join(params, StrUtil.DASHED, StrUtil.DASHED));
record.setResponse(result);
recordService.save(record);
}
}
@@ -1,8 +1,26 @@
package com.pig4cloud.pigx.pay.handler;
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.pay.handler.impl;
import com.pig4cloud.common.sequence.sequence.Sequence;
import com.pig4cloud.pigx.pay.entity.PayGoodsOrder;
import com.pig4cloud.pigx.pay.entity.PayTradeOrder;
import com.pig4cloud.pigx.pay.handler.PayOrderHandler;
import com.pig4cloud.pigx.pay.mapper.PayGoodsOrderMapper;
import com.pig4cloud.pigx.pay.utils.OrderStatusEnum;
import org.springframework.beans.factory.annotation.Autowired;
@@ -15,7 +15,7 @@
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.pay.handler;
package com.pig4cloud.pigx.pay.handler.impl;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.CharsetUtil;
@@ -30,6 +30,7 @@ import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
import com.pig4cloud.pigx.pay.entity.PayGoodsOrder;
import com.pig4cloud.pigx.pay.entity.PayNotifyRecord;
import com.pig4cloud.pigx.pay.entity.PayTradeOrder;
import com.pig4cloud.pigx.pay.handler.MessageDuplicateCheckerHandler;
import com.pig4cloud.pigx.pay.service.PayGoodsOrderService;
import com.pig4cloud.pigx.pay.service.PayNotifyRecordService;
import com.pig4cloud.pigx.pay.service.PayTradeOrderService;
@@ -75,9 +76,15 @@ public class AlipayPayNotifyCallbackHandler extends AbstractPayNotifyCallbakHand
*/
@Override
public Boolean duplicateChecker(Map<String, String> params) {
//判断是否是为支付中
if (StrUtil.equals(TradeStatusEnum.WAIT_BUYER_PAY.getDescription(), params.get(PayConstants.TRADE_STATUS))) {
log.info("支付宝订单待支付 {} 不做处理", params);
return true;
}
// 判断10秒内是否已经回调处理
if (!duplicateCheckerHandler.isDuplicate(params.get(PayConstants.OUT_TRADE_NO))) {
log.warn("支付宝订单重复回调 {} 不做处理", params);
if (duplicateCheckerHandler.isDuplicate(params.get(PayConstants.OUT_TRADE_NO))) {
log.info("支付宝订单重复回调 {} 不做处理", params);
this.saveNotifyRecord(params, "重复回调");
return true;
}
@@ -124,9 +131,9 @@ public class AlipayPayNotifyCallbackHandler extends AbstractPayNotifyCallbakHand
*/
@Override
public String parse(Map<String, String> params) {
String tradeStatus = EnumUtil.fromString(TradeStatusEnum.class, params.get("trade_status")).getStatus();
String tradeStatus = EnumUtil.fromString(TradeStatusEnum.class, params.get(PayConstants.TRADE_STATUS)).getStatus();
String orderNo = params.get("out_trade_no");
String orderNo = params.get(PayConstants.OUT_TRADE_NO);
PayGoodsOrder goodsOrder = goodsOrderService.getOne(Wrappers.<PayGoodsOrder>lambdaQuery()
.eq(PayGoodsOrder::getPayOrderId, orderNo));
goodsOrder.setStatus(tradeStatus);
@@ -136,6 +143,7 @@ public class AlipayPayNotifyCallbackHandler extends AbstractPayNotifyCallbakHand
.eq(PayTradeOrder::getOrderId, orderNo));
Long succTime = MapUtil.getLong(params, "time_end");
tradeOrder.setPaySuccTime(succTime);
tradeOrder.setChannelOrderNo(params.get("trade_no"));
tradeOrder.setStatus(TradeStatusEnum.TRADE_SUCCESS.getStatus());
tradeOrder.setChannelOrderNo(params.get("transaction_id"));
tradeOrderService.updateById(tradeOrder);
@@ -153,11 +161,7 @@ public class AlipayPayNotifyCallbackHandler extends AbstractPayNotifyCallbakHand
public void saveNotifyRecord(Map<String, String> params, String result) {
PayNotifyRecord record = new PayNotifyRecord();
String notifyId = params.get("notify_id");
record.setNotifyId(notifyId);
String orderNo = params.get("out_trade_no");
record.setOrderNo(orderNo);
record.setRequest(MapUtil.join(params, StrUtil.DASHED, StrUtil.DASHED));
record.setResponse(result);
recordService.save(record);
saveRecord(params, result, record, notifyId, recordService);
}
}
@@ -1,4 +1,21 @@
package com.pig4cloud.pigx.pay.handler;
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.pay.handler.impl;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.URLUtil;
@@ -54,7 +71,7 @@ public class AlipayWapPayOrderHandler extends AbstractPayOrderHandler {
tradeOrder.setChannelMchId(AliPayApiConfigKit.getAliPayApiConfig().getAppId());
tradeOrder.setClientIp(ServletUtil.getClientIP(request));
tradeOrder.setCurrency("cny");
tradeOrder.setExpireTime(Long.parseLong(payCommonProperties.getAliPayConfig().getReturnUrl()));
tradeOrder.setExpireTime(Long.parseLong(payCommonProperties.getAliPayConfig().getExpireTime()));
tradeOrder.setStatus(OrderStatusEnum.INIT.getStatus());
tradeOrder.setBody(goodsOrder.getGoodsName());
tradeOrderMapper.insert(tradeOrder);
@@ -83,7 +100,7 @@ public class AlipayWapPayOrderHandler extends AbstractPayOrderHandler {
AliPayApi.wapPay(response, model, payCommonProperties.getAliPayConfig().getReturnUrl()
, payCommonProperties.getAliPayConfig().getNotifyUrl());
} catch (AlipayApiException e) {
log.warn("支付宝支付失败 {} {}", e.getErrCode(), e.getErrMsg());
log.error("支付宝手机支付失败", e);
tradeOrder.setErrMsg(e.getErrMsg());
tradeOrder.setErrCode(e.getErrCode());
tradeOrder.setStatus(OrderStatusEnum.FAIL.getStatus());
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.pay.handler.impl;
import com.pig4cloud.pigx.pay.handler.MessageDuplicateCheckerHandler;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.time.Duration;
/**
* @author lengleng
* @date 2019-06-14
* <p>
* 消息去重
*/
@Service
@AllArgsConstructor
public class MessageRedisDuplicateCheckerHandler implements MessageDuplicateCheckerHandler {
private final RedisTemplate redisTemplate;
/**
* 判断回调消息是否重复.
*
* @param messageId messageId需要根据上面讲的方式构造
* @return 如果是重复消息true,否则返回false
*/
@Override
public boolean isDuplicate(String messageId) {
return !redisTemplate.opsForValue()
.setIfAbsent(messageId, messageId, Duration.ofSeconds(10L));
}
}
@@ -1,4 +1,21 @@
package com.pig4cloud.pigx.pay.handler;
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.pay.handler.impl;
import cn.hutool.extra.servlet.ServletUtil;
import com.jpay.ext.kit.PaymentKit;
@@ -8,6 +25,7 @@ import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
import com.pig4cloud.pigx.pay.config.PayCommonProperties;
import com.pig4cloud.pigx.pay.entity.PayGoodsOrder;
import com.pig4cloud.pigx.pay.entity.PayTradeOrder;
import com.pig4cloud.pigx.pay.handler.impl.AbstractPayOrderHandler;
import com.pig4cloud.pigx.pay.mapper.PayGoodsOrderMapper;
import com.pig4cloud.pigx.pay.mapper.PayTradeOrderMapper;
import com.pig4cloud.pigx.pay.utils.OrderStatusEnum;
@@ -15,11 +15,10 @@
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.pay.handler;
package com.pig4cloud.pigx.pay.handler.impl;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jpay.ext.kit.PaymentKit;
import com.jpay.weixin.api.WxPayApiConfigKit;
@@ -27,6 +26,7 @@ import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
import com.pig4cloud.pigx.pay.entity.PayGoodsOrder;
import com.pig4cloud.pigx.pay.entity.PayNotifyRecord;
import com.pig4cloud.pigx.pay.entity.PayTradeOrder;
import com.pig4cloud.pigx.pay.handler.MessageDuplicateCheckerHandler;
import com.pig4cloud.pigx.pay.service.PayGoodsOrderService;
import com.pig4cloud.pigx.pay.service.PayNotifyRecordService;
import com.pig4cloud.pigx.pay.service.PayTradeOrderService;
@@ -74,8 +74,8 @@ public class WeChatPayNotifyCallbackHandler extends AbstractPayNotifyCallbakHand
@Override
public Boolean duplicateChecker(Map<String, String> params) {
// 判断10秒内是否已经回调处理
if (!duplicateCheckerHandler.isDuplicate(params.get(PayConstants.OUT_TRADE_NO))) {
log.warn("微信订单重复回调 {} 不做处理", params);
if (duplicateCheckerHandler.isDuplicate(params.get(PayConstants.OUT_TRADE_NO))) {
log.info("微信订单重复回调 {} 不做处理", params);
this.saveNotifyRecord(params, "重复回调");
return true;
}
@@ -106,9 +106,9 @@ public class WeChatPayNotifyCallbackHandler extends AbstractPayNotifyCallbakHand
*/
@Override
public String parse(Map<String, String> params) {
String orderNo = params.get("out_trade_no");
String tradeStatus = EnumUtil.fromString(TradeStatusEnum.class, params.get("result_code")).getStatus();
String tradeStatus = EnumUtil.fromString(TradeStatusEnum.class, params.get(PayConstants.RESULT_CODE)).getStatus();
String orderNo = params.get(PayConstants.OUT_TRADE_NO);
PayGoodsOrder goodsOrder = goodsOrderService.getOne(Wrappers.<PayGoodsOrder>lambdaQuery()
.eq(PayGoodsOrder::getPayOrderId, orderNo));
goodsOrder.setStatus(tradeStatus);
@@ -140,11 +140,6 @@ public class WeChatPayNotifyCallbackHandler extends AbstractPayNotifyCallbakHand
public void saveNotifyRecord(Map<String, String> params, String result) {
PayNotifyRecord record = new PayNotifyRecord();
String notifyId = params.get("transaction_id");
record.setNotifyId(notifyId);
String orderNo = params.get("out_trade_no");
record.setOrderNo(orderNo);
record.setRequest(MapUtil.join(params, StrUtil.DASHED, StrUtil.DASHED));
record.setResponse(result);
recordService.save(record);
saveRecord(params, result, record, notifyId, recordService);
}
}
@@ -23,4 +23,15 @@ public interface PayConstants {
*/
String MICRO_MESSENGER = "MicroMessenger";
/**
* 返回码
*/
String RESULT_CODE = "result_code";
/**
* 支付状态(支付宝)
*/
String TRADE_STATUS = "trade_status";
}
@@ -13,7 +13,7 @@ public enum TradeStatusEnum {
/**
* 交易完成
*/
WAIT_BUYER_PAY("TRADE_FINISHED", OrderStatusEnum.INIT.getStatus()),
WAIT_BUYER_PAY("WAIT_BUYER_PAY", OrderStatusEnum.INIT.getStatus()),
/**
* TRADE_CLOSED