Browse Source

Merge branch 'for_member_only' of https://git.youlane.cn/server/formallProject into for_member_only

release_toaliyun_real
xhxu 5 years ago
parent
commit
fe2c312b65
29 changed files with 1307 additions and 1195 deletions
  1. +1
    -1
      mallinkCallback/src/main/java/com/iformall/controller/callback/WxPayController.java
  2. +8
    -6
      mallinkMQConsumer/src/main/java/com/iformall/mq/MqBaseConsumer.java
  3. +48
    -48
      mallinkSchedule/src/main/java/com/iformall/schedule/MsgReSendSchedule.java
  4. +1
    -1
      mallinkSchedule/src/main/java/com/iformall/schedule/OrderExpiringSchedule.java
  5. +2
    -0
      mallinkService/src/main/java/com/iformall/domain/po/WxRefundOrder.java
  6. +1
    -1
      mallinkService/src/main/java/com/iformall/enums/EnumMsgRecordType.java
  7. +3
    -3
      mallinkService/src/main/java/com/iformall/service/WxPayOrderService.java
  8. +15
    -110
      mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java
  9. +1
    -1
      mallinkService/src/main/java/com/iformall/service/impl/WxProfitSharingOrderServiceImpl.java
  10. +62
    -961
      mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java
  11. +14
    -14
      mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideNotifyPaySuccessMsgServiceImpl.java
  12. +58
    -28
      mallinkService/src/main/java/com/iformall/service/pay/PayServiceFactory.java
  13. +2
    -2
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/CPassivePayService.java
  14. +2
    -2
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/PayAdapterService.java
  15. +1
    -1
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/entity/CreateCUser.java
  16. +1
    -1
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/entity/PayAdapterResult.java
  17. +1
    -1
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/entity/PayQueryAdapterResult.java
  18. +2
    -2
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/BaseWxPayAdapterService.java
  19. +45
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/h5/WxH5PayService.java
  20. +4
    -4
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/miniApp/appPay/WxMiniAppPayAdapterService.java
  21. +5
    -5
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/miniApp/maPay/WxMiniMaPayAdapterService.java
  22. +42
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/refund/RefundPayAdapterService.java
  23. +50
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/refund/entity/RefundAdapterResult.java
  24. +87
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/refund/entity/RefundNotifyAdapterResult.java
  25. +636
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/WxRefundAdapterService.java
  26. +8
    -1
      mallinkService/src/main/java/com/iformall/service/pay/service/share/PayShareAdapterService.java
  27. +1
    -1
      mallinkService/src/main/java/com/iformall/service/pay/service/share/entity/PayShareResult.java
  28. +76
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/share/entity/ShareNotifyAdapterResult.java
  29. +130
    -1
      mallinkService/src/main/java/com/iformall/service/pay/service/share/wx/WxPayShareService.java

+ 1
- 1
mallinkCallback/src/main/java/com/iformall/controller/callback/WxPayController.java View File

@@ -180,7 +180,7 @@ public class WxPayController extends BaseController {
xml = IOUtils.toString(request.getInputStream(), Charset.forName("UTF-8"));
paramMap = WxPayment.xmlToMap(xml);
logger.info("share wxpay, notify, param: " + xml );
response = wxPayOrderService.notify(paramMap, EnumPayWay.PAY_WAY_WECHAT);
response = wxPayOrderService.shareNotify(paramMap, EnumPayWay.PAY_WAY_WECHAT);
logger.info("share wxpay, notify success, req : " + xml + ", resp: " + response.toString());
return response;
} catch (BizMessageException e) {


+ 8
- 6
mallinkMQConsumer/src/main/java/com/iformall/mq/MqBaseConsumer.java View File

@@ -37,8 +37,8 @@ public class MqBaseConsumer {
@Autowired
private MqBaseProducer mqBaseProducer;

@Autowired
private FmInsideNotifyPaySuccessMsgServiceImpl fmInsideNotifyPaySuccessMsgService;
//@Autowired
//private FmInsideNotifyPaySuccessMsgServiceImpl fmInsideNotifyPaySuccessMsgService;
@Autowired
private FmInsideNotifyRefundSuccessMsgServiceImpl fmInsideNotifyRefundSuccessMsgService;
@Autowired
@@ -89,11 +89,13 @@ public class MqBaseConsumer {
// 内部消息 - c端登录
FmInsideCLoginMsg msg = (FmInsideCLoginMsg)JsonUtil.readValue(message,FmInsideCLoginMsg.class);
fmInsideCouponVerifyMsgService.send(msg);
} else if(EnumMsgRecordType.INSIDE_NOTIFY_PAY_SUCCESS.getCode().equals(baseMsg.getMsgType())) {
}
//else if(EnumMsgRecordType.INSIDE_NOTIFY_PAY_SUCCESS.getCode().equals(baseMsg.getMsgType())) {
// 内部消息 - 微信支付通知
FmInsideNotifyPaySuccessMsg msg = (FmInsideNotifyPaySuccessMsg)JsonUtil.readValue(message,FmInsideNotifyPaySuccessMsg.class);
fmInsideNotifyPaySuccessMsgService.send(msg);
} else if(EnumMsgRecordType.INSIDE_NOTIFY_REFUND_SUCCESS.getCode().equals(baseMsg.getMsgType())) {
//FmInsideNotifyPaySuccessMsg msg = (FmInsideNotifyPaySuccessMsg)JsonUtil.readValue(message,FmInsideNotifyPaySuccessMsg.class);
//fmInsideNotifyPaySuccessMsgService.send(msg);
//}
else if(EnumMsgRecordType.INSIDE_NOTIFY_REFUND_SUCCESS.getCode().equals(baseMsg.getMsgType())) {
// 内部消息 - 微信退款通知
FmInsideNotifyRefundSuccessMsg msg = (FmInsideNotifyRefundSuccessMsg)JsonUtil.readValue(message,FmInsideNotifyRefundSuccessMsg.class);
fmInsideNotifyRefundSuccessMsgService.send(msg);


+ 48
- 48
mallinkSchedule/src/main/java/com/iformall/schedule/MsgReSendSchedule.java View File

@@ -25,56 +25,56 @@ public class MsgReSendSchedule {
@Autowired
private MqBaseProducer mqBaseProducer;

@Scheduled(cron = "0 */5 * * * *?") // 每5分钟检查一次
//@Scheduled(cron = "0 */5 * * * *?") // 每5分钟检查一次
//@Scheduled(cron = "*/10 * * * * ?") // 测试10秒中一次
public void msgReSend() {
logger.info("消息重发开始...");
//消息重发
WxMsgRecord msgRecord = new WxMsgRecord();
msgRecord.setMsgStatus(EnumMsgRecordStatus.SEND_FAIL.getCode());
List<WxMsgRecord> recordList = wxMsgRecordService.findList(msgRecord);
for (WxMsgRecord wxMsgRecord:recordList) {
logger.info("消息重发:{}",wxMsgRecord.getMsgJson());
TenantEntity tenantEntity = wxMsgRecord.getTenantInfo();
try {
if(EnumMsgRecordType.INSIDE_ORDER_SUCCESS.getCode().equals(wxMsgRecord.getMsgType())){
//内部消息 - 下订单成功
FmInsideOrderSuccessMsg msg = (FmInsideOrderSuccessMsg) JsonUtil.readValue(wxMsgRecord.getMsgJson(),FmInsideOrderSuccessMsg.class);
msg.setMsgType(wxMsgRecord.getMsgType());
msg.setReceiver(wxMsgRecord.getReceiver());
msg.updateTenantInfo(tenantEntity);
mqBaseProducer.sendMessage(msg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
}else if(EnumMsgRecordType.INSIDE_COUPON_VERIFY.getCode().equals(wxMsgRecord.getMsgType())){
FmInsideCouponVerifyMsg msg = (FmInsideCouponVerifyMsg) JsonUtil.readValue(wxMsgRecord.getMsgJson(),FmInsideCouponVerifyMsg.class);
msg.setMsgType(wxMsgRecord.getMsgType());
msg.setReceiver(wxMsgRecord.getReceiver());
msg.updateTenantInfo(tenantEntity);
mqBaseProducer.sendMessage(msg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
}else if(EnumMsgRecordType.INSIDE_C_LOGIN.getCode().equals(wxMsgRecord.getMsgType())){
FmInsideCLoginMsg msg = (FmInsideCLoginMsg) JsonUtil.readValue(wxMsgRecord.getMsgJson(),FmInsideCLoginMsg.class);
msg.setMsgType(wxMsgRecord.getMsgType());
msg.setReceiver(wxMsgRecord.getReceiver());
msg.updateTenantInfo(tenantEntity);
mqBaseProducer.sendMessage(msg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
}else if(EnumMsgRecordType.INSIDE_NOTIFY_PAY_SUCCESS.getCode().equals(wxMsgRecord.getMsgType())){
FmInsideNotifyPaySuccessMsg msg = (FmInsideNotifyPaySuccessMsg) JsonUtil.readValue(wxMsgRecord.getMsgJson(),FmInsideNotifyPaySuccessMsg.class);
msg.setMsgType(wxMsgRecord.getMsgType());
msg.setReceiver(wxMsgRecord.getReceiver());
msg.updateTenantInfo(tenantEntity);
mqBaseProducer.sendMessage(msg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
}else if(EnumMsgRecordType.INSIDE_NOTIFY_REFUND_SUCCESS.getCode().equals(wxMsgRecord.getMsgType())){
FmInsideNotifyRefundSuccessMsg msg = (FmInsideNotifyRefundSuccessMsg) JsonUtil.readValue(wxMsgRecord.getMsgJson(),FmInsideNotifyRefundSuccessMsg.class);
msg.setMsgType(wxMsgRecord.getMsgType());
msg.setReceiver(wxMsgRecord.getReceiver());
msg.updateTenantInfo(tenantEntity);
mqBaseProducer.sendMessage(msg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
}
} catch (Exception e) {
e.printStackTrace();
logger.error("消息重发错误:" + e.getMessage());
}
}
logger.info("消息重发结束...");
// logger.info("消息重发开始...");
// //消息重发
// WxMsgRecord msgRecord = new WxMsgRecord();
// msgRecord.setMsgStatus(EnumMsgRecordStatus.SEND_FAIL.getCode());
// List<WxMsgRecord> recordList = wxMsgRecordService.findList(msgRecord);
// for (WxMsgRecord wxMsgRecord:recordList) {
// logger.info("消息重发:{}",wxMsgRecord.getMsgJson());
// TenantEntity tenantEntity = wxMsgRecord.getTenantInfo();
// try {
// if(EnumMsgRecordType.INSIDE_ORDER_SUCCESS.getCode().equals(wxMsgRecord.getMsgType())){
// //内部消息 - 下订单成功
// FmInsideOrderSuccessMsg msg = (FmInsideOrderSuccessMsg) JsonUtil.readValue(wxMsgRecord.getMsgJson(),FmInsideOrderSuccessMsg.class);
// msg.setMsgType(wxMsgRecord.getMsgType());
// msg.setReceiver(wxMsgRecord.getReceiver());
// msg.updateTenantInfo(tenantEntity);
// mqBaseProducer.sendMessage(msg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
// }else if(EnumMsgRecordType.INSIDE_COUPON_VERIFY.getCode().equals(wxMsgRecord.getMsgType())){
// FmInsideCouponVerifyMsg msg = (FmInsideCouponVerifyMsg) JsonUtil.readValue(wxMsgRecord.getMsgJson(),FmInsideCouponVerifyMsg.class);
// msg.setMsgType(wxMsgRecord.getMsgType());
// msg.setReceiver(wxMsgRecord.getReceiver());
// msg.updateTenantInfo(tenantEntity);
// mqBaseProducer.sendMessage(msg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
// }else if(EnumMsgRecordType.INSIDE_C_LOGIN.getCode().equals(wxMsgRecord.getMsgType())){
// FmInsideCLoginMsg msg = (FmInsideCLoginMsg) JsonUtil.readValue(wxMsgRecord.getMsgJson(),FmInsideCLoginMsg.class);
// msg.setMsgType(wxMsgRecord.getMsgType());
// msg.setReceiver(wxMsgRecord.getReceiver());
// msg.updateTenantInfo(tenantEntity);
// mqBaseProducer.sendMessage(msg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
// }else if(EnumMsgRecordType.INSIDE_NOTIFY_PAY_SUCCESS.getCode().equals(wxMsgRecord.getMsgType())){
// FmInsideNotifyPaySuccessMsg msg = (FmInsideNotifyPaySuccessMsg) JsonUtil.readValue(wxMsgRecord.getMsgJson(),FmInsideNotifyPaySuccessMsg.class);
// msg.setMsgType(wxMsgRecord.getMsgType());
// msg.setReceiver(wxMsgRecord.getReceiver());
// msg.updateTenantInfo(tenantEntity);
// mqBaseProducer.sendMessage(msg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
// }else if(EnumMsgRecordType.INSIDE_NOTIFY_REFUND_SUCCESS.getCode().equals(wxMsgRecord.getMsgType())){
// FmInsideNotifyRefundSuccessMsg msg = (FmInsideNotifyRefundSuccessMsg) JsonUtil.readValue(wxMsgRecord.getMsgJson(),FmInsideNotifyRefundSuccessMsg.class);
// msg.setMsgType(wxMsgRecord.getMsgType());
// msg.setReceiver(wxMsgRecord.getReceiver());
// msg.updateTenantInfo(tenantEntity);
// mqBaseProducer.sendMessage(msg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
// }
// } catch (Exception e) {
// e.printStackTrace();
// logger.error("消息重发错误:" + e.getMessage());
// }
// }
// logger.info("消息重发结束...");
}



+ 1
- 1
mallinkSchedule/src/main/java/com/iformall/schedule/OrderExpiringSchedule.java View File

@@ -30,7 +30,7 @@ import com.iformall.service.WxPayOrderService;
import com.iformall.service.WxRefundOrderService;
import com.iformall.service.helper.WxPayOrderServiceHelper;
import com.iformall.service.pay.PayServiceFactory;
import com.iformall.service.pay.entity.PayQueryAdapterResult;
import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult;
import com.iformall.utils.DateUtils;

@Component


+ 2
- 0
mallinkService/src/main/java/com/iformall/domain/po/WxRefundOrder.java View File

@@ -4,12 +4,14 @@ import com.baomidou.mybatisplus.annotation.TableName;
import com.iformall.domain.po.base.TenantEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.util.*;

@TableName(value = "wx_refund_order")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString
public class WxRefundOrder extends TenantEntity {

protected Long id;


+ 1
- 1
mallinkService/src/main/java/com/iformall/enums/EnumMsgRecordType.java View File

@@ -15,7 +15,7 @@ public enum EnumMsgRecordType {
INSIDE_ORDER_SUCCESS(100, "下订单成功"),
INSIDE_COUPON_VERIFY(101, "券核销"),
INSIDE_C_LOGIN(102, "C端用户登录"),
INSIDE_NOTIFY_PAY_SUCCESS(103, "微信支付回调"),
//INSIDE_NOTIFY_PAY_SUCCESS(103, "微信支付回调"),
INSIDE_NOTIFY_REFUND_SUCCESS(104, "微信退款回调"),
COUPON_STOCK(105, "券库存更新"),
;


+ 3
- 3
mallinkService/src/main/java/com/iformall/service/WxPayOrderService.java View File

@@ -14,9 +14,9 @@ import com.iformall.domain.po.WxPayAccount;
import com.iformall.domain.po.WxPayOrder;
import com.iformall.enums.EnumPayShare;
import com.iformall.enums.EnumPayWay;
import com.iformall.service.pay.entity.PayAdapterResult;
import com.iformall.service.pay.entity.PayExtraParam;
import com.iformall.service.pay.entity.PayQueryAdapterResult;
import com.iformall.service.pay.service.pay.entity.PayAdapterResult;
import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult;

public interface WxPayOrderService {

@@ -68,7 +68,7 @@ public interface WxPayOrderService {
* @param payWay 支付方式
* @return
*/
String notify(Map<String, String> paramMap, EnumPayWay payWay);
String shareNotify(Map<String, String> paramMap, EnumPayWay payWay);

/**
* 支付成功处理


+ 15
- 110
mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java View File

@@ -19,13 +19,14 @@ import com.iformall.pay.*;
import com.iformall.service.*;
import com.iformall.service.helper.WxPayOrderServiceHelper;
import com.iformall.service.pay.PayServiceFactory;
import com.iformall.service.pay.entity.CreateCUser;
import com.iformall.service.pay.entity.PayAdapterResult;
import com.iformall.service.pay.entity.PayExtraParam;
import com.iformall.service.pay.entity.PayQueryAdapterResult;
import com.iformall.service.pay.service.pay.CDrivingPayService;
import com.iformall.service.pay.service.pay.CPassivePayService;
import com.iformall.service.pay.service.pay.PayAdapterService;
import com.iformall.service.pay.service.pay.entity.CreateCUser;
import com.iformall.service.pay.service.pay.entity.PayAdapterResult;
import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult;
import com.iformall.service.pay.service.share.entity.ShareNotifyAdapterResult;
import com.iformall.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@@ -877,119 +878,23 @@ public class WxPayOrderServiceImpl implements WxPayOrderService {


/**
* 提供微信支付回调调用
* 提供微信支付回调调用 --- 分账通知
*
* @param paramMap 异步通知参数
* @param payWay 支付方式
* @return
*/
@Override
public String notify(Map<String, String> paramMap, EnumPayWay payWay) {
// how to get wechatAppId, wechatMchId, partnerKey
String appId = paramMap.get("appid");
String subAppId = paramMap.get("sub_appid");
String mchId = paramMap.get("mch_id");
String subMchId = paramMap.get("sub_mch_id");
WxAppinfo appinfo = null;
boolean isNormal = true;
if (StringUtils.isBlank(subAppId) && StringUtils.isBlank(subMchId)) {
// 普通商户号
appinfo = wxAppinfoMapper.findByAppId(appId);
if (appinfo == null) {
logger.error("appid not found: " + appId);
throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND);
}
isNormal = true;
} else {
// 服务号 现在用hmac-sha256
appinfo = wxAppinfoMapper.findByAppId(subAppId);
if (appinfo == null) {
logger.error("subappid not found: " + subAppId);
throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND);
}
isNormal = false;
}

WxPayAccount payAccount = wxPayAccountMapper.selectById(appinfo.getPayId());
if (payAccount == null) {
throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND);
}
String partnerKey = payAccount.getApiKey();
try {
if (payWay == EnumPayWay.PAY_WAY_WECHAT) {
boolean signVerified = false;
if (isNormal) {
// 普通商户号支付
signVerified = WxPayment.verifyNotify(paramMap, partnerKey);
if (!signVerified) {
logger.warn("notify order, wxpay checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
throw new MallinkException(ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR);
}
} else {
// 服务号 现在用hmac-sha256
signVerified = WxPayment.verifyNotifyHMAC(paramMap, partnerKey);
if (!signVerified) {
logger.warn("notify order, wxpay checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
throw new MallinkException(ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR);
}
}

if (!"SUCCESS".equals(paramMap.get("return_code"))) {
logger.warn("notify order, wxpay status not success, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
SortedMap resultMap = new TreeMap();
resultMap.put("return_code", "FAIL");
resultMap.put("return_msg", "订单状态码非SUCCESS");
return XmlUtil.getRequestXml(resultMap);
}

String payOrderNo = paramMap.get("out_trade_no");
String timEndStr = paramMap.get("time_end");
Long payOrderId = Long.valueOf(payOrderNo);
WxPayOrder payOrder = wxPayOrderMapper.selectById(payOrderId);
if (payOrder == null) {
logger.warn("notify order, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
SortedMap resultMap = new TreeMap();
resultMap.put("return_code", "FAIL");
resultMap.put("return_msg", "订单不存在");
return XmlUtil.getRequestXml(resultMap);
}
// 验证支付金额
if (!paramMap.get("total_fee").equals(payOrder.getPayAmount().toString())) {
logger.warn("notify order, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
SortedMap resultMap = new TreeMap();
resultMap.put("return_code", "FAIL");
resultMap.put("return_msg", "订单总金额不一致");
return XmlUtil.getRequestXml(resultMap);
}

Date timeEnd = null;

try {
timeEnd = Utility.getDateFromString(timEndStr);
} catch (ParseException e) {
logger.error("解析timeEnd失败");
timeEnd = new Date();
}
payOrder.setPayTimeEnd(timeEnd);
payOrder.setPayEndFrom(EnumPayEndFrom.CALLBACK.getCode());

// 处理支付成功
handleOrderPaySuccess(payOrder, paramMap.get("transaction_id"));
logger.info("notify order, wxpay checksign success, paramMap:{}, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
SortedMap resultMap = new TreeMap();
resultMap.put("return_code", "SUCCESS");
resultMap.put("return_msg", "OK");
return XmlUtil.getRequestXml(resultMap);
}
} catch (RuntimeException e) {
logger.warn("notify order, checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage());
throw new MallinkException(ErrorCode.PAY_ORDER_ERROR);
}

SortedMap resultMap = new TreeMap();
resultMap.put("return_code", "FAIL");
resultMap.put("return_msg", "FAILED");
return XmlUtil.getRequestXml(resultMap);
public String shareNotify(Map<String, String> paramMap, EnumPayWay payWay) {
ShareNotifyAdapterResult shareResult = payServiceFactory.getPayShareAdapterService(payWay.getCode()).notify(paramMap,payWay);
if (shareResult.isSuccess()) {
// 处理支付成功
shareResult.getPayOrder().setPayEndFrom(EnumPayEndFrom.CALLBACK.getCode());
handleOrderPaySuccess(shareResult.getPayOrder(), shareResult.getTranscationId());
return shareResult.getReturnJson();
}else {
return shareResult.getReturnJson();
}
}

@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class})


+ 1
- 1
mallinkService/src/main/java/com/iformall/service/impl/WxProfitSharingOrderServiceImpl.java View File

@@ -21,7 +21,7 @@ import com.iformall.mapper.*;
import com.iformall.pay.*;
import com.iformall.service.WxProfitSharingOrderService;
import com.iformall.service.pay.PayServiceFactory;
import com.iformall.service.pay.entity.PayShareResult;
import com.iformall.service.pay.service.share.entity.PayShareResult;
import com.iformall.utils.BeanUtils;
import com.iformall.utils.DateUtils;
import com.iformall.utils.Utility;


+ 62
- 961
mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java
File diff suppressed because it is too large
View File


+ 14
- 14
mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideNotifyPaySuccessMsgServiceImpl.java View File

@@ -18,17 +18,17 @@ import java.util.Map;
* @author Stormeye Wu
* @date 2019/5/10
*/
@Service
public class FmInsideNotifyPaySuccessMsgServiceImpl implements MsgSendService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private WxPayOrderService wxPayOrderService;
@Override
public void send(BaseMsg baseMsg) throws Exception {
FmInsideNotifyPaySuccessMsg msg = (FmInsideNotifyPaySuccessMsg)baseMsg;
Map<String, String> paramMap = JSON.parseObject(msg.getJsonMsg(), Map.class);
wxPayOrderService.notify(paramMap, EnumPayWay.getEnum(msg.getPayWay()));
}
}
//@Service
//public class FmInsideNotifyPaySuccessMsgServiceImpl implements MsgSendService {
// private final Logger logger = LoggerFactory.getLogger(this.getClass());
//
// @Autowired
// private WxPayOrderService wxPayOrderService;
//
// @Override
// public void send(BaseMsg baseMsg) throws Exception {
// FmInsideNotifyPaySuccessMsg msg = (FmInsideNotifyPaySuccessMsg)baseMsg;
// Map<String, String> paramMap = JSON.parseObject(msg.getJsonMsg(), Map.class);
// wxPayOrderService.notify(paramMap, EnumPayWay.getEnum(msg.getPayWay()));
// }
//}

+ 58
- 28
mallinkService/src/main/java/com/iformall/service/pay/PayServiceFactory.java View File

@@ -14,8 +14,11 @@ import com.iformall.service.WxPayOrderService;
import com.iformall.service.pay.service.pay.CDrivingPayService;
import com.iformall.service.pay.service.pay.CPassivePayService;
import com.iformall.service.pay.service.pay.PayAdapterService;
import com.iformall.service.pay.service.pay.miniApp.wx.appPay.WxMiniAppPayAdapterService;
import com.iformall.service.pay.service.pay.miniApp.wx.maPay.WxMiniMaPayAdapterService;
import com.iformall.service.pay.service.pay.wx.h5.WxH5PayService;
import com.iformall.service.pay.service.pay.wx.miniApp.appPay.WxMiniAppPayAdapterService;
import com.iformall.service.pay.service.pay.wx.miniApp.maPay.WxMiniMaPayAdapterService;
import com.iformall.service.pay.service.refund.RefundPayAdapterService;
import com.iformall.service.pay.service.refund.wx.WxRefundAdapterService;
import com.iformall.service.pay.service.share.PayShareAdapterService;
import com.iformall.service.pay.service.share.neupos.NeuPosPayShareService;
import com.iformall.service.pay.service.share.wx.WxPayShareService;
@@ -29,22 +32,60 @@ public class PayServiceFactory {

private Map<Integer,PayAdapterService> serviceMap = null;
private Map<Integer,PayShareAdapterService> shareMap = null;
private Map<Integer,RefundPayAdapterService> refundMap = null;
@Autowired
WxMiniAppPayAdapterService wxMiniAppPayService;
@Autowired
WxMiniMaPayAdapterService wxMiniAppMaPayService;
@Autowired
WxPayOrderService wxPayOrderService;
WxH5PayService wxH5PayService;
@Autowired
WxPayShareService wxShareService;
@Autowired
NeuPosPayShareService neuPosPayShareService;
@Autowired
WxRefundAdapterService wxRefundService;

private Map<Integer,PayAdapterService> getServiceMap() {
if (null == serviceMap) {
serviceMap = new ConcurrentHashMap<Integer,PayAdapterService>();
serviceMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode(), wxMiniAppPayService);
serviceMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode(), wxMiniAppMaPayService);
serviceMap.put(EnumPayWay.PAY_WAY_WECHAT_WAP.getCode(), wxH5PayService);
}
return serviceMap;
}
private Map<Integer,PayShareAdapterService> getShareMap(){
if (null == shareMap ) {
shareMap = new ConcurrentHashMap<Integer, PayShareAdapterService>();
shareMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode(), wxShareService);
shareMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode(), wxShareService);
shareMap.put(EnumPayWay.PAY_WAY_POS_NEU.getCode(), neuPosPayShareService);
}
return shareMap;
}
private Map<Integer,RefundPayAdapterService> getRefundMap(){
if (null == refundMap ) {
refundMap = new ConcurrentHashMap<Integer, RefundPayAdapterService>();
refundMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode(), wxRefundService);
refundMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode(), wxRefundService);
}
return refundMap;
}
public PayAdapterService getPayAdapterService(Integer type) throws MallinkException{
PayAdapterService service = getServiceMap().get(type);
if (null == service) {
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payType["+type+"] 支付service未找到");
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 支付service未找到");
}
return service;
}
@@ -52,51 +93,40 @@ public class PayServiceFactory {
public CDrivingPayService getCDrivingPayService(Integer type) throws MallinkException{
PayAdapterService service = getServiceMap().get(type);
if (null == service) {
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payType["+type+"] 支付service未找到");
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 支付service未找到");
}
if (service instanceof CDrivingPayService) {
return (CDrivingPayService) service;
}else {
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payType["+type+"] 支付service不是CDrivingPayService");
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 支付service不是CDrivingPayService");
}
}
public CPassivePayService getCPassivePayService(Integer type) throws MallinkException{
PayAdapterService service = getServiceMap().get(type);
if (null == service) {
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payType["+type+"] 支付service未找到");
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 支付service未找到");
}
if (service instanceof CPassivePayService) {
return (CPassivePayService) service;
}else {
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payType["+type+"] 支付service不是CPassivePayService");
}
}
private Map<Integer,PayAdapterService> getServiceMap() {
if (null != serviceMap) {
serviceMap = new ConcurrentHashMap<Integer,PayAdapterService>();
serviceMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode(), wxMiniAppPayService);
serviceMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode(), wxMiniAppMaPayService);
}
return serviceMap;
}
private Map<Integer,PayShareAdapterService> getShareMap(){
if (null != shareMap ) {
shareMap = new ConcurrentHashMap<Integer, PayShareAdapterService>();
shareMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode(), wxShareService);
shareMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode(), wxShareService);
shareMap.put(EnumPayWay.PAY_WAY_POS_NEU.getCode(), neuPosPayShareService);
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 支付service不是CPassivePayService");
}
return shareMap;
}
public PayShareAdapterService getPayShareAdapterService(Integer type) throws MallinkException{
PayShareAdapterService shareService = getShareMap().get(type);
if (null == shareService) {
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payType["+type+"] 分账service未找到");
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 分账service未找到");
}
return shareService;
}
public RefundPayAdapterService getRefundPayAdapterService(Integer type) throws MallinkException{
RefundPayAdapterService refundService = getRefundMap().get(type);
if (null == refundService) {
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 退款service未找到");
}
return refundService;
}
}

+ 2
- 2
mallinkService/src/main/java/com/iformall/service/pay/service/pay/CPassivePayService.java View File

@@ -7,9 +7,9 @@ import com.iformall.domain.po.WxOrder;
import com.iformall.domain.po.WxPayAccount;
import com.iformall.domain.po.WxPayOrder;
import com.iformall.enums.EnumPayShare;
import com.iformall.service.pay.entity.CreateCUser;
import com.iformall.service.pay.entity.PayAdapterResult;
import com.iformall.service.pay.entity.PayExtraParam;
import com.iformall.service.pay.service.pay.entity.CreateCUser;
import com.iformall.service.pay.service.pay.entity.PayAdapterResult;

/**
* C端被动发起的支付


+ 2
- 2
mallinkService/src/main/java/com/iformall/service/pay/service/pay/PayAdapterService.java View File

@@ -6,9 +6,9 @@ import com.iformall.domain.po.WxOrder;
import com.iformall.domain.po.WxPayAccount;
import com.iformall.domain.po.WxPayOrder;
import com.iformall.enums.EnumPayShare;
import com.iformall.service.pay.entity.PayAdapterResult;
import com.iformall.service.pay.entity.PayExtraParam;
import com.iformall.service.pay.entity.PayQueryAdapterResult;
import com.iformall.service.pay.service.pay.entity.PayAdapterResult;
import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult;

public interface PayAdapterService {



mallinkService/src/main/java/com/iformall/service/pay/entity/CreateCUser.java → mallinkService/src/main/java/com/iformall/service/pay/service/pay/entity/CreateCUser.java View File

@@ -1,4 +1,4 @@
package com.iformall.service.pay.entity;
package com.iformall.service.pay.service.pay.entity;

import java.io.Serializable;


mallinkService/src/main/java/com/iformall/service/pay/entity/PayAdapterResult.java → mallinkService/src/main/java/com/iformall/service/pay/service/pay/entity/PayAdapterResult.java View File

@@ -1,4 +1,4 @@
package com.iformall.service.pay.entity;
package com.iformall.service.pay.service.pay.entity;

import java.io.Serializable;


mallinkService/src/main/java/com/iformall/service/pay/entity/PayQueryAdapterResult.java → mallinkService/src/main/java/com/iformall/service/pay/service/pay/entity/PayQueryAdapterResult.java View File

@@ -1,4 +1,4 @@
package com.iformall.service.pay.entity;
package com.iformall.service.pay.service.pay.entity;

import java.io.Serializable;


mallinkService/src/main/java/com/iformall/service/pay/service/pay/miniApp/wx/BaseWxPayAdapterService.java → mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/BaseWxPayAdapterService.java View File

@@ -1,4 +1,4 @@
package com.iformall.service.pay.service.pay.miniApp.wx;
package com.iformall.service.pay.service.pay.wx;

import java.util.Map;

@@ -7,8 +7,8 @@ import com.iformall.domain.po.WxOrder;
import com.iformall.domain.po.WxPayAccount;
import com.iformall.domain.po.WxPayOrder;
import com.iformall.service.helper.WxPayOrderServiceHelper;
import com.iformall.service.pay.entity.PayQueryAdapterResult;
import com.iformall.service.pay.service.pay.PayAdapterService;
import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult;

public class BaseWxPayAdapterService {


+ 45
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/h5/WxH5PayService.java View File

@@ -0,0 +1,45 @@
package com.iformall.service.pay.service.pay.wx.h5;

import java.util.Date;

import org.springframework.stereotype.Service;

import com.iformall.domain.po.WxAppinfo;
import com.iformall.domain.po.WxOrder;
import com.iformall.domain.po.WxPayAccount;
import com.iformall.domain.po.WxPayOrder;
import com.iformall.enums.EnumPayShare;
import com.iformall.service.pay.entity.PayExtraParam;
import com.iformall.service.pay.service.pay.CDrivingPayService;
import com.iformall.service.pay.service.pay.entity.PayAdapterResult;
import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult;
import com.iformall.service.pay.service.pay.wx.BaseWxPayAdapterService;

@Service
public class WxH5PayService extends BaseWxPayAdapterService implements CDrivingPayService{

@Override
public PayAdapterResult pay(WxPayAccount payAccount, WxOrder order, WxPayOrder record, EnumPayShare isShare,
WxAppinfo appInfo, Date currentDate, PayExtraParam params) throws Exception {
// TODO Auto-generated method stub
return null;
}

@Override
public PayQueryAdapterResult queryPayStatus(WxPayOrder oldRecord, WxOrder order, WxAppinfo appInfo,
WxPayAccount payAccount) throws Exception {
return super.queryPayStatus(oldRecord, order, appInfo, payAccount);
}

@Override
public int queryPayStatus(PayQueryAdapterResult statusObject, String orderOutNo) throws Exception {
return super.queryPayStatus(statusObject, orderOutNo);
}

@Override
public int queryPayStatusCode(WxPayOrder oldRecord, WxOrder order, WxAppinfo appInfo, WxPayAccount payAccount)
throws Exception {
return super.queryPayStatusCode(oldRecord, order, appInfo, payAccount);
}
}

mallinkService/src/main/java/com/iformall/service/pay/service/pay/miniApp/wx/appPay/WxMiniAppPayAdapterService.java → mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/miniApp/appPay/WxMiniAppPayAdapterService.java View File

@@ -1,4 +1,4 @@
package com.iformall.service.pay.service.pay.miniApp.wx.appPay;
package com.iformall.service.pay.service.pay.wx.miniApp.appPay;

import java.util.Date;
import java.util.Map;
@@ -22,11 +22,11 @@ import com.iformall.pay.WxPay;
import com.iformall.pay.WxPayOrderP;
import com.iformall.pay.WxPayOrderSP;
import com.iformall.pay.WxPayment;
import com.iformall.service.pay.entity.PayAdapterResult;
import com.iformall.service.pay.entity.PayExtraParam;
import com.iformall.service.pay.entity.PayQueryAdapterResult;
import com.iformall.service.pay.service.pay.CDrivingPayService;
import com.iformall.service.pay.service.pay.miniApp.wx.BaseWxPayAdapterService;
import com.iformall.service.pay.service.pay.entity.PayAdapterResult;
import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult;
import com.iformall.service.pay.service.pay.wx.BaseWxPayAdapterService;
import com.iformall.utils.BeanUtils;
import com.iformall.utils.MapUtil;
import com.iformall.utils.Utility;

mallinkService/src/main/java/com/iformall/service/pay/service/pay/miniApp/wx/maPay/WxMiniMaPayAdapterService.java → mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/miniApp/maPay/WxMiniMaPayAdapterService.java View File

@@ -1,4 +1,4 @@
package com.iformall.service.pay.service.pay.miniApp.wx.maPay;
package com.iformall.service.pay.service.pay.wx.miniApp.maPay;

import java.util.Date;
import java.util.Map;
@@ -22,12 +22,12 @@ import com.iformall.pay.WxMicroPayOrderSP;
import com.iformall.pay.WxPay;
import com.iformall.pay.WxPayment;
import com.iformall.service.WxCUserService;
import com.iformall.service.pay.entity.CreateCUser;
import com.iformall.service.pay.entity.PayAdapterResult;
import com.iformall.service.pay.entity.PayExtraParam;
import com.iformall.service.pay.entity.PayQueryAdapterResult;
import com.iformall.service.pay.service.pay.CPassivePayService;
import com.iformall.service.pay.service.pay.miniApp.wx.BaseWxPayAdapterService;
import com.iformall.service.pay.service.pay.entity.CreateCUser;
import com.iformall.service.pay.service.pay.entity.PayAdapterResult;
import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult;
import com.iformall.service.pay.service.pay.wx.BaseWxPayAdapterService;
import com.iformall.utils.BeanUtils;
import com.iformall.utils.Utility;
import lombok.extern.slf4j.Slf4j;

+ 42
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/refund/RefundPayAdapterService.java View File

@@ -0,0 +1,42 @@
package com.iformall.service.pay.service.refund;

import java.util.Map;

import com.iformall.domain.po.WxAppinfo;
import com.iformall.domain.po.WxPayAccount;
import com.iformall.domain.po.WxPayOrder;
import com.iformall.domain.po.WxRefundOrder;
import com.iformall.enums.EnumPayType;
import com.iformall.enums.EnumPayWay;
import com.iformall.service.pay.service.refund.entity.RefundAdapterResult;
import com.iformall.service.pay.service.refund.entity.RefundNotifyAdapterResult;

public interface RefundPayAdapterService {

/**
* API退款
* @param payAccount
* @param appInfo
* @param record
* @param payOrder
* @param payType
* @return
*/
public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType);
/**
* API查询退款
* @param appInfo
* @param payAccount
* @param record
* @return
*/
public RefundAdapterResult queryRefund(WxAppinfo appInfo,WxPayAccount payAccount, WxRefundOrder record);
/**
* 平台方 异步通知
* @param paramMap
* @param payWay
*/
public RefundNotifyAdapterResult notify(Map<String, String> paramMap, EnumPayWay payWay);
}

+ 50
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/refund/entity/RefundAdapterResult.java View File

@@ -0,0 +1,50 @@
package com.iformall.service.pay.service.refund.entity;

import java.io.Serializable;

public class RefundAdapterResult implements Serializable{
private static final long serialVersionUID = -6647306162758854293L;
private boolean isSuccess;
private Integer code;
private String msg;
private Object data;
public RefundAdapterResult() {
}
public RefundAdapterResult(boolean isSuccess,Integer code,String msg,Object data) {
this.isSuccess = isSuccess;
this.msg = msg;
this.data = data;
}
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}

public Integer getCode() {
return code;
}

public void setCode(Integer code) {
this.code = code;
}

}

+ 87
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/refund/entity/RefundNotifyAdapterResult.java View File

@@ -0,0 +1,87 @@
package com.iformall.service.pay.service.refund.entity;

import java.io.Serializable;

import com.iformall.domain.po.WxRefundOrder;

public class RefundNotifyAdapterResult implements Serializable{
private static final long serialVersionUID = -6647306162758854293L;
private boolean isSuccess;
private Integer code;
private String msg;
private String returnJson;
private String transcationId;
private String refundId;
private WxRefundOrder refundOrder;
public RefundNotifyAdapterResult() {
}
public RefundNotifyAdapterResult(boolean isSuccess,Integer code,String msg,String returnJson) {
this.isSuccess = isSuccess;
this.msg = msg;
this.returnJson = returnJson;
}
public RefundNotifyAdapterResult(String transcationId,String refundId,WxRefundOrder refundOrder,String returnJson) {
this.isSuccess = true;
this.transcationId = transcationId;
this.refundId = refundId;
this.refundOrder = refundOrder;
this.returnJson = returnJson;
}
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Integer getCode() {
return code;
}

public void setCode(Integer code) {
this.code = code;
}

public String getTranscationId() {
return transcationId;
}

public void setTranscationId(String transcationId) {
this.transcationId = transcationId;
}

public String getRefundId() {
return refundId;
}

public void setRefundId(String refundId) {
this.refundId = refundId;
}

public String getReturnJson() {
return returnJson;
}

public void setReturnJson(String returnJson) {
this.returnJson = returnJson;
}

public WxRefundOrder getRefundOrder() {
return refundOrder;
}

public void setRefundOrder(WxRefundOrder refundOrder) {
this.refundOrder = refundOrder;
}
}

+ 636
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/WxRefundAdapterService.java View File

@@ -0,0 +1,636 @@
package com.iformall.service.pay.service.refund.wx;

import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.iformall.common.ErrorCode;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.domain.po.WxAppinfo;
import com.iformall.domain.po.WxPayAccount;
import com.iformall.domain.po.WxPayOrder;
import com.iformall.domain.po.WxRefundOrder;
import com.iformall.enums.EnumPayMode;
import com.iformall.enums.EnumPayType;
import com.iformall.enums.EnumPayWay;
import com.iformall.enums.EnumRefundStatus;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.WxAppinfoMapper;
import com.iformall.mapper.WxPayAccountMapper;
import com.iformall.mapper.WxPayOrderMapper;
import com.iformall.mapper.WxRefundOrderMapper;
import com.iformall.pay.WxPay;
import com.iformall.pay.WxPayment;
import com.iformall.pay.WxRefundOrderP;
import com.iformall.pay.WxRefundOrderSP;
import com.iformall.service.pay.service.refund.RefundPayAdapterService;
import com.iformall.service.pay.service.refund.entity.RefundAdapterResult;
import com.iformall.service.pay.service.refund.entity.RefundNotifyAdapterResult;
import com.iformall.utils.BeanUtils;
import com.iformall.utils.CipherUtil;
import com.iformall.utils.Utility;
import com.iformall.utils.XmlUtil;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class WxRefundAdapterService implements RefundPayAdapterService{

JSONObject errorRefundReqMap = JSON.parseObject("{\n" +
" \"SYSTEMERROR\": {\n" +
" \"detail\": \"接口返回错误\",\n" +
" \"reason\": \"系统超时等\",\n" +
" \"resolution\": \"请不要更换商户退款单号,请使用相同参数再次调用API。\"\n" +
" },\n" +
" \"BIZERR_NEED_RETRY\": {\n" +
" \"detail\": \"退款业务流程错误,需要商户触发重试来解决\",\n" +
" \"reason\": \"并发情况下,业务被拒绝,商户重试即可解决\",\n" +
" \"resolution\": \"请不要更换商户退款单号,请使用相同参数再次调用API。\"\n" +
" },\n" +
" \"TRADE_OVERDUE\": {\n" +
" \"detail\": \"订单已经超过退款期限\",\n" +
" \"reason\": \"订单已经超过可退款的最大期限(支付后一年内可退款)\\t\",\n" +
" \"resolution\": \"请选择其他方式自行退款\"\n" +
" },\n" +
" \"ERROR\": {\n" +
" \"detail\": \"业务错误\",\n" +
" \"reason\": \"申请退款业务发生错误\",\n" +
" \"resolution\": \"该错误都会返回具体的错误原因,请根据实际返回做相应处理。\"\n" +
" },\n" +
" \"USER_ACCOUNT_ABNORMAL\": {\n" +
" \"detail\": \"退款请求失败\",\n" +
" \"reason\": \"用户帐号注销\",\n" +
" \"resolution\": \"此状态代表退款申请失败,商户可自行处理退款。\"\n" +
" },\n" +
" \"INVALID_REQ_TOO_MUCH\": {\n" +
" \"detail\": \"无效请求过多\",\n" +
" \"reason\": \"连续错误请求数过多被系统短暂屏蔽\\t\",\n" +
" \"resolution\": \"请检查业务是否正常,确认业务正常后请在1分钟后再来重试\"\n" +
" },\n" +
" \"NOTENOUGH\": {\n" +
" \"detail\": \"余额不足\",\n" +
" \"reason\": \"商户可用退款余额不足\",\n" +
" \"resolution\": \"此状态代表退款申请失败,商户可根据具体的错误提示做相应的处理。\"\n" +
" },\n" +
" \"INVALID_TRANSACTIONID\": {\n" +
" \"detail\": \"无效transaction_id\",\n" +
" \"reason\": \"请求参数未按指引进行填写\",\n" +
" \"resolution\": \"请求参数错误,检查原交易号是否存在或发起支付交易接口返回失败\"\n" +
" },\n" +
" \"PARAM_ERROR\": {\n" +
" \"detail\": \"参数错误\",\n" +
" \"reason\": \"请求参数未按指引进行填写\",\n" +
" \"resolution\": \"请求参数错误,请重新检查再调用退款申请\"\n" +
" },\n" +
" \"APPID_NOT_EXIST\": {\n" +
" \"detail\": \"APPID不存在\",\n" +
" \"reason\": \"参数中缺少APPID\",\n" +
" \"resolution\": \"请检查APPID是否正确\"\n" +
" },\n" +
" \"MCHID_NOT_EXIST\": {\n" +
" \"detail\": \"MCHID不存在\",\n" +
" \"reason\": \"参数中缺少MCHID\",\n" +
" \"resolution\": \"请检查MCHID是否正确\"\n" +
" },\n" +
" \"REQUIRE_POST_METHOD\": {\n" +
" \"detail\": \"请使用post方法\",\n" +
" \"reason\": \"未使用post传递参数\",\n" +
" \"resolution\": \"请检查请求参数是否通过post方法提交\"\n" +
" },\n" +
" \"SIGNERROR\": {\n" +
" \"detail\": \"签名错误\",\n" +
" \"reason\": \"参数签名结果不正确\",\n" +
" \"resolution\": \"请检查签名参数和方法是否都符合签名算法要求\"\n" +
" },\n" +
" \"XML_FORMAT_ERROR\": {\n" +
" \"detail\": \"XML格式错误\",\n" +
" \"reason\": \"XML格式错误\",\n" +
" \"resolution\": \"请检查XML参数格式是否正确\"\n" +
" },\n" +
" \"FREQUENCY_LIMITED\": {\n" +
" \"detail\": \"频率限制\",\n" +
" \"reason\": \"2个月之前的订单申请退款有频率限制\",\n" +
" \"resolution\": \"该笔退款未受理,请降低频率后重试\"\n" +
" }\n" +
"}");
JSONObject errorRefundQueryMap = JSON.parseObject("{\n" +
" \"SYSTEMERROR\": {\n" +
" \"detail\": \"接口返回错误\",\n" +
" \"reason\": \"系统超时等\",\n" +
" \"resolution\": \"请不要更换商户退款单号,请使用相同参数再次调用API。\"\n" +
" },\n" +
" \"BIZERR_NEED_RETRY\": {\n" +
" \"detail\": \"退款业务流程错误,需要商户触发重试来解决\",\n" +
" \"reason\": \"并发情况下,业务被拒绝,商户重试即可解决\",\n" +
" \"resolution\": \"请不要更换商户退款单号,请使用相同参数再次调用API。\"\n" +
" },\n" +
" \"TRADE_OVERDUE\": {\n" +
" \"detail\": \"订单已经超过退款期限\",\n" +
" \"reason\": \"订单已经超过可退款的最大期限(支付后一年内可退款)\\t\",\n" +
" \"resolution\": \"请选择其他方式自行退款\"\n" +
" },\n" +
" \"ERROR\": {\n" +
" \"detail\": \"业务错误\",\n" +
" \"reason\": \"申请退款业务发生错误\",\n" +
" \"resolution\": \"该错误都会返回具体的错误原因,请根据实际返回做相应处理。\"\n" +
" },\n" +
" \"USER_ACCOUNT_ABNORMAL\": {\n" +
" \"detail\": \"退款请求失败\",\n" +
" \"reason\": \"用户帐号注销\",\n" +
" \"resolution\": \"此状态代表退款申请失败,商户可自行处理退款。\"\n" +
" },\n" +
" \"INVALID_REQ_TOO_MUCH\": {\n" +
" \"detail\": \"无效请求过多\",\n" +
" \"reason\": \"连续错误请求数过多被系统短暂屏蔽\\t\",\n" +
" \"resolution\": \"请检查业务是否正常,确认业务正常后请在1分钟后再来重试\"\n" +
" },\n" +
" \"NOTENOUGH\": {\n" +
" \"detail\": \"余额不足\",\n" +
" \"reason\": \"商户可用退款余额不足\",\n" +
" \"resolution\": \"此状态代表退款申请失败,商户可根据具体的错误提示做相应的处理。\"\n" +
" },\n" +
" \"INVALID_TRANSACTIONID\": {\n" +
" \"detail\": \"无效transaction_id\",\n" +
" \"reason\": \"请求参数未按指引进行填写\",\n" +
" \"resolution\": \"请求参数错误,检查原交易号是否存在或发起支付交易接口返回失败\"\n" +
" },\n" +
" \"PARAM_ERROR\": {\n" +
" \"detail\": \"参数错误\",\n" +
" \"reason\": \"请求参数未按指引进行填写\",\n" +
" \"resolution\": \"请求参数错误,请重新检查再调用退款申请\"\n" +
" },\n" +
" \"APPID_NOT_EXIST\": {\n" +
" \"detail\": \"APPID不存在\",\n" +
" \"reason\": \"参数中缺少APPID\",\n" +
" \"resolution\": \"请检查APPID是否正确\"\n" +
" },\n" +
" \"MCHID_NOT_EXIST\": {\n" +
" \"detail\": \"MCHID不存在\",\n" +
" \"reason\": \"参数中缺少MCHID\",\n" +
" \"resolution\": \"请检查MCHID是否正确\"\n" +
" },\n" +
" \"REQUIRE_POST_METHOD\": {\n" +
" \"detail\": \"请使用post方法\",\n" +
" \"reason\": \"未使用post传递参数\",\n" +
" \"resolution\": \"请检查请求参数是否通过post方法提交\"\n" +
" },\n" +
" \"SIGNERROR\": {\n" +
" \"detail\": \"签名错误\",\n" +
" \"reason\": \"参数签名结果不正确\",\n" +
" \"resolution\": \"请检查签名参数和方法是否都符合签名算法要求\"\n" +
" },\n" +
" \"XML_FORMAT_ERROR\": {\n" +
" \"detail\": \"XML格式错误\",\n" +
" \"reason\": \"XML格式错误\",\n" +
" \"resolution\": \"请检查XML参数格式是否正确\"\n" +
" },\n" +
" \"FREQUENCY_LIMITED\": {\n" +
" \"detail\": \"频率限制\",\n" +
" \"reason\": \"2个月之前的订单申请退款有频率限制\",\n" +
" \"resolution\": \"该笔退款未受理,请降低频率后重试\"\n" +
" }\n" +
"}");
private WxRefundOrderP generateWxRefundOrderP(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType) {
String noncestr = Utility.generate32UUID();
WxRefundOrderP wxRefundOrderP = new WxRefundOrderP();
wxRefundOrderP.setAppid(appInfo.getAppId());
wxRefundOrderP.setMch_id(payAccount.getMchId());
wxRefundOrderP.setNonce_str(noncestr);
// 微信内部订单号
if (record.getTransactionId() != null)
wxRefundOrderP.setTransaction_id(record.getTransactionId());
// 支付订单号
wxRefundOrderP.setOut_trade_no(payOrder.getPayOrderNo());
// 退款支付订单号
wxRefundOrderP.setOut_refund_no(String.valueOf(record.getId()));
wxRefundOrderP.setTotal_fee(record.getTotalFee());
wxRefundOrderP.setRefund_fee(record.getRefundFee());
if(null != payType) {
if (payType == EnumPayType.PAY_B_REFUND) {
wxRefundOrderP.setRefund_desc("B端商户退款");
} else if (payType == EnumPayType.PAY_ADMIN_REFUND) {
wxRefundOrderP.setRefund_desc("管理端商户退款");
} else if (payType == EnumPayType.PAY_AUTO_REFUND) {
wxRefundOrderP.setRefund_desc("超期自动退款");
} else {
wxRefundOrderP.setRefund_desc("用户自己退款");
}
}
wxRefundOrderP.setNotify_url(payAccount.getRefundNotifyUrl());
return wxRefundOrderP;
}
private RefundAdapterResult getReusltFromp(String response,WxRefundOrder record,WxPayOrder payOrder) throws MallinkException{
Map<String, String> returnMap = WxPayment.xmlToMap(response);
String result_no = returnMap.get("result_code");
String refund_id = returnMap.get("refund_id");
// 设置 微信退款订单号
record.setRefundId(refund_id);
record.setRefundVendor(payOrder.getPayVendor());
if ("SUCCESS".equals(result_no)) {
log.info("微信退款订单申请成功: " + returnMap.toString());
try {
return new RefundAdapterResult(true,EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(),"退款订单申请成功",returnMap);
} catch (Exception e) {
log.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR);
}
} else {
String errDesc = returnMap.get("err_code_des");
if (errDesc.equalsIgnoreCase("订单已全额退款")) {
return new RefundAdapterResult(true,EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(),"退款订单申请成功",returnMap);
}
log.error("微信退款订单申请失败: " + response);
String errMsg = "";
JSONObject errObj = errorRefundReqMap.getJSONObject(result_no);
if (errObj != null) {
errMsg = errObj.toJSONString();
record.setFailReason(errMsg);
} else {
errMsg = returnMap.get("return_msg");
record.setFailReason(errMsg);
}
if (errDesc.equalsIgnoreCase("超期订单不允许退款")) {
// 更新券状态
throw new MallinkException(ErrorCode.REFUND_NOT_ALLOW);
}
return new RefundAdapterResult(false, EnumRefundStatus.REFUND_REQ_FAIL.getCode(), errMsg, returnMap);
}
}
private WxRefundOrderSP generateWxRefundOrderSP(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType) {
String noncestr = Utility.generate32UUID();
WxRefundOrderSP wxRefundOrderSP = new WxRefundOrderSP();
wxRefundOrderSP.setAppid(appInfo.getParentAppId());
wxRefundOrderSP.setSub_appid(appInfo.getAppId());
wxRefundOrderSP.setMch_id(payAccount.getMchId());
wxRefundOrderSP.setSub_mch_id(payAccount.getSubMchId());
wxRefundOrderSP.setNonce_str(noncestr);
// 微信内部订单号
if (record.getTransactionId() != null)
wxRefundOrderSP.setTransaction_id(record.getTransactionId());
// 支付订单号
wxRefundOrderSP.setOut_trade_no(payOrder.getPayOrderNo());
// 退款支付订单号
wxRefundOrderSP.setOut_refund_no(String.valueOf(record.getId()));
wxRefundOrderSP.setTotal_fee(record.getTotalFee());
wxRefundOrderSP.setRefund_fee(record.getRefundFee());
if(null != payType) {
if (payType == EnumPayType.PAY_B_REFUND) {
wxRefundOrderSP.setRefund_desc("B端商户退款");
} else if (payType == EnumPayType.PAY_ADMIN_REFUND) {
wxRefundOrderSP.setRefund_desc("管理端商户退款");
} else if (payType == EnumPayType.PAY_AUTO_REFUND) {
wxRefundOrderSP.setRefund_desc("超期自动退款");
} else {
wxRefundOrderSP.setRefund_desc("用户自己退款");
}
}
wxRefundOrderSP.setNotify_url(payAccount.getRefundNotifyUrl());
wxRefundOrderSP.setSign_type("HMAC-SHA256");
return wxRefundOrderSP;
}
private RefundAdapterResult getResultFromSp(String response,WxRefundOrder record,WxPayOrder payOrder) {
Map<String, String> returnMap = WxPayment.xmlToMap(response);
String result_no = returnMap.get("result_code");
String refund_id = returnMap.get("refund_id");
// 设置 微信退款订单号
record.setRefundId(refund_id);
record.setRefundVendor(payOrder.getPayVendor());
if ("SUCCESS".equals(result_no)) {
log.info("微信退款订单申请成功: " + returnMap.toString());
try {
return new RefundAdapterResult(true, EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(), "退款订单申请成功", returnMap);
} catch (Exception e) {
log.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "订单状态更新失败");
}
} else {
// 特殊处理
String errDesc = returnMap.get("err_code_des");
if (errDesc.equalsIgnoreCase("订单已全额退款")) {
return new RefundAdapterResult(true, EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(), "退款订单申请成功", returnMap);
}
log.error("微信退款订单申请失败: " + response);
String errMsg = "";
JSONObject errObj = errorRefundReqMap.getJSONObject(result_no);
if (errObj != null) {
errMsg = errObj.toJSONString();
record.setFailReason(errMsg);
} else {
errMsg = returnMap.get("err_code_des");
record.setFailReason(errMsg);
}
if (errDesc.equalsIgnoreCase("超期订单不允许退款")) {
// 更新券状态
throw new MallinkException(ErrorCode.REFUND_NOT_ALLOW);
}
return new RefundAdapterResult(false,EnumRefundStatus.REFUND_REQ_FAIL.getCode(),errMsg,returnMap);
}
}
@Override
public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType) {
if (StringUtils.isBlank(payAccount.getApiKey())) {
log.error("支付密钥为空");
throw new MallinkException(ErrorCode.API_KEY_NOT_FOUND.getCode(), "支付密钥为空,请联系商城管理员");
}
if (StringUtils.isBlank(payAccount.getCertPath())) {
log.error("证书路径为空");
throw new MallinkException(ErrorCode.CERT_PATH_NOT_FOUND.getCode(), "证书路径为空,请联系商城管理员");
}
if (!Utility.isFileExist(payAccount.getCertPath())) {
log.error("证书文件不存在");
throw new MallinkException(ErrorCode.CERT_PATH_NOT_FOUND.getCode(), "证书文件不存在,请联系商城管理员");
}

// 实际支付
// 向微信提交退款申请
if (payAccount.getType() == EnumPayMode.MCH.getCode()) {
// 普通商户模式
WxRefundOrderP wxRefundOrderP = generateWxRefundOrderP(payAccount, appInfo, record, payOrder, payType);

Map signMap = null;
try {
signMap = BeanUtils.toStringMap(wxRefundOrderP);
} catch (Exception e) {
log.error("退款命令生辰: " + e.getMessage());
throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "退款签名异常");
}

String signAgent = WxPayment.createSign(signMap, payAccount.getApiKey());
signMap.put("sign", signAgent);
String response = null;
try {
response = WxPay.orderRefund(signMap, payAccount.getCertPath(), payAccount.getMchId());
} catch (Exception e) {
log.error("退款异常: " + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常");
}
log.info("微信退款订单:" + wxRefundOrderP.toString() + ", response: " + response.toString());
return getReusltFromp(response, record, payOrder);
} else {
// 服务商模式
WxRefundOrderSP wxRefundOrderSP = generateWxRefundOrderSP(payAccount, appInfo, record, payOrder, payType);

Map signMap = null;
try {
signMap = BeanUtils.toStringMap(wxRefundOrderSP);
} catch (Exception e) {
log.error("退款命令生成: " + e.getMessage());
throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "退款签名异常");
}

String signAgent = WxPayment.createSignHMAC(signMap, payAccount.getApiKey());
signMap.put("sign", signAgent);
String response = null;
try {
response = WxPay.orderRefund(signMap, payAccount.getCertPath(), payAccount.getMchId());
} catch (Exception e) {
log.error("退款异常: " + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常");
}
log.info("微信退款订单:" + wxRefundOrderSP.toString() + ", response: " + response.toString());
return getResultFromSp(response, record, payOrder);
}
}

@Override
public RefundAdapterResult queryRefund(WxAppinfo appInfo,WxPayAccount payAccount, WxRefundOrder record) {
if (payAccount.getType() == EnumPayMode.MCH.getCode()) {
Map<String, String> paramMap = WxPayment.buildWeappRefundQueryMap(
appInfo.getAppId(), payAccount.getMchId(),
record.getTransactionId(), record.getPayOrderNo(), String.valueOf(record.getId()),
record.getRefundId(), payAccount.getApiKey());
String response = WxPay.orderRefundQuery(paramMap);
Map<String, String> returnMap = WxPayment.xmlToMap(response);
String result_no = returnMap.get("result_code");
if ("SUCCESS".equals(result_no)) {
String refund_id = returnMap.get("refund_id");
return new RefundAdapterResult(true,0,"退款",returnMap);
} else {
String errMsg = "";
JSONObject errObj = errorRefundReqMap.getJSONObject(result_no);
if (errObj != null) {
errMsg = errObj.toJSONString();
} else {
errMsg = returnMap.get("return_msg");
}
return new RefundAdapterResult(false,ErrorCode.REFUND_ORDER_ERROR.getCode(),errMsg,returnMap);
}
} else {
Map<String, String> paramMap = WxPayment.buildSWeappRefundQueryMap(
appInfo.getParentAppId(), appInfo.getAppId(), payAccount.getMchId(), payAccount.getSubMchId(),
record.getTransactionId(), record.getPayOrderNo(), String.valueOf(record.getId()), record.getRefundId(), payAccount.getApiKey());
String response = WxPay.orderRefundQuery(paramMap);
Map<String, String> returnMap = WxPayment.xmlToMap(response);
String result_no = returnMap.get("result_code");
if ("SUCCESS".equals(result_no)) {
String refund_id = returnMap.get("refund_id");
return new RefundAdapterResult(true,0,"退款",returnMap);
} else {
String errMsg = "";
JSONObject errObj = errorRefundQueryMap.getJSONObject(result_no);
if (errObj != null) {
errMsg = errObj.toJSONString();
} else {
errMsg = returnMap.get("return_msg");
}
return new RefundAdapterResult(false,ErrorCode.REFUND_ORDER_ERROR.getCode(),errMsg,returnMap);
}
}
}

@Autowired
WxAppinfoMapper wxAppinfoMapper;
@Autowired
WxPayAccountMapper wxPayAccountMapper;
@Autowired
WxPayOrderMapper wxPayOrderMapper;
@Autowired
WxRefundOrderMapper wxRefundOrderMapper;
private RefundNotifyAdapterResult notifyErrorResult(String msg) {
SortedMap resultMap = new TreeMap();
resultMap.put("return_code", "FAIL");
resultMap.put("return_msg", msg);
return new RefundNotifyAdapterResult(false,ErrorCode.REFUND_ORDER_ERROR.getCode(),msg,XmlUtil.getRequestXml(resultMap));
}
private RefundNotifyAdapterResult notifySuccessResult(String transactionId,String refundId,WxRefundOrder refundOrder) {
SortedMap resultMap = new TreeMap();
resultMap.put("return_code", "SUCCESS");
resultMap.put("return_msg", "OK");
return new RefundNotifyAdapterResult(transactionId, refundId,refundOrder,XmlUtil.getRequestXml(resultMap));
}
@Override
public RefundNotifyAdapterResult notify(Map<String, String> paramMap, EnumPayWay payWay) {
// how to get wechatAppId, wechatMchId, partnerKey
String appId = paramMap.get("appid");
String subAppId = paramMap.get("sub_appid");
String mchId = paramMap.get("mch_id");
String subMchId = paramMap.get("sub_mch_id");
if (StringUtils.isBlank(subAppId) && StringUtils.isBlank(subMchId)) {
// 普通商户号
WxAppinfo appinfo = wxAppinfoMapper.findByAppId(appId);
if (appinfo == null) {
log.error("未找到appid信息:" + appId);
throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND);
}
WxPayAccount payAccount = wxPayAccountMapper.selectById(appinfo.getPayId());
if (payAccount == null) {
log.error("未找到mch_id信息:" + mchId);
throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND);
}
if (!mchId.equalsIgnoreCase(payAccount.getMchId())) {
log.error("mch_id不对应:" + mchId + ",account:" + payAccount.getMchId());
throw new MallinkException(ErrorCode.MCH_INFO_NOT_EQUAL);
}
String partnerKey = payAccount.getApiKey();
try {
if (payWay.getType() == EnumPayWay.EnumPayWayType.WX_MINIPAY) {
if (!"SUCCESS".equals(paramMap.get("return_code"))) {
log.warn("notify refund, wxpay status not success, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("订单状态码非SUCCESS");
}

// 解密req_info
String req_info = CipherUtil.decryptReqInfo(paramMap.get("req_info"), partnerKey);
Map<String, String> reqMap = WxPayment.xmlToMap(req_info);

String payOrderNo = reqMap.get("out_trade_no");
Long payOrderId = Long.valueOf(payOrderNo);
WxPayOrder payOrder = wxPayOrderMapper.selectById(payOrderId);
if (payOrder == null) {
log.warn("notify refund, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("支付订单不存在");
}
// 验证支付金额
if (!reqMap.get("total_fee").equals(payOrder.getPayAmount().toString())) {
log.warn("notify refund, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("支付订单总金额不一致");
}
String refundIdStr = reqMap.get("out_refund_no");
Long refundOrderId = Long.valueOf(refundIdStr);
WxRefundOrder refundOrder = wxRefundOrderMapper.selectById(refundOrderId);
if (refundOrder == null) {
log.warn("notify refund, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("退款订单不存在");
}
// 验证支付金额
if (!reqMap.get("total_fee").equals(refundOrder.getTotalFee().toString())) {
log.warn("notify refund, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("订单总金额不一致");
}
// 验证退款金额
if (!reqMap.get("refund_fee").equals(refundOrder.getRefundFee().toString())) {
log.warn("notify refund, wxpay check refund_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("退款总金额不一致");
}
// 处理支付成功
//handleRefundSuccess(refundOrder, reqMap.get("transaction_id"), reqMap.get("refund_id"));
log.info("notify refund, wxpay checksign success, paramMap:{}, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifySuccessResult(reqMap.get("transaction_id"), reqMap.get("refund_id"), refundOrder);
}
} catch (RuntimeException e) {
log.warn("notify refund paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getMessage());
} catch (Exception e) {
log.warn("notify refund, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getMessage());
}
} else {
// 服务号回调
WxAppinfo appinfo = wxAppinfoMapper.findByAppId(subAppId);
if (appinfo == null) {
log.error("未找到appid信息:" + appId);
throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND);
}
WxPayAccount payAccount = wxPayAccountMapper.selectById(appinfo.getPayId());
if (payAccount == null) {
log.error("未找到mch_id信息:" + mchId);
throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND);
}
if (!mchId.equalsIgnoreCase(payAccount.getMchId())) {
log.error("mch_id不对应:" + mchId + ",account:" + payAccount.getMchId());
throw new MallinkException(ErrorCode.MCH_INFO_NOT_EQUAL);
}
String partnerKey = payAccount.getApiKey();
try {
if (payWay.getType() == EnumPayWay.EnumPayWayType.WX_MINIPAY) {
if (!"SUCCESS".equals(paramMap.get("return_code"))) {
log.warn("notify order, wxpay status not success, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("订单状态码非SUCCESS");
}

// 解密req_info
String req_info = CipherUtil.decryptReqInfo(paramMap.get("req_info"), partnerKey);
log.info(req_info);
Map<String, String> reqMap = WxPayment.xmlToMap(req_info);

String payOrderNo = reqMap.get("out_trade_no");
if (payOrderNo == null) {
return notifySuccessResult(reqMap.get("transaction_id"), reqMap.get("refund_id"), null);
}
Long payOrderId = Long.valueOf(payOrderNo);
WxPayOrder payOrder = wxPayOrderMapper.selectById(payOrderId);
if (payOrder == null) {
log.warn("notify refund, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("支付订单不存在");
}
// 验证支付金额
if (!reqMap.get("total_fee").equals(payOrder.getPayAmount().toString())) {
log.warn("notify refund, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("支付订单总金额不一致");
}
String refundIdStr = reqMap.get("out_refund_no");
Long refundOrderId = Long.valueOf(refundIdStr);
WxRefundOrder refundOrder = wxRefundOrderMapper.selectById(refundOrderId);
if (refundOrder == null) {
log.warn("notify refund, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("退款订单不存在");
}
// 验证支付金额
if (!reqMap.get("total_fee").equals(refundOrder.getTotalFee().toString())) {
log.warn("notify refund, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("订单总金额不一致");
}
// 验证退款金额
if (!reqMap.get("refund_fee").equals(refundOrder.getRefundFee().toString())) {
log.warn("notify refund, wxpay check refund_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("退款总金额不一致");
}

log.info("notify refund, wxpay checksign success, paramMap:{}, paramMap: " + reqMap.toString() + ", payWay:" + payWay.toString());
return notifySuccessResult(reqMap.get("transaction_id"), reqMap.get("refund_id"), refundOrder);
}
} catch (RuntimeException e) {
log.warn("notify refund, wepay checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR);
} catch (Exception e) {
log.warn("notify refund, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getMessage());
}
}

return notifyErrorResult("FAILED");
}

}

+ 8
- 1
mallinkService/src/main/java/com/iformall/service/pay/service/share/PayShareAdapterService.java View File

@@ -1,13 +1,17 @@
package com.iformall.service.pay.service.share;

import java.util.Map;

import com.alibaba.fastjson.JSONArray;
import com.iformall.domain.po.WxAppinfo;
import com.iformall.domain.po.WxPayAccount;
import com.iformall.domain.po.WxProfitSharingOrder;
import com.iformall.enums.EnumPayWay;
import com.iformall.enums.EnumProfitSharingOrderType;
import com.iformall.enums.EnumProfitSharingReceiverType;
import com.iformall.exception.MallinkException;
import com.iformall.service.pay.entity.PayShareResult;
import com.iformall.service.pay.service.share.entity.PayShareResult;
import com.iformall.service.pay.service.share.entity.ShareNotifyAdapterResult;

/**
* 分账接口
@@ -58,4 +62,7 @@ public interface PayShareAdapterService {
*/
public EnumProfitSharingReceiverType getShareAccount(Integer accountType);
public ShareNotifyAdapterResult notify(Map<String, String> paramMap,EnumPayWay payWay);
}

mallinkService/src/main/java/com/iformall/service/pay/entity/PayShareResult.java → mallinkService/src/main/java/com/iformall/service/pay/service/share/entity/PayShareResult.java View File

@@ -1,4 +1,4 @@
package com.iformall.service.pay.entity;
package com.iformall.service.pay.service.share.entity;

import java.io.Serializable;


+ 76
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/share/entity/ShareNotifyAdapterResult.java View File

@@ -0,0 +1,76 @@
package com.iformall.service.pay.service.share.entity;

import java.io.Serializable;
import com.iformall.domain.po.WxPayOrder;

public class ShareNotifyAdapterResult implements Serializable{
private static final long serialVersionUID = -6647306162758854293L;
private boolean isSuccess;
private Integer code;
private String msg;
private String returnJson;
private String transcationId;
private WxPayOrder payOrder;
public ShareNotifyAdapterResult() {
}
public ShareNotifyAdapterResult(boolean isSuccess,Integer code,String msg,String returnJson) {
this.isSuccess = isSuccess;
this.msg = msg;
this.returnJson = returnJson;
}
public ShareNotifyAdapterResult(String transcationId,WxPayOrder payOrder,String returnJson) {
this.isSuccess = true;
this.transcationId = transcationId;
this.payOrder = payOrder;
this.returnJson = returnJson;
}
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Integer getCode() {
return code;
}

public void setCode(Integer code) {
this.code = code;
}

public String getTranscationId() {
return transcationId;
}

public void setTranscationId(String transcationId) {
this.transcationId = transcationId;
}

public String getReturnJson() {
return returnJson;
}

public void setReturnJson(String returnJson) {
this.returnJson = returnJson;
}

public WxPayOrder getPayOrder() {
return payOrder;
}

public void setPayOrder(WxPayOrder payOrder) {
this.payOrder = payOrder;
}
}

+ 130
- 1
mallinkService/src/main/java/com/iformall/service/pay/service/share/wx/WxPayShareService.java View File

@@ -1,28 +1,44 @@
package com.iformall.service.pay.service.share.wx;

import java.text.ParseException;
import java.util.Date;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.iformall.common.ErrorCode;
import com.iformall.domain.po.WxAppinfo;
import com.iformall.domain.po.WxPayAccount;
import com.iformall.domain.po.WxPayOrder;
import com.iformall.domain.po.WxProfitSharingOrder;
import com.iformall.enums.EnumMerchantSubsidyType;
import com.iformall.enums.EnumPayEndFrom;
import com.iformall.enums.EnumPayWay;
import com.iformall.enums.EnumProfitSharingOrderStatus;
import com.iformall.enums.EnumProfitSharingOrderType;
import com.iformall.enums.EnumProfitSharingReceiverType;
import com.iformall.enums.EnumProfitSharingType;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.WxAppinfoMapper;
import com.iformall.mapper.WxPayAccountMapper;
import com.iformall.mapper.WxPayOrderMapper;
import com.iformall.pay.WxPayment;
import com.iformall.pay.WxProfitSharing;
import com.iformall.pay.WxProfitSharingFinishP;
import com.iformall.pay.WxProfitSharingP;
import com.iformall.service.pay.entity.PayShareResult;
import com.iformall.service.pay.service.share.PayShareAdapterService;
import com.iformall.service.pay.service.share.PayShareBaseAdapterService;
import com.iformall.service.pay.service.share.entity.PayShareResult;
import com.iformall.service.pay.service.share.entity.ShareNotifyAdapterResult;
import com.iformall.utils.BeanUtils;
import com.iformall.utils.Utility;
import com.iformall.utils.XmlUtil;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@@ -130,4 +146,117 @@ public class WxPayShareService extends PayShareBaseAdapterService{
return new PayShareResult(true, null, "success",returnMap, returnMap.get("order_id"));
}

@Autowired
WxAppinfoMapper wxAppinfoMapper;
@Autowired
WxPayAccountMapper wxPayAccountMapper;
@Autowired
WxPayOrderMapper wxPayOrderMapper;
private ShareNotifyAdapterResult getErrorResult(String msg) {
SortedMap resultMap = new TreeMap();
resultMap.put("return_code", "FAIL");
resultMap.put("return_msg", msg);
return new ShareNotifyAdapterResult(false,ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR.getCode(),msg,XmlUtil.getRequestXml(resultMap));
}
private ShareNotifyAdapterResult getSuccessResult(WxPayOrder payOrder, String transcationId){
SortedMap resultMap = new TreeMap();
resultMap.put("return_code", "SUCCESS");
resultMap.put("return_msg", "OK");
return new ShareNotifyAdapterResult(transcationId, payOrder, XmlUtil.getRequestXml(resultMap));
}
@Override
public ShareNotifyAdapterResult notify(Map<String, String> paramMap,EnumPayWay payWay) {
// how to get wechatAppId, wechatMchId, partnerKey
String appId = paramMap.get("appid");
String subAppId = paramMap.get("sub_appid");
String mchId = paramMap.get("mch_id");
String subMchId = paramMap.get("sub_mch_id");
WxAppinfo appinfo = null;
boolean isNormal = true;
if (StringUtils.isBlank(subAppId) && StringUtils.isBlank(subMchId)) {
// 普通商户号
appinfo = wxAppinfoMapper.findByAppId(appId);
if (appinfo == null) {
log.error("appid not found: " + appId);
throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND);
}
isNormal = true;
} else {
// 服务号 现在用hmac-sha256
appinfo = wxAppinfoMapper.findByAppId(subAppId);
if (appinfo == null) {
log.error("subappid not found: " + subAppId);
throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND);
}
isNormal = false;
}

WxPayAccount payAccount = wxPayAccountMapper.selectById(appinfo.getPayId());
if (payAccount == null) {
throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND);
}
String partnerKey = payAccount.getApiKey();
try {
if (payWay == EnumPayWay.PAY_WAY_WECHAT) {
boolean signVerified = false;
if (isNormal) {
// 普通商户号支付
signVerified = WxPayment.verifyNotify(paramMap, partnerKey);
if (!signVerified) {
log.warn("notify order, wxpay checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
throw new MallinkException(ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR);
}
} else {
// 服务号 现在用hmac-sha256
signVerified = WxPayment.verifyNotifyHMAC(paramMap, partnerKey);
if (!signVerified) {
log.warn("notify order, wxpay checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
throw new MallinkException(ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR);
}
}

if (!"SUCCESS".equals(paramMap.get("return_code"))) {
log.warn("notify order, wxpay status not success, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return getErrorResult("订单状态码非SUCCESS");
}

String payOrderNo = paramMap.get("out_trade_no");
String timEndStr = paramMap.get("time_end");
Long payOrderId = Long.valueOf(payOrderNo);
WxPayOrder payOrder = wxPayOrderMapper.selectById(payOrderId);
if (payOrder == null) {
log.warn("notify order, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return getErrorResult("订单不存在");
}
// 验证支付金额
if (!paramMap.get("total_fee").equals(payOrder.getPayAmount().toString())) {
log.warn("notify order, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return getErrorResult("订单总金额不一致");
}

Date timeEnd = null;

try {
timeEnd = Utility.getDateFromString(timEndStr);
} catch (ParseException e) {
log.error("解析timeEnd失败");
timeEnd = new Date();
}
payOrder.setPayTimeEnd(timeEnd);

log.info("notify order, wxpay checksign success, paramMap:{}, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return getSuccessResult(payOrder, paramMap.get("transaction_id"));
}
} catch (RuntimeException e) {
log.warn("notify order, checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage());
throw new MallinkException(ErrorCode.PAY_ORDER_ERROR);
}

return getErrorResult("FAILED");
}
}

Loading…
Cancel
Save