diff --git a/mallinkApi/src/main/resources/application-dev.yml b/mallinkApi/src/main/resources/application-dev.yml index 8bcd356f3..9878c17ce 100644 --- a/mallinkApi/src/main/resources/application-dev.yml +++ b/mallinkApi/src/main/resources/application-dev.yml @@ -1,9 +1,9 @@ spring: # JDBC datasource: - url: jdbc:mysql://127.0.0.1:63306/mallink?characterEncoding=UTF-8&useSSL=false - username: root - password: root + url: jdbc:mysql://202.165.179.86:63306/mallink?characterEncoding=UTF-8&useSSL=false + username: mallone + password: m@1l0ne123@# type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver filters: stat @@ -25,7 +25,8 @@ spring: # REDIS redis: host: 127.0.0.1 - port: 6379 + port: 6789 + password: JGtest123 timeout: 0 expire: 1800 #30分钟 pool: diff --git a/mallinkApi/src/main/resources/application.yml b/mallinkApi/src/main/resources/application.yml index bec78e171..74ae8cbee 100644 --- a/mallinkApi/src/main/resources/application.yml +++ b/mallinkApi/src/main/resources/application.yml @@ -1,5 +1,5 @@ server: - port: 9000 + port: 9001 context-path: / spring: diff --git a/mallinkService/src/main/java/com/simple/common/ErrorCode.java b/mallinkService/src/main/java/com/simple/common/ErrorCode.java index cf3c4ff8d..50bf0e156 100644 --- a/mallinkService/src/main/java/com/simple/common/ErrorCode.java +++ b/mallinkService/src/main/java/com/simple/common/ErrorCode.java @@ -49,7 +49,8 @@ public enum ErrorCode{ ORDER_IS_FAIL(12001, "订单创建失败"), ORDER_IS_NOT_FIND(12002, "订单不存在"), ORDER_IS_NOT_PAY(12003, "订单已不能进行支付"), - PAYORDER_ERROR(12004, "支付订单异常"); + PAYORDER_ERROR(12004, "支付订单异常"), + PAYORDER_NOTIFY_CHECK_SIGN_ERROR(12005 , "验签失败"); /** * 支付 diff --git a/mallinkService/src/main/java/com/simple/service/WxPayOrderService.java b/mallinkService/src/main/java/com/simple/service/WxPayOrderService.java index 0ab5d0ff0..21ba7ce49 100644 --- a/mallinkService/src/main/java/com/simple/service/WxPayOrderService.java +++ b/mallinkService/src/main/java/com/simple/service/WxPayOrderService.java @@ -16,6 +16,8 @@ public interface WxPayOrderService { */ ResultData createPayOrder(WxPayOrder record, EnumPayWay payWay); + void handleOrderPaySuccess(WxPayOrder record, String tradeNo); + /** * 异步通知 * @param paramMap 异步通知参数 diff --git a/mallinkService/src/main/java/com/simple/service/impl/WxPayOrderServiceImpl.java b/mallinkService/src/main/java/com/simple/service/impl/WxPayOrderServiceImpl.java index 8f9e9fed0..94209e9ca 100644 --- a/mallinkService/src/main/java/com/simple/service/impl/WxPayOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/simple/service/impl/WxPayOrderServiceImpl.java @@ -15,15 +15,18 @@ import com.simple.exception.BizMessageException; import com.simple.exception.MallinkException; import com.simple.mapper.WxOrderMapper; import com.simple.mapper.WxPayOrderMapper; +import com.simple.pay.WxPayment; import com.simple.service.WxOrderService; import com.simple.service.WxPayOrderService; import com.simple.utils.Utility; +import com.simple.utils.XmlUtil; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.simple.common.IdWorker; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; +import tk.mybatis.mapper.entity.Example; @Service public class WxPayOrderServiceImpl implements WxPayOrderService { @@ -32,11 +35,14 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { @Autowired WxOrderMapper wxOrderMapper; + @Autowired WxPayOrderMapper wxPayOrderMapper; + @Autowired + WxOrderService wxOrderService; + @Override - @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) public ResultData createPayOrder(WxPayOrder record, EnumPayWay payWay) { try { // 1. check 订单 @@ -75,6 +81,81 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { @Override public String notify(Map paramMap, EnumPayWay payWay) { + // how to get wechatAppId, wechatMchId, partnerKey + String wechatAppId = ""; + String wechatMchId = ""; + String partnerKey = ""; + try { + if (payWay == EnumPayWay.PAY_WAY_WEAPP) { + boolean signVerified = false; + if (payWay == EnumPayWay.PAY_WAY_WECHAT) { + // 微信支付 + signVerified = WxPayment.verifyNotify(paramMap, partnerKey); + } + if (!signVerified) { + logger.warn("notify order, wxpay checksign error, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + throw new MallinkException(ErrorCode.PAYORDER_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()); + Map resultMap = new LinkedHashMap<>(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "订单状态码非SUCCESS"); + return XmlUtil.parseDto2Xml(resultMap, ""); + } + if (!wechatAppId.equals(paramMap.get("appid"))) { + logger.warn("notify order, wxpay appid is invalid, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + Map resultMap = new LinkedHashMap<>(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "非法请求appid"); + return XmlUtil.parseDto2Xml(resultMap, ""); + } + if (!(wechatMchId.equals(paramMap.get("mch_id")))) { + logger.warn("notify order, wxpay mch_id is invalid, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + Map resultMap = new LinkedHashMap<>(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "非法请求mch_id"); + return XmlUtil.parseDto2Xml(resultMap, ""); + } + + if (!"SUCCESS".equals(paramMap.get("result_code"))) { + logger.warn("notify order, wxpay result_code is invalid, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + Map resultMap = new LinkedHashMap<>(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "result_code fail"); + return XmlUtil.parseDto2Xml(resultMap, ""); + } + String payOrderNo = paramMap.get("out_trade_no"); + Long payOrderId = Long.valueOf(payOrderNo); + WxPayOrder payOrder = wxPayOrderMapper.selectByPrimaryKey(payOrderId); + if (payOrder == null) { + logger.warn("notify order, wxpay check pay order not exists, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + Map resultMap = new LinkedHashMap<>(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "订单不存在"); + return XmlUtil.parseDto2Xml(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()); + Map resultMap = new LinkedHashMap<>(); + resultMap.put("return_code", "FAIL"); + resultMap.put("return_msg", "订单总金额不一致"); + return XmlUtil.parseDto2Xml(resultMap, ""); + } + + // 处理支付成功 + handleOrderPaySuccess(payOrder, paramMap.get("transaction_id")); + logger.info("notify order, wxpay checksign success, paramMap:{}, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); + Map resultMap = new LinkedHashMap<>(); + resultMap.put("return_code", "SUCCESS"); + resultMap.put("return_msg", "OK"); + return XmlUtil.parseDto2Xml(resultMap, ""); + } + } catch (RuntimeException e) { + logger.warn("notify order, alipay checksign error, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); + throw new MallinkException(ErrorCode.PAYORDER_NOTIFY_CHECK_SIGN_ERROR); + } return ""; } @@ -83,6 +164,47 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { } + @Override + @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) + public void handleOrderPaySuccess(WxPayOrder record, String tradeNo) { + EnumPayStatus payStatus = EnumPayStatus.getEnum(record.getPayOrderStatus()); + // 判断支付状态 + if (payStatus != EnumPayStatus.PAY_WAY_WAIT) { + logger.error("pay success handle, payOrder " + record.getPayOrderNo() + + "is paid success , orderId : " + record.getOrderId()); + return; + } + WxOrder order = wxOrderMapper.selectByPrimaryKey(record.getOrderId()); + if (order == null) { + logger.error("pay success handle, order " + record.getOrderId() +" not found , payOrderGid : " + record.getPayOrderNo()); + throw new MallinkException(ErrorCode.ORDER_IS_NOT_FIND); + } + + // 修改订单状态 + wxOrderService.updateOrderStatus(order.getId(), EnumOrderStatus.ORDER_STATUS_PAYMENT_SUCCESS); + + // 修改支付订单状态 + Date currentDate = new Date(); + WxPayOrder updatePayOrder = new WxPayOrder(); + updatePayOrder.setId(record.getId()); + updatePayOrder.setOrderId(record.getOrderId()); + updatePayOrder.setUpdateTime(currentDate); + updatePayOrder.setPayOrderStatus(EnumPayStatus.PAY_WAY_SUCCESS.getCode()); + //updatePayOrder.setTradeNo(tradeNo); + wxPayOrderMapper.updateByPrimaryKeySelective(updatePayOrder); + + Map msgMap = new HashMap<>(); + try { + msgMap.put("name", String.valueOf(order.getCouponId())); + msgMap.put("orderNo", String.valueOf(order.getId())); + msgMap.put("createTime", Utility.getDataFormatString3(order.getCreateDate())); + msgMap.put("standingTime", order.getCreateDate() + "-" + currentDate ); + //smsSenderHandler.sendSms("SMS_18195394", order.getMobile(), msgMap); + } catch (Exception e) { + logger.error("pay success handle, sms send exception, payOrderi: " + updatePayOrder+ ", msgMap: " + msgMap.toString() + ", e: " + e.getMessage()); + } + } + @Override public PageInfo listAsPage(WxPayOrder record, Integer pageIndex, Integer pageSize) { diff --git a/mallinkService/src/main/java/com/simple/utils/Utility.java b/mallinkService/src/main/java/com/simple/utils/Utility.java index 347d70676..e86068665 100644 --- a/mallinkService/src/main/java/com/simple/utils/Utility.java +++ b/mallinkService/src/main/java/com/simple/utils/Utility.java @@ -254,6 +254,11 @@ public final class Utility { return sf.format(((long) currentSec) * 1000); } + public static String getDataFormatString3(Date date) { + SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日"); + return sf.format(date); + } + public static String convertDecimal2PercentRate(BigDecimal rate) { NumberFormat percent = NumberFormat.getPercentInstance(); percent.setMaximumFractionDigits(1);