Commit e712f029 by wuwenlong

wechat pay callback dev;

parent 53d83141
package com.zbkj.admin.controller;
import com.zbkj.service.service.CallbackService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
/**
* 支付回调
*/
@Slf4j
@RestController
@RequestMapping("api/admin/payment/callback")
@Api(tags = "支付回调")
public class CallbackController {
@Autowired
private CallbackService callbackService;
/**
* 微信支付回调
*/
@ApiOperation(value = "微信支付回调")
@RequestMapping(value = "/wechat", method = RequestMethod.POST)
public String weChat(@RequestBody String request) {
System.out.println("微信支付回调 request ===> " + request);
String response = callbackService.weChat(request);
System.out.println("微信支付回调 response ===> " + response);
return response;
}
/**
* 微信退款回调
*/
@ApiOperation(value = "微信退款回调")
@RequestMapping(value = "/wechat/refund", method = RequestMethod.POST)
public String weChatRefund(@RequestBody String request) {
System.out.println("微信退款回调 request ===> " + request);
String response = callbackService.weChatRefund(request);
System.out.println("微信退款回调 response ===> " + response);
return response;
}
}
...@@ -27,6 +27,8 @@ public class WeChatConfig ...@@ -27,6 +27,8 @@ public class WeChatConfig
private String publicAppSecret; private String publicAppSecret;
private String publicSignKey;
private Integer wechatJsApiDebug; private Integer wechatJsApiDebug;
} }
...@@ -9,6 +9,7 @@ import io.jsonwebtoken.Claims; ...@@ -9,6 +9,7 @@ import io.jsonwebtoken.Claims;
*/ */
public class Constants public class Constants
{ {
public static final String CONFIG_KEY_SITE_URL = "site_url"; //域名 public static final String CONFIG_KEY_SITE_URL = "site_url"; //域名
public static final String CONFIG_KEY_API_URL = "api_url"; //admin接口地址 public static final String CONFIG_KEY_API_URL = "api_url"; //admin接口地址
// 订单取消Key // 订单取消Key
...@@ -40,6 +41,16 @@ public class Constants ...@@ -40,6 +41,16 @@ public class Constants
public static final int THIRD_LOGIN_TOKEN_TYPE_ANDROID_WX = 6; //android微信 public static final int THIRD_LOGIN_TOKEN_TYPE_ANDROID_WX = 6; //android微信
public static final int THIRD_LOGIN_TOKEN_TYPE_IOS = 7; //ios public static final int THIRD_LOGIN_TOKEN_TYPE_IOS = 7; //ios
/** 订单支付成功后Task */
public static final String ORDER_TASK_PAY_SUCCESS_AFTER = "orderPaySuccessTask";
//订单操作redis队列
public static final String ORDER_TASK_REDIS_KEY_AFTER_DELETE_BY_USER = "alterOrderDeleteByUser"; // 用户删除订单后续操作
public static final String ORDER_TASK_REDIS_KEY_AFTER_COMPLETE_BY_USER = "alterOrderCompleteByUser"; // 用户完成订单后续操作
public static final String ORDER_TASK_REDIS_KEY_AFTER_CANCEL_BY_USER = "alterOrderCancelByUser"; // 用户取消订单后续操作
public static final String ORDER_TASK_REDIS_KEY_AFTER_REFUND_BY_USER = "alterOrderRefundByUser"; // 用户订单退款后续操作
public static final int NUM_ZERO = 0; public static final int NUM_ZERO = 0;
public static final int NUM_ONE = 1; public static final int NUM_ONE = 1;
public static final int NUM_TWO = 2; public static final int NUM_TWO = 2;
......
package share.common.enums; package share.common.enums;
import share.common.utils.StringUtils;
/** /**
* @Author wwl * @Author wwl
* @Date 2023/10/20 10:57 * @Date 2023/10/20 10:57
*/ */
public enum OrderTypeEnum { public enum OrderTypeEnum {
RESERVER(1,"预定"), RESERVER(1,"reserver","预定"),
RENEW(2,"续费"), RENEW(2,"renew","续费"),
RECHARGE(3,"充值"); RECHARGE(3,"recharge","充值");
private Integer code; private Integer code;
private String value;
private String name; private String name;
OrderTypeEnum(Integer code, String name) { OrderTypeEnum(Integer code, String value, String name) {
this.code = code; this.code = code;
this.value = value;
this.name = name; this.name = name;
} }
...@@ -26,10 +30,25 @@ public enum OrderTypeEnum { ...@@ -26,10 +30,25 @@ public enum OrderTypeEnum {
return null; return null;
} }
public static OrderTypeEnum getEnumByValue(String value){
if(StringUtils.isNotBlank(value)) {
for (OrderTypeEnum type : OrderTypeEnum.values()) {
if (type.value.equals(value)) {
return type;
}
}
}
return null;
}
public Integer getCode(){ public Integer getCode(){
return code; return code;
} }
public String getValue() {
return value;
}
public String getName() { public String getName() {
return name; return name;
} }
......
package share.system.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 支付附加对象
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="AttachVo对象", description="支付附加对象")
public class AttachVo {
public AttachVo() {
}
public AttachVo(String type, Long userId) {
this.type = type;
this.userId = userId;
}
@ApiModelProperty(value = "业务类型, 订单 = order, 充值 = recharge", required = true)
private String type = "order";
@ApiModelProperty(value = "用户id", required = true)
private Long userId;
}
package com.zbkj.common.vo;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 微信回调对象
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="CallbackVo对象", description="微信回调")
public class CallbackVo {
@ApiModelProperty(value = "调用接口提交的公众账号ID")
@JsonProperty(value = "appid")
private String appId;
@ApiModelProperty(value = "调用接口提交的商户号")
@JsonProperty(value = "mch_id")
private String mchId;
@ApiModelProperty(value = "调用接口提交的终端设备号")
@JsonProperty(value = "device_info")
private String deviceInfo;
@ApiModelProperty(value = "微信返回的随机字符串")
@JsonProperty(value = "nonce_str")
private String nonceStr;
@ApiModelProperty(value = "微信返回的签名")
private String sign;
@ApiModelProperty(value = "SUCCESS/FAIL此字段是通信标识,非交易标识,交易是否成功需要查看trade_state来判断")
@JsonProperty(value = "return_code")
private String returnCode;
@ApiModelProperty(value = "当return_code为FAIL时返回信息为错误原因 ,例如 签名失败 参数格式校验错误")
@JsonProperty(value = "return_msg")
private String returnMsg;
@ApiModelProperty(value = "SUCCESS/FAIL 业务结果")
@JsonProperty(value = "result_code")
private String resultCode;
@ApiModelProperty(value = "详细参见错误列表")
@JsonProperty(value = "err_code")
private String errCode;
@ApiModelProperty(value = "错误返回的信息描述")
@JsonProperty(value = "err_code_des")
private String errCodeDes;
@ApiModelProperty(value = "用户在商户appid下的唯一标识")
private String openid;
@ApiModelProperty(value = "微信支付订单号")
@JsonProperty(value = "transaction_id")
private String transactionId;
@ApiModelProperty(value = "微信支付订单号")
@JsonProperty(value = "out_trade_no")
private String outTradeNo;
@ApiModelProperty(value = "商家数据包,原样返回")
private String attach;
@ApiModelProperty(value = "支付完成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则")
@JsonProperty(value = "time_end")
private String timeEnd;
@ApiModelProperty(value = "用户是否关注公众账号,Y-关注,N-未关注")
@JsonProperty(value = "is_subscribe")
private String isSubscribe;
@ApiModelProperty(value = "银行类型")
@JsonProperty(value = "bank_type")
private String bankType;
@ApiModelProperty(value = "现金支付金额")
@JsonProperty(value = "cash_fee")
private Integer cashFee;
@ApiModelProperty(value = "总代金券金额")
@JsonProperty(value = "coupon_fee")
private Integer couponFee;
}
package com.zbkj.service.service;
import javax.servlet.http.HttpServletRequest;
/**
* 订单支付回调 service
*/
public interface CallbackService {
/**
* 微信支付回调
* @param xmlInfo 微信回调json
* @return String
*/
String weChat(String xmlInfo);
/**
* 微信退款回调
* @param request 微信回调json
* @return String
*/
String weChatRefund(String request);
}
...@@ -96,4 +96,6 @@ public interface ISOrderService extends IService<SOrder> ...@@ -96,4 +96,6 @@ public interface ISOrderService extends IService<SOrder>
* @return * @return
*/ */
SOrder getByOrderNo(String orderNo); SOrder getByOrderNo(String orderNo);
SOrder getInfoByEntity(SOrder orderParam);
} }
package share.system.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.zbkj.common.vo.AttachVo;
import com.zbkj.common.vo.CallbackVo;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import share.common.config.WeChatConfig;
import share.common.constant.Constants;
import share.common.core.redis.RedisUtil;
import share.common.enums.OrderTypeEnum;
import share.common.enums.YesNoEnum;
import share.common.exception.base.BaseException;
import share.common.utils.BaseUtil;
import share.common.utils.DateUtils;
import share.system.domain.SConsumer;
import share.system.domain.SOrder;
import share.system.domain.WechatPayInfo;
import share.system.domain.vo.MyRecord;
import share.system.service.ISOrderService;
import share.system.service.ISysConfigService;
import share.system.service.SConsumerService;
import share.system.service.WechatPayInfoService;
import share.system.util.WxPayUtil;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.*;
/**
* 订单支付回调 CallbackService 实现类
*/
@Service
public class CallbackServiceImpl implements com.zbkj.service.service.CallbackService {
private static final Logger logger = LoggerFactory.getLogger(CallbackServiceImpl.class);
@Autowired
private ISOrderService sOrderService;
@Autowired
private SConsumerService sConsumerService;
@Autowired
private RedisUtil redisUtil;
@Autowired
private WechatPayInfoService wechatPayInfoService;
@Autowired
private WeChatConfig weChatConfig;
/**
* 微信支付回调
*/
@DSTransactional
@Override
public String weChat(String xmlInfo) {
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
if(StrUtil.isBlank(xmlInfo)){
sb.append("<return_code><![CDATA[FAIL]]></return_code>");
sb.append("<return_msg><![CDATA[xmlInfo is blank]]></return_msg>");
sb.append("</xml>");
logger.error("wechat callback error : " + sb.toString());
return sb.toString();
}
try{
HashMap<String, Object> map = WxPayUtil.processResponseXml(xmlInfo);
// 通信是否成功
String returnCode = (String) map.get("return_code");
if (!returnCode.equals(Constants.SUCCESS)) {
sb.append("<return_code><![CDATA[SUCCESS]]></return_code>");
sb.append("<return_msg><![CDATA[OK]]></return_msg>");
sb.append("</xml>");
logger.error("wechat callback error : wx pay return code is fail returnMsg : " + map.get("return_msg"));
return sb.toString();
}
// 交易是否成功
String resultCode = (String) map.get("result_code");
if (!resultCode.equals(Constants.SUCCESS)) {
sb.append("<return_code><![CDATA[SUCCESS]]></return_code>");
sb.append("<return_msg><![CDATA[OK]]></return_msg>");
sb.append("</xml>");
logger.error("wechat callback error : wx pay result code is fail");
return sb.toString();
}
//解析xml
CallbackVo callbackVo = BaseUtil.mapToObj(map, CallbackVo.class);
AttachVo attachVo = JSONObject.toJavaObject(JSONObject.parseObject(callbackVo.getAttach()), AttachVo.class);
//判断openid
SConsumer sConsumer = sConsumerService.getById(attachVo.getUserId());
if (ObjectUtil.isNull(sConsumer)) {
//用户信息错误
throw new BaseException("用户信息错误!");
}
OrderTypeEnum orderTypeEnum = OrderTypeEnum.getEnumByValue(attachVo.getType());
switch (orderTypeEnum){
case RESERVER:
case RENEW:
SOrder orderParam = new SOrder();
orderParam.setOutTradeNo(callbackVo.getOutTradeNo());
orderParam.setConsumerId(attachVo.getUserId());
SOrder sOrder = sOrderService.getInfoByEntity(orderParam);
if (ObjectUtil.isNull(sOrder)) {
logger.error("wechat pay error : 订单信息不存在==》" + callbackVo.getOutTradeNo());
throw new BaseException("wechat pay error : 订单信息不存在==》" + callbackVo.getOutTradeNo());
}
if (YesNoEnum.yes.getIndex().equals(sOrder.getPayStatus())) {
logger.error("wechat pay error : 订单已处理==》" + callbackVo.getOutTradeNo());
sb.append("<return_code><![CDATA[SUCCESS]]></return_code>");
sb.append("<return_msg><![CDATA[OK]]></return_msg>");
sb.append("</xml>");
return sb.toString();
}
WechatPayInfo wechatPayInfo = wechatPayInfoService.getByNo(sOrder.getOutTradeNo());
if (ObjectUtil.isNull(wechatPayInfo)) {
logger.error("wechat pay error : 微信订单信息不存在==》" + callbackVo.getOutTradeNo());
throw new BaseException("wechat pay error : 微信订单信息不存在==》" + callbackVo.getOutTradeNo());
}
wechatPayInfo.setIsSubscribe(callbackVo.getIsSubscribe());
wechatPayInfo.setBankType(callbackVo.getBankType());
wechatPayInfo.setCashFee(callbackVo.getCashFee());
wechatPayInfo.setCouponFee(callbackVo.getCouponFee());
wechatPayInfo.setTransactionId(callbackVo.getTransactionId());
wechatPayInfo.setTimeEnd(callbackVo.getTimeEnd());
Boolean execute = Boolean.FALSE;
try {
sOrder.setPayStatus(YesNoEnum.yes.getIndex());
sOrder.setPayTime(DateUtils.getNowDate());
sOrderService.updateById(sOrder);
wechatPayInfoService.updateById(wechatPayInfo);
execute = Boolean.TRUE;
} catch (Exception e) {
logger.error("微信支付回调出错");
logger.error(e.toString());
}
if (!execute) {
logger.error("wechat pay error : 订单更新失败==》" + callbackVo.getOutTradeNo());
sb.append("<return_code><![CDATA[SUCCESS]]></return_code>");
sb.append("<return_msg><![CDATA[OK]]></return_msg>");
sb.append("</xml>");
return sb.toString();
}
redisUtil.lPush(Constants.ORDER_TASK_PAY_SUCCESS_AFTER, sOrder.getOrderNo());
sb.append("<return_code><![CDATA[SUCCESS]]></return_code>");
sb.append("<return_msg><![CDATA[OK]]></return_msg>");
break;
case RECHARGE:
break;
default:
logger.error("wechat pay err : 未知的支付类型==》" + callbackVo.getOutTradeNo());
throw new BaseException("未知的支付类型!");
}
}catch (Exception e){
sb.append("<return_code><![CDATA[FAIL]]></return_code>");
sb.append("<return_msg><![CDATA[").append(e.getMessage()).append("]]></return_msg>");
logger.error("wechat pay error : 业务异常==》" + e.getMessage());
}
sb.append("</xml>");
logger.error("wechat callback response : " + sb.toString());
return sb.toString();
}
/**
* 将request中的参数转换成Map
* @param request
* @return
*/
private Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
Map<String, String> retMap = new HashMap<String, String>();
Map requestParams = request.getParameterMap();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i]
: valueStr + values[i] + ",";
}
//乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
retMap.put(name, valueStr);
}
return retMap;
}
/**
* 微信退款回调
* @param xmlInfo 微信回调json
* @return MyRecord
*/
@Override
public String weChatRefund(String xmlInfo) {
MyRecord notifyRecord = new MyRecord();
MyRecord refundRecord = refundNotify(xmlInfo, notifyRecord);
if (refundRecord.getStr("status").equals("fail")) {
logger.error("微信退款回调失败==>" + refundRecord.getColumns() + ", rawData==>" + xmlInfo + ", data==>" + notifyRecord);
return refundRecord.getStr("returnXml");
}
if (!refundRecord.getBoolean("isRefund")) {
logger.error("微信退款回调失败==>" + refundRecord.getColumns() + ", rawData==>" + xmlInfo + ", data==>" + notifyRecord);
return refundRecord.getStr("returnXml");
}
String outRefundNo = notifyRecord.getStr("out_refund_no");
SOrder sOrder = sOrderService.getByOrderNo(outRefundNo);
if (ObjectUtil.isNull(sOrder)) {
logger.error("微信退款订单查询失败==>" + refundRecord.getColumns() + ", rawData==>" + xmlInfo + ", data==>" + notifyRecord);
return refundRecord.getStr("returnXml");
}
if (sOrder.getRefundStatus() == 2) {
logger.warn("微信退款订单已确认成功==>" + refundRecord.getColumns() + ", rawData==>" + xmlInfo + ", data==>" + notifyRecord);
return refundRecord.getStr("returnXml");
}
sOrder.setRefundStatus(2);
boolean update = sOrderService.updateById(sOrder);
if (update) {
// 退款task
redisUtil.lPush(Constants.ORDER_TASK_REDIS_KEY_AFTER_REFUND_BY_USER, sOrder.getId());
} else {
logger.warn("微信退款订单更新失败==>" + refundRecord.getColumns() + ", rawData==>" + xmlInfo + ", data==>" + notifyRecord);
}
return refundRecord.getStr("returnXml");
}
/**
* 支付订单回调通知
* @return MyRecord
*/
private MyRecord refundNotify(String xmlInfo, MyRecord notifyRecord) {
MyRecord refundRecord = new MyRecord();
refundRecord.set("status", "fail");
StringBuilder sb = new StringBuilder();
sb.append("<xml>");
if(StrUtil.isBlank(xmlInfo)){
sb.append("<return_code><![CDATA[FAIL]]></return_code>");
sb.append("<return_msg><![CDATA[xmlInfo is blank]]></return_msg>");
sb.append("</xml>");
logger.error("wechat refund callback error : " + sb.toString());
return refundRecord.set("returnXml", sb.toString()).set("errMsg", "xmlInfo is blank");
}
Map<String, String> respMap;
try {
respMap = WxPayUtil.xmlToMap(xmlInfo);
} catch (Exception e) {
sb.append("<return_code><![CDATA[FAIL]]></return_code>");
sb.append("<return_msg><![CDATA[").append(e.getMessage()).append("]]></return_msg>");
sb.append("</xml>");
logger.error("wechat refund callback error : " + e.getMessage());
return refundRecord.set("returnXml", sb.toString()).set("errMsg", e.getMessage());
}
notifyRecord.setColums(_strMap2ObjMap(respMap));
// 这里的可以应该根据小程序还是公众号区分
String return_code = respMap.get("return_code");
if (return_code.equals(Constants.SUCCESS)) {
String appid = respMap.get("appid");
String signKey = getSignKey(appid);
// 解码加密信息
String reqInfo = respMap.get("req_info");
System.out.println("encodeReqInfo==>" + reqInfo);
try {
String decodeInfo = decryptToStr(reqInfo, signKey);
Map<String, String> infoMap = WxPayUtil.xmlToMap(decodeInfo);
notifyRecord.setColums(_strMap2ObjMap(infoMap));
String refund_status = infoMap.get("refund_status");
refundRecord.set("isRefund", refund_status.equals(Constants.SUCCESS));
} catch (Exception e) {
refundRecord.set("isRefund", false);
logger.error("微信退款回调异常,e==》" + e.getMessage());
}
} else {
notifyRecord.set("return_msg", respMap.get("return_msg"));
refundRecord.set("isRefund", false);
}
sb.append("<return_code><![CDATA[SUCCESS]]></return_code>");
sb.append("<return_msg><![CDATA[OK]]></return_msg>");
sb.append("</xml>");
return refundRecord.set("returnXml", sb.toString()).set("status", "ok");
}
private String getSignKey(String appid) {
String publicAppid = weChatConfig.getPublicAppId();
String miniAppid = weChatConfig.getAppId();
String signKey = "";
if (StrUtil.isBlank(publicAppid) && StrUtil.isBlank(miniAppid)) {
throw new BaseException("pay_weixin_appid或pay_routine_appid不能都为空");
}
if (StrUtil.isNotBlank(publicAppid) && appid.equals(publicAppid)) {
signKey = weChatConfig.getSignKey();
}
if (StrUtil.isNotBlank(miniAppid) && appid.equals(miniAppid)) {
signKey = weChatConfig.getPublicSignKey();
}
return signKey;
}
/**
* java自带的是PKCS5Padding填充,不支持PKCS7Padding填充。
* 通过BouncyCastle组件来让java里面支持PKCS7Padding填充
* 在加解密之前加上:Security.addProvider(new BouncyCastleProvider()),
* 并给Cipher.getInstance方法传入参数来指定Java使用这个库里的加/解密算法。
*/
public static String decryptToStr(String reqInfo, String signKey) throws Exception {
Security.addProvider(new BouncyCastleProvider());
// byte[] decodeReqInfo = Base64.decode(reqInfo);
byte[] decodeReqInfo = base64DecodeJustForWxPay(reqInfo).getBytes(StandardCharsets.ISO_8859_1);
SecretKeySpec key = new SecretKeySpec(SecureUtil.md5(signKey).toLowerCase().getBytes(), "AES");
Cipher cipher;
cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
return new String(cipher.doFinal(decodeReqInfo), StandardCharsets.UTF_8);
}
private static final List<String> list = new ArrayList<>();
static {
list.add("total_fee");
list.add("cash_fee");
list.add("coupon_fee");
list.add("coupon_count");
list.add("refund_fee");
list.add("settlement_refund_fee");
list.add("settlement_total_fee");
list.add("cash_refund_fee");
list.add("coupon_refund_fee");
list.add("coupon_refund_count");
}
private Map<String, Object> _strMap2ObjMap(Map<String, String> params) {
Map<String, Object> map = new HashMap<>();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (list.contains(entry.getKey())) {
try {
map.put(entry.getKey(), Integer.parseInt(entry.getValue()));
} catch (NumberFormatException e) {
map.put(entry.getKey(), 0);
logger.error("字段格式错误,key==》" + entry.getKey() + ", value==》" + entry.getValue());
}
continue;
}
map.put(entry.getKey(), entry.getValue());
}
return map;
}
/**
* 仅仅为微信解析密文使用
* @param source 待解析密文
* @return 结果
*/
public static String base64DecodeJustForWxPay(final String source) {
String result = "";
final Base64.Decoder decoder = Base64.getDecoder();
try {
result = new String(decoder.decode(source), "ISO-8859-1");
} catch (final UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
}
package share.system.service.impl; package share.system.service.impl;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -8,6 +9,7 @@ import org.springframework.stereotype.Service; ...@@ -8,6 +9,7 @@ import org.springframework.stereotype.Service;
import share.common.config.WeChatConfig; import share.common.config.WeChatConfig;
import share.common.constant.Constants; import share.common.constant.Constants;
import share.common.constant.PayConstants; import share.common.constant.PayConstants;
import share.common.enums.OrderTypeEnum;
import share.common.enums.PayTypeEnum; import share.common.enums.PayTypeEnum;
import share.common.enums.YesNoEnum; import share.common.enums.YesNoEnum;
import share.common.exception.base.BaseException; import share.common.exception.base.BaseException;
...@@ -16,6 +18,7 @@ import share.common.utils.DateUtil; ...@@ -16,6 +18,7 @@ import share.common.utils.DateUtil;
import share.common.utils.JsonConvertUtil; import share.common.utils.JsonConvertUtil;
import share.system.domain.SConsumerToken; import share.system.domain.SConsumerToken;
import share.system.domain.SOrder; import share.system.domain.SOrder;
import share.system.domain.vo.AttachVo;
import share.system.domain.vo.CreateOrderRequestVo; import share.system.domain.vo.CreateOrderRequestVo;
import share.system.domain.vo.CreateOrderResponseVo; import share.system.domain.vo.CreateOrderResponseVo;
import share.system.domain.vo.WxPayJsResultVo; import share.system.domain.vo.WxPayJsResultVo;
...@@ -117,11 +120,14 @@ public class OrderPayServiceImpl implements OrderPayService { ...@@ -117,11 +120,14 @@ public class OrderPayServiceImpl implements OrderPayService {
private CreateOrderRequestVo getUnifiedorderVo(SOrder sOrder, String openid, String appId, String mchId, String signKey) { private CreateOrderRequestVo getUnifiedorderVo(SOrder sOrder, String openid, String appId, String mchId, String signKey) {
// 获取域名 // 获取域名
String apiDomain = Constants.CONFIG_KEY_API_URL; String apiDomain = Constants.CONFIG_KEY_API_URL;
AttachVo attachVo = new AttachVo(OrderTypeEnum.getEnumByCode(sOrder.getOrderType()).getValue(), sOrder.getConsumerId());
CreateOrderRequestVo vo = new CreateOrderRequestVo(); CreateOrderRequestVo vo = new CreateOrderRequestVo();
vo.setAppid(appId); vo.setAppid(appId);
vo.setMch_id(mchId); vo.setMch_id(mchId);
vo.setNonce_str(WxPayUtil.getNonceStr()); vo.setNonce_str(WxPayUtil.getNonceStr());
vo.setSign_type(PayConstants.WX_PAY_SIGN_TYPE_MD5); vo.setSign_type(PayConstants.WX_PAY_SIGN_TYPE_MD5);
vo.setAttach(JSONObject.toJSONString(attachVo));
vo.setOut_trade_no(BaseUtil.getOrderNo("wxNo")); vo.setOut_trade_no(BaseUtil.getOrderNo("wxNo"));
// 订单中使用的是BigDecimal,这里要转为Integer类型 // 订单中使用的是BigDecimal,这里要转为Integer类型
vo.setTotal_fee(sOrder.getPayPrice().multiply(BigDecimal.TEN).multiply(BigDecimal.TEN).intValue()); vo.setTotal_fee(sOrder.getPayPrice().multiply(BigDecimal.TEN).multiply(BigDecimal.TEN).intValue());
......
...@@ -269,6 +269,13 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper,SOrder> implemen ...@@ -269,6 +269,13 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper,SOrder> implemen
return getOne(lqw); return getOne(lqw);
} }
@Override
public SOrder getInfoByEntity(SOrder orderParam) {
LambdaQueryWrapper<SOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.setEntity(orderParam);
return getOne(lambdaQueryWrapper);
}
private BigDecimal computeTotalPrice(BigDecimal unitPrice, Date startTime, Date endTime){ private BigDecimal computeTotalPrice(BigDecimal unitPrice, Date startTime, Date endTime){
return DateUtils.differentHour(startTime,endTime).multiply(unitPrice); return DateUtils.differentHour(startTime,endTime).multiply(unitPrice);
} }
...@@ -298,10 +305,10 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper,SOrder> implemen ...@@ -298,10 +305,10 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper,SOrder> implemen
if (ObjectUtil.isNull(consumerCoupon) || !consumerCoupon.getCouponId().equals(user.getId())) { if (ObjectUtil.isNull(consumerCoupon) || !consumerCoupon.getCouponId().equals(user.getId())) {
throw new BaseException("优惠券领取记录不存在!"); throw new BaseException("优惠券领取记录不存在!");
} }
if (CouponStatusEnum.USED.getValue().compareTo(Integer.parseInt(consumerCoupon.getUseStatus())) == 0) { if (CouponStatusEnum.USED.getValue().compareTo(consumerCoupon.getUseStatus()) == 0) {
throw new BaseException("此优惠券已使用!"); throw new BaseException("此优惠券已使用!");
} }
if (CouponStatusEnum.EXPIRED.getValue().compareTo(Integer.parseInt(consumerCoupon.getUseStatus())) == 0) { if (CouponStatusEnum.EXPIRED.getValue().compareTo(consumerCoupon.getUseStatus()) == 0) {
throw new BaseException("此优惠券已失效!"); throw new BaseException("此优惠券已失效!");
} }
//判断是否在使用时间内 //判断是否在使用时间内
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment