'完成创建订单'

dev-discount
199901012 4 years ago
parent 8726456126
commit 2aea8d4fbc
  1. 36
      hai-cweb/src/main/java/com/cweb/config/SysConfig.java
  2. 22
      hai-cweb/src/main/java/com/cweb/controller/HighMerchantStoreController.java
  3. 176
      hai-cweb/src/main/java/com/cweb/controller/HighOrderController.java
  4. 136
      hai-cweb/src/main/java/com/cweb/controller/pay/OrderController.java
  5. 146
      hai-cweb/src/main/java/com/cweb/controller/pay/WechatPayController.java
  6. 7
      hai-cweb/src/main/resources/dev/config.properties
  7. 4
      hai-service/src/main/java/com/hai/common/exception/ErrorCode.java
  8. 81
      hai-service/src/main/java/com/hai/common/pay/WechatPayUtil.java
  9. 151
      hai-service/src/main/java/com/hai/common/pay/entity/AliPayReqInfo.java
  10. 43
      hai-service/src/main/java/com/hai/common/pay/entity/OrderType.java
  11. 205
      hai-service/src/main/java/com/hai/common/pay/entity/WeChatPayReqInfo.java
  12. 154
      hai-service/src/main/java/com/hai/common/pay/entity/WechatCallBackInfo.java
  13. 151
      hai-service/src/main/java/com/hai/common/pay/entity/WechatPayReturnParam.java
  14. 77
      hai-service/src/main/java/com/hai/common/pay/entity/WechatReturn.java
  15. 329
      hai-service/src/main/java/com/hai/common/pay/util/HttpReqUtil.java
  16. 73
      hai-service/src/main/java/com/hai/common/pay/util/IOUtil.java
  17. 55
      hai-service/src/main/java/com/hai/common/pay/util/MD5Util.java
  18. 24
      hai-service/src/main/java/com/hai/common/pay/util/MyX509TrustManager.java
  19. 358
      hai-service/src/main/java/com/hai/common/pay/util/SignatureUtil.java
  20. 274
      hai-service/src/main/java/com/hai/common/pay/util/XmlUtil.java
  21. 42
      hai-service/src/main/java/com/hai/common/pay/util/sdk/IWXPayDomain.java
  22. 689
      hai-service/src/main/java/com/hai/common/pay/util/sdk/WXPay.java
  23. 103
      hai-service/src/main/java/com/hai/common/pay/util/sdk/WXPayConfig.java
  24. 59
      hai-service/src/main/java/com/hai/common/pay/util/sdk/WXPayConstants.java
  25. 265
      hai-service/src/main/java/com/hai/common/pay/util/sdk/WXPayReport.java
  26. 258
      hai-service/src/main/java/com/hai/common/pay/util/sdk/WXPayRequest.java
  27. 295
      hai-service/src/main/java/com/hai/common/pay/util/sdk/WXPayUtil.java
  28. 30
      hai-service/src/main/java/com/hai/common/pay/util/sdk/WXPayXmlUtil.java
  29. 63
      hai-service/src/main/java/com/hai/common/utils/IDGenerator.java
  30. 25
      hai-service/src/main/java/com/hai/common/utils/MathUtils.java
  31. 16
      hai-service/src/main/java/com/hai/dao/HighChildOrderMapper.java
  32. 16
      hai-service/src/main/java/com/hai/dao/HighChildOrderSqlProvider.java
  33. 29
      hai-service/src/main/java/com/hai/dao/HighCouponMapper.java
  34. 44
      hai-service/src/main/java/com/hai/dao/HighCouponSqlProvider.java
  35. 32
      hai-service/src/main/java/com/hai/dao/HighOrderMapper.java
  36. 44
      hai-service/src/main/java/com/hai/dao/HighOrderSqlProvider.java
  37. 65
      hai-service/src/main/java/com/hai/dao/HighPayRecordMapper.java
  38. 48
      hai-service/src/main/java/com/hai/dao/HighPayRecordSqlProvider.java
  39. 13
      hai-service/src/main/java/com/hai/entity/HighChildOrder.java
  40. 41
      hai-service/src/main/java/com/hai/entity/HighChildOrderExample.java
  41. 52
      hai-service/src/main/java/com/hai/entity/HighCoupon.java
  42. 168
      hai-service/src/main/java/com/hai/entity/HighCouponExample.java
  43. 55
      hai-service/src/main/java/com/hai/entity/HighOrder.java
  44. 160
      hai-service/src/main/java/com/hai/entity/HighOrderExample.java
  45. 47
      hai-service/src/main/java/com/hai/entity/HighPayRecord.java
  46. 137
      hai-service/src/main/java/com/hai/entity/HighPayRecordExample.java
  47. 50
      hai-service/src/main/java/com/hai/service/HighOrderService.java
  48. 95
      hai-service/src/main/java/com/hai/service/impl/HighOrderServiceImpl.java
  49. 30
      hai-service/src/main/java/com/hai/service/pay/NotifyService.java
  50. 30
      hai-service/src/main/java/com/hai/service/pay/PayRecordService.java
  51. 21
      hai-service/src/main/java/com/hai/service/pay/PayService.java
  52. 39
      hai-service/src/main/java/com/hai/service/pay/impl/GoodsOrderServiceImpl.java
  53. 121
      hai-service/src/main/java/com/hai/service/pay/impl/NotifyServiceImpl.java
  54. 60
      hai-service/src/main/java/com/hai/service/pay/impl/PayRecordServiceImpl.java
  55. 23
      hai-service/src/main/java/com/hai/service/pay/impl/TestPayService.java

@ -13,6 +13,10 @@ public class SysConfig {
private String wxAppId;
private String wxAppSecret;
private String wxApiKey;
private String wxMchId;
private String wxUnifiedOrderUrl;
private String notifyUrl;
public String getFileUrl() {
return fileUrl;
@ -37,4 +41,36 @@ public class SysConfig {
public void setWxAppSecret(String wxAppSecret) {
this.wxAppSecret = wxAppSecret;
}
public String getWxApiKey() {
return wxApiKey;
}
public void setWxApiKey(String wxApiKey) {
this.wxApiKey = wxApiKey;
}
public String getWxMchId() {
return wxMchId;
}
public void setWxMchId(String wxMchId) {
this.wxMchId = wxMchId;
}
public String getWxUnifiedOrderUrl() {
return wxUnifiedOrderUrl;
}
public void setWxUnifiedOrderUrl(String wxUnifiedOrderUrl) {
this.wxUnifiedOrderUrl = wxUnifiedOrderUrl;
}
public String getNotifyUrl() {
return notifyUrl;
}
public void setNotifyUrl(String notifyUrl) {
this.notifyUrl = notifyUrl;
}
}

@ -12,10 +12,7 @@ import com.hai.common.utils.ResponseMsgUtil;
import com.hai.entity.HighCoupon;
import com.hai.entity.HighMerchant;
import com.hai.entity.HighMerchantStore;
import com.hai.model.HighCouponModel;
import com.hai.model.HighMerchantStoreModel;
import com.hai.model.ResponseData;
import com.hai.model.UserInfoModel;
import com.hai.model.*;
import com.hai.service.HighCouponService;
import com.hai.service.HighMerchantService;
import com.hai.service.HighMerchantStoreService;
@ -33,6 +30,7 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@ -79,7 +77,9 @@ public class HighMerchantStoreController {
@RequestMapping(value="/getStoreListByCoupon",method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "根据卡卷查询门店列表")
public ResponseData getStoreListByCoupon(@RequestParam(name = "couponId", required = true) Long couponId) {
public ResponseData getStoreListByCoupon(@RequestParam(name = "couponId", required = true) Long couponId,
@RequestParam(name = "pageNum", required = true) Integer pageNum,
@RequestParam(name = "pageSize", required = true) Integer pageSize) {
try {
HighCouponModel coupon = highCouponService.getCouponById(couponId);
@ -88,7 +88,17 @@ public class HighMerchantStoreController {
}
Map<String,Object> map = new HashMap<>();
map.put("merchantId", coupon.getMerchantId());
return ResponseMsgUtil.success(highMerchantStoreService.getMerchantStoreList(map));
PageHelper.startPage(pageNum, pageSize);
List<HighMerchantStore> storeList = highMerchantStoreService.getMerchantStoreList(map);
if (storeList != null && storeList.size() > 0) {
HighMerchantModel merchant = highMerchantService.getMerchantById(coupon.getMerchantId());
for (HighMerchantStore store : storeList) {
store.setExt1(merchant.getMerchantLogo());
}
}
return ResponseMsgUtil.success(storeList);
} catch (Exception e) {
log.error("HighMerchantStoreController -> getStoreListByCoupon() error!",e);

@ -0,0 +1,176 @@
package com.cweb.controller;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hai.common.exception.ErrorCode;
import com.hai.common.exception.ErrorHelp;
import com.hai.common.exception.SysCode;
import com.hai.common.security.SessionObject;
import com.hai.common.security.UserCenter;
import com.hai.common.utils.DateUtil;
import com.hai.common.utils.IDGenerator;
import com.hai.common.utils.ResponseMsgUtil;
import com.hai.entity.HighChildOrder;
import com.hai.entity.HighCoupon;
import com.hai.entity.HighCouponCode;
import com.hai.entity.HighOrder;
import com.hai.model.HighCouponModel;
import com.hai.model.HighUserModel;
import com.hai.model.ResponseData;
import com.hai.model.UserInfoModel;
import com.hai.service.HighCouponCodeService;
import com.hai.service.HighCouponService;
import com.hai.service.HighOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @Auther: 胡锐
* @Description:
* @Date: 2021/3/26 23:08
*/
@Controller
@RequestMapping(value = "/highOrder")
@Api(value = "订单接口")
public class HighOrderController {
private static Logger log = LoggerFactory.getLogger(HighMerchantStoreController.class);
@Autowired
private UserCenter userCenter;
@Resource
private HighOrderService highOrderService;
@Resource
private HighCouponService highCouponService;
@Resource
private HighCouponCodeService highCouponCodeService;
@RequestMapping(value="/addOrder",method = RequestMethod.POST)
@ResponseBody
@ApiOperation(value = "增加订单")
public ResponseData addOrder(@RequestBody HighOrder highOrder, HttpServletRequest request) {
try {
// 用户
SessionObject sessionObject = userCenter.getSessionObject(request);
HighUserModel userInfoModel = (HighUserModel) sessionObject.getObject();
if (highOrder.getPayModel() == null
|| highOrder.getPayType() == null
|| highOrder.getHighChildOrderList() == null
|| highOrder.getHighChildOrderList().size() == 0
) {
log.error("HighOrderController --> addOrder() error!", "参数错误");
throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
}
BigDecimal totalPrice = new BigDecimal("0");
for (HighChildOrder childOrder : highOrder.getHighChildOrderList()) {
if (childOrder.getGoodsType() == null || childOrder.getGoodsId() == null || childOrder.getSaleCount() == null) {
log.error("HighOrderController --> addOrder() error!", "参数错误");
throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
}
// 商品类型 1:卡卷
if (childOrder.getGoodsType() == 1) {
// 查询卡卷信息
HighCouponModel coupon = highCouponService.getCouponById(childOrder.getGoodsId());
if (coupon == null) {
log.error("HighOrderController --> addOrder() error!", "未找到卡卷信息");
throw ErrorHelp.genException(SysCode.System, ErrorCode.NOT_FOUND_COUPON, "");
}
if (highCouponCodeService.getStockCountByCoupon(coupon.getId()) <= 0) {
log.error("HighOrderController --> addOrder() error!", "卡卷库存数量不足");
throw ErrorHelp.genException(SysCode.System, ErrorCode.COUPON_STOCK_INSUFFICIENT, "");
}
childOrder.setGoodsName(coupon.getCouponName());
childOrder.setGoodsImg(coupon.getCouponImg());
childOrder.setGoodsSpecName("默认");
childOrder.setGoodsPrice(coupon.getDiscountPrice());
childOrder.setTotalPrice(childOrder.getGoodsPrice().multiply(new BigDecimal(childOrder.getSaleCount().toString())));
childOrder.setGiveawayType(false); // 是否是赠品 0:否 1:是
childOrder.setChildOrdeStatus(1); // 1 待支付 2 已支付 3.已完成 4. 已退款 5.已取消
childOrder.setPraiseStatus(0);
}
// 累计订单价格
totalPrice.add(childOrder.getTotalPrice());
}
highOrder.setOrderNo("HF" + DateUtil.date2String(new Date(),"yyyyMMddHHmmss") + IDGenerator.nextId(5));
highOrder.setMemId(userInfoModel.getHighUser().getId());
highOrder.setMemName(userInfoModel.getHighUser().getName());
highOrder.setTotalPrice(totalPrice);
highOrder.setPayPrice(totalPrice);
highOrder.setCreateTime(new Date());
highOrder.setOrderStatus(1);
highOrderService.insertOrder(highOrder);
return ResponseMsgUtil.success("操作成功");
} catch (Exception e) {
log.error("HighOrderController -> addOrder() error!",e);
return ResponseMsgUtil.exception(e);
}
}
@RequestMapping(value = "/getOrderById", method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "根据id查询订单详情")
public ResponseData getOrderById(@RequestParam(name = "orderId", required = true) Long orderId) {
try {
return ResponseMsgUtil.success(highOrderService.getOrderById(orderId));
} catch (Exception e) {
log.error("HighOrderController --> getOrderById() error!", e);
return ResponseMsgUtil.exception(e);
}
}
@RequestMapping(value = "/getUserOrderList", method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "获取用户订单")
public ResponseData getUserOrderList(@RequestParam(name = "pageNum", required = true) Integer pageNum,
@RequestParam(name = "pageSize", required = true) Integer pageSize,
HttpServletRequest request) {
try {
// 用户
SessionObject sessionObject = userCenter.getSessionObject(request);
HighUserModel userInfoModel = (HighUserModel) sessionObject.getObject();
Map<String,Object> map = new HashMap<>();
map.put("memId", userInfoModel.getHighUser().getId());
PageHelper.startPage(pageNum,pageSize);
return ResponseMsgUtil.success(new PageInfo<>(highCouponService.getCouponList(map)));
} catch (Exception e) {
log.error("HighOrderController --> getUserOrderList() error!", e);
return ResponseMsgUtil.exception(e);
}
}
}

@ -0,0 +1,136 @@
package com.cweb.controller.pay;
import com.alibaba.fastjson.JSONObject;
import com.cweb.config.SysConst;
import com.hai.common.exception.ErrorCode;
import com.hai.common.exception.ErrorHelp;
import com.hai.common.exception.SysCode;
import com.hai.common.pay.WechatPayUtil;
import com.hai.common.pay.entity.OrderType;
import com.hai.common.pay.entity.WeChatPayReqInfo;
import com.hai.common.pay.util.MD5Util;
import com.hai.common.security.SessionObject;
import com.hai.common.security.UserCenter;
import com.hai.common.utils.MathUtils;
import com.hai.common.utils.ResponseMsgUtil;
import com.hai.entity.HighOrder;
import com.hai.model.ResponseData;
import com.hai.model.UserInfoModel;
import com.hai.service.HighOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
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.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.concurrent.ThreadLocalRandom;
/**
*
* @Title:
* @Description: 对订单的操作
* @author: 魏真峰
* @param:
* @return:
* @throws
*/
@Controller
@RequestMapping("/order")
@Api(value = "对订单的操作")
public class OrderController {
private static Logger log = LoggerFactory.getLogger(OrderController.class);
@Autowired
private UserCenter userCenter;
@Resource
private WechatPayUtil wechatPayUtil;
@Resource
private HighOrderService highOrderService;
/**
*
* @Title: orderToPay
* @Description: 订单支付发起支付
* @author: 魏真峰
* @param: [pageNum, pageSize]
* @return: com.shinwoten.haj.common.model.ResponseData
* @throws
*/
@RequestMapping(value="/orderToPay",method = RequestMethod.POST)
@ResponseBody
@ApiOperation(value = "订单支付发起支付")
public ResponseData orderToPay(@RequestBody String reqBodyStr,
HttpServletRequest request) {
try {
if (StringUtils.isBlank(reqBodyStr)) {
log.error("orderToPay error!", "参数错误");
throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
}
JSONObject jsonObject = JSONObject.parseObject(reqBodyStr);
Long orderId = jsonObject.getLong("orderId");
String openId = jsonObject.getString("openId"); // openId
if ( orderId == null || StringUtils.isBlank(openId)) {
log.error("orderToPay error!", "参数错误");
throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
}
HighOrder order = highOrderService.getOrderById(orderId);
if(order == null) {
log.error("OrderController --> orderToPay() ERROR", "未找到订单信息");
throw ErrorHelp.genException(SysCode.System, ErrorCode.NOT_FOUND_ORDER, "");
}
//校验订单状态 订单状态:1 待支付 2 已支付 3.已完成 4. 已退款 5.已取消
if(order.getOrderStatus() != 1) {
log.error("OrderController --> orderToPay() ERROR", "订单不处于待支付状态");
throw ErrorHelp.genException(SysCode.System, ErrorCode.ORDER_NO_STAY_PAY, "");
}
Map<String,Object> map = new HashMap<>();
map.put("orderNo", order.getOrderNo());
map.put("payPrice", order.getPayPrice());
map.put("body","购买卡券");
map.put("subject","购买卡券");
//微信支付
String nonce_str = MD5Util.MD5Encode(String.valueOf(ThreadLocalRandom.current().nextInt(10000)), "UTF-8");
int total_fee = MathUtils.objectConvertBigDecimal(map.get("payPrice")).multiply(new BigDecimal("100")).intValue();
WeChatPayReqInfo weChatPayReqInfo = new WeChatPayReqInfo();
weChatPayReqInfo.setAppid(SysConst.getSysConfig().getWxAppId()); //公众号id
weChatPayReqInfo.setOpenid(openId);
weChatPayReqInfo.setMch_id(SysConst.getSysConfig().getWxMchId()); //商户号
weChatPayReqInfo.setNonce_str(nonce_str); //随机字符串
weChatPayReqInfo.setBody(map.get("body").toString()); //商品描述
weChatPayReqInfo.setOut_trade_no(map.get("orderNo").toString()); //商户订单号
weChatPayReqInfo.setTotal_fee(total_fee); //总金额
weChatPayReqInfo.setSpbill_create_ip("139.159.177.244"); //终端ip
weChatPayReqInfo.setNotify_url(SysConst.getSysConfig().getNotifyUrl()); //通知url
weChatPayReqInfo.setTrade_type("JSAPI"); //交易类型
// weChatPayReqInfo.setAttach(map.get("orderScene").toString()); //附加数据,区分订单类型
Map<String,String> payMap = new HashMap<>();
payMap.put("app_id",SysConst.getSysConfig().getWxAppId());
payMap.put("api_key",SysConst.getSysConfig().getWxApiKey());
payMap.put("unified_order_url",SysConst.getSysConfig().getWxUnifiedOrderUrl());
SortedMap<Object, Object> sortedMap = wechatPayUtil.goWechatPay(weChatPayReqInfo,payMap);
return ResponseMsgUtil.success(sortedMap);
} catch (Exception e) {
log.error("orderToPay error!", e);
return ResponseMsgUtil.exception(e);
}
}
}

@ -0,0 +1,146 @@
package com.cweb.controller.pay;
import com.cweb.config.SysConst;
import com.hai.common.pay.WechatPayUtil;
import com.hai.common.pay.util.IOUtil;
import com.hai.common.pay.util.SignatureUtil;
import com.hai.common.pay.util.XmlUtil;
import com.hai.service.pay.NotifyService;
import com.hai.service.pay.PayRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.util.SortedMap;
@Controller
@RequestMapping(value = "/wechatpay")
@Api(value = "微信支付")
public class WechatPayController {
private static Logger log = LoggerFactory.getLogger(WechatPayController.class);
@Resource
private NotifyService notifyService;
@Resource
private PayRecordService payRecordService;
@Resource
private WechatPayUtil wechatPayUtil;
@RequestMapping(value = "/notify", method = RequestMethod.POST)
@ApiOperation(value = "微信支付 -> 异步回调")
public void wechatNotify(HttpServletRequest request, HttpServletResponse response) {
try {
log.info("微信支付 -> 异步通知:处理开始");
String resXml = ""; // 反馈给微信服务器
String notifyXml = null; // 微信支付系统发送的数据(<![CDATA[product_001]]>格式)
notifyXml = IOUtil.inputStreamToString(request.getInputStream(), "UTF-8");
if (SignatureUtil.reCheckIsSignValidFromWeiXin(notifyXml, SysConst.getSysConfig().getWxApiKey(), "UTF-8")) {
log.info("微信支付系统发送的数据:" + notifyXml);
SortedMap<String, String> map = XmlUtil.parseXmlToTreeMap(notifyXml, "UTF-8");
resXml = notifyService.wechatNotify(map);
} else {
log.error("微信支付 -> 异步通知:验签失败");
log.error("apiKey:" + SysConst.getSysConfig().getWxApiKey());
log.error("返回信息:" + notifyXml);
resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
+ "<return_msg><![CDATA[签名验证错误]]></return_msg>" + "</xml> ";
}
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
out.write(resXml.getBytes());
out.flush();
out.close();
log.info("微信支付 -> 异步通知:处理完成");
} catch (Exception e) {
log.error("WechatPayController --> wechatNotify() error!", e);
}
}
/*@RequestMapping(value = "/testCreateOrder", method = RequestMethod.GET)
@ApiOperation(value = "微信测试 创建支付信息(发版时注释此接口)")
@ResponseBody
public SortedMap<Object, Object> testCreateOrder(@RequestParam(value = "subject", required = true) String subject,
@RequestParam(value = "orderNo", required = true) String orderNo,
@RequestParam(value = "totalPrice", required = true) Integer totalPrice,
HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
try {
String nonce_str = MD5Util.MD5Encode(String.valueOf(ThreadLocalRandom.current().nextInt(10000)), "UTF-8");
WeChatPayReqInfo weChatPayReqInfo = new WeChatPayReqInfo();
weChatPayReqInfo.setAppid(wechatConfig.getApp_id()); //公众号id
weChatPayReqInfo.setMch_id(wechatConfig.getMch_id()); //商户号
weChatPayReqInfo.setNonce_str(nonce_str); //随机字符串
weChatPayReqInfo.setBody(subject); //商品描述
weChatPayReqInfo.setOut_trade_no(orderNo); //商户订单号
weChatPayReqInfo.setTotal_fee(totalPrice); //总
weChatPayReqInfo.setSpbill_create_ip("182.43.154.4"); //终端ip
weChatPayReqInfo.setNotify_url(wechatConfig.getNotify_url()); //通知url
//weChatPayReqInfo.setTrade_type("APP"); //交易类型
weChatPayReqInfo.setTrade_type("JSAPI");
//weChatPayReqInfo.setOpenid("");
weChatPayReqInfo.setAttach("Test");
*//** 获取沙箱key start *//*
String sandboxKey = GetSignKey();
*//** 获取沙箱key end *//*
String sign = SignatureUtil.createSign(weChatPayReqInfo, sandboxKey, "UTF-8"); // 测试 todo del
weChatPayReqInfo.setSign(sign);
String unifiedXmL = XmlUtil.toSplitXml(weChatPayReqInfo);
String unifiedOrderResultXmL = HttpReqUtil.HttpsDefaultExecute("POST", wechatConfig.getUnified_order_url(), null, unifiedXmL, null);
log.error("支付信息:" + unifiedOrderResultXmL);
// 签名校验
SortedMap<Object,Object> sortedMap = null;
// 组装支付参数
WechatCallBackInfo wechatCallBackInfo = XmlUtil.getObjectFromXML(unifiedOrderResultXmL, WechatCallBackInfo.class);
Long timeStamp = System.currentTimeMillis()/1000;
sortedMap = new TreeMap<>();
sortedMap.put("appid",wechatConfig.getApp_id());
sortedMap.put("partnerid",wechatConfig.getMch_id());
sortedMap.put("prepayid",wechatCallBackInfo.getPrepay_id());
sortedMap.put("noncestr",wechatCallBackInfo.getNonce_str());
sortedMap.put("timestamp",timeStamp);
sortedMap.put("package","Sign=WXPay");
String secondSign = SignatureUtil.createSign(sortedMap, wechatConfig.getApi_key(), "UTF-8");
sortedMap.put("sign",secondSign);
return sortedMap;
} catch (Exception e) {
log.error("AlipayTest -> createOrder:生成订单错误", e);
}
return null;
}*/
/**
* @desc 获取沙箱key
*/
/*public String GetSignKey() throws Exception {
String nonce_str = WXPayUtil.generateNonceStr(); //生成随机字符
Map<String, String> param = new HashMap<>();
param.put("mch_id", wechatConfig.getMch_id()); //需要真实商户号
param.put("nonce_str", nonce_str); //随机字符
String sign = WXPayUtil.generateSignature(param, wechatConfig.getApi_key(), WXPayConstants.SignType.MD5); //通过SDK生成签名其中API_KEY为商户对应的真实密钥
param.put("sign", sign);
String xml = WXPayUtil.mapToXml(param); //将map转换为xml格式
String url = "https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey"; //沙箱密钥获取api
String signKey = HttpUtil.post(url, xml);
System.out.println("signkey+"+signKey);
Map<String, String> param1 = new HashMap<String, String>();
param1 = WXPayUtil.xmlToMap(signKey.toString());
String key = param1.get("sandbox_signkey");
return key;
}*/
}

@ -1,8 +1,11 @@
# 微信配置
wxAppId=wx8d49e2f83025229d
wxAppSecret=d8d6dcaef77d3b659258a01b5ddba5df
mch_id=1603942866
api_key=HfkjWxPayHaiShengGuang0123456789
wxApiKey=HfkjWxPayHaiShengGuang0123456789
wxMchId=1603942866
wxUnifiedOrderUrl=https://api.mch.weixin.qq.com/pay/unifiedorder
notifyUrl=https://hsgcs.dctpay.com//crest/wechatpay/notify
fileUrl=/home/project/hsg/filesystem
cmsPath=/home/project/hsg/filesystem/cmsPath

@ -96,6 +96,10 @@ public enum ErrorCode {
NEED_WRITE_DISCOUNT_PRICE("2124","请填写正确的折扣数,折扣数范围【0】 ~ 【10】"),
DISCOUNT_PRICE_RANGE("2125","请输入正确的"),
TEL_EXISTED("2126","联系方式已被使用"),
ORDER_TYPE_ERROR("2127","订单类型错误"),
COUPON_STOCK_INSUFFICIENT("2118","卡卷库存数量不足"),
NOT_FOUND_ORDER("2119","未找到订单信息"),
ORDER_NO_STAY_PAY("2120","订单不处于待支付状态"),
STATUS_ERROR("3000","状态错误"),
ADD_DATA_ERROR("3001","增加数据失败"),

@ -0,0 +1,81 @@
package com.hai.common.pay;
import com.hai.common.pay.entity.WeChatPayReqInfo;
import com.hai.common.pay.entity.WechatCallBackInfo;
import com.hai.common.pay.util.HttpReqUtil;
import com.hai.common.pay.util.SignatureUtil;
import com.hai.common.pay.util.XmlUtil;
import com.hai.entity.HighPayRecord;
import com.hai.service.pay.PayRecordService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
@Component
public class WechatPayUtil {
private static Logger log = LoggerFactory.getLogger(WechatPayUtil.class);
@Resource
private PayRecordService payRecordService;
/**
* @throws
* @Title: goAlipay
* @Description: 微信支付请求体
* @author: 魏真峰
* @param: [orderId]
* @return: java.lang.String
*/
@RequestMapping("/goWechatPay")
@ResponseBody
public SortedMap<Object,Object> goWechatPay(WeChatPayReqInfo weChatPayReqInfo, Map<String,String> map) throws Exception{
log.info("微信支付 -> 组装支付参数:开始");
String sign = SignatureUtil.createSign(weChatPayReqInfo, map.get("api_key"), "UTF-8");
weChatPayReqInfo.setSign(sign);
String unifiedXmL = XmlUtil.toSplitXml(weChatPayReqInfo);
String unifiedOrderResultXmL = HttpReqUtil.HttpsDefaultExecute("POST", map.get("unified_order_url"), null, unifiedXmL, null);
// 签名校验
SortedMap<Object,Object> sortedMap = null;
if (SignatureUtil.checkIsSignValidFromWeiXin(unifiedOrderResultXmL, map.get("api_key"), "UTF-8")) {
// 组装支付参数
WechatCallBackInfo wechatCallBackInfo = XmlUtil.getObjectFromXML(unifiedOrderResultXmL, WechatCallBackInfo.class);
Long timeStamp = System.currentTimeMillis()/1000;
sortedMap = new TreeMap<>();
sortedMap.put("appId",map.get("app_id"));
// sortedMap.put("partnerid",SysConst.getSysConfig().getMch_id());
// sortedMap.put("prepayid",wechatCallBackInfo.getPrepay_id());
sortedMap.put("nonceStr",wechatCallBackInfo.getNonce_str());
sortedMap.put("timeStamp",timeStamp.toString());
sortedMap.put("signType","MD5");
sortedMap.put("package", "prepay_id=" + wechatCallBackInfo.getPrepay_id());
String secondSign = SignatureUtil.createSign(sortedMap, map.get("api_key"), "UTF-8");
sortedMap.put("sign",secondSign);
// 将支付请求存入支付纪录
HighPayRecord payRecord = new HighPayRecord();
payRecord.setBodyInfo(unifiedXmL);
payRecord.setResType(1);
payRecord.setPayType(2);
payRecord.setPayMoney(new BigDecimal(weChatPayReqInfo.getTotal_fee()/100D));
payRecordService.addPayRecord(payRecord);
log.info("微信支付 -> 组装支付参数:完成");
} else {
log.error("微信支付 -> 组装支付参数:支付信息错误");
log.error("错误信息:" + unifiedOrderResultXmL);
}
return sortedMap;
}
}

@ -0,0 +1,151 @@
package com.hai.common.pay.entity;
/**
* @Description: 支付宝統一下单参数
*/
public class AliPayReqInfo {
private String timeout_express; //该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m。 90m
private String total_amount; //必填。订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000] 9.00
private String seller_id; //收款支付宝用户ID。 如果该值为空,则默认为商户签约账号对应的支付宝用户ID 2088102147948060
private String product_code; //销售产品码,商家和支付宝签约的产品码 QUICK_MSECURITY_PAY
private String body; //对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。 Iphone6 16G
private String subject; //必填。商品的标题/交易标题/订单标题/订单关键字等。 大乐透
private String out_trade_no; //必填。商户网站唯一订单号 70501111111S001111119
private String time_expire; //绝对超时时间,格式为yyyy-MM-dd HH:mm。 2016-12-31 10:05
private String goods_type; //商品主类型 :0-虚拟类商品,1-实物类商品 0
private String promo_params; //优惠参数
private String passback_params; //必填。公用回传参数,如果请求时传递了该参数,则返回给商户时会回传该参数。支付宝只会在同步返回(包括跳转回商户网站)和异步通知时将该参数原样返回。本参数必须进行UrlEncode之后才可以发送给支付宝。 merchantBizType%3d3C%26merchantBizNo%3d2016010101111
private String enable_pay_channels; //可用渠道,用户只能在指定渠道范围内支付
private String store_id; //商户门店编号 NJ_001
private String specified_channel; //指定渠道,目前仅支持传入pcredit
private String disable_pay_channels; //禁用渠道,用户不可用指定渠道支付
private String business_params; //商户传入业务信息,具体值要和支付宝约定,应用于安全,营销等参数直传场景,格式为json格式
public String getTimeout_express() {
return timeout_express;
}
public void setTimeout_express(String timeout_express) {
this.timeout_express = timeout_express;
}
public String getTotal_amount() {
return total_amount;
}
public void setTotal_amount(String total_amount) {
this.total_amount = total_amount;
}
public String getSeller_id() {
return seller_id;
}
public void setSeller_id(String seller_id) {
this.seller_id = seller_id;
}
public String getProduct_code() {
return product_code;
}
public void setProduct_code(String product_code) {
this.product_code = product_code;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getOut_trade_no() {
return out_trade_no;
}
public void setOut_trade_no(String out_trade_no) {
this.out_trade_no = out_trade_no;
}
public String getTime_expire() {
return time_expire;
}
public void setTime_expire(String time_expire) {
this.time_expire = time_expire;
}
public String getGoods_type() {
return goods_type;
}
public void setGoods_type(String goods_type) {
this.goods_type = goods_type;
}
public String getPromo_params() {
return promo_params;
}
public void setPromo_params(String promo_params) {
this.promo_params = promo_params;
}
public String getPassback_params() {
return passback_params;
}
public void setPassback_params(String passback_params) {
this.passback_params = passback_params;
}
public String getEnable_pay_channels() {
return enable_pay_channels;
}
public void setEnable_pay_channels(String enable_pay_channels) {
this.enable_pay_channels = enable_pay_channels;
}
public String getStore_id() {
return store_id;
}
public void setStore_id(String store_id) {
this.store_id = store_id;
}
public String getSpecified_channel() {
return specified_channel;
}
public void setSpecified_channel(String specified_channel) {
this.specified_channel = specified_channel;
}
public String getDisable_pay_channels() {
return disable_pay_channels;
}
public void setDisable_pay_channels(String disable_pay_channels) {
this.disable_pay_channels = disable_pay_channels;
}
public String getBusiness_params() {
return business_params;
}
public void setBusiness_params(String business_params) {
this.business_params = business_params;
}
}

@ -0,0 +1,43 @@
package com.hai.common.pay.entity;
public enum OrderType {
// 建议将支付频率高的模块放在前面
GOODS_ORDER("GOODS_ORDER", "goodsOrderService", "购买商品"),
GOLD("GOLD", "", "金币充值"),
TEST("TEST", "testPayService", "支付测试")
;
private String moduleCode;
private String service;
private String moduleName;
private OrderType(String moduleCode, String service, String moduleName) {
this.moduleCode = moduleCode;
this.service = service;
this.moduleName = moduleName;
}
public String getModuleCode() {
return moduleCode;
}
private void setModuleCode(String moduleCode) {
this.moduleCode = moduleCode;
}
public String getService() {
return service;
}
private void setService(String service) {
this.service = service;
}
public String getModuleName() {
return moduleName;
}
private void setModuleName(String moduleName) {
this.moduleName = moduleName;
}
}

@ -0,0 +1,205 @@
package com.hai.common.pay.entity;
import java.io.Serializable;
/**
* @Description: 微信統一下单参数
*/
public class WeChatPayReqInfo implements Serializable {
private static final long serialVersionUID = -7642108447915413137L;
private String appid; // 公众号id 必填
private String mch_id; // 商户号 必填
private String nonce_str; // 随机字符串 必填
private String sign; // 签名 必填
private String device_info; // 设备号 可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB"
private String body; // 商品描述 必填
private String detail; // 商品详情
private String attach; // 附加数据
private String out_trade_no; // 商户订单号 必填
private String fee_type; // 货币类型 默认为人民币CNY
private Integer total_fee; // 总金额 传入int型的数据 必填
private String spbill_create_ip; // 终端ip 必填
private String time_start; // 交易起始时间 订单生成时间
private String time_expire; // 交易结束时间 订单失效时间
private String goods_tag; // 订单优惠标记
private String notify_url; // 通知url 必填
private String trade_type; // 交易类型 JSAPI,NATIVE,APP 必填
private String product_id; //商品id trade_type=NATIVE时(即扫码支付),此参数必传
private String limit_pay; // 指定支付方式 no_credit--可限制用户不能使用信用卡支付
private String openid; // 用户标识(trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识)
private String scene_info; // 该字段用于统一下单时上报场景信息,目前支持上报实际门店信息 格式{"store_id":// "SZT10000", "store_name":"腾讯大厦腾大餐厅"}
public static long getSerialVersionUID() {
return serialVersionUID;
}
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getMch_id() {
return mch_id;
}
public void setMch_id(String mch_id) {
this.mch_id = mch_id;
}
public String getNonce_str() {
return nonce_str;
}
public void setNonce_str(String nonce_str) {
this.nonce_str = nonce_str;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getDevice_info() {
return device_info;
}
public void setDevice_info(String device_info) {
this.device_info = device_info;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
public String getAttach() {
return attach;
}
public void setAttach(String attach) {
this.attach = attach;
}
public String getOut_trade_no() {
return out_trade_no;
}
public void setOut_trade_no(String out_trade_no) {
this.out_trade_no = out_trade_no;
}
public String getFee_type() {
return fee_type;
}
public void setFee_type(String fee_type) {
this.fee_type = fee_type;
}
public Integer getTotal_fee() {
return total_fee;
}
public void setTotal_fee(Integer total_fee) {
this.total_fee = total_fee;
}
public String getSpbill_create_ip() {
return spbill_create_ip;
}
public void setSpbill_create_ip(String spbill_create_ip) {
this.spbill_create_ip = spbill_create_ip;
}
public String getTime_start() {
return time_start;
}
public void setTime_start(String time_start) {
this.time_start = time_start;
}
public String getTime_expire() {
return time_expire;
}
public void setTime_expire(String time_expire) {
this.time_expire = time_expire;
}
public String getGoods_tag() {
return goods_tag;
}
public void setGoods_tag(String goods_tag) {
this.goods_tag = goods_tag;
}
public String getNotify_url() {
return notify_url;
}
public void setNotify_url(String notify_url) {
this.notify_url = notify_url;
}
public String getTrade_type() {
return trade_type;
}
public void setTrade_type(String trade_type) {
this.trade_type = trade_type;
}
public String getProduct_id() {
return product_id;
}
public void setProduct_id(String product_id) {
this.product_id = product_id;
}
public String getLimit_pay() {
return limit_pay;
}
public void setLimit_pay(String limit_pay) {
this.limit_pay = limit_pay;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getScene_info() {
return scene_info;
}
public void setScene_info(String scene_info) {
this.scene_info = scene_info;
}
}

@ -0,0 +1,154 @@
package com.hai.common.pay.entity;
/**
* 统一下单返回结果
* @author phil
* @data 2017年6月27日
*
*/
public class WechatCallBackInfo {
private static final long serialVersionUID = 9030465964635155064L;
private String appid; // 公众号id
private String mch_id; // 商户号
private String nonce_str; // 随机字符串
private String sign; // 签名
private String return_code; // 返回状态码
private String return_msg; // 返回信息
// 以下字段在return_code为SUCCESS的时候有返回(包括父类)
private String device_info; // 设备号
private String result_code; // 业务结果 SUCCESS/FAIL
private String err_code; // 错误代码
private String err_code_des; // 错误代码描述
// 以下字段在return_code 和result_code都为SUCCESS的时候有返回
private String trade_type; // 交易类型
private String prepay_id; // 预支付交易会话标识,有效期为2小时
private String code_url; // 二维码链接
public static long getSerialVersionUID() {
return serialVersionUID;
}
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getMch_id() {
return mch_id;
}
public void setMch_id(String mch_id) {
this.mch_id = mch_id;
}
public String getNonce_str() {
return nonce_str;
}
public void setNonce_str(String nonce_str) {
this.nonce_str = nonce_str;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getReturn_code() {
return return_code;
}
public void setReturn_code(String return_code) {
this.return_code = return_code;
}
public String getReturn_msg() {
return return_msg;
}
public void setReturn_msg(String return_msg) {
this.return_msg = return_msg;
}
public String getDevice_info() {
return device_info;
}
public void setDevice_info(String device_info) {
this.device_info = device_info;
}
public String getResult_code() {
return result_code;
}
public void setResult_code(String result_code) {
this.result_code = result_code;
}
public String getErr_code() {
return err_code;
}
public void setErr_code(String err_code) {
this.err_code = err_code;
}
public String getErr_code_des() {
return err_code_des;
}
public void setErr_code_des(String err_code_des) {
this.err_code_des = err_code_des;
}
public String getTrade_type() {
return trade_type;
}
public void setTrade_type(String trade_type) {
this.trade_type = trade_type;
}
public String getPrepay_id() {
return prepay_id;
}
public void setPrepay_id(String prepay_id) {
this.prepay_id = prepay_id;
}
public String getCode_url() {
return code_url;
}
public void setCode_url(String code_url) {
this.code_url = code_url;
}
@Override
public String toString() {
return "WechatCallBackInfo{" +
"appid='" + appid + '\'' +
", mch_id='" + mch_id + '\'' +
", nonce_str='" + nonce_str + '\'' +
", sign='" + sign + '\'' +
", return_code='" + return_code + '\'' +
", return_msg='" + return_msg + '\'' +
", device_info='" + device_info + '\'' +
", result_code='" + result_code + '\'' +
", err_code='" + err_code + '\'' +
", err_code_des='" + err_code_des + '\'' +
", trade_type='" + trade_type + '\'' +
", prepay_id='" + prepay_id + '\'' +
", code_url='" + code_url + '\'' +
'}';
}
}

@ -0,0 +1,151 @@
package com.hai.common.pay.entity;
/**
*
* @Description: 微信支付异步回调参数
*/
public class WechatPayReturnParam {
private String appid; //是 String(32) wx8888888888888888 微信开放平台审核通过的应用APPID
private String attach; //否 String(128) 123456 商家数据包,原样返回
private String bank_type; //是 String(16) CMC 银行类型,采用字符串类型的银行标识,银行类型见银行列表
private String cash_fee; //是 Int 100 现金支付金额订单现金支付金额,详见支付金额
private String fee_type; //否 String(8) CNY 货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
private String is_subscribe; //是 String(1) Y 用户是否关注公众账号,Y-关注,N-未关注
private String mch_id; //是 String(32) 1900000109 微信支付分配的商户号
private String nonce_str; //是 String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,不长于32位
private String openid; //是 String(128) wxd930ea5d5a258f4f 用户在商户appid下的唯一标识
private String out_trade_no; //是 String(32) 1212321211201407033568112322 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。
private String result_code; //是 String(16) SUCCESS SUCCESS/FAIL
private String return_code;
private String time_end; //是 String(14) 20141030133525 支付完成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规
private String total_fee; //是 Int 100 订单总金额,单位为分
private String trade_type; //是 String(16) APP APP
private String transaction_id; //微信支付订单号
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getAttach() {
return attach;
}
public void setAttach(String attach) {
this.attach = attach;
}
public String getBank_type() {
return bank_type;
}
public void setBank_type(String bank_type) {
this.bank_type = bank_type;
}
public String getCash_fee() {
return cash_fee;
}
public void setCash_fee(String cash_fee) {
this.cash_fee = cash_fee;
}
public String getFee_type() {
return fee_type;
}
public void setFee_type(String fee_type) {
this.fee_type = fee_type;
}
public String getIs_subscribe() {
return is_subscribe;
}
public void setIs_subscribe(String is_subscribe) {
this.is_subscribe = is_subscribe;
}
public String getMch_id() {
return mch_id;
}
public void setMch_id(String mch_id) {
this.mch_id = mch_id;
}
public String getNonce_str() {
return nonce_str;
}
public void setNonce_str(String nonce_str) {
this.nonce_str = nonce_str;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getOut_trade_no() {
return out_trade_no;
}
public void setOut_trade_no(String out_trade_no) {
this.out_trade_no = out_trade_no;
}
public String getResult_code() {
return result_code;
}
public void setResult_code(String result_code) {
this.result_code = result_code;
}
public String getReturn_code() {
return return_code;
}
public void setReturn_code(String return_code) {
this.return_code = return_code;
}
public String getTime_end() {
return time_end;
}
public void setTime_end(String time_end) {
this.time_end = time_end;
}
public String getTotal_fee() {
return total_fee;
}
public void setTotal_fee(String total_fee) {
this.total_fee = total_fee;
}
public String getTrade_type() {
return trade_type;
}
public void setTrade_type(String trade_type) {
this.trade_type = trade_type;
}
public String getTransaction_id() {
return transaction_id;
}
public void setTransaction_id(String transaction_id) {
this.transaction_id = transaction_id;
}
}

@ -0,0 +1,77 @@
package com.hai.common.pay.entity;
public class WechatReturn {
private String appid;
private String mch_id;
private String nonce_str;
private String prepay_id;
private String result_code;
private String return_code;
private String return_msg;
private String trade_type;
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getMch_id() {
return mch_id;
}
public void setMch_id(String mch_id) {
this.mch_id = mch_id;
}
public String getNonce_str() {
return nonce_str;
}
public void setNonce_str(String nonce_str) {
this.nonce_str = nonce_str;
}
public String getPrepay_id() {
return prepay_id;
}
public void setPrepay_id(String prepay_id) {
this.prepay_id = prepay_id;
}
public String getResult_code() {
return result_code;
}
public void setResult_code(String result_code) {
this.result_code = result_code;
}
public String getReturn_code() {
return return_code;
}
public void setReturn_code(String return_code) {
this.return_code = return_code;
}
public String getReturn_msg() {
return return_msg;
}
public void setReturn_msg(String return_msg) {
this.return_msg = return_msg;
}
public String getTrade_type() {
return trade_type;
}
public void setTrade_type(String trade_type) {
this.trade_type = trade_type;
}
}

@ -0,0 +1,329 @@
package com.hai.common.pay.util;
import org.apache.commons.lang3.StringUtils;
import javax.imageio.ImageIO;
import javax.net.ssl.*;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
/**
* Http连接工具类
*
* @author phil
* @date 2017年7月2日
*
*/
public class HttpReqUtil {
private static int DEFAULT_CONNTIME = 5000;
private static int DEFAULT_READTIME = 5000;
private static int DEFAULT_UPLOAD_READTIME = 10 * 1000;
public static String POST = "POST";
public static String GET = "GET";
/**
* http请求
*
* @param method
* 请求方法GET/POST
* @param path
* 请求路径
* @param timeout
* 连接超时时间 默认为5000
* @param readTimeout
* 读取超时时间 默认为5000
* @param data
* 数据
* @return
*/
private static String defaultConnection(String method, String path, int timeout, int readTimeout, String data, String encoding)
throws Exception {
String result = "";
URL url = new URL(path);
if (url != null) {
HttpURLConnection conn = getConnection(method, url);
conn.setConnectTimeout(timeout == 0 ? DEFAULT_CONNTIME : timeout);
conn.setReadTimeout(readTimeout == 0 ? DEFAULT_READTIME : readTimeout);
if (data != null && !"".equals(data)) {
OutputStream output = conn.getOutputStream();
output.write(data.getBytes("UTF-8"));
output.flush();
output.close();
}
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream input = conn.getInputStream();
result = IOUtil.inputStreamToString(input, encoding);
input.close();
conn.disconnect();
}
}
return result;
}
/**
* 根据url的协议选择对应的请求方式
*
* @param method
* 请求的方法
* @return
* @throws IOException
*/
private static HttpURLConnection getConnection(String method, URL url) throws IOException {
HttpURLConnection conn = null;
if ("https".equals(url.getProtocol())) {
SSLContext context = null;
try {
context = SSLContext.getInstance("SSL", "SunJSSE");
context.init(new KeyManager[0], new TrustManager[] { new MyX509TrustManager() },
new java.security.SecureRandom());
} catch (Exception e) {
throw new IOException(e);
}
HttpsURLConnection connHttps = (HttpsURLConnection) url.openConnection();
connHttps.setSSLSocketFactory(context.getSocketFactory());
connHttps.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
conn = connHttps;
} else {
conn = (HttpURLConnection) url.openConnection();
}
conn.setRequestMethod(method);
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
return conn;
}
/**
* 设置参数
*
* @param map
* 参数map
* @param path
* 需要赋值的path
* @param charset
* 编码格式 默认编码为utf-8(取消默认)
* @return 已经赋值好的url 只需要访问即可
*/
public static String setParmas(Map<String, String> map, String path, String charset) throws Exception {
String result = "";
boolean hasParams = false;
if (path != null && !"".equals(path)) {
if (map != null && map.size() > 0) {
StringBuilder builder = new StringBuilder();
Set<Entry<String, String>> params = map.entrySet();
for (Entry<String, String> entry : params) {
String key = entry.getKey().trim();
String value = entry.getValue().trim();
if (hasParams) {
builder.append("&");
} else {
hasParams = true;
}
if (charset != null && !"".equals(charset)) {
// builder.append(key).append("=").append(URLDecoder.(value,charset));
builder.append(key).append("=").append(IOUtil.urlEncode(value, charset));
} else {
builder.append(key).append("=").append(value);
}
}
result = builder.toString();
}
}
return doUrlPath(path, result).toString();
}
/**
* 设置连接参数
*
* @param path
* 路径
* @return
*/
private static URL doUrlPath(String path, String query) throws Exception {
URL url = new URL(path);
if (StringUtils.isEmpty(path)) {
return url;
}
if (StringUtils.isEmpty(url.getQuery())) {
if (path.endsWith("?")) {
path += query;
} else {
path = path + "?" + query;
}
} else {
if (path.endsWith("&")) {
path += query;
} else {
path = path + "&" + query;
}
}
return new URL(path);
}
/**
* 默认的http请求执行方法,返回
*
* @param method
* 请求的方法 POST/GET
* @param path
* 请求path 路径
* @param map
* 请求参数集合
* @param data
* 输入的数据 允许为空
* @return
*/
public static String HttpDefaultExecute(String method, String path, Map<String, String> map, String data, String encoding) {
String result = "";
try {
String url = setParmas((TreeMap<String, String>) map, path, "");
result = defaultConnection(method, url, DEFAULT_CONNTIME, DEFAULT_READTIME, data, encoding);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 默认的https执行方法,返回
*
* @param method
* 请求的方法 POST/GET
* @param path
* 请求path 路径
* @param map
* 请求参数集合
* @param data
* 输入的数据 允许为空
* @return
*/
public static String HttpsDefaultExecute(String method, String path, Map<String, String> map, String data, String encoding) {
String result = "";
try {
String url = setParmas((TreeMap<String, String>) map, path, "");
result = defaultConnection(method, url, DEFAULT_CONNTIME, DEFAULT_READTIME, data, encoding);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 文件路径
*
* @param mediaUrl
* url 例如
* http://su.bdimg.com/static/superplus/img/logo_white_ee663702.png
* @return logo_white_ee663702.png
*/
private static String getFileName(String mediaUrl) {
String result = mediaUrl.substring(mediaUrl.lastIndexOf("/") + 1, mediaUrl.length());
return result;
}
/**
* 根据内容类型判断文件扩展名
*
* @param ContentType
* 内容类型
* @return
*/
private static String getFileExt(String contentType) {
String fileExt = "";
if (contentType == null) {
return null;
}
if (contentType.contains("image/jpeg")) {
fileExt = ".jpg";
} else if (contentType.contains("audio/mpeg")) {
fileExt = ".mp3";
} else if (contentType.contains("audio/amr")) {
fileExt = ".amr";
} else if (contentType.contains("video/mp4")) {
fileExt = ".mp4";
} else if (contentType.contains("video/mpeg4")) {
fileExt = ".mp4";
} else if (contentType.contains("image/png")) {
fileExt = ".png";
}
return fileExt;
}
/**
* 改变图片大小格式
*
* @param is
* @param os
* @param size
* @param format
* @return
* @throws IOException
*/
public static OutputStream resizeImage(InputStream inputStream, OutputStream outputStream, int size, String format)
throws IOException {
BufferedImage prevImage = ImageIO.read(inputStream);
double width = prevImage.getWidth();
double height = prevImage.getHeight();
double percent = size / width;
int newWidth = (int) (width * percent);
int newHeight = (int) (height * percent);
BufferedImage image = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_BGR);
Graphics graphics = image.createGraphics();
graphics.drawImage(prevImage, 0, 0, newWidth, newHeight, null);
ImageIO.write(image, format, outputStream);
outputStream.flush();
return outputStream;
}
/**
* 获取客户端ip
*
* @param request
* @return
*/
public static String getRemortIP(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
// squid的squid.conf 的配制文件中forwarded_for项改为off时
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
// 多级反向代理
if (ip != null && ip.indexOf(",") > 0 && ip.split(",").length > 1) {
ip = ip.split(",")[0];
}
return ip;
}
}

@ -0,0 +1,73 @@
package com.hai.common.pay.util;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
/**
* IO流工具类
* @author 魏真峰
*/
public class IOUtil {
/**
* 将输入流转换为字符串
*待转换为字符串的输入流
* @return 由输入流转换String的字符串
* @throws IOException
*/
public static String inputStreamToString(InputStream inputStream, String encoding) throws IOException {
if(StringUtils.isEmpty(encoding)) {
encoding = "UTF-8";
}
return IOUtils.toString(inputStream, encoding);
}
/**
* 将字符串转换为输入流
* 待转换为输入流的字符串
* @return
* @throws IOException
*/
public static InputStream toInputStream(String inputStr, String encoding) throws IOException {
if (StringUtils.isEmpty(inputStr)) {
return null;
}
if(StringUtils.isEmpty(encoding)) {
encoding = "UTF-8";
}
return IOUtils.toInputStream(inputStr, encoding);
}
/**
* 编码
*
* @param source
* @param encode
* @return
*/
public static String urlEncode(String source, String encode) {
String result = source;
try {
result = URLEncoder.encode(source, encode);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
/**
* 将输入流转换字节数组
* @return
* @throws IOException
*/
public static byte[] inputStreamToByteArray(InputStream inputStream) throws IOException {
return IOUtils.toByteArray(inputStream);
}
}

@ -0,0 +1,55 @@
package com.hai.common.pay.util;
import org.apache.commons.lang3.StringUtils;
import java.security.MessageDigest;
/**
* MD5加密工具类
*
* @author phil
* @date 2017年7月2日
*
*/
public class MD5Util {
private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d",
"e", "f" };
private static String byteArrayToHexString(byte b[]) {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < b.length; i++)
buffer.append(byteToHexString(b[i]));
return buffer.toString();
}
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n += 256;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
public static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if(StringUtils.isEmpty(charsetname)) {
resultString = byteArrayToHexString(md.digest(resultString.getBytes("UTF-8")));
} else {
resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
}
} catch (Exception exception) {
}
return resultString;
}
public static void main(String args[]) {
System.out.println(MD5Encode("ceshi", "gbk"));
System.out.println(MD5Encode("ceshi", "utf-8"));
}
}

@ -0,0 +1,24 @@
package com.hai.common.pay.util;
import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
/**
* 自定义信任管理器
*
* @author phil
* @date 2017年7月2日
*/
class MyX509TrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}

@ -0,0 +1,358 @@
package com.hai.common.pay.util;
import com.shinwoten.train.common.pay.entity.WechatPayReturnParam;
import com.shinwoten.train.common.pay.entity.WechatReturn;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import java.util.SortedMap;
/**
*
* @Title:
* @Description: 微信支付签名工具类
* @author: 魏真峰
* @param:
* @return:
* @throws
*/
public class SignatureUtil {
private static Logger logger = LoggerFactory.getLogger(SignatureUtil.class);
/**
* 将字节数组转换为十六进制字符串
* @param byteArray
* @return
*/
private static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = 0; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
/**
* 将字节转换为十六进制字符串
*
* @param mByte
* @return
*/
private static String byteToHexStr(byte mByte) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
char[] tempArr = new char[2];
tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
tempArr[1] = Digit[mByte & 0X0F];
return new String(tempArr);
}
/**
* 获取签名
*
* @param o
* 待加密的对象 该处仅限于Class
* @return
*/
public static String createSign(Object o, String apiKey, String encoding) {
String result = notSignParams(o, apiKey);
result = MD5Util.MD5Encode(result, encoding).toUpperCase();
return result;
}
/**
* 签名算法
*
* @param o
* 要参与签名的数据对象
* @param apiKey
* API密匙
* @return 签名
* @throws IllegalAccessException
*/
public static String notSignParams(Object o, String apiKey) {
ArrayList<String> list = new ArrayList<>();
String result = "";
try {
Class<?> cls = o.getClass();
Field[] fields = cls.getDeclaredFields();
list = getFieldList(fields, o);
Field[] superFields = cls.getSuperclass().getDeclaredFields(); // 获取父类的私有属性
list.addAll(getFieldList(superFields, o));
int size = list.size();
String[] arrayToSort = list.toArray(new String[size]);
Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER); // 严格按字母表顺序排序
StringBuilder sb = new StringBuilder();
for (int i = 0; i < size; i++) {
sb.append(arrayToSort[i]);
}
result = sb.toString();
if (apiKey != null && !"".equals(apiKey)) {
result += "key=" + apiKey;
} else {
result = result.substring(0, result.lastIndexOf("&"));
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 将字段集合方法转换
*
* @param array
* @param object
* @return
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
private static ArrayList<String> getFieldList(Field[] array, Object object)
throws IllegalArgumentException, IllegalAccessException {
ArrayList<String> list = new ArrayList<String>();
for (Field f : array) {
f.setAccessible(true);
if (f.get(object) != null && f.get(object) != "" && !f.getName().equals("serialVersionUID")
&& !f.getName().equals("sign")) {
if (f.getName().equals("packageStr")) {
list.add("package" + "=" + f.get(object) + "&");
} else {
list.add(f.getName() + "=" + f.get(object) + "&");
}
}
}
return list;
}
/**
* 通过Map<String,Object>中的所有元素参与签名
*
* @param map
* 待参与签名的map集合
* @params apikey apikey中 如果为空则不参与签名如果不为空则参与签名
* @return
*/
public static String createSign(Map<Object, Object> map, String apiKey, String characterEncoding) {
String result = notSignParams(map, apiKey);
result = MD5Util.MD5Encode(result, characterEncoding).toUpperCase();
logger.debug("sign result {}", result);
return result;
}
/**
* 通过Map<SortedMap,Object>中的所有元素参与签名
*
* @param map
* 待参与签名的map集合
* @params apikey apikey中 如果为空则不参与签名如果不为空则参与签名
* @return
*/
public static String createSign(SortedMap<Object, Object> map, String apiKey, String characterEncoding) {
String result = notSignParams(map, apiKey);
result = MD5Util.MD5Encode(result, characterEncoding).toUpperCase();
logger.debug("sign result {}", result);
return result;
}
/**
* 通过Map<SortedMap,Object>中的所有元素参与签名
*
* @param map
* 待参与签名的map集合
* @params apikey apikey中 如果为空则不参与签名如果不为空则参与签名
* @return
*/
public static String createSha1Sign(SortedMap<Object, Object> map, String apiKey, String characterEncoding) {
String result = notSignParams(map, apiKey);
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-1");
byte[] digest = md.digest(result.getBytes(characterEncoding));
result = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
/**
* 返回未加密的字符串
*
* @param params
* @param apiKey
* @return 待加密的字符串
*/
private static String notSignParams(SortedMap<Object, Object> params, String apiKey) {
StringBuffer buffer = new StringBuffer();
for (Map.Entry<Object, Object> entry : params.entrySet()) {
if (!org.springframework.util.StringUtils.isEmpty(entry.getValue())) {
buffer.append(entry.getKey() + "=" + entry.getValue() + "&");
}
}
buffer.append("key=" + apiKey);
return buffer.toString();
}
/**
* 返回未加密的字符串
*
* @param params
* @param apiKey
* @return 待加密的字符串
*/
public static String notSignParams(Map<Object, Object> params, String apiKey) {
ArrayList<String> list = new ArrayList<>();
for (Map.Entry<Object, Object> entry : params.entrySet()) {
if (entry.getValue() != "" && entry.getValue() != null) {
list.add(entry.getKey() + "=" + entry.getValue() + "&");
}
}
int size = list.size();
String[] arrayToSort = list.toArray(new String[size]);
Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < size; i++) {
sb.append(arrayToSort[i]);
}
String result = sb.toString();
if (apiKey != null && !"".equals(apiKey)) {
result += "key=" + apiKey;
} else {
result = result.substring(0, result.lastIndexOf("&"));
}
return result;
}
/**
* 从API返回的XML数据里面重新计算一次签名
*
* @param responseString
* API返回的XML数据
* @param apiKey
* Key
* @return 新的签名
* @throws ParserConfigurationException
* @throws IOException
* @throws SAXException
*/
public static String reCreateSign(String responseString, String apiKey, String encoding)
throws IOException, SAXException, ParserConfigurationException {
Map<String, Object> map = XmlUtil.parseXmlToMap(responseString, encoding);
// 清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名
map.replace("sign","");
// 将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
return createSign(map, apiKey, encoding);
}
/**
* 检验API返回的数据里面的签名是否合法,规则是:按参数名称a-z排序,遇到空值的参数不参加签名
*
* @param resultXml
* API返回的XML数据字符串
* @param apiKey
* Key
* @return API签名是否合法
* @throws ParserConfigurationException
* @throws IOException
* @throws SAXException
* @throws DocumentException
*/
public static boolean checkIsSignValidFromWeiXin(String checktXml, String apiKey, String encoding)
throws ParserConfigurationException, IOException, SAXException, DocumentException {
SortedMap<String, String> map = XmlUtil.parseXmlToTreeMap(checktXml,encoding);
String signFromresultXml = (String) map.get("sign");
WechatReturn wechatReturn = new WechatReturn();
wechatReturn.setAppid((String) map.get("appid"));
wechatReturn.setMch_id((String) map.get("mch_id"));
wechatReturn.setNonce_str((String) map.get("nonce_str"));
wechatReturn.setPrepay_id((String) map.get("prepay_id"));
wechatReturn.setResult_code((String) map.get("result_code"));
wechatReturn.setReturn_code((String) map.get("return_code"));
wechatReturn.setReturn_msg((String) map.get("return_msg"));
wechatReturn.setTrade_type((String) map.get("trade_type"));
if (StringUtils.isEmpty(signFromresultXml)) {
logger.debug("API返回的数据签名数据不存在");
return false;
}
if(!("SUCCESS".equals(map.get("return_code"))) || !("SUCCESS".equals(map.get("result_code")))){
logger.debug("返回代码不成功!");
return false;
}
logger.debug("服务器回包里面的签名{}", signFromresultXml);
// 清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名
// 将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
String signForAPIResponse = createSign(wechatReturn, apiKey, encoding);
if (!signForAPIResponse.equals(signFromresultXml)) {
// 签名验不过,表示这个API返回的数据有可能已经被篡改了
logger.debug("API返回的数据签名验证不通过");
return false;
}
logger.debug("API返回的数据签名验证通过");
return true;
}
/**
*
* @Title: reCheckIsSignValidFromWeiXin
* @Description: 微信支付异步回调检验签名是否正确
* @author: 魏真峰
* @param: [checktXml, apiKey, encoding]
* @return: boolean
* @throws
*/
public static boolean reCheckIsSignValidFromWeiXin(String checktXml, String apiKey, String encoding)
throws ParserConfigurationException, IOException, SAXException, DocumentException {
SortedMap<String, String> map = XmlUtil.parseXmlToTreeMap(checktXml,encoding);
String signFromresultXml = (String) map.get("sign");
WechatPayReturnParam wechatPayReturnParam = new WechatPayReturnParam();
wechatPayReturnParam.setAppid((String) map.get("appid"));
wechatPayReturnParam.setAttach((String) map.get("attach"));
wechatPayReturnParam.setBank_type((String) map.get("bank_type"));
wechatPayReturnParam.setCash_fee((String) map.get("cash_fee"));
wechatPayReturnParam.setFee_type((String) map.get("fee_type"));
wechatPayReturnParam.setIs_subscribe((String) map.get("is_subscribe"));
wechatPayReturnParam.setMch_id((String) map.get("mch_id"));
wechatPayReturnParam.setNonce_str((String) map.get("nonce_str"));
wechatPayReturnParam.setOpenid((String) map.get("openid"));
wechatPayReturnParam.setOut_trade_no((String) map.get("out_trade_no"));
wechatPayReturnParam.setResult_code((String) map.get("result_code"));
wechatPayReturnParam.setReturn_code((String) map.get("return_code"));
wechatPayReturnParam.setTime_end((String) map.get("time_end"));
wechatPayReturnParam.setTotal_fee((String) map.get("total_fee"));
wechatPayReturnParam.setTrade_type((String) map.get("trade_type"));
wechatPayReturnParam.setTransaction_id((String) map.get("transaction_id"));
if (StringUtils.isEmpty(signFromresultXml)) {
logger.debug("API返回的数据签名数据不存在");
return false;
}
if(!("SUCCESS".equals(map.get("return_code"))) || !("SUCCESS".equals(map.get("result_code")))){
logger.debug("返回代码不成功!");
return false;
}
logger.debug("服务器回包里面的签名{}", signFromresultXml);
// 清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名
// 将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
String signForAPIResponse = createSign(wechatPayReturnParam, apiKey, encoding);
if (!signForAPIResponse.equals(signFromresultXml)) {
// 签名验不过,表示这个API返回的数据有可能已经被篡改了
logger.debug("API返回的数据签名验证不通过");
return false;
}
logger.debug("API返回的数据签名验证通过");
return true;
}
}

@ -0,0 +1,274 @@
package com.hai.common.pay.util;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.thoughtworks.xstream.io.xml.XppDriver;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.xml.sax.SAXException;
import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
/**
* XML解析工具类
*
* @author phil
* @date 2017年7月3日
*
*/
public class XmlUtil {
/**
* 解析微信发来的请求XML xml示例 <xml> <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[FromUser]]></FromUserName>
* <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType>
* <Event><![CDATA[CLICK]]></Event>
* <EventKey><![CDATA[EVENTKEY]]></EventKey> </xml>
*
* @param request
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public static Map<String, String> parseXmlToMap(HttpServletRequest request){
Map<String, String> map = new HashMap<>();
InputStream inputStream = null;
try {
// 从request中取得输入流
inputStream = request.getInputStream();
// 读取输入流
SAXReader reader = new SAXReader();
Document document = reader.read(inputStream);
// 得到xml根元素
Element root = document.getRootElement();
// 得到根元素的所有子节点
List<Element> elementList = root.elements();
// 遍历所有子节点
for (Element e : elementList) {
map.put(e.getName(), e.getText());
}
} catch (IOException | DocumentException e) {
e.printStackTrace();
}
return map;
}
/**
* 解析微信发来的请求XML xml示例 <xml> <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[FromUser]]></FromUserName>
* <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType>
* <Event><![CDATA[CLICK]]></Event>
* <EventKey><![CDATA[EVENTKEY]]></EventKey> </xml>
*
* @param request
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public static Map<String, String> parseStreamToMap(InputStream inputStream) throws Exception {
Map<String, String> map = new HashMap<>();
try {
// 读取输入流
SAXReader reader = new SAXReader();
Document document = reader.read(inputStream);
// 得到xml根元素
Element root = document.getRootElement();
// 得到根元素的所有子节点
List<Element> elementList = root.elements();
// 遍历所有子节点
for (Element e : elementList) {
map.put(e.getName(), e.getText());
}
} catch (DocumentException e) {
e.printStackTrace();
}
return map;
}
/**
* 使用dom4将xml文件中的数据转换成SortedMap<String,Object>
*
* @param xmlString
* xml格式的字符串
* @throws ParserConfigurationException
* @throws IOException
* @throws SAXException
*/
public static TreeMap<String, String> parseXmlToTreeMap(String xml, String encoding)
throws ParserConfigurationException, IOException, SAXException {
// 这里用Dom的方式解析回包的最主要目的是防止API新增回包字段
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputStream is = IOUtil.toInputStream(xml, encoding);
org.w3c.dom.Document document = builder.parse(is);
// 获取到document里面的全部结点
org.w3c.dom.NodeList allNodes = document.getFirstChild().getChildNodes();
org.w3c.dom.Node node;
TreeMap<String, String> map = new TreeMap<>();
int i = 0;
while (i < allNodes.getLength()) {
node = allNodes.item(i);
if (node instanceof org.w3c.dom.Element) {
map.put(node.getNodeName(), node.getTextContent());
}
i++;
}
return map;
}
/**
* 使用dom4将xml文件中的数据转换成Map<String,Object>
*
* @param xmlString xml格式的字符串
* @throws ParserConfigurationException
* @throws IOException
* @throws SAXException
*/
public static Map<String, Object> parseXmlToMap(String xml, String encoding)
throws ParserConfigurationException, IOException, SAXException {
// 这里用Dom的方式解析回包的最主要目的是防止API新增回包字段
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputStream is = IOUtil.toInputStream(xml, encoding);
org.w3c.dom.Document document = builder.parse(is);
// 获取到document里面的全部结点
org.w3c.dom.NodeList allNodes = document.getFirstChild().getChildNodes();
org.w3c.dom.Node node;
Map<String, Object> map = new HashMap<>();
int i = 0;
while (i < allNodes.getLength()) {
node = allNodes.item(i);
if (node instanceof org.w3c.dom.Element) {
map.put(node.getNodeName(), node.getTextContent());
}
i++;
}
return map;
}
/**
* 示例 <xml> <return_code><![CDATA[SUCCESS]]></return_code>
* <return_msg><![CDATA[OK]]></return_msg>
* <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
* <mch_id><![CDATA[10000100]]></mch_id>
* <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
* <openid><![CDATA[oUpF8uMuAJO_M2pxb1Q9zNjWeS6o]]></openid>
* <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
* <result_code><![CDATA[SUCCESS]]></result_code>
* <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
* <trade_type><![CDATA[JSAPI]]></trade_type> </xml>
*
* 将xml数据(<![CDATA[SUCCESS]]>格式)映射到java对象中
*
* @param xml
* 待转换的xml格式的数据
* @param t
* 待转换为的java对象
* @return
*/
public static <T> T getObjectFromXML(String xml, Class<T> t) {
// 将从API返回的XML数据映射到Java对象
XStream xstream = XStreamFactroy.init(true);
xstream.alias("xml", t);
xstream.ignoreUnknownElements();// 暂时忽略掉一些新增的字段
// if(Objects.equals(xstream.fromXML(xml).getClass(), t.getClass())) {
// return t.cast(xstream.fromXML(xml));
// }
// return null;
return t.cast(xstream.fromXML(xml));
}
/**
* 将java对象转换为xml(<![CDATA[SUCCESS]]>格式)
*
* @param obj
* @return
*/
public static String toXml(Object obj) {
String result = "";
XStream xstream = XStreamFactroy.init(true);
xstream.alias("xml", obj.getClass());
result = xstream.toXML(obj);
return result;
}
/**
* 将java对象转换为xml文件,并去除 _ 应用场景是 去除实体中有_划线的实体, 默认会有两个_,调用该方法则会去除一个
*
* @param obj
* @return
*/
public static String toSplitXml(Object obj) {
String result = "";
XStream xstream = XStreamFactroy.initSplitLine();
xstream.alias("xml", obj.getClass());
result = xstream.toXML(obj);
return result;
}
/**
* XStream工具类
* @author phil
*
*/
static class XStreamFactroy {
private static final String START_CADA = "<![CDATA[";
private static final String END_CADA = "]]>";
/**
* 是否启用<![CDATA[]]>
*
* @param flag true 表示启用 false表示不启用
* @return
*/
static XStream init(boolean flag) {
XStream xstream = null;
if (flag) {
xstream = new XStream(new XppDriver() {
public HierarchicalStreamWriter createWriter(Writer out) {
return new PrettyPrintWriter(out) {
@Override
protected void writeText(QuickWriter writer, String text) {
if (!text.startsWith(START_CADA)) {
text = START_CADA + text + END_CADA;
}
writer.write(text);
}
};
}
});
} else {
xstream = new XStream();
}
return xstream;
}
/**
* 用于处理在实体对象中带有_的属性,如果用上述方法会出现有两个__,导致结果不正确! 属性中有_的属性一定要有改方法
*
* @return 返回xstream 对象 new DomDriver("UTF-8", new
* XmlFriendlyNameCoder("-_", "_")
*/
public static XStream initSplitLine() {
XStream xstream = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
return xstream;
}
}
}

@ -0,0 +1,42 @@
package com.hai.common.pay.util.sdk;
/**
* 域名管理实现主备域名自动切换
*/
public abstract interface IWXPayDomain {
/**
* 上报域名网络状况
* @param domain 域名 比如api.mch.weixin.qq.com
* @param elapsedTimeMillis 耗时
* @param ex 网络请求中出现的异常
* null表示没有异常
* ConnectTimeoutException表示建立网络连接异常
* UnknownHostException 表示dns解析异常
*/
abstract void report(final String domain, long elapsedTimeMillis, final Exception ex);
/**
* 获取域名
* @param config 配置
* @return 域名
*/
abstract DomainInfo getDomain(final WXPayConfig config);
static class DomainInfo{
public String domain; //域名
public boolean primaryDomain; //该域名是否为主域名。例如:api.mch.weixin.qq.com为主域名
public DomainInfo(String domain, boolean primaryDomain) {
this.domain = domain;
this.primaryDomain = primaryDomain;
}
@Override
public String toString() {
return "DomainInfo{" +
"domain='" + domain + '\'' +
", primaryDomain=" + primaryDomain +
'}';
}
}
}

@ -0,0 +1,689 @@
package com.hai.common.pay.util.sdk;
import com.hai.common.pay.util.sdk.WXPayConstants.SignType;
import java.util.HashMap;
import java.util.Map;
public class WXPay {
private WXPayConfig config;
private SignType signType;
private boolean autoReport;
private boolean useSandbox;
private String notifyUrl;
private WXPayRequest wxPayRequest;
public WXPay(final WXPayConfig config) throws Exception {
this(config, null, true, false);
}
public WXPay(final WXPayConfig config, final boolean autoReport) throws Exception {
this(config, null, autoReport, false);
}
public WXPay(final WXPayConfig config, final boolean autoReport, final boolean useSandbox) throws Exception{
this(config, null, autoReport, useSandbox);
}
public WXPay(final WXPayConfig config, final String notifyUrl) throws Exception {
this(config, notifyUrl, true, false);
}
public WXPay(final WXPayConfig config, final String notifyUrl, final boolean autoReport) throws Exception {
this(config, notifyUrl, autoReport, false);
}
public WXPay(final WXPayConfig config, final String notifyUrl, final boolean autoReport, final boolean useSandbox) throws Exception {
this.config = config;
this.notifyUrl = notifyUrl;
this.autoReport = autoReport;
this.useSandbox = useSandbox;
if (useSandbox) {
this.signType = SignType.MD5; // 沙箱环境
}
else {
this.signType = SignType.HMACSHA256;
}
this.wxPayRequest = new WXPayRequest(config);
}
private void checkWXPayConfig() throws Exception {
if (this.config == null) {
throw new Exception("config is null");
}
if (this.config.getAppID() == null || this.config.getAppID().trim().length() == 0) {
throw new Exception("appid in config is empty");
}
if (this.config.getMchID() == null || this.config.getMchID().trim().length() == 0) {
throw new Exception("appid in config is empty");
}
if (this.config.getCertStream() == null) {
throw new Exception("cert stream in config is empty");
}
if (this.config.getWXPayDomain() == null){
throw new Exception("config.getWXPayDomain() is null");
}
if (this.config.getHttpConnectTimeoutMs() < 10) {
throw new Exception("http connect timeout is too small");
}
if (this.config.getHttpReadTimeoutMs() < 10) {
throw new Exception("http read timeout is too small");
}
}
/**
* Map 中添加 appidmch_idnonce_strsign_typesign <br>
* 该函数适用于商户适用于统一下单等接口不适用于红包代金券接口
*
* @param reqData
* @return
* @throws Exception
*/
public Map<String, String> fillRequestData(Map<String, String> reqData) throws Exception {
reqData.put("appid", config.getAppID());
reqData.put("mch_id", config.getMchID());
reqData.put("nonce_str", WXPayUtil.generateNonceStr());
if (SignType.MD5.equals(this.signType)) {
reqData.put("sign_type", WXPayConstants.MD5);
}
else if (SignType.HMACSHA256.equals(this.signType)) {
reqData.put("sign_type", WXPayConstants.HMACSHA256);
}
reqData.put("sign", WXPayUtil.generateSignature(reqData, config.getKey(), this.signType));
return reqData;
}
/**
* 判断xml数据的sign是否有效必须包含sign字段否则返回false
*
* @param reqData 向wxpay post的请求数据
* @return 签名是否有效
* @throws Exception
*/
public boolean isResponseSignatureValid(Map<String, String> reqData) throws Exception {
// 返回数据的签名方式和请求中给定的签名方式是一致的
return WXPayUtil.isSignatureValid(reqData, this.config.getKey(), this.signType);
}
/**
* 判断支付结果通知中的sign是否有效
*
* @param reqData 向wxpay post的请求数据
* @return 签名是否有效
* @throws Exception
*/
public boolean isPayResultNotifySignatureValid(Map<String, String> reqData) throws Exception {
String signTypeInData = reqData.get(WXPayConstants.FIELD_SIGN_TYPE);
SignType signType;
if (signTypeInData == null) {
signType = SignType.MD5;
}
else {
signTypeInData = signTypeInData.trim();
if (signTypeInData.length() == 0) {
signType = SignType.MD5;
}
else if (WXPayConstants.MD5.equals(signTypeInData)) {
signType = SignType.MD5;
}
else if (WXPayConstants.HMACSHA256.equals(signTypeInData)) {
signType = SignType.HMACSHA256;
}
else {
throw new Exception(String.format("Unsupported sign_type: %s", signTypeInData));
}
}
return WXPayUtil.isSignatureValid(reqData, this.config.getKey(), signType);
}
/**
* 不需要证书的请求
* @param urlSuffix String
* @param reqData 向wxpay post的请求数据
* @param connectTimeoutMs 超时时间单位是毫秒
* @param readTimeoutMs 超时时间单位是毫秒
* @return API返回数据
* @throws Exception
*/
public String requestWithoutCert(String urlSuffix, Map<String, String> reqData,
int connectTimeoutMs, int readTimeoutMs) throws Exception {
String msgUUID = reqData.get("nonce_str");
String reqBody = WXPayUtil.mapToXml(reqData);
String resp = this.wxPayRequest.requestWithoutCert(urlSuffix, msgUUID, reqBody, connectTimeoutMs, readTimeoutMs, autoReport);
return resp;
}
/**
* 需要证书的请求
* @param urlSuffix String
* @param reqData 向wxpay post的请求数据 Map
* @param connectTimeoutMs 超时时间单位是毫秒
* @param readTimeoutMs 超时时间单位是毫秒
* @return API返回数据
* @throws Exception
*/
public String requestWithCert(String urlSuffix, Map<String, String> reqData,
int connectTimeoutMs, int readTimeoutMs) throws Exception {
String msgUUID= reqData.get("nonce_str");
String reqBody = WXPayUtil.mapToXml(reqData);
String resp = this.wxPayRequest.requestWithCert(urlSuffix, msgUUID, reqBody, connectTimeoutMs, readTimeoutMs, this.autoReport);
return resp;
}
/**
* 处理 HTTPS API返回数据转换成Map对象return_code为SUCCESS时验证签名
* @param xmlStr API返回的XML格式数据
* @return Map类型数据
* @throws Exception
*/
public Map<String, String> processResponseXml(String xmlStr) throws Exception {
String RETURN_CODE = "return_code";
String return_code;
Map<String, String> respData = WXPayUtil.xmlToMap(xmlStr);
if (respData.containsKey(RETURN_CODE)) {
return_code = respData.get(RETURN_CODE);
}
else {
throw new Exception(String.format("No `return_code` in XML: %s", xmlStr));
}
if (return_code.equals(WXPayConstants.FAIL)) {
return respData;
}
else if (return_code.equals(WXPayConstants.SUCCESS)) {
if (this.isResponseSignatureValid(respData)) {
return respData;
}
else {
throw new Exception(String.format("Invalid sign value in XML: %s", xmlStr));
}
}
else {
throw new Exception(String.format("return_code value %s is invalid in XML: %s", return_code, xmlStr));
}
}
/**
* 作用提交刷卡支付<br>
* 场景刷卡支付
* @param reqData 向wxpay post的请求数据
* @return API返回数据
* @throws Exception
*/
public Map<String, String> microPay(Map<String, String> reqData) throws Exception {
return this.microPay(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
}
/**
* 作用提交刷卡支付<br>
* 场景刷卡支付
* @param reqData 向wxpay post的请求数据
* @param connectTimeoutMs 连接超时时间单位是毫秒
* @param readTimeoutMs 读超时时间单位是毫秒
* @return API返回数据
* @throws Exception
*/
public Map<String, String> microPay(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
String url;
if (this.useSandbox) {
url = WXPayConstants.SANDBOX_MICROPAY_URL_SUFFIX;
}
else {
url = WXPayConstants.MICROPAY_URL_SUFFIX;
}
String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
return this.processResponseXml(respXml);
}
/**
* 提交刷卡支付针对软POS尽可能做成功
* 内置重试机制最多60s
* @param reqData
* @return
* @throws Exception
*/
public Map<String, String> microPayWithPos(Map<String, String> reqData) throws Exception {
return this.microPayWithPos(reqData, this.config.getHttpConnectTimeoutMs());
}
/**
* 提交刷卡支付针对软POS尽可能做成功
* 内置重试机制最多60s
* @param reqData
* @param connectTimeoutMs
* @return
* @throws Exception
*/
public Map<String, String> microPayWithPos(Map<String, String> reqData, int connectTimeoutMs) throws Exception {
int remainingTimeMs = 60*1000;
long startTimestampMs = 0;
Map<String, String> lastResult = null;
Exception lastException = null;
while (true) {
startTimestampMs = WXPayUtil.getCurrentTimestampMs();
int readTimeoutMs = remainingTimeMs - connectTimeoutMs;
if (readTimeoutMs > 1000) {
try {
lastResult = this.microPay(reqData, connectTimeoutMs, readTimeoutMs);
String returnCode = lastResult.get("return_code");
if (returnCode.equals("SUCCESS")) {
String resultCode = lastResult.get("result_code");
String errCode = lastResult.get("err_code");
if (resultCode.equals("SUCCESS")) {
break;
}
else {
// 看错误码,若支付结果未知,则重试提交刷卡支付
if (errCode.equals("SYSTEMERROR") || errCode.equals("BANKERROR") || errCode.equals("USERPAYING")) {
remainingTimeMs = remainingTimeMs - (int)(WXPayUtil.getCurrentTimestampMs() - startTimestampMs);
if (remainingTimeMs <= 100) {
break;
}
else {
WXPayUtil.getLogger().info("microPayWithPos: try micropay again");
if (remainingTimeMs > 5*1000) {
Thread.sleep(5*1000);
}
else {
Thread.sleep(1*1000);
}
continue;
}
}
else {
break;
}
}
}
else {
break;
}
}
catch (Exception ex) {
lastResult = null;
lastException = ex;
}
}
else {
break;
}
}
if (lastResult == null) {
throw lastException;
}
else {
return lastResult;
}
}
/**
* 作用统一下单<br>
* 场景公共号支付扫码支付APP支付
* @param reqData 向wxpay post的请求数据
* @return API返回数据
* @throws Exception
*/
public Map<String, String> unifiedOrder(Map<String, String> reqData) throws Exception {
return this.unifiedOrder(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
}
/**
* 作用统一下单<br>
* 场景公共号支付扫码支付APP支付
* @param reqData 向wxpay post的请求数据
* @param connectTimeoutMs 连接超时时间单位是毫秒
* @param readTimeoutMs 读超时时间单位是毫秒
* @return API返回数据
* @throws Exception
*/
public Map<String, String> unifiedOrder(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
String url;
if (this.useSandbox) {
url = WXPayConstants.SANDBOX_UNIFIEDORDER_URL_SUFFIX;
}
else {
url = WXPayConstants.UNIFIEDORDER_URL_SUFFIX;
}
if(this.notifyUrl != null) {
reqData.put("notify_url", this.notifyUrl);
}
String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
return this.processResponseXml(respXml);
}
/**
* 作用查询订单<br>
* 场景刷卡支付公共号支付扫码支付APP支付
* @param reqData 向wxpay post的请求数据
* @return API返回数据
* @throws Exception
*/
public Map<String, String> orderQuery(Map<String, String> reqData) throws Exception {
return this.orderQuery(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
}
/**
* 作用查询订单<br>
* 场景刷卡支付公共号支付扫码支付APP支付
* @param reqData 向wxpay post的请求数据 int
* @param connectTimeoutMs 连接超时时间单位是毫秒
* @param readTimeoutMs 读超时时间单位是毫秒
* @return API返回数据
* @throws Exception
*/
public Map<String, String> orderQuery(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
String url;
if (this.useSandbox) {
url = WXPayConstants.SANDBOX_ORDERQUERY_URL_SUFFIX;
}
else {
url = WXPayConstants.ORDERQUERY_URL_SUFFIX;
}
String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
return this.processResponseXml(respXml);
}
/**
* 作用撤销订单<br>
* 场景刷卡支付
* @param reqData 向wxpay post的请求数据
* @return API返回数据
* @throws Exception
*/
public Map<String, String> reverse(Map<String, String> reqData) throws Exception {
return this.reverse(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
}
/**
* 作用撤销订单<br>
* 场景刷卡支付<br>
* 其他需要证书
* @param reqData 向wxpay post的请求数据
* @param connectTimeoutMs 连接超时时间单位是毫秒
* @param readTimeoutMs 读超时时间单位是毫秒
* @return API返回数据
* @throws Exception
*/
public Map<String, String> reverse(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
String url;
if (this.useSandbox) {
url = WXPayConstants.SANDBOX_REVERSE_URL_SUFFIX;
}
else {
url = WXPayConstants.REVERSE_URL_SUFFIX;
}
String respXml = this.requestWithCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
return this.processResponseXml(respXml);
}
/**
* 作用关闭订单<br>
* 场景公共号支付扫码支付APP支付
* @param reqData 向wxpay post的请求数据
* @return API返回数据
* @throws Exception
*/
public Map<String, String> closeOrder(Map<String, String> reqData) throws Exception {
return this.closeOrder(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
}
/**
* 作用关闭订单<br>
* 场景公共号支付扫码支付APP支付
* @param reqData 向wxpay post的请求数据
* @param connectTimeoutMs 连接超时时间单位是毫秒
* @param readTimeoutMs 读超时时间单位是毫秒
* @return API返回数据
* @throws Exception
*/
public Map<String, String> closeOrder(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
String url;
if (this.useSandbox) {
url = WXPayConstants.SANDBOX_CLOSEORDER_URL_SUFFIX;
}
else {
url = WXPayConstants.CLOSEORDER_URL_SUFFIX;
}
String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
return this.processResponseXml(respXml);
}
/**
* 作用申请退款<br>
* 场景刷卡支付公共号支付扫码支付APP支付
* @param reqData 向wxpay post的请求数据
* @return API返回数据
* @throws Exception
*/
public Map<String, String> refund(Map<String, String> reqData) throws Exception {
return this.refund(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
}
/**
* 作用申请退款<br>
* 场景刷卡支付公共号支付扫码支付APP支付<br>
* 其他需要证书
* @param reqData 向wxpay post的请求数据
* @param connectTimeoutMs 连接超时时间单位是毫秒
* @param readTimeoutMs 读超时时间单位是毫秒
* @return API返回数据
* @throws Exception
*/
public Map<String, String> refund(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
String url;
if (this.useSandbox) {
url = WXPayConstants.SANDBOX_REFUND_URL_SUFFIX;
}
else {
url = WXPayConstants.REFUND_URL_SUFFIX;
}
String respXml = this.requestWithCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
return this.processResponseXml(respXml);
}
/**
* 作用退款查询<br>
* 场景刷卡支付公共号支付扫码支付APP支付
* @param reqData 向wxpay post的请求数据
* @return API返回数据
* @throws Exception
*/
public Map<String, String> refundQuery(Map<String, String> reqData) throws Exception {
return this.refundQuery(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
}
/**
* 作用退款查询<br>
* 场景刷卡支付公共号支付扫码支付APP支付
* @param reqData 向wxpay post的请求数据
* @param connectTimeoutMs 连接超时时间单位是毫秒
* @param readTimeoutMs 读超时时间单位是毫秒
* @return API返回数据
* @throws Exception
*/
public Map<String, String> refundQuery(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
String url;
if (this.useSandbox) {
url = WXPayConstants.SANDBOX_REFUNDQUERY_URL_SUFFIX;
}
else {
url = WXPayConstants.REFUNDQUERY_URL_SUFFIX;
}
String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
return this.processResponseXml(respXml);
}
/**
* 作用对账单下载成功时返回对账单数据失败时返回XML格式数据<br>
* 场景刷卡支付公共号支付扫码支付APP支付
* @param reqData 向wxpay post的请求数据
* @return API返回数据
* @throws Exception
*/
public Map<String, String> downloadBill(Map<String, String> reqData) throws Exception {
return this.downloadBill(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
}
/**
* 作用对账单下载<br>
* 场景刷卡支付公共号支付扫码支付APP支付<br>
* 其他无论是否成功都返回Map若成功返回的Map中含有return_codereturn_msgdata
* 其中return_code为`SUCCESS`data为对账单数据
* @param reqData 向wxpay post的请求数据
* @param connectTimeoutMs 连接超时时间单位是毫秒
* @param readTimeoutMs 读超时时间单位是毫秒
* @return 经过封装的API返回数据
* @throws Exception
*/
public Map<String, String> downloadBill(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
String url;
if (this.useSandbox) {
url = WXPayConstants.SANDBOX_DOWNLOADBILL_URL_SUFFIX;
}
else {
url = WXPayConstants.DOWNLOADBILL_URL_SUFFIX;
}
String respStr = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs).trim();
Map<String, String> ret;
// 出现错误,返回XML数据
if (respStr.indexOf("<") == 0) {
ret = WXPayUtil.xmlToMap(respStr);
}
else {
// 正常返回csv数据
ret = new HashMap<String, String>();
ret.put("return_code", WXPayConstants.SUCCESS);
ret.put("return_msg", "ok");
ret.put("data", respStr);
}
return ret;
}
/**
* 作用交易保障<br>
* 场景刷卡支付公共号支付扫码支付APP支付
* @param reqData 向wxpay post的请求数据
* @return API返回数据
* @throws Exception
*/
public Map<String, String> report(Map<String, String> reqData) throws Exception {
return this.report(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
}
/**
* 作用交易保障<br>
* 场景刷卡支付公共号支付扫码支付APP支付
* @param reqData 向wxpay post的请求数据
* @param connectTimeoutMs 连接超时时间单位是毫秒
* @param readTimeoutMs 读超时时间单位是毫秒
* @return API返回数据
* @throws Exception
*/
public Map<String, String> report(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
String url;
if (this.useSandbox) {
url = WXPayConstants.SANDBOX_REPORT_URL_SUFFIX;
}
else {
url = WXPayConstants.REPORT_URL_SUFFIX;
}
String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
return WXPayUtil.xmlToMap(respXml);
}
/**
* 作用转换短链接<br>
* 场景刷卡支付扫码支付
* @param reqData 向wxpay post的请求数据
* @return API返回数据
* @throws Exception
*/
public Map<String, String> shortUrl(Map<String, String> reqData) throws Exception {
return this.shortUrl(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
}
/**
* 作用转换短链接<br>
* 场景刷卡支付扫码支付
* @param reqData 向wxpay post的请求数据
* @return API返回数据
* @throws Exception
*/
public Map<String, String> shortUrl(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
String url;
if (this.useSandbox) {
url = WXPayConstants.SANDBOX_SHORTURL_URL_SUFFIX;
}
else {
url = WXPayConstants.SHORTURL_URL_SUFFIX;
}
String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
return this.processResponseXml(respXml);
}
/**
* 作用授权码查询OPENID接口<br>
* 场景刷卡支付
* @param reqData 向wxpay post的请求数据
* @return API返回数据
* @throws Exception
*/
public Map<String, String> authCodeToOpenid(Map<String, String> reqData) throws Exception {
return this.authCodeToOpenid(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
}
/**
* 作用授权码查询OPENID接口<br>
* 场景刷卡支付
* @param reqData 向wxpay post的请求数据
* @param connectTimeoutMs 连接超时时间单位是毫秒
* @param readTimeoutMs 读超时时间单位是毫秒
* @return API返回数据
* @throws Exception
*/
public Map<String, String> authCodeToOpenid(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
String url;
if (this.useSandbox) {
url = WXPayConstants.SANDBOX_AUTHCODETOOPENID_URL_SUFFIX;
}
else {
url = WXPayConstants.AUTHCODETOOPENID_URL_SUFFIX;
}
String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
return this.processResponseXml(respXml);
}
} // end class

@ -0,0 +1,103 @@
package com.hai.common.pay.util.sdk;
import java.io.InputStream;
public abstract class WXPayConfig {
/**
* 获取 App ID
*
* @return App ID
*/
abstract String getAppID();
/**
* 获取 Mch ID
*
* @return Mch ID
*/
abstract String getMchID();
/**
* 获取 API 密钥
*
* @return API密钥
*/
abstract String getKey();
/**
* 获取商户证书内容
*
* @return 商户证书内容
*/
abstract InputStream getCertStream();
/**
* HTTP(S) 连接超时时间单位毫秒
*
* @return
*/
public int getHttpConnectTimeoutMs() {
return 6*1000;
}
/**
* HTTP(S) 读数据超时时间单位毫秒
*
* @return
*/
public int getHttpReadTimeoutMs() {
return 8*1000;
}
/**
* 获取WXPayDomain, 用于多域名容灾自动切换
* @return
*/
abstract IWXPayDomain getWXPayDomain();
/**
* 是否自动上报
* 若要关闭自动上报子类中实现该函数返回 false 即可
*
* @return
*/
public boolean shouldAutoReport() {
return true;
}
/**
* 进行健康上报的线程的数量
*
* @return
*/
public int getReportWorkerNum() {
return 6;
}
/**
* 健康上报缓存消息的最大数量会有线程去独立上报
* 粗略计算加入一条消息200B10000消息占用空间 2000 KB约为2MB可以接受
*
* @return
*/
public int getReportQueueMaxSize() {
return 10000;
}
/**
* 批量上报一次最多上报多个数据
*
* @return
*/
public int getReportBatchSize() {
return 10;
}
}

@ -0,0 +1,59 @@
package com.hai.common.pay.util.sdk;
import org.apache.http.client.HttpClient;
/**
* 常量
*/
public class WXPayConstants {
public enum SignType {
MD5, HMACSHA256
}
public static final String DOMAIN_API = "api.mch.weixin.qq.com";
public static final String DOMAIN_API2 = "api2.mch.weixin.qq.com";
public static final String DOMAIN_APIHK = "apihk.mch.weixin.qq.com";
public static final String DOMAIN_APIUS = "apius.mch.weixin.qq.com";
public static final String FAIL = "FAIL";
public static final String SUCCESS = "SUCCESS";
public static final String HMACSHA256 = "HMAC-SHA256";
public static final String MD5 = "MD5";
public static final String FIELD_SIGN = "sign";
public static final String FIELD_SIGN_TYPE = "sign_type";
public static final String WXPAYSDK_VERSION = "WXPaySDK/3.0.9";
public static final String USER_AGENT = WXPAYSDK_VERSION +
" (" + System.getProperty("os.arch") + " " + System.getProperty("os.name") + " " + System.getProperty("os.version") +
") Java/" + System.getProperty("java.version") + " HttpClient/" + HttpClient.class.getPackage().getImplementationVersion();
public static final String MICROPAY_URL_SUFFIX = "/pay/micropay";
public static final String UNIFIEDORDER_URL_SUFFIX = "/pay/unifiedorder";
public static final String ORDERQUERY_URL_SUFFIX = "/pay/orderquery";
public static final String REVERSE_URL_SUFFIX = "/secapi/pay/reverse";
public static final String CLOSEORDER_URL_SUFFIX = "/pay/closeorder";
public static final String REFUND_URL_SUFFIX = "/secapi/pay/refund";
public static final String REFUNDQUERY_URL_SUFFIX = "/pay/refundquery";
public static final String DOWNLOADBILL_URL_SUFFIX = "/pay/downloadbill";
public static final String REPORT_URL_SUFFIX = "/payitil/report";
public static final String SHORTURL_URL_SUFFIX = "/tools/shorturl";
public static final String AUTHCODETOOPENID_URL_SUFFIX = "/tools/authcodetoopenid";
// sandbox
public static final String SANDBOX_MICROPAY_URL_SUFFIX = "/sandboxnew/pay/micropay";
public static final String SANDBOX_UNIFIEDORDER_URL_SUFFIX = "/sandboxnew/pay/unifiedorder";
public static final String SANDBOX_ORDERQUERY_URL_SUFFIX = "/sandboxnew/pay/orderquery";
public static final String SANDBOX_REVERSE_URL_SUFFIX = "/sandboxnew/secapi/pay/reverse";
public static final String SANDBOX_CLOSEORDER_URL_SUFFIX = "/sandboxnew/pay/closeorder";
public static final String SANDBOX_REFUND_URL_SUFFIX = "/sandboxnew/secapi/pay/refund";
public static final String SANDBOX_REFUNDQUERY_URL_SUFFIX = "/sandboxnew/pay/refundquery";
public static final String SANDBOX_DOWNLOADBILL_URL_SUFFIX = "/sandboxnew/pay/downloadbill";
public static final String SANDBOX_REPORT_URL_SUFFIX = "/sandboxnew/payitil/report";
public static final String SANDBOX_SHORTURL_URL_SUFFIX = "/sandboxnew/tools/shorturl";
public static final String SANDBOX_AUTHCODETOOPENID_URL_SUFFIX = "/sandboxnew/tools/authcodetoopenid";
}

@ -0,0 +1,265 @@
package com.hai.common.pay.util.sdk;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
/**
* 交易保障
*/
public class WXPayReport {
public static class ReportInfo {
/**
* 布尔变量使用int0为false 1为true
*/
// 基本信息
private String version = "v1";
private String sdk = WXPayConstants.WXPAYSDK_VERSION;
private String uuid; // 交易的标识
private long timestamp; // 上报时的时间戳,单位秒
private long elapsedTimeMillis; // 耗时,单位 毫秒
// 针对主域名
private String firstDomain; // 第1次请求的域名
private boolean primaryDomain; //是否主域名
private int firstConnectTimeoutMillis; // 第1次请求设置的连接超时时间,单位 毫秒
private int firstReadTimeoutMillis; // 第1次请求设置的读写超时时间,单位 毫秒
private int firstHasDnsError; // 第1次请求是否出现dns问题
private int firstHasConnectTimeout; // 第1次请求是否出现连接超时
private int firstHasReadTimeout; // 第1次请求是否出现连接超时
public ReportInfo(String uuid, long timestamp, long elapsedTimeMillis, String firstDomain, boolean primaryDomain, int firstConnectTimeoutMillis, int firstReadTimeoutMillis, boolean firstHasDnsError, boolean firstHasConnectTimeout, boolean firstHasReadTimeout) {
this.uuid = uuid;
this.timestamp = timestamp;
this.elapsedTimeMillis = elapsedTimeMillis;
this.firstDomain = firstDomain;
this.primaryDomain = primaryDomain;
this.firstConnectTimeoutMillis = firstConnectTimeoutMillis;
this.firstReadTimeoutMillis = firstReadTimeoutMillis;
this.firstHasDnsError = firstHasDnsError?1:0;
this.firstHasConnectTimeout = firstHasConnectTimeout?1:0;
this.firstHasReadTimeout = firstHasReadTimeout?1:0;
}
@Override
public String toString() {
return "ReportInfo{" +
"version='" + version + '\'' +
", sdk='" + sdk + '\'' +
", uuid='" + uuid + '\'' +
", timestamp=" + timestamp +
", elapsedTimeMillis=" + elapsedTimeMillis +
", firstDomain='" + firstDomain + '\'' +
", primaryDomain=" + primaryDomain +
", firstConnectTimeoutMillis=" + firstConnectTimeoutMillis +
", firstReadTimeoutMillis=" + firstReadTimeoutMillis +
", firstHasDnsError=" + firstHasDnsError +
", firstHasConnectTimeout=" + firstHasConnectTimeout +
", firstHasReadTimeout=" + firstHasReadTimeout +
'}';
}
/**
* 转换成 csv 格式
*
* @return
*/
public String toLineString(String key) {
String separator = ",";
Object[] objects = new Object[] {
version, sdk, uuid, timestamp, elapsedTimeMillis,
firstDomain, primaryDomain, firstConnectTimeoutMillis, firstReadTimeoutMillis,
firstHasDnsError, firstHasConnectTimeout, firstHasReadTimeout
};
StringBuffer sb = new StringBuffer();
for(Object obj: objects) {
sb.append(obj).append(separator);
}
try {
String sign = WXPayUtil.HMACSHA256(sb.toString(), key);
sb.append(sign);
return sb.toString();
}
catch (Exception ex) {
return null;
}
}
}
private static final String REPORT_URL = "http://report.mch.weixin.qq.com/wxpay/report/default";
// private static final String REPORT_URL = "http://127.0.0.1:5000/test";
private static final int DEFAULT_CONNECT_TIMEOUT_MS = 6*1000;
private static final int DEFAULT_READ_TIMEOUT_MS = 8*1000;
private LinkedBlockingQueue<String> reportMsgQueue = null;
private WXPayConfig config;
private ExecutorService executorService;
private volatile static WXPayReport INSTANCE;
private WXPayReport(final WXPayConfig config) {
this.config = config;
reportMsgQueue = new LinkedBlockingQueue<String>(config.getReportQueueMaxSize());
// 添加处理线程
executorService = Executors.newFixedThreadPool(config.getReportWorkerNum(), new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setDaemon(true);
return t;
}
});
if (config.shouldAutoReport()) {
WXPayUtil.getLogger().info("report worker num: {}", config.getReportWorkerNum());
for (int i = 0; i < config.getReportWorkerNum(); ++i) {
executorService.execute(new Runnable() {
public void run() {
while (true) {
// 先用 take 获取数据
try {
StringBuffer sb = new StringBuffer();
String firstMsg = reportMsgQueue.take();
WXPayUtil.getLogger().info("get first report msg: {}", firstMsg);
String msg = null;
sb.append(firstMsg); //会阻塞至有消息
int remainNum = config.getReportBatchSize() - 1;
for (int j=0; j<remainNum; ++j) {
WXPayUtil.getLogger().info("try get remain report msg");
// msg = reportMsgQueue.poll(); // 不阻塞了
msg = reportMsgQueue.take();
WXPayUtil.getLogger().info("get remain report msg: {}", msg);
if (msg == null) {
break;
}
else {
sb.append("\n");
sb.append(msg);
}
}
// 上报
WXPayReport.httpRequest(sb.toString(), DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_READ_TIMEOUT_MS);
}
catch (Exception ex) {
WXPayUtil.getLogger().warn("report fail. reason: {}", ex.getMessage());
}
}
}
});
}
}
}
/**
* 单例双重校验请在 JDK 1.5及更高版本中使用
*
* @param config
* @return
*/
public static WXPayReport getInstance(WXPayConfig config) {
if (INSTANCE == null) {
synchronized (WXPayReport.class) {
if (INSTANCE == null) {
INSTANCE = new WXPayReport(config);
}
}
}
return INSTANCE;
}
public void report(String uuid, long elapsedTimeMillis,
String firstDomain, boolean primaryDomain, int firstConnectTimeoutMillis, int firstReadTimeoutMillis,
boolean firstHasDnsError, boolean firstHasConnectTimeout, boolean firstHasReadTimeout) {
long currentTimestamp = WXPayUtil.getCurrentTimestamp();
ReportInfo reportInfo = new ReportInfo(uuid, currentTimestamp, elapsedTimeMillis,
firstDomain, primaryDomain, firstConnectTimeoutMillis, firstReadTimeoutMillis,
firstHasDnsError, firstHasConnectTimeout, firstHasReadTimeout);
String data = reportInfo.toLineString(config.getKey());
WXPayUtil.getLogger().info("report {}", data);
if (data != null) {
reportMsgQueue.offer(data);
}
}
@Deprecated
private void reportSync(final String data) throws Exception {
httpRequest(data, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_READ_TIMEOUT_MS);
}
@Deprecated
private void reportAsync(final String data) throws Exception {
new Thread(new Runnable() {
public void run() {
try {
httpRequest(data, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_READ_TIMEOUT_MS);
}
catch (Exception ex) {
WXPayUtil.getLogger().warn("report fail. reason: {}", ex.getMessage());
}
}
}).start();
}
/**
* http 请求
* @param data
* @param connectTimeoutMs
* @param readTimeoutMs
* @return
* @throws Exception
*/
private static String httpRequest(String data, int connectTimeoutMs, int readTimeoutMs) throws Exception{
BasicHttpClientConnectionManager connManager;
connManager = new BasicHttpClientConnectionManager(
RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", SSLConnectionSocketFactory.getSocketFactory())
.build(),
null,
null,
null
);
HttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(connManager)
.build();
HttpPost httpPost = new HttpPost(REPORT_URL);
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeoutMs).setConnectTimeout(connectTimeoutMs).build();
httpPost.setConfig(requestConfig);
StringEntity postEntity = new StringEntity(data, "UTF-8");
httpPost.addHeader("Content-Type", "text/xml");
httpPost.addHeader("User-Agent", WXPayConstants.USER_AGENT);
httpPost.setEntity(postEntity);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
return EntityUtils.toString(httpEntity, "UTF-8");
}
}

@ -0,0 +1,258 @@
package com.hai.common.pay.util.sdk;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import java.io.InputStream;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.security.KeyStore;
import java.security.SecureRandom;
import static com.shinwoten.train.common.pay.util.sdk.WXPayConstants.USER_AGENT;
public class WXPayRequest {
private WXPayConfig config;
public WXPayRequest(WXPayConfig config) throws Exception{
this.config = config;
}
/**
* 请求只请求一次不做重试
* @param domain
* @param urlSuffix
* @param uuid
* @param data
* @param connectTimeoutMs
* @param readTimeoutMs
* @param useCert 是否使用证书针对退款撤销等操作
* @return
* @throws Exception
*/
private String requestOnce(final String domain, String urlSuffix, String uuid, String data, int connectTimeoutMs, int readTimeoutMs, boolean useCert) throws Exception {
BasicHttpClientConnectionManager connManager;
if (useCert) {
// 证书
char[] password = config.getMchID().toCharArray();
InputStream certStream = config.getCertStream();
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(certStream, password);
// 实例化密钥库 & 初始化密钥工厂
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, password);
// 创建 SSLContext
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), null, new SecureRandom());
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
sslContext,
new String[]{"TLSv1"},
null,
new DefaultHostnameVerifier());
connManager = new BasicHttpClientConnectionManager(
RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslConnectionSocketFactory)
.build(),
null,
null,
null
);
}
else {
connManager = new BasicHttpClientConnectionManager(
RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", SSLConnectionSocketFactory.getSocketFactory())
.build(),
null,
null,
null
);
}
HttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(connManager)
.build();
String url = "https://" + domain + urlSuffix;
HttpPost httpPost = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeoutMs).setConnectTimeout(connectTimeoutMs).build();
httpPost.setConfig(requestConfig);
StringEntity postEntity = new StringEntity(data, "UTF-8");
httpPost.addHeader("Content-Type", "text/xml");
httpPost.addHeader("User-Agent", USER_AGENT + " " + config.getMchID());
httpPost.setEntity(postEntity);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
return EntityUtils.toString(httpEntity, "UTF-8");
}
private String request(String urlSuffix, String uuid, String data, int connectTimeoutMs, int readTimeoutMs, boolean useCert, boolean autoReport) throws Exception {
Exception exception = null;
long elapsedTimeMillis = 0;
long startTimestampMs = WXPayUtil.getCurrentTimestampMs();
boolean firstHasDnsErr = false;
boolean firstHasConnectTimeout = false;
boolean firstHasReadTimeout = false;
IWXPayDomain.DomainInfo domainInfo = config.getWXPayDomain().getDomain(config);
if(domainInfo == null){
throw new Exception("WXPayConfig.getWXPayDomain().getDomain() is empty or null");
}
try {
String result = requestOnce(domainInfo.domain, urlSuffix, uuid, data, connectTimeoutMs, readTimeoutMs, useCert);
elapsedTimeMillis = WXPayUtil.getCurrentTimestampMs()-startTimestampMs;
config.getWXPayDomain().report(domainInfo.domain, elapsedTimeMillis, null);
WXPayReport.getInstance(config).report(
uuid,
elapsedTimeMillis,
domainInfo.domain,
domainInfo.primaryDomain,
connectTimeoutMs,
readTimeoutMs,
firstHasDnsErr,
firstHasConnectTimeout,
firstHasReadTimeout);
return result;
}
catch (UnknownHostException ex) { // dns 解析错误,或域名不存在
exception = ex;
firstHasDnsErr = true;
elapsedTimeMillis = WXPayUtil.getCurrentTimestampMs()-startTimestampMs;
WXPayUtil.getLogger().warn("UnknownHostException for domainInfo {}", domainInfo);
WXPayReport.getInstance(config).report(
uuid,
elapsedTimeMillis,
domainInfo.domain,
domainInfo.primaryDomain,
connectTimeoutMs,
readTimeoutMs,
firstHasDnsErr,
firstHasConnectTimeout,
firstHasReadTimeout
);
}
catch (ConnectTimeoutException ex) {
exception = ex;
firstHasConnectTimeout = true;
elapsedTimeMillis = WXPayUtil.getCurrentTimestampMs()-startTimestampMs;
WXPayUtil.getLogger().warn("connect timeout happened for domainInfo {}", domainInfo);
WXPayReport.getInstance(config).report(
uuid,
elapsedTimeMillis,
domainInfo.domain,
domainInfo.primaryDomain,
connectTimeoutMs,
readTimeoutMs,
firstHasDnsErr,
firstHasConnectTimeout,
firstHasReadTimeout
);
}
catch (SocketTimeoutException ex) {
exception = ex;
firstHasReadTimeout = true;
elapsedTimeMillis = WXPayUtil.getCurrentTimestampMs()-startTimestampMs;
WXPayUtil.getLogger().warn("timeout happened for domainInfo {}", domainInfo);
WXPayReport.getInstance(config).report(
uuid,
elapsedTimeMillis,
domainInfo.domain,
domainInfo.primaryDomain,
connectTimeoutMs,
readTimeoutMs,
firstHasDnsErr,
firstHasConnectTimeout,
firstHasReadTimeout);
}
catch (Exception ex) {
exception = ex;
elapsedTimeMillis = WXPayUtil.getCurrentTimestampMs()-startTimestampMs;
WXPayReport.getInstance(config).report(
uuid,
elapsedTimeMillis,
domainInfo.domain,
domainInfo.primaryDomain,
connectTimeoutMs,
readTimeoutMs,
firstHasDnsErr,
firstHasConnectTimeout,
firstHasReadTimeout);
}
config.getWXPayDomain().report(domainInfo.domain, elapsedTimeMillis, exception);
throw exception;
}
/**
* 可重试的非双向认证的请求
* @param urlSuffix
* @param uuid
* @param data
* @return
*/
public String requestWithoutCert(String urlSuffix, String uuid, String data, boolean autoReport) throws Exception {
return this.request(urlSuffix, uuid, data, config.getHttpConnectTimeoutMs(), config.getHttpReadTimeoutMs(), false, autoReport);
}
/**
* 可重试的非双向认证的请求
* @param urlSuffix
* @param uuid
* @param data
* @param connectTimeoutMs
* @param readTimeoutMs
* @return
*/
public String requestWithoutCert(String urlSuffix, String uuid, String data, int connectTimeoutMs, int readTimeoutMs, boolean autoReport) throws Exception {
return this.request(urlSuffix, uuid, data, connectTimeoutMs, readTimeoutMs, false, autoReport);
}
/**
* 可重试的双向认证的请求
* @param urlSuffix
* @param uuid
* @param data
* @return
*/
public String requestWithCert(String urlSuffix, String uuid, String data, boolean autoReport) throws Exception {
return this.request(urlSuffix, uuid, data, config.getHttpConnectTimeoutMs(), config.getHttpReadTimeoutMs(), true, autoReport);
}
/**
* 可重试的双向认证的请求
* @param urlSuffix
* @param uuid
* @param data
* @param connectTimeoutMs
* @param readTimeoutMs
* @return
*/
public String requestWithCert(String urlSuffix, String uuid, String data, int connectTimeoutMs, int readTimeoutMs, boolean autoReport) throws Exception {
return this.request(urlSuffix, uuid, data, connectTimeoutMs, readTimeoutMs, true, autoReport);
}
}

@ -0,0 +1,295 @@
package com.hai.common.pay.util.sdk;
import com.hai.common.pay.util.sdk.WXPayConstants.SignType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.*;
public class WXPayUtil {
private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final Random RANDOM = new SecureRandom();
/**
* XML格式字符串转换为Map
*
* @param strXML XML字符串
* @return XML数据转换后的Map
* @throws Exception
*/
public static Map<String, String> xmlToMap(String strXML) throws Exception {
try {
Map<String, String> data = new HashMap<String, String>();
DocumentBuilder documentBuilder = WXPayXmlUtil.newDocumentBuilder();
InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
org.w3c.dom.Document doc = documentBuilder.parse(stream);
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getDocumentElement().getChildNodes();
for (int idx = 0; idx < nodeList.getLength(); ++idx) {
Node node = nodeList.item(idx);
if (node.getNodeType() == Node.ELEMENT_NODE) {
org.w3c.dom.Element element = (org.w3c.dom.Element) node;
data.put(element.getNodeName(), element.getTextContent());
}
}
try {
stream.close();
} catch (Exception ex) {
// do nothing
}
return data;
} catch (Exception ex) {
WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
throw ex;
}
}
/**
* 将Map转换为XML格式的字符串
*
* @param data Map类型数据
* @return XML格式的字符串
* @throws Exception
*/
public static String mapToXml(Map<String, String> data) throws Exception {
org.w3c.dom.Document document = WXPayXmlUtil.newDocument();
org.w3c.dom.Element root = document.createElement("xml");
document.appendChild(root);
for (String key: data.keySet()) {
String value = data.get(key);
if (value == null) {
value = "";
}
value = value.trim();
org.w3c.dom.Element filed = document.createElement(key);
filed.appendChild(document.createTextNode(value));
root.appendChild(filed);
}
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
DOMSource source = new DOMSource(document);
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
transformer.transform(source, result);
String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
try {
writer.close();
}
catch (Exception ex) {
}
return output;
}
/**
* 生成带有 sign XML 格式字符串
*
* @param data Map类型数据
* @param key API密钥
* @return 含有sign字段的XML
*/
public static String generateSignedXml(final Map<String, String> data, String key) throws Exception {
return generateSignedXml(data, key, SignType.MD5);
}
/**
* 生成带有 sign XML 格式字符串
*
* @param data Map类型数据
* @param key API密钥
* @param signType 签名类型
* @return 含有sign字段的XML
*/
public static String generateSignedXml(final Map<String, String> data, String key, SignType signType) throws Exception {
String sign = generateSignature(data, key, signType);
data.put(WXPayConstants.FIELD_SIGN, sign);
return mapToXml(data);
}
/**
* 判断签名是否正确
*
* @param xmlStr XML格式数据
* @param key API密钥
* @return 签名是否正确
* @throws Exception
*/
public static boolean isSignatureValid(String xmlStr, String key) throws Exception {
Map<String, String> data = xmlToMap(xmlStr);
if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) {
return false;
}
String sign = data.get(WXPayConstants.FIELD_SIGN);
return generateSignature(data, key).equals(sign);
}
/**
* 判断签名是否正确必须包含sign字段否则返回false使用MD5签名
*
* @param data Map类型数据
* @param key API密钥
* @return 签名是否正确
* @throws Exception
*/
public static boolean isSignatureValid(Map<String, String> data, String key) throws Exception {
return isSignatureValid(data, key, SignType.MD5);
}
/**
* 判断签名是否正确必须包含sign字段否则返回false
*
* @param data Map类型数据
* @param key API密钥
* @param signType 签名方式
* @return 签名是否正确
* @throws Exception
*/
public static boolean isSignatureValid(Map<String, String> data, String key, SignType signType) throws Exception {
if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) {
return false;
}
String sign = data.get(WXPayConstants.FIELD_SIGN);
return generateSignature(data, key, signType).equals(sign);
}
/**
* 生成签名
*
* @param data 待签名数据
* @param key API密钥
* @return 签名
*/
public static String generateSignature(final Map<String, String> data, String key) throws Exception {
return generateSignature(data, key, SignType.MD5);
}
/**
* 生成签名. 注意若含有sign_type字段必须和signType参数保持一致
*
* @param data 待签名数据
* @param key API密钥
* @param signType 签名方式
* @return 签名
*/
public static String generateSignature(final Map<String, String> data, String key, SignType signType) throws Exception {
Set<String> keySet = data.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
for (String k : keyArray) {
if (k.equals(WXPayConstants.FIELD_SIGN)) {
continue;
}
if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名
sb.append(k).append("=").append(data.get(k).trim()).append("&");
}
sb.append("key=").append(key);
if (SignType.MD5.equals(signType)) {
return MD5(sb.toString()).toUpperCase();
}
else if (SignType.HMACSHA256.equals(signType)) {
return HMACSHA256(sb.toString(), key);
}
else {
throw new Exception(String.format("Invalid sign_type: %s", signType));
}
}
/**
* 获取随机字符串 Nonce Str
*
* @return String 随机字符串
*/
public static String generateNonceStr() {
char[] nonceChars = new char[32];
for (int index = 0; index < nonceChars.length; ++index) {
nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
}
return new String(nonceChars);
}
/**
* 生成 MD5
*
* @param data 待处理数据
* @return MD5结果
*/
public static String MD5(String data) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] array = md.digest(data.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString().toUpperCase();
}
/**
* 生成 HMACSHA256
* @param data 待处理数据
* @param key 密钥
* @return 加密结果
* @throws Exception
*/
public static String HMACSHA256(String data, String key) throws Exception {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString().toUpperCase();
}
/**
* 日志
* @return
*/
public static Logger getLogger() {
Logger logger = LoggerFactory.getLogger("wxpay java sdk");
return logger;
}
/**
* 获取当前时间戳单位秒
* @return
*/
public static long getCurrentTimestamp() {
return System.currentTimeMillis()/1000;
}
/**
* 获取当前时间戳单位毫秒
* @return
*/
public static long getCurrentTimestampMs() {
return System.currentTimeMillis();
}
}

@ -0,0 +1,30 @@
package com.hai.common.pay.util.sdk;
import org.w3c.dom.Document;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
/**
* 2018/7/3
*/
public final class WXPayXmlUtil {
public static DocumentBuilder newDocumentBuilder() throws ParserConfigurationException {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
documentBuilderFactory.setXIncludeAware(false);
documentBuilderFactory.setExpandEntityReferences(false);
return documentBuilderFactory.newDocumentBuilder();
}
public static Document newDocument() throws ParserConfigurationException {
return newDocumentBuilder().newDocument();
}
}

@ -0,0 +1,63 @@
package com.hai.common.utils;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class IDGenerator {
private static final long ONE_STEP = 10;
private static final Lock LOCK = new ReentrantLock();
private static long lastTime = System.nanoTime();
private static short lastCount = 0;
private static int count = 0;
/**
* 可传入指定长度的值
* @param length
* @return
*/
@SuppressWarnings("finally")
public static String nextId(int... length)
{
LOCK.lock();
try {
if (lastCount == ONE_STEP) {
boolean done = false;
while (!done) {
long now = System.nanoTime();
if (now == lastTime) {
try {
Thread.currentThread();
Thread.sleep(1);
} catch (InterruptedException e) {
}
continue;
} else {
lastTime = now;
lastCount = 0;
done = true;
}
}
}
count = lastCount++;
}
finally
{
LOCK.unlock();
String idStr = lastTime+""+String.format("%02d",count);
if(length.length > 0 && length[0] > 0){
idStr = idStr.substring(idStr.length()-length[0]<0?0:idStr.length()-length[0], idStr.length());
}
return idStr;
}
}
public static void main(String[] args)
{
// for(int i=0;i<100;i++)
// {
// System.out.println(nextId());
// }
// nextId(20);
System.out.println(System.currentTimeMillis());
}
}

@ -0,0 +1,25 @@
package com.hai.common.utils;
import java.math.BigDecimal;
import java.math.BigInteger;
public class MathUtils {
public static BigDecimal objectConvertBigDecimal(Object value) {
BigDecimal ret = null;
if (value != null) {
if (value instanceof BigDecimal) {
ret = (BigDecimal) value;
} else if (value instanceof String) {
ret = new BigDecimal((String) value);
} else if (value instanceof BigInteger) {
ret = new BigDecimal((BigInteger) value);
} else if (value instanceof Number) {
ret = new BigDecimal(((Number) value).doubleValue());
} else {
throw new ClassCastException("Not possible to coerce [" + value + "] from class " + value.getClass() + " into a BigDecimal.");
}
}
return ret;
}
}

@ -49,8 +49,8 @@ public interface HighChildOrderMapper extends HighChildOrderMapperExt {
"values (#{orderId,jdbcType=BIGINT}, #{goodsType,jdbcType=INTEGER}, ",
"#{goodsId,jdbcType=BIGINT}, #{goodsName,jdbcType=VARCHAR}, ",
"#{goodsImg,jdbcType=VARCHAR}, #{goodsSpecName,jdbcType=VARCHAR}, ",
"#{goodsPrice,jdbcType=REAL}, #{saleCount,jdbcType=INTEGER}, ",
"#{totalPrice,jdbcType=REAL}, #{giveawayType,jdbcType=BIT}, ",
"#{goodsPrice,jdbcType=DECIMAL}, #{saleCount,jdbcType=INTEGER}, ",
"#{totalPrice,jdbcType=DECIMAL}, #{giveawayType,jdbcType=BIT}, ",
"#{childOrdeStatus,jdbcType=INTEGER}, #{praiseStatus,jdbcType=INTEGER}, ",
"#{ext1,jdbcType=VARCHAR}, #{ext2,jdbcType=VARCHAR}, #{ext3,jdbcType=VARCHAR})"
})
@ -70,9 +70,9 @@ public interface HighChildOrderMapper extends HighChildOrderMapperExt {
@Result(column="goods_name", property="goodsName", jdbcType=JdbcType.VARCHAR),
@Result(column="goods_img", property="goodsImg", jdbcType=JdbcType.VARCHAR),
@Result(column="goods_spec_name", property="goodsSpecName", jdbcType=JdbcType.VARCHAR),
@Result(column="goods_price", property="goodsPrice", jdbcType=JdbcType.REAL),
@Result(column="goods_price", property="goodsPrice", jdbcType=JdbcType.DECIMAL),
@Result(column="sale_count", property="saleCount", jdbcType=JdbcType.INTEGER),
@Result(column="total_price", property="totalPrice", jdbcType=JdbcType.REAL),
@Result(column="total_price", property="totalPrice", jdbcType=JdbcType.DECIMAL),
@Result(column="giveaway_type", property="giveawayType", jdbcType=JdbcType.BIT),
@Result(column="child_orde_status", property="childOrdeStatus", jdbcType=JdbcType.INTEGER),
@Result(column="praise_status", property="praiseStatus", jdbcType=JdbcType.INTEGER),
@ -98,9 +98,9 @@ public interface HighChildOrderMapper extends HighChildOrderMapperExt {
@Result(column="goods_name", property="goodsName", jdbcType=JdbcType.VARCHAR),
@Result(column="goods_img", property="goodsImg", jdbcType=JdbcType.VARCHAR),
@Result(column="goods_spec_name", property="goodsSpecName", jdbcType=JdbcType.VARCHAR),
@Result(column="goods_price", property="goodsPrice", jdbcType=JdbcType.REAL),
@Result(column="goods_price", property="goodsPrice", jdbcType=JdbcType.DECIMAL),
@Result(column="sale_count", property="saleCount", jdbcType=JdbcType.INTEGER),
@Result(column="total_price", property="totalPrice", jdbcType=JdbcType.REAL),
@Result(column="total_price", property="totalPrice", jdbcType=JdbcType.DECIMAL),
@Result(column="giveaway_type", property="giveawayType", jdbcType=JdbcType.BIT),
@Result(column="child_orde_status", property="childOrdeStatus", jdbcType=JdbcType.INTEGER),
@Result(column="praise_status", property="praiseStatus", jdbcType=JdbcType.INTEGER),
@ -127,9 +127,9 @@ public interface HighChildOrderMapper extends HighChildOrderMapperExt {
"goods_name = #{goodsName,jdbcType=VARCHAR},",
"goods_img = #{goodsImg,jdbcType=VARCHAR},",
"goods_spec_name = #{goodsSpecName,jdbcType=VARCHAR},",
"goods_price = #{goodsPrice,jdbcType=REAL},",
"goods_price = #{goodsPrice,jdbcType=DECIMAL},",
"sale_count = #{saleCount,jdbcType=INTEGER},",
"total_price = #{totalPrice,jdbcType=REAL},",
"total_price = #{totalPrice,jdbcType=DECIMAL},",
"giveaway_type = #{giveawayType,jdbcType=BIT},",
"child_orde_status = #{childOrdeStatus,jdbcType=INTEGER},",
"praise_status = #{praiseStatus,jdbcType=INTEGER},",

@ -53,7 +53,7 @@ public class HighChildOrderSqlProvider {
}
if (record.getGoodsPrice() != null) {
sql.VALUES("goods_price", "#{goodsPrice,jdbcType=REAL}");
sql.VALUES("goods_price", "#{goodsPrice,jdbcType=DECIMAL}");
}
if (record.getSaleCount() != null) {
@ -61,7 +61,7 @@ public class HighChildOrderSqlProvider {
}
if (record.getTotalPrice() != null) {
sql.VALUES("total_price", "#{totalPrice,jdbcType=REAL}");
sql.VALUES("total_price", "#{totalPrice,jdbcType=DECIMAL}");
}
if (record.getGiveawayType() != null) {
@ -159,7 +159,7 @@ public class HighChildOrderSqlProvider {
}
if (record.getGoodsPrice() != null) {
sql.SET("goods_price = #{record.goodsPrice,jdbcType=REAL}");
sql.SET("goods_price = #{record.goodsPrice,jdbcType=DECIMAL}");
}
if (record.getSaleCount() != null) {
@ -167,7 +167,7 @@ public class HighChildOrderSqlProvider {
}
if (record.getTotalPrice() != null) {
sql.SET("total_price = #{record.totalPrice,jdbcType=REAL}");
sql.SET("total_price = #{record.totalPrice,jdbcType=DECIMAL}");
}
if (record.getGiveawayType() != null) {
@ -209,9 +209,9 @@ public class HighChildOrderSqlProvider {
sql.SET("goods_name = #{record.goodsName,jdbcType=VARCHAR}");
sql.SET("goods_img = #{record.goodsImg,jdbcType=VARCHAR}");
sql.SET("goods_spec_name = #{record.goodsSpecName,jdbcType=VARCHAR}");
sql.SET("goods_price = #{record.goodsPrice,jdbcType=REAL}");
sql.SET("goods_price = #{record.goodsPrice,jdbcType=DECIMAL}");
sql.SET("sale_count = #{record.saleCount,jdbcType=INTEGER}");
sql.SET("total_price = #{record.totalPrice,jdbcType=REAL}");
sql.SET("total_price = #{record.totalPrice,jdbcType=DECIMAL}");
sql.SET("giveaway_type = #{record.giveawayType,jdbcType=BIT}");
sql.SET("child_orde_status = #{record.childOrdeStatus,jdbcType=INTEGER}");
sql.SET("praise_status = #{record.praiseStatus,jdbcType=INTEGER}");
@ -253,7 +253,7 @@ public class HighChildOrderSqlProvider {
}
if (record.getGoodsPrice() != null) {
sql.SET("goods_price = #{goodsPrice,jdbcType=REAL}");
sql.SET("goods_price = #{goodsPrice,jdbcType=DECIMAL}");
}
if (record.getSaleCount() != null) {
@ -261,7 +261,7 @@ public class HighChildOrderSqlProvider {
}
if (record.getTotalPrice() != null) {
sql.SET("total_price = #{totalPrice,jdbcType=REAL}");
sql.SET("total_price = #{totalPrice,jdbcType=DECIMAL}");
}
if (record.getGiveawayType() != null) {

@ -49,8 +49,8 @@ public interface HighCouponMapper extends HighCouponMapperExt {
"sales_count, is_present, ",
"create_time, update_time, ",
"operator_id, operator_name, ",
"`status`, ext_1, ext_2, ",
"ext_3)",
"pay_type, ext_1, ext_2, ",
"ext_3, `status`, display_area)",
"values (#{companyId,jdbcType=BIGINT}, #{merchantId,jdbcType=BIGINT}, ",
"#{couponKey,jdbcType=VARCHAR}, #{couponName,jdbcType=VARCHAR}, ",
"#{couponPrice,jdbcType=DECIMAL}, #{couponImg,jdbcType=VARCHAR}, ",
@ -61,8 +61,8 @@ public interface HighCouponMapper extends HighCouponMapperExt {
"#{salesCount,jdbcType=INTEGER}, #{isPresent,jdbcType=BIT}, ",
"#{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP}, ",
"#{operatorId,jdbcType=BIGINT}, #{operatorName,jdbcType=VARCHAR}, ",
"#{status,jdbcType=INTEGER}, #{ext1,jdbcType=VARCHAR}, #{ext2,jdbcType=VARCHAR}, ",
"#{ext3,jdbcType=VARCHAR})"
"#{payType,jdbcType=INTEGER}, #{ext1,jdbcType=VARCHAR}, #{ext2,jdbcType=VARCHAR}, ",
"#{ext3,jdbcType=VARCHAR}, #{status,jdbcType=INTEGER}, #{displayArea,jdbcType=INTEGER})"
})
@Options(useGeneratedKeys=true,keyProperty="id")
int insert(HighCoupon record);
@ -94,10 +94,12 @@ public interface HighCouponMapper extends HighCouponMapperExt {
@Result(column="update_time", property="updateTime", jdbcType=JdbcType.TIMESTAMP),
@Result(column="operator_id", property="operatorId", jdbcType=JdbcType.BIGINT),
@Result(column="operator_name", property="operatorName", jdbcType=JdbcType.VARCHAR),
@Result(column="status", property="status", jdbcType=JdbcType.INTEGER),
@Result(column="pay_type", property="payType", jdbcType=JdbcType.INTEGER),
@Result(column="ext_1", property="ext1", jdbcType=JdbcType.VARCHAR),
@Result(column="ext_2", property="ext2", jdbcType=JdbcType.VARCHAR),
@Result(column="ext_3", property="ext3", jdbcType=JdbcType.VARCHAR)
@Result(column="ext_3", property="ext3", jdbcType=JdbcType.VARCHAR),
@Result(column="status", property="status", jdbcType=JdbcType.INTEGER),
@Result(column="display_area", property="displayArea", jdbcType=JdbcType.INTEGER)
})
List<HighCoupon> selectByExample(HighCouponExample example);
@ -106,7 +108,8 @@ public interface HighCouponMapper extends HighCouponMapperExt {
"id, company_id, merchant_id, coupon_key, coupon_name, coupon_price, coupon_img, ",
"coupon_carousel_img, coupon_desc, coupon_type, sales_end_time, recycle_day, ",
"limit_number, sales_price, discount_price, sales_count, is_present, create_time, ",
"update_time, operator_id, operator_name, `status`, ext_1, ext_2, ext_3",
"update_time, operator_id, operator_name, pay_type, ext_1, ext_2, ext_3, `status`, ",
"display_area",
"from high_coupon",
"where id = #{id,jdbcType=BIGINT}"
})
@ -132,10 +135,12 @@ public interface HighCouponMapper extends HighCouponMapperExt {
@Result(column="update_time", property="updateTime", jdbcType=JdbcType.TIMESTAMP),
@Result(column="operator_id", property="operatorId", jdbcType=JdbcType.BIGINT),
@Result(column="operator_name", property="operatorName", jdbcType=JdbcType.VARCHAR),
@Result(column="status", property="status", jdbcType=JdbcType.INTEGER),
@Result(column="pay_type", property="payType", jdbcType=JdbcType.INTEGER),
@Result(column="ext_1", property="ext1", jdbcType=JdbcType.VARCHAR),
@Result(column="ext_2", property="ext2", jdbcType=JdbcType.VARCHAR),
@Result(column="ext_3", property="ext3", jdbcType=JdbcType.VARCHAR)
@Result(column="ext_3", property="ext3", jdbcType=JdbcType.VARCHAR),
@Result(column="status", property="status", jdbcType=JdbcType.INTEGER),
@Result(column="display_area", property="displayArea", jdbcType=JdbcType.INTEGER)
})
HighCoupon selectByPrimaryKey(Long id);
@ -170,10 +175,12 @@ public interface HighCouponMapper extends HighCouponMapperExt {
"update_time = #{updateTime,jdbcType=TIMESTAMP},",
"operator_id = #{operatorId,jdbcType=BIGINT},",
"operator_name = #{operatorName,jdbcType=VARCHAR},",
"`status` = #{status,jdbcType=INTEGER},",
"pay_type = #{payType,jdbcType=INTEGER},",
"ext_1 = #{ext1,jdbcType=VARCHAR},",
"ext_2 = #{ext2,jdbcType=VARCHAR},",
"ext_3 = #{ext3,jdbcType=VARCHAR}",
"ext_3 = #{ext3,jdbcType=VARCHAR},",
"`status` = #{status,jdbcType=INTEGER},",
"display_area = #{displayArea,jdbcType=INTEGER}",
"where id = #{id,jdbcType=BIGINT}"
})
int updateByPrimaryKey(HighCoupon record);

@ -108,8 +108,8 @@ public class HighCouponSqlProvider {
sql.VALUES("operator_name", "#{operatorName,jdbcType=VARCHAR}");
}
if (record.getStatus() != null) {
sql.VALUES("`status`", "#{status,jdbcType=INTEGER}");
if (record.getPayType() != null) {
sql.VALUES("pay_type", "#{payType,jdbcType=INTEGER}");
}
if (record.getExt1() != null) {
@ -124,6 +124,14 @@ public class HighCouponSqlProvider {
sql.VALUES("ext_3", "#{ext3,jdbcType=VARCHAR}");
}
if (record.getStatus() != null) {
sql.VALUES("`status`", "#{status,jdbcType=INTEGER}");
}
if (record.getDisplayArea() != null) {
sql.VALUES("display_area", "#{displayArea,jdbcType=INTEGER}");
}
return sql.toString();
}
@ -154,10 +162,12 @@ public class HighCouponSqlProvider {
sql.SELECT("update_time");
sql.SELECT("operator_id");
sql.SELECT("operator_name");
sql.SELECT("`status`");
sql.SELECT("pay_type");
sql.SELECT("ext_1");
sql.SELECT("ext_2");
sql.SELECT("ext_3");
sql.SELECT("`status`");
sql.SELECT("display_area");
sql.FROM("high_coupon");
applyWhere(sql, example, false);
@ -259,8 +269,8 @@ public class HighCouponSqlProvider {
sql.SET("operator_name = #{record.operatorName,jdbcType=VARCHAR}");
}
if (record.getStatus() != null) {
sql.SET("`status` = #{record.status,jdbcType=INTEGER}");
if (record.getPayType() != null) {
sql.SET("pay_type = #{record.payType,jdbcType=INTEGER}");
}
if (record.getExt1() != null) {
@ -275,6 +285,14 @@ public class HighCouponSqlProvider {
sql.SET("ext_3 = #{record.ext3,jdbcType=VARCHAR}");
}
if (record.getStatus() != null) {
sql.SET("`status` = #{record.status,jdbcType=INTEGER}");
}
if (record.getDisplayArea() != null) {
sql.SET("display_area = #{record.displayArea,jdbcType=INTEGER}");
}
applyWhere(sql, example, true);
return sql.toString();
}
@ -304,10 +322,12 @@ public class HighCouponSqlProvider {
sql.SET("update_time = #{record.updateTime,jdbcType=TIMESTAMP}");
sql.SET("operator_id = #{record.operatorId,jdbcType=BIGINT}");
sql.SET("operator_name = #{record.operatorName,jdbcType=VARCHAR}");
sql.SET("`status` = #{record.status,jdbcType=INTEGER}");
sql.SET("pay_type = #{record.payType,jdbcType=INTEGER}");
sql.SET("ext_1 = #{record.ext1,jdbcType=VARCHAR}");
sql.SET("ext_2 = #{record.ext2,jdbcType=VARCHAR}");
sql.SET("ext_3 = #{record.ext3,jdbcType=VARCHAR}");
sql.SET("`status` = #{record.status,jdbcType=INTEGER}");
sql.SET("display_area = #{record.displayArea,jdbcType=INTEGER}");
HighCouponExample example = (HighCouponExample) parameter.get("example");
applyWhere(sql, example, true);
@ -398,8 +418,8 @@ public class HighCouponSqlProvider {
sql.SET("operator_name = #{operatorName,jdbcType=VARCHAR}");
}
if (record.getStatus() != null) {
sql.SET("`status` = #{status,jdbcType=INTEGER}");
if (record.getPayType() != null) {
sql.SET("pay_type = #{payType,jdbcType=INTEGER}");
}
if (record.getExt1() != null) {
@ -414,6 +434,14 @@ public class HighCouponSqlProvider {
sql.SET("ext_3 = #{ext3,jdbcType=VARCHAR}");
}
if (record.getStatus() != null) {
sql.SET("`status` = #{status,jdbcType=INTEGER}");
}
if (record.getDisplayArea() != null) {
sql.SET("display_area = #{displayArea,jdbcType=INTEGER}");
}
sql.WHERE("id = #{id,jdbcType=BIGINT}");
return sql.toString();

@ -39,8 +39,7 @@ public interface HighOrderMapper extends HighOrderMapperExt {
int deleteByPrimaryKey(Long id);
@Insert({
"insert into high_order (order_no, order_type, ",
"order_source, mem_id, ",
"insert into high_order (order_no, mem_id, ",
"mem_name, pay_model, ",
"pay_type, pay_gold, ",
"pay_price, pay_real_price, ",
@ -49,11 +48,10 @@ public interface HighOrderMapper extends HighOrderMapperExt {
"pay_time, cancel_time, ",
"finish_time, remarks, ",
"ext_1, ext_2, ext_3)",
"values (#{orderNo,jdbcType=VARCHAR}, #{orderType,jdbcType=INTEGER}, ",
"#{orderSource,jdbcType=BIGINT}, #{memId,jdbcType=BIGINT}, ",
"values (#{orderNo,jdbcType=VARCHAR}, #{memId,jdbcType=BIGINT}, ",
"#{memName,jdbcType=VARCHAR}, #{payModel,jdbcType=INTEGER}, ",
"#{payType,jdbcType=INTEGER}, #{payGold,jdbcType=INTEGER}, ",
"#{payPrice,jdbcType=REAL}, #{payRealPrice,jdbcType=REAL}, ",
"#{payPrice,jdbcType=DECIMAL}, #{payRealPrice,jdbcType=DECIMAL}, ",
"#{paySerialNo,jdbcType=VARCHAR}, #{orderStatus,jdbcType=INTEGER}, ",
"#{totalPrice,jdbcType=DECIMAL}, #{createTime,jdbcType=TIMESTAMP}, ",
"#{payTime,jdbcType=TIMESTAMP}, #{cancelTime,jdbcType=TIMESTAMP}, ",
@ -71,15 +69,13 @@ public interface HighOrderMapper extends HighOrderMapperExt {
@Results({
@Result(column="id", property="id", jdbcType=JdbcType.BIGINT, id=true),
@Result(column="order_no", property="orderNo", jdbcType=JdbcType.VARCHAR),
@Result(column="order_type", property="orderType", jdbcType=JdbcType.INTEGER),
@Result(column="order_source", property="orderSource", jdbcType=JdbcType.BIGINT),
@Result(column="mem_id", property="memId", jdbcType=JdbcType.BIGINT),
@Result(column="mem_name", property="memName", jdbcType=JdbcType.VARCHAR),
@Result(column="pay_model", property="payModel", jdbcType=JdbcType.INTEGER),
@Result(column="pay_type", property="payType", jdbcType=JdbcType.INTEGER),
@Result(column="pay_gold", property="payGold", jdbcType=JdbcType.INTEGER),
@Result(column="pay_price", property="payPrice", jdbcType=JdbcType.REAL),
@Result(column="pay_real_price", property="payRealPrice", jdbcType=JdbcType.REAL),
@Result(column="pay_price", property="payPrice", jdbcType=JdbcType.DECIMAL),
@Result(column="pay_real_price", property="payRealPrice", jdbcType=JdbcType.DECIMAL),
@Result(column="pay_serial_no", property="paySerialNo", jdbcType=JdbcType.VARCHAR),
@Result(column="order_status", property="orderStatus", jdbcType=JdbcType.INTEGER),
@Result(column="total_price", property="totalPrice", jdbcType=JdbcType.DECIMAL),
@ -96,24 +92,22 @@ public interface HighOrderMapper extends HighOrderMapperExt {
@Select({
"select",
"id, order_no, order_type, order_source, mem_id, mem_name, pay_model, pay_type, ",
"pay_gold, pay_price, pay_real_price, pay_serial_no, order_status, total_price, ",
"create_time, pay_time, cancel_time, finish_time, remarks, ext_1, ext_2, ext_3",
"id, order_no, mem_id, mem_name, pay_model, pay_type, pay_gold, pay_price, pay_real_price, ",
"pay_serial_no, order_status, total_price, create_time, pay_time, cancel_time, ",
"finish_time, remarks, ext_1, ext_2, ext_3",
"from high_order",
"where id = #{id,jdbcType=BIGINT}"
})
@Results({
@Result(column="id", property="id", jdbcType=JdbcType.BIGINT, id=true),
@Result(column="order_no", property="orderNo", jdbcType=JdbcType.VARCHAR),
@Result(column="order_type", property="orderType", jdbcType=JdbcType.INTEGER),
@Result(column="order_source", property="orderSource", jdbcType=JdbcType.BIGINT),
@Result(column="mem_id", property="memId", jdbcType=JdbcType.BIGINT),
@Result(column="mem_name", property="memName", jdbcType=JdbcType.VARCHAR),
@Result(column="pay_model", property="payModel", jdbcType=JdbcType.INTEGER),
@Result(column="pay_type", property="payType", jdbcType=JdbcType.INTEGER),
@Result(column="pay_gold", property="payGold", jdbcType=JdbcType.INTEGER),
@Result(column="pay_price", property="payPrice", jdbcType=JdbcType.REAL),
@Result(column="pay_real_price", property="payRealPrice", jdbcType=JdbcType.REAL),
@Result(column="pay_price", property="payPrice", jdbcType=JdbcType.DECIMAL),
@Result(column="pay_real_price", property="payRealPrice", jdbcType=JdbcType.DECIMAL),
@Result(column="pay_serial_no", property="paySerialNo", jdbcType=JdbcType.VARCHAR),
@Result(column="order_status", property="orderStatus", jdbcType=JdbcType.INTEGER),
@Result(column="total_price", property="totalPrice", jdbcType=JdbcType.DECIMAL),
@ -140,15 +134,13 @@ public interface HighOrderMapper extends HighOrderMapperExt {
@Update({
"update high_order",
"set order_no = #{orderNo,jdbcType=VARCHAR},",
"order_type = #{orderType,jdbcType=INTEGER},",
"order_source = #{orderSource,jdbcType=BIGINT},",
"mem_id = #{memId,jdbcType=BIGINT},",
"mem_name = #{memName,jdbcType=VARCHAR},",
"pay_model = #{payModel,jdbcType=INTEGER},",
"pay_type = #{payType,jdbcType=INTEGER},",
"pay_gold = #{payGold,jdbcType=INTEGER},",
"pay_price = #{payPrice,jdbcType=REAL},",
"pay_real_price = #{payRealPrice,jdbcType=REAL},",
"pay_price = #{payPrice,jdbcType=DECIMAL},",
"pay_real_price = #{payRealPrice,jdbcType=DECIMAL},",
"pay_serial_no = #{paySerialNo,jdbcType=VARCHAR},",
"order_status = #{orderStatus,jdbcType=INTEGER},",
"total_price = #{totalPrice,jdbcType=DECIMAL},",

@ -32,14 +32,6 @@ public class HighOrderSqlProvider {
sql.VALUES("order_no", "#{orderNo,jdbcType=VARCHAR}");
}
if (record.getOrderType() != null) {
sql.VALUES("order_type", "#{orderType,jdbcType=INTEGER}");
}
if (record.getOrderSource() != null) {
sql.VALUES("order_source", "#{orderSource,jdbcType=BIGINT}");
}
if (record.getMemId() != null) {
sql.VALUES("mem_id", "#{memId,jdbcType=BIGINT}");
}
@ -61,11 +53,11 @@ public class HighOrderSqlProvider {
}
if (record.getPayPrice() != null) {
sql.VALUES("pay_price", "#{payPrice,jdbcType=REAL}");
sql.VALUES("pay_price", "#{payPrice,jdbcType=DECIMAL}");
}
if (record.getPayRealPrice() != null) {
sql.VALUES("pay_real_price", "#{payRealPrice,jdbcType=REAL}");
sql.VALUES("pay_real_price", "#{payRealPrice,jdbcType=DECIMAL}");
}
if (record.getPaySerialNo() != null) {
@ -123,8 +115,6 @@ public class HighOrderSqlProvider {
sql.SELECT("id");
}
sql.SELECT("order_no");
sql.SELECT("order_type");
sql.SELECT("order_source");
sql.SELECT("mem_id");
sql.SELECT("mem_name");
sql.SELECT("pay_model");
@ -168,14 +158,6 @@ public class HighOrderSqlProvider {
sql.SET("order_no = #{record.orderNo,jdbcType=VARCHAR}");
}
if (record.getOrderType() != null) {
sql.SET("order_type = #{record.orderType,jdbcType=INTEGER}");
}
if (record.getOrderSource() != null) {
sql.SET("order_source = #{record.orderSource,jdbcType=BIGINT}");
}
if (record.getMemId() != null) {
sql.SET("mem_id = #{record.memId,jdbcType=BIGINT}");
}
@ -197,11 +179,11 @@ public class HighOrderSqlProvider {
}
if (record.getPayPrice() != null) {
sql.SET("pay_price = #{record.payPrice,jdbcType=REAL}");
sql.SET("pay_price = #{record.payPrice,jdbcType=DECIMAL}");
}
if (record.getPayRealPrice() != null) {
sql.SET("pay_real_price = #{record.payRealPrice,jdbcType=REAL}");
sql.SET("pay_real_price = #{record.payRealPrice,jdbcType=DECIMAL}");
}
if (record.getPaySerialNo() != null) {
@ -258,15 +240,13 @@ public class HighOrderSqlProvider {
sql.SET("id = #{record.id,jdbcType=BIGINT}");
sql.SET("order_no = #{record.orderNo,jdbcType=VARCHAR}");
sql.SET("order_type = #{record.orderType,jdbcType=INTEGER}");
sql.SET("order_source = #{record.orderSource,jdbcType=BIGINT}");
sql.SET("mem_id = #{record.memId,jdbcType=BIGINT}");
sql.SET("mem_name = #{record.memName,jdbcType=VARCHAR}");
sql.SET("pay_model = #{record.payModel,jdbcType=INTEGER}");
sql.SET("pay_type = #{record.payType,jdbcType=INTEGER}");
sql.SET("pay_gold = #{record.payGold,jdbcType=INTEGER}");
sql.SET("pay_price = #{record.payPrice,jdbcType=REAL}");
sql.SET("pay_real_price = #{record.payRealPrice,jdbcType=REAL}");
sql.SET("pay_price = #{record.payPrice,jdbcType=DECIMAL}");
sql.SET("pay_real_price = #{record.payRealPrice,jdbcType=DECIMAL}");
sql.SET("pay_serial_no = #{record.paySerialNo,jdbcType=VARCHAR}");
sql.SET("order_status = #{record.orderStatus,jdbcType=INTEGER}");
sql.SET("total_price = #{record.totalPrice,jdbcType=DECIMAL}");
@ -292,14 +272,6 @@ public class HighOrderSqlProvider {
sql.SET("order_no = #{orderNo,jdbcType=VARCHAR}");
}
if (record.getOrderType() != null) {
sql.SET("order_type = #{orderType,jdbcType=INTEGER}");
}
if (record.getOrderSource() != null) {
sql.SET("order_source = #{orderSource,jdbcType=BIGINT}");
}
if (record.getMemId() != null) {
sql.SET("mem_id = #{memId,jdbcType=BIGINT}");
}
@ -321,11 +293,11 @@ public class HighOrderSqlProvider {
}
if (record.getPayPrice() != null) {
sql.SET("pay_price = #{payPrice,jdbcType=REAL}");
sql.SET("pay_price = #{payPrice,jdbcType=DECIMAL}");
}
if (record.getPayRealPrice() != null) {
sql.SET("pay_real_price = #{payRealPrice,jdbcType=REAL}");
sql.SET("pay_real_price = #{payRealPrice,jdbcType=DECIMAL}");
}
if (record.getPaySerialNo() != null) {

@ -7,6 +7,7 @@ import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
@ -33,38 +34,38 @@ public interface HighPayRecordMapper extends HighPayRecordMapperExt {
@Delete({
"delete from high_pay_record",
"where pay_record_id = #{payRecordId,jdbcType=BIGINT}"
"where id = #{id,jdbcType=BIGINT}"
})
int deleteByPrimaryKey(Long payRecordId);
int deleteByPrimaryKey(Long id);
@Insert({
"insert into high_pay_record (pay_record_id, pay_serial_no, ",
"serail_state, pay_type, ",
"pay_money, pay_time, ",
"body_info, pay_result, ",
"fail_code, fail_reason, ",
"create_time, ext_1, ",
"ext_2, ext_3)",
"values (#{payRecordId,jdbcType=BIGINT}, #{paySerialNo,jdbcType=VARCHAR}, ",
"#{serailState,jdbcType=INTEGER}, #{payType,jdbcType=BIGINT}, ",
"#{payMoney,jdbcType=REAL}, #{payTime,jdbcType=TIMESTAMP}, ",
"#{bodyInfo,jdbcType=VARCHAR}, #{payResult,jdbcType=VARCHAR}, ",
"#{failCode,jdbcType=VARCHAR}, #{failReason,jdbcType=TIMESTAMP}, ",
"#{createTime,jdbcType=TIMESTAMP}, #{ext1,jdbcType=VARCHAR}, ",
"#{ext2,jdbcType=VARCHAR}, #{ext3,jdbcType=VARCHAR})"
"insert into high_pay_record (pay_serial_no, res_type, ",
"pay_type, pay_money, ",
"pay_time, body_info, ",
"pay_result, fail_code, ",
"fail_reason, create_time, ",
"ext_1, ext_2, ext_3)",
"values (#{paySerialNo,jdbcType=VARCHAR}, #{resType,jdbcType=INTEGER}, ",
"#{payType,jdbcType=INTEGER}, #{payMoney,jdbcType=DECIMAL}, ",
"#{payTime,jdbcType=TIMESTAMP}, #{bodyInfo,jdbcType=VARCHAR}, ",
"#{payResult,jdbcType=VARCHAR}, #{failCode,jdbcType=VARCHAR}, ",
"#{failReason,jdbcType=TIMESTAMP}, #{createTime,jdbcType=TIMESTAMP}, ",
"#{ext1,jdbcType=VARCHAR}, #{ext2,jdbcType=VARCHAR}, #{ext3,jdbcType=VARCHAR})"
})
@Options(useGeneratedKeys=true,keyProperty="id")
int insert(HighPayRecord record);
@InsertProvider(type=HighPayRecordSqlProvider.class, method="insertSelective")
@Options(useGeneratedKeys=true,keyProperty="id")
int insertSelective(HighPayRecord record);
@SelectProvider(type=HighPayRecordSqlProvider.class, method="selectByExample")
@Results({
@Result(column="pay_record_id", property="payRecordId", jdbcType=JdbcType.BIGINT, id=true),
@Result(column="id", property="id", jdbcType=JdbcType.BIGINT, id=true),
@Result(column="pay_serial_no", property="paySerialNo", jdbcType=JdbcType.VARCHAR),
@Result(column="serail_state", property="serailState", jdbcType=JdbcType.INTEGER),
@Result(column="pay_type", property="payType", jdbcType=JdbcType.BIGINT),
@Result(column="pay_money", property="payMoney", jdbcType=JdbcType.REAL),
@Result(column="res_type", property="resType", jdbcType=JdbcType.INTEGER),
@Result(column="pay_type", property="payType", jdbcType=JdbcType.INTEGER),
@Result(column="pay_money", property="payMoney", jdbcType=JdbcType.DECIMAL),
@Result(column="pay_time", property="payTime", jdbcType=JdbcType.TIMESTAMP),
@Result(column="body_info", property="bodyInfo", jdbcType=JdbcType.VARCHAR),
@Result(column="pay_result", property="payResult", jdbcType=JdbcType.VARCHAR),
@ -79,17 +80,17 @@ public interface HighPayRecordMapper extends HighPayRecordMapperExt {
@Select({
"select",
"pay_record_id, pay_serial_no, serail_state, pay_type, pay_money, pay_time, body_info, ",
"pay_result, fail_code, fail_reason, create_time, ext_1, ext_2, ext_3",
"id, pay_serial_no, res_type, pay_type, pay_money, pay_time, body_info, pay_result, ",
"fail_code, fail_reason, create_time, ext_1, ext_2, ext_3",
"from high_pay_record",
"where pay_record_id = #{payRecordId,jdbcType=BIGINT}"
"where id = #{id,jdbcType=BIGINT}"
})
@Results({
@Result(column="pay_record_id", property="payRecordId", jdbcType=JdbcType.BIGINT, id=true),
@Result(column="id", property="id", jdbcType=JdbcType.BIGINT, id=true),
@Result(column="pay_serial_no", property="paySerialNo", jdbcType=JdbcType.VARCHAR),
@Result(column="serail_state", property="serailState", jdbcType=JdbcType.INTEGER),
@Result(column="pay_type", property="payType", jdbcType=JdbcType.BIGINT),
@Result(column="pay_money", property="payMoney", jdbcType=JdbcType.REAL),
@Result(column="res_type", property="resType", jdbcType=JdbcType.INTEGER),
@Result(column="pay_type", property="payType", jdbcType=JdbcType.INTEGER),
@Result(column="pay_money", property="payMoney", jdbcType=JdbcType.DECIMAL),
@Result(column="pay_time", property="payTime", jdbcType=JdbcType.TIMESTAMP),
@Result(column="body_info", property="bodyInfo", jdbcType=JdbcType.VARCHAR),
@Result(column="pay_result", property="payResult", jdbcType=JdbcType.VARCHAR),
@ -100,7 +101,7 @@ public interface HighPayRecordMapper extends HighPayRecordMapperExt {
@Result(column="ext_2", property="ext2", jdbcType=JdbcType.VARCHAR),
@Result(column="ext_3", property="ext3", jdbcType=JdbcType.VARCHAR)
})
HighPayRecord selectByPrimaryKey(Long payRecordId);
HighPayRecord selectByPrimaryKey(Long id);
@UpdateProvider(type=HighPayRecordSqlProvider.class, method="updateByExampleSelective")
int updateByExampleSelective(@Param("record") HighPayRecord record, @Param("example") HighPayRecordExample example);
@ -114,9 +115,9 @@ public interface HighPayRecordMapper extends HighPayRecordMapperExt {
@Update({
"update high_pay_record",
"set pay_serial_no = #{paySerialNo,jdbcType=VARCHAR},",
"serail_state = #{serailState,jdbcType=INTEGER},",
"pay_type = #{payType,jdbcType=BIGINT},",
"pay_money = #{payMoney,jdbcType=REAL},",
"res_type = #{resType,jdbcType=INTEGER},",
"pay_type = #{payType,jdbcType=INTEGER},",
"pay_money = #{payMoney,jdbcType=DECIMAL},",
"pay_time = #{payTime,jdbcType=TIMESTAMP},",
"body_info = #{bodyInfo,jdbcType=VARCHAR},",
"pay_result = #{payResult,jdbcType=VARCHAR},",
@ -126,7 +127,7 @@ public interface HighPayRecordMapper extends HighPayRecordMapperExt {
"ext_1 = #{ext1,jdbcType=VARCHAR},",
"ext_2 = #{ext2,jdbcType=VARCHAR},",
"ext_3 = #{ext3,jdbcType=VARCHAR}",
"where pay_record_id = #{payRecordId,jdbcType=BIGINT}"
"where id = #{id,jdbcType=BIGINT}"
})
int updateByPrimaryKey(HighPayRecord record);
}

@ -28,24 +28,20 @@ public class HighPayRecordSqlProvider {
SQL sql = new SQL();
sql.INSERT_INTO("high_pay_record");
if (record.getPayRecordId() != null) {
sql.VALUES("pay_record_id", "#{payRecordId,jdbcType=BIGINT}");
}
if (record.getPaySerialNo() != null) {
sql.VALUES("pay_serial_no", "#{paySerialNo,jdbcType=VARCHAR}");
}
if (record.getSerailState() != null) {
sql.VALUES("serail_state", "#{serailState,jdbcType=INTEGER}");
if (record.getResType() != null) {
sql.VALUES("res_type", "#{resType,jdbcType=INTEGER}");
}
if (record.getPayType() != null) {
sql.VALUES("pay_type", "#{payType,jdbcType=BIGINT}");
sql.VALUES("pay_type", "#{payType,jdbcType=INTEGER}");
}
if (record.getPayMoney() != null) {
sql.VALUES("pay_money", "#{payMoney,jdbcType=REAL}");
sql.VALUES("pay_money", "#{payMoney,jdbcType=DECIMAL}");
}
if (record.getPayTime() != null) {
@ -90,12 +86,12 @@ public class HighPayRecordSqlProvider {
public String selectByExample(HighPayRecordExample example) {
SQL sql = new SQL();
if (example != null && example.isDistinct()) {
sql.SELECT_DISTINCT("pay_record_id");
sql.SELECT_DISTINCT("id");
} else {
sql.SELECT("pay_record_id");
sql.SELECT("id");
}
sql.SELECT("pay_serial_no");
sql.SELECT("serail_state");
sql.SELECT("res_type");
sql.SELECT("pay_type");
sql.SELECT("pay_money");
sql.SELECT("pay_time");
@ -124,24 +120,24 @@ public class HighPayRecordSqlProvider {
SQL sql = new SQL();
sql.UPDATE("high_pay_record");
if (record.getPayRecordId() != null) {
sql.SET("pay_record_id = #{record.payRecordId,jdbcType=BIGINT}");
if (record.getId() != null) {
sql.SET("id = #{record.id,jdbcType=BIGINT}");
}
if (record.getPaySerialNo() != null) {
sql.SET("pay_serial_no = #{record.paySerialNo,jdbcType=VARCHAR}");
}
if (record.getSerailState() != null) {
sql.SET("serail_state = #{record.serailState,jdbcType=INTEGER}");
if (record.getResType() != null) {
sql.SET("res_type = #{record.resType,jdbcType=INTEGER}");
}
if (record.getPayType() != null) {
sql.SET("pay_type = #{record.payType,jdbcType=BIGINT}");
sql.SET("pay_type = #{record.payType,jdbcType=INTEGER}");
}
if (record.getPayMoney() != null) {
sql.SET("pay_money = #{record.payMoney,jdbcType=REAL}");
sql.SET("pay_money = #{record.payMoney,jdbcType=DECIMAL}");
}
if (record.getPayTime() != null) {
@ -188,11 +184,11 @@ public class HighPayRecordSqlProvider {
SQL sql = new SQL();
sql.UPDATE("high_pay_record");
sql.SET("pay_record_id = #{record.payRecordId,jdbcType=BIGINT}");
sql.SET("id = #{record.id,jdbcType=BIGINT}");
sql.SET("pay_serial_no = #{record.paySerialNo,jdbcType=VARCHAR}");
sql.SET("serail_state = #{record.serailState,jdbcType=INTEGER}");
sql.SET("pay_type = #{record.payType,jdbcType=BIGINT}");
sql.SET("pay_money = #{record.payMoney,jdbcType=REAL}");
sql.SET("res_type = #{record.resType,jdbcType=INTEGER}");
sql.SET("pay_type = #{record.payType,jdbcType=INTEGER}");
sql.SET("pay_money = #{record.payMoney,jdbcType=DECIMAL}");
sql.SET("pay_time = #{record.payTime,jdbcType=TIMESTAMP}");
sql.SET("body_info = #{record.bodyInfo,jdbcType=VARCHAR}");
sql.SET("pay_result = #{record.payResult,jdbcType=VARCHAR}");
@ -216,16 +212,16 @@ public class HighPayRecordSqlProvider {
sql.SET("pay_serial_no = #{paySerialNo,jdbcType=VARCHAR}");
}
if (record.getSerailState() != null) {
sql.SET("serail_state = #{serailState,jdbcType=INTEGER}");
if (record.getResType() != null) {
sql.SET("res_type = #{resType,jdbcType=INTEGER}");
}
if (record.getPayType() != null) {
sql.SET("pay_type = #{payType,jdbcType=BIGINT}");
sql.SET("pay_type = #{payType,jdbcType=INTEGER}");
}
if (record.getPayMoney() != null) {
sql.SET("pay_money = #{payMoney,jdbcType=REAL}");
sql.SET("pay_money = #{payMoney,jdbcType=DECIMAL}");
}
if (record.getPayTime() != null) {
@ -264,7 +260,7 @@ public class HighPayRecordSqlProvider {
sql.SET("ext_3 = #{ext3,jdbcType=VARCHAR}");
}
sql.WHERE("pay_record_id = #{payRecordId,jdbcType=BIGINT}");
sql.WHERE("id = #{id,jdbcType=BIGINT}");
return sql.toString();
}

@ -1,6 +1,7 @@
package com.hai.entity;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* high_child_order
@ -50,7 +51,7 @@ public class HighChildOrder implements Serializable {
/**
* 商品的单价
*/
private Float goodsPrice;
private BigDecimal goodsPrice;
/**
* 商品的数量
@ -60,7 +61,7 @@ public class HighChildOrder implements Serializable {
/**
* 商品的价格单价*数量
*/
private Float totalPrice;
private BigDecimal totalPrice;
/**
* 是否是赠品 0 1
@ -141,11 +142,11 @@ public class HighChildOrder implements Serializable {
this.goodsSpecName = goodsSpecName;
}
public Float getGoodsPrice() {
public BigDecimal getGoodsPrice() {
return goodsPrice;
}
public void setGoodsPrice(Float goodsPrice) {
public void setGoodsPrice(BigDecimal goodsPrice) {
this.goodsPrice = goodsPrice;
}
@ -157,11 +158,11 @@ public class HighChildOrder implements Serializable {
this.saleCount = saleCount;
}
public Float getTotalPrice() {
public BigDecimal getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(Float totalPrice) {
public void setTotalPrice(BigDecimal totalPrice) {
this.totalPrice = totalPrice;
}

@ -1,5 +1,6 @@
package com.hai.entity;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
@ -584,52 +585,52 @@ public class HighChildOrderExample {
return (Criteria) this;
}
public Criteria andGoodsPriceEqualTo(Float value) {
public Criteria andGoodsPriceEqualTo(BigDecimal value) {
addCriterion("goods_price =", value, "goodsPrice");
return (Criteria) this;
}
public Criteria andGoodsPriceNotEqualTo(Float value) {
public Criteria andGoodsPriceNotEqualTo(BigDecimal value) {
addCriterion("goods_price <>", value, "goodsPrice");
return (Criteria) this;
}
public Criteria andGoodsPriceGreaterThan(Float value) {
public Criteria andGoodsPriceGreaterThan(BigDecimal value) {
addCriterion("goods_price >", value, "goodsPrice");
return (Criteria) this;
}
public Criteria andGoodsPriceGreaterThanOrEqualTo(Float value) {
public Criteria andGoodsPriceGreaterThanOrEqualTo(BigDecimal value) {
addCriterion("goods_price >=", value, "goodsPrice");
return (Criteria) this;
}
public Criteria andGoodsPriceLessThan(Float value) {
public Criteria andGoodsPriceLessThan(BigDecimal value) {
addCriterion("goods_price <", value, "goodsPrice");
return (Criteria) this;
}
public Criteria andGoodsPriceLessThanOrEqualTo(Float value) {
public Criteria andGoodsPriceLessThanOrEqualTo(BigDecimal value) {
addCriterion("goods_price <=", value, "goodsPrice");
return (Criteria) this;
}
public Criteria andGoodsPriceIn(List<Float> values) {
public Criteria andGoodsPriceIn(List<BigDecimal> values) {
addCriterion("goods_price in", values, "goodsPrice");
return (Criteria) this;
}
public Criteria andGoodsPriceNotIn(List<Float> values) {
public Criteria andGoodsPriceNotIn(List<BigDecimal> values) {
addCriterion("goods_price not in", values, "goodsPrice");
return (Criteria) this;
}
public Criteria andGoodsPriceBetween(Float value1, Float value2) {
public Criteria andGoodsPriceBetween(BigDecimal value1, BigDecimal value2) {
addCriterion("goods_price between", value1, value2, "goodsPrice");
return (Criteria) this;
}
public Criteria andGoodsPriceNotBetween(Float value1, Float value2) {
public Criteria andGoodsPriceNotBetween(BigDecimal value1, BigDecimal value2) {
addCriterion("goods_price not between", value1, value2, "goodsPrice");
return (Criteria) this;
}
@ -704,52 +705,52 @@ public class HighChildOrderExample {
return (Criteria) this;
}
public Criteria andTotalPriceEqualTo(Float value) {
public Criteria andTotalPriceEqualTo(BigDecimal value) {
addCriterion("total_price =", value, "totalPrice");
return (Criteria) this;
}
public Criteria andTotalPriceNotEqualTo(Float value) {
public Criteria andTotalPriceNotEqualTo(BigDecimal value) {
addCriterion("total_price <>", value, "totalPrice");
return (Criteria) this;
}
public Criteria andTotalPriceGreaterThan(Float value) {
public Criteria andTotalPriceGreaterThan(BigDecimal value) {
addCriterion("total_price >", value, "totalPrice");
return (Criteria) this;
}
public Criteria andTotalPriceGreaterThanOrEqualTo(Float value) {
public Criteria andTotalPriceGreaterThanOrEqualTo(BigDecimal value) {
addCriterion("total_price >=", value, "totalPrice");
return (Criteria) this;
}
public Criteria andTotalPriceLessThan(Float value) {
public Criteria andTotalPriceLessThan(BigDecimal value) {
addCriterion("total_price <", value, "totalPrice");
return (Criteria) this;
}
public Criteria andTotalPriceLessThanOrEqualTo(Float value) {
public Criteria andTotalPriceLessThanOrEqualTo(BigDecimal value) {
addCriterion("total_price <=", value, "totalPrice");
return (Criteria) this;
}
public Criteria andTotalPriceIn(List<Float> values) {
public Criteria andTotalPriceIn(List<BigDecimal> values) {
addCriterion("total_price in", values, "totalPrice");
return (Criteria) this;
}
public Criteria andTotalPriceNotIn(List<Float> values) {
public Criteria andTotalPriceNotIn(List<BigDecimal> values) {
addCriterion("total_price not in", values, "totalPrice");
return (Criteria) this;
}
public Criteria andTotalPriceBetween(Float value1, Float value2) {
public Criteria andTotalPriceBetween(BigDecimal value1, BigDecimal value2) {
addCriterion("total_price between", value1, value2, "totalPrice");
return (Criteria) this;
}
public Criteria andTotalPriceNotBetween(Float value1, Float value2) {
public Criteria andTotalPriceNotBetween(BigDecimal value1, BigDecimal value2) {
addCriterion("total_price not between", value1, value2, "totalPrice");
return (Criteria) this;
}

@ -120,9 +120,9 @@ public class HighCoupon implements Serializable {
private String operatorName;
/**
* 状态0.删除 1.编辑中 2.已上架 3.已下架 101.上架审批中 102.上架审批驳回
* 支付类型1.微信支付 2.金币支付
*/
private Integer status;
private Integer payType;
private String ext1;
@ -130,6 +130,16 @@ public class HighCoupon implements Serializable {
private String ext3;
/**
* 状态0.删除 1.编辑中 2.已上架 3.已下架 101.上架审批中 102.上架审批驳回
*/
private Integer status;
/**
* 1.赠券专区 2.金币专区
*/
private Integer displayArea;
private static final long serialVersionUID = 1L;
public Long getId() {
@ -300,12 +310,12 @@ public class HighCoupon implements Serializable {
this.operatorName = operatorName;
}
public Integer getStatus() {
return status;
public Integer getPayType() {
return payType;
}
public void setStatus(Integer status) {
this.status = status;
public void setPayType(Integer payType) {
this.payType = payType;
}
public String getExt1() {
@ -332,6 +342,22 @@ public class HighCoupon implements Serializable {
this.ext3 = ext3;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Integer getDisplayArea() {
return displayArea;
}
public void setDisplayArea(Integer displayArea) {
this.displayArea = displayArea;
}
@Override
public boolean equals(Object that) {
if (this == that) {
@ -365,10 +391,12 @@ public class HighCoupon implements Serializable {
&& (this.getUpdateTime() == null ? other.getUpdateTime() == null : this.getUpdateTime().equals(other.getUpdateTime()))
&& (this.getOperatorId() == null ? other.getOperatorId() == null : this.getOperatorId().equals(other.getOperatorId()))
&& (this.getOperatorName() == null ? other.getOperatorName() == null : this.getOperatorName().equals(other.getOperatorName()))
&& (this.getStatus() == null ? other.getStatus() == null : this.getStatus().equals(other.getStatus()))
&& (this.getPayType() == null ? other.getPayType() == null : this.getPayType().equals(other.getPayType()))
&& (this.getExt1() == null ? other.getExt1() == null : this.getExt1().equals(other.getExt1()))
&& (this.getExt2() == null ? other.getExt2() == null : this.getExt2().equals(other.getExt2()))
&& (this.getExt3() == null ? other.getExt3() == null : this.getExt3().equals(other.getExt3()));
&& (this.getExt3() == null ? other.getExt3() == null : this.getExt3().equals(other.getExt3()))
&& (this.getStatus() == null ? other.getStatus() == null : this.getStatus().equals(other.getStatus()))
&& (this.getDisplayArea() == null ? other.getDisplayArea() == null : this.getDisplayArea().equals(other.getDisplayArea()));
}
@Override
@ -396,10 +424,12 @@ public class HighCoupon implements Serializable {
result = prime * result + ((getUpdateTime() == null) ? 0 : getUpdateTime().hashCode());
result = prime * result + ((getOperatorId() == null) ? 0 : getOperatorId().hashCode());
result = prime * result + ((getOperatorName() == null) ? 0 : getOperatorName().hashCode());
result = prime * result + ((getStatus() == null) ? 0 : getStatus().hashCode());
result = prime * result + ((getPayType() == null) ? 0 : getPayType().hashCode());
result = prime * result + ((getExt1() == null) ? 0 : getExt1().hashCode());
result = prime * result + ((getExt2() == null) ? 0 : getExt2().hashCode());
result = prime * result + ((getExt3() == null) ? 0 : getExt3().hashCode());
result = prime * result + ((getStatus() == null) ? 0 : getStatus().hashCode());
result = prime * result + ((getDisplayArea() == null) ? 0 : getDisplayArea().hashCode());
return result;
}
@ -430,10 +460,12 @@ public class HighCoupon implements Serializable {
sb.append(", updateTime=").append(updateTime);
sb.append(", operatorId=").append(operatorId);
sb.append(", operatorName=").append(operatorName);
sb.append(", status=").append(status);
sb.append(", payType=").append(payType);
sb.append(", ext1=").append(ext1);
sb.append(", ext2=").append(ext2);
sb.append(", ext3=").append(ext3);
sb.append(", status=").append(status);
sb.append(", displayArea=").append(displayArea);
sb.append(", serialVersionUID=").append(serialVersionUID);
sb.append("]");
return sb.toString();

@ -1446,63 +1446,63 @@ public class HighCouponExample {
return (Criteria) this;
}
public Criteria andStatusIsNull() {
addCriterion("`status` is null");
public Criteria andPayTypeIsNull() {
addCriterion("pay_type is null");
return (Criteria) this;
}
public Criteria andStatusIsNotNull() {
addCriterion("`status` is not null");
public Criteria andPayTypeIsNotNull() {
addCriterion("pay_type is not null");
return (Criteria) this;
}
public Criteria andStatusEqualTo(Integer value) {
addCriterion("`status` =", value, "status");
public Criteria andPayTypeEqualTo(Integer value) {
addCriterion("pay_type =", value, "payType");
return (Criteria) this;
}
public Criteria andStatusNotEqualTo(Integer value) {
addCriterion("`status` <>", value, "status");
public Criteria andPayTypeNotEqualTo(Integer value) {
addCriterion("pay_type <>", value, "payType");
return (Criteria) this;
}
public Criteria andStatusGreaterThan(Integer value) {
addCriterion("`status` >", value, "status");
public Criteria andPayTypeGreaterThan(Integer value) {
addCriterion("pay_type >", value, "payType");
return (Criteria) this;
}
public Criteria andStatusGreaterThanOrEqualTo(Integer value) {
addCriterion("`status` >=", value, "status");
public Criteria andPayTypeGreaterThanOrEqualTo(Integer value) {
addCriterion("pay_type >=", value, "payType");
return (Criteria) this;
}
public Criteria andStatusLessThan(Integer value) {
addCriterion("`status` <", value, "status");
public Criteria andPayTypeLessThan(Integer value) {
addCriterion("pay_type <", value, "payType");
return (Criteria) this;
}
public Criteria andStatusLessThanOrEqualTo(Integer value) {
addCriterion("`status` <=", value, "status");
public Criteria andPayTypeLessThanOrEqualTo(Integer value) {
addCriterion("pay_type <=", value, "payType");
return (Criteria) this;
}
public Criteria andStatusIn(List<Integer> values) {
addCriterion("`status` in", values, "status");
public Criteria andPayTypeIn(List<Integer> values) {
addCriterion("pay_type in", values, "payType");
return (Criteria) this;
}
public Criteria andStatusNotIn(List<Integer> values) {
addCriterion("`status` not in", values, "status");
public Criteria andPayTypeNotIn(List<Integer> values) {
addCriterion("pay_type not in", values, "payType");
return (Criteria) this;
}
public Criteria andStatusBetween(Integer value1, Integer value2) {
addCriterion("`status` between", value1, value2, "status");
public Criteria andPayTypeBetween(Integer value1, Integer value2) {
addCriterion("pay_type between", value1, value2, "payType");
return (Criteria) this;
}
public Criteria andStatusNotBetween(Integer value1, Integer value2) {
addCriterion("`status` not between", value1, value2, "status");
public Criteria andPayTypeNotBetween(Integer value1, Integer value2) {
addCriterion("pay_type not between", value1, value2, "payType");
return (Criteria) this;
}
@ -1715,6 +1715,126 @@ public class HighCouponExample {
addCriterion("ext_3 not between", value1, value2, "ext3");
return (Criteria) this;
}
public Criteria andStatusIsNull() {
addCriterion("`status` is null");
return (Criteria) this;
}
public Criteria andStatusIsNotNull() {
addCriterion("`status` is not null");
return (Criteria) this;
}
public Criteria andStatusEqualTo(Integer value) {
addCriterion("`status` =", value, "status");
return (Criteria) this;
}
public Criteria andStatusNotEqualTo(Integer value) {
addCriterion("`status` <>", value, "status");
return (Criteria) this;
}
public Criteria andStatusGreaterThan(Integer value) {
addCriterion("`status` >", value, "status");
return (Criteria) this;
}
public Criteria andStatusGreaterThanOrEqualTo(Integer value) {
addCriterion("`status` >=", value, "status");
return (Criteria) this;
}
public Criteria andStatusLessThan(Integer value) {
addCriterion("`status` <", value, "status");
return (Criteria) this;
}
public Criteria andStatusLessThanOrEqualTo(Integer value) {
addCriterion("`status` <=", value, "status");
return (Criteria) this;
}
public Criteria andStatusIn(List<Integer> values) {
addCriterion("`status` in", values, "status");
return (Criteria) this;
}
public Criteria andStatusNotIn(List<Integer> values) {
addCriterion("`status` not in", values, "status");
return (Criteria) this;
}
public Criteria andStatusBetween(Integer value1, Integer value2) {
addCriterion("`status` between", value1, value2, "status");
return (Criteria) this;
}
public Criteria andStatusNotBetween(Integer value1, Integer value2) {
addCriterion("`status` not between", value1, value2, "status");
return (Criteria) this;
}
public Criteria andDisplayAreaIsNull() {
addCriterion("display_area is null");
return (Criteria) this;
}
public Criteria andDisplayAreaIsNotNull() {
addCriterion("display_area is not null");
return (Criteria) this;
}
public Criteria andDisplayAreaEqualTo(Integer value) {
addCriterion("display_area =", value, "displayArea");
return (Criteria) this;
}
public Criteria andDisplayAreaNotEqualTo(Integer value) {
addCriterion("display_area <>", value, "displayArea");
return (Criteria) this;
}
public Criteria andDisplayAreaGreaterThan(Integer value) {
addCriterion("display_area >", value, "displayArea");
return (Criteria) this;
}
public Criteria andDisplayAreaGreaterThanOrEqualTo(Integer value) {
addCriterion("display_area >=", value, "displayArea");
return (Criteria) this;
}
public Criteria andDisplayAreaLessThan(Integer value) {
addCriterion("display_area <", value, "displayArea");
return (Criteria) this;
}
public Criteria andDisplayAreaLessThanOrEqualTo(Integer value) {
addCriterion("display_area <=", value, "displayArea");
return (Criteria) this;
}
public Criteria andDisplayAreaIn(List<Integer> values) {
addCriterion("display_area in", values, "displayArea");
return (Criteria) this;
}
public Criteria andDisplayAreaNotIn(List<Integer> values) {
addCriterion("display_area not in", values, "displayArea");
return (Criteria) this;
}
public Criteria andDisplayAreaBetween(Integer value1, Integer value2) {
addCriterion("display_area between", value1, value2, "displayArea");
return (Criteria) this;
}
public Criteria andDisplayAreaNotBetween(Integer value1, Integer value2) {
addCriterion("display_area not between", value1, value2, "displayArea");
return (Criteria) this;
}
}
/**

@ -3,6 +3,7 @@ package com.hai.entity;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* high_order
@ -24,16 +25,6 @@ public class HighOrder implements Serializable {
*/
private String orderNo;
/**
* 订单类型 1卡券
*/
private Integer orderType;
/**
* 订单来源id
*/
private Long orderSource;
/**
* 用户表ID
*/
@ -62,12 +53,12 @@ public class HighOrder implements Serializable {
/**
* 支付金额
*/
private Float payPrice;
private BigDecimal payPrice;
/**
* 实付金额
*/
private Float payRealPrice;
private BigDecimal payRealPrice;
/**
* 支付流水号
@ -117,6 +108,16 @@ public class HighOrder implements Serializable {
private static final long serialVersionUID = 1L;
private List<HighChildOrder> highChildOrderList;
public List<HighChildOrder> getHighChildOrderList() {
return highChildOrderList;
}
public void setHighChildOrderList(List<HighChildOrder> highChildOrderList) {
this.highChildOrderList = highChildOrderList;
}
public Long getId() {
return id;
}
@ -133,22 +134,6 @@ public class HighOrder implements Serializable {
this.orderNo = orderNo;
}
public Integer getOrderType() {
return orderType;
}
public void setOrderType(Integer orderType) {
this.orderType = orderType;
}
public Long getOrderSource() {
return orderSource;
}
public void setOrderSource(Long orderSource) {
this.orderSource = orderSource;
}
public Long getMemId() {
return memId;
}
@ -189,19 +174,19 @@ public class HighOrder implements Serializable {
this.payGold = payGold;
}
public Float getPayPrice() {
public BigDecimal getPayPrice() {
return payPrice;
}
public void setPayPrice(Float payPrice) {
public void setPayPrice(BigDecimal payPrice) {
this.payPrice = payPrice;
}
public Float getPayRealPrice() {
public BigDecimal getPayRealPrice() {
return payRealPrice;
}
public void setPayRealPrice(Float payRealPrice) {
public void setPayRealPrice(BigDecimal payRealPrice) {
this.payRealPrice = payRealPrice;
}
@ -307,8 +292,6 @@ public class HighOrder implements Serializable {
HighOrder other = (HighOrder) that;
return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
&& (this.getOrderNo() == null ? other.getOrderNo() == null : this.getOrderNo().equals(other.getOrderNo()))
&& (this.getOrderType() == null ? other.getOrderType() == null : this.getOrderType().equals(other.getOrderType()))
&& (this.getOrderSource() == null ? other.getOrderSource() == null : this.getOrderSource().equals(other.getOrderSource()))
&& (this.getMemId() == null ? other.getMemId() == null : this.getMemId().equals(other.getMemId()))
&& (this.getMemName() == null ? other.getMemName() == null : this.getMemName().equals(other.getMemName()))
&& (this.getPayModel() == null ? other.getPayModel() == null : this.getPayModel().equals(other.getPayModel()))
@ -335,8 +318,6 @@ public class HighOrder implements Serializable {
int result = 1;
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
result = prime * result + ((getOrderNo() == null) ? 0 : getOrderNo().hashCode());
result = prime * result + ((getOrderType() == null) ? 0 : getOrderType().hashCode());
result = prime * result + ((getOrderSource() == null) ? 0 : getOrderSource().hashCode());
result = prime * result + ((getMemId() == null) ? 0 : getMemId().hashCode());
result = prime * result + ((getMemName() == null) ? 0 : getMemName().hashCode());
result = prime * result + ((getPayModel() == null) ? 0 : getPayModel().hashCode());
@ -366,8 +347,6 @@ public class HighOrder implements Serializable {
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", orderNo=").append(orderNo);
sb.append(", orderType=").append(orderType);
sb.append(", orderSource=").append(orderSource);
sb.append(", memId=").append(memId);
sb.append(", memName=").append(memName);
sb.append(", payModel=").append(payModel);

@ -256,126 +256,6 @@ public class HighOrderExample {
return (Criteria) this;
}
public Criteria andOrderTypeIsNull() {
addCriterion("order_type is null");
return (Criteria) this;
}
public Criteria andOrderTypeIsNotNull() {
addCriterion("order_type is not null");
return (Criteria) this;
}
public Criteria andOrderTypeEqualTo(Integer value) {
addCriterion("order_type =", value, "orderType");
return (Criteria) this;
}
public Criteria andOrderTypeNotEqualTo(Integer value) {
addCriterion("order_type <>", value, "orderType");
return (Criteria) this;
}
public Criteria andOrderTypeGreaterThan(Integer value) {
addCriterion("order_type >", value, "orderType");
return (Criteria) this;
}
public Criteria andOrderTypeGreaterThanOrEqualTo(Integer value) {
addCriterion("order_type >=", value, "orderType");
return (Criteria) this;
}
public Criteria andOrderTypeLessThan(Integer value) {
addCriterion("order_type <", value, "orderType");
return (Criteria) this;
}
public Criteria andOrderTypeLessThanOrEqualTo(Integer value) {
addCriterion("order_type <=", value, "orderType");
return (Criteria) this;
}
public Criteria andOrderTypeIn(List<Integer> values) {
addCriterion("order_type in", values, "orderType");
return (Criteria) this;
}
public Criteria andOrderTypeNotIn(List<Integer> values) {
addCriterion("order_type not in", values, "orderType");
return (Criteria) this;
}
public Criteria andOrderTypeBetween(Integer value1, Integer value2) {
addCriterion("order_type between", value1, value2, "orderType");
return (Criteria) this;
}
public Criteria andOrderTypeNotBetween(Integer value1, Integer value2) {
addCriterion("order_type not between", value1, value2, "orderType");
return (Criteria) this;
}
public Criteria andOrderSourceIsNull() {
addCriterion("order_source is null");
return (Criteria) this;
}
public Criteria andOrderSourceIsNotNull() {
addCriterion("order_source is not null");
return (Criteria) this;
}
public Criteria andOrderSourceEqualTo(Long value) {
addCriterion("order_source =", value, "orderSource");
return (Criteria) this;
}
public Criteria andOrderSourceNotEqualTo(Long value) {
addCriterion("order_source <>", value, "orderSource");
return (Criteria) this;
}
public Criteria andOrderSourceGreaterThan(Long value) {
addCriterion("order_source >", value, "orderSource");
return (Criteria) this;
}
public Criteria andOrderSourceGreaterThanOrEqualTo(Long value) {
addCriterion("order_source >=", value, "orderSource");
return (Criteria) this;
}
public Criteria andOrderSourceLessThan(Long value) {
addCriterion("order_source <", value, "orderSource");
return (Criteria) this;
}
public Criteria andOrderSourceLessThanOrEqualTo(Long value) {
addCriterion("order_source <=", value, "orderSource");
return (Criteria) this;
}
public Criteria andOrderSourceIn(List<Long> values) {
addCriterion("order_source in", values, "orderSource");
return (Criteria) this;
}
public Criteria andOrderSourceNotIn(List<Long> values) {
addCriterion("order_source not in", values, "orderSource");
return (Criteria) this;
}
public Criteria andOrderSourceBetween(Long value1, Long value2) {
addCriterion("order_source between", value1, value2, "orderSource");
return (Criteria) this;
}
public Criteria andOrderSourceNotBetween(Long value1, Long value2) {
addCriterion("order_source not between", value1, value2, "orderSource");
return (Criteria) this;
}
public Criteria andMemIdIsNull() {
addCriterion("mem_id is null");
return (Criteria) this;
@ -696,52 +576,52 @@ public class HighOrderExample {
return (Criteria) this;
}
public Criteria andPayPriceEqualTo(Float value) {
public Criteria andPayPriceEqualTo(BigDecimal value) {
addCriterion("pay_price =", value, "payPrice");
return (Criteria) this;
}
public Criteria andPayPriceNotEqualTo(Float value) {
public Criteria andPayPriceNotEqualTo(BigDecimal value) {
addCriterion("pay_price <>", value, "payPrice");
return (Criteria) this;
}
public Criteria andPayPriceGreaterThan(Float value) {
public Criteria andPayPriceGreaterThan(BigDecimal value) {
addCriterion("pay_price >", value, "payPrice");
return (Criteria) this;
}
public Criteria andPayPriceGreaterThanOrEqualTo(Float value) {
public Criteria andPayPriceGreaterThanOrEqualTo(BigDecimal value) {
addCriterion("pay_price >=", value, "payPrice");
return (Criteria) this;
}
public Criteria andPayPriceLessThan(Float value) {
public Criteria andPayPriceLessThan(BigDecimal value) {
addCriterion("pay_price <", value, "payPrice");
return (Criteria) this;
}
public Criteria andPayPriceLessThanOrEqualTo(Float value) {
public Criteria andPayPriceLessThanOrEqualTo(BigDecimal value) {
addCriterion("pay_price <=", value, "payPrice");
return (Criteria) this;
}
public Criteria andPayPriceIn(List<Float> values) {
public Criteria andPayPriceIn(List<BigDecimal> values) {
addCriterion("pay_price in", values, "payPrice");
return (Criteria) this;
}
public Criteria andPayPriceNotIn(List<Float> values) {
public Criteria andPayPriceNotIn(List<BigDecimal> values) {
addCriterion("pay_price not in", values, "payPrice");
return (Criteria) this;
}
public Criteria andPayPriceBetween(Float value1, Float value2) {
public Criteria andPayPriceBetween(BigDecimal value1, BigDecimal value2) {
addCriterion("pay_price between", value1, value2, "payPrice");
return (Criteria) this;
}
public Criteria andPayPriceNotBetween(Float value1, Float value2) {
public Criteria andPayPriceNotBetween(BigDecimal value1, BigDecimal value2) {
addCriterion("pay_price not between", value1, value2, "payPrice");
return (Criteria) this;
}
@ -756,52 +636,52 @@ public class HighOrderExample {
return (Criteria) this;
}
public Criteria andPayRealPriceEqualTo(Float value) {
public Criteria andPayRealPriceEqualTo(BigDecimal value) {
addCriterion("pay_real_price =", value, "payRealPrice");
return (Criteria) this;
}
public Criteria andPayRealPriceNotEqualTo(Float value) {
public Criteria andPayRealPriceNotEqualTo(BigDecimal value) {
addCriterion("pay_real_price <>", value, "payRealPrice");
return (Criteria) this;
}
public Criteria andPayRealPriceGreaterThan(Float value) {
public Criteria andPayRealPriceGreaterThan(BigDecimal value) {
addCriterion("pay_real_price >", value, "payRealPrice");
return (Criteria) this;
}
public Criteria andPayRealPriceGreaterThanOrEqualTo(Float value) {
public Criteria andPayRealPriceGreaterThanOrEqualTo(BigDecimal value) {
addCriterion("pay_real_price >=", value, "payRealPrice");
return (Criteria) this;
}
public Criteria andPayRealPriceLessThan(Float value) {
public Criteria andPayRealPriceLessThan(BigDecimal value) {
addCriterion("pay_real_price <", value, "payRealPrice");
return (Criteria) this;
}
public Criteria andPayRealPriceLessThanOrEqualTo(Float value) {
public Criteria andPayRealPriceLessThanOrEqualTo(BigDecimal value) {
addCriterion("pay_real_price <=", value, "payRealPrice");
return (Criteria) this;
}
public Criteria andPayRealPriceIn(List<Float> values) {
public Criteria andPayRealPriceIn(List<BigDecimal> values) {
addCriterion("pay_real_price in", values, "payRealPrice");
return (Criteria) this;
}
public Criteria andPayRealPriceNotIn(List<Float> values) {
public Criteria andPayRealPriceNotIn(List<BigDecimal> values) {
addCriterion("pay_real_price not in", values, "payRealPrice");
return (Criteria) this;
}
public Criteria andPayRealPriceBetween(Float value1, Float value2) {
public Criteria andPayRealPriceBetween(BigDecimal value1, BigDecimal value2) {
addCriterion("pay_real_price between", value1, value2, "payRealPrice");
return (Criteria) this;
}
public Criteria andPayRealPriceNotBetween(Float value1, Float value2) {
public Criteria andPayRealPriceNotBetween(BigDecimal value1, BigDecimal value2) {
addCriterion("pay_real_price not between", value1, value2, "payRealPrice");
return (Criteria) this;
}

@ -1,6 +1,7 @@
package com.hai.entity;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
@ -16,7 +17,7 @@ public class HighPayRecord implements Serializable {
/**
* 主键ID
*/
private Long payRecordId;
private Long id;
/**
* 支付的流水号
@ -26,17 +27,17 @@ public class HighPayRecord implements Serializable {
/**
* 流水类型1请求2响应
*/
private Integer serailState;
private Integer resType;
/**
* 支付方式 1支付宝 2微信 3金币
* 支付方式 1支付宝 2微信
*/
private Long payType;
private Integer payType;
/**
* 支付的金额
*/
private Float payMoney;
private BigDecimal payMoney;
/**
* 支付订单的时间
@ -76,12 +77,12 @@ public class HighPayRecord implements Serializable {
private static final long serialVersionUID = 1L;
public Long getPayRecordId() {
return payRecordId;
public Long getId() {
return id;
}
public void setPayRecordId(Long payRecordId) {
this.payRecordId = payRecordId;
public void setId(Long id) {
this.id = id;
}
public String getPaySerialNo() {
@ -92,27 +93,27 @@ public class HighPayRecord implements Serializable {
this.paySerialNo = paySerialNo;
}
public Integer getSerailState() {
return serailState;
public Integer getResType() {
return resType;
}
public void setSerailState(Integer serailState) {
this.serailState = serailState;
public void setResType(Integer resType) {
this.resType = resType;
}
public Long getPayType() {
public Integer getPayType() {
return payType;
}
public void setPayType(Long payType) {
public void setPayType(Integer payType) {
this.payType = payType;
}
public Float getPayMoney() {
public BigDecimal getPayMoney() {
return payMoney;
}
public void setPayMoney(Float payMoney) {
public void setPayMoney(BigDecimal payMoney) {
this.payMoney = payMoney;
}
@ -200,9 +201,9 @@ public class HighPayRecord implements Serializable {
return false;
}
HighPayRecord other = (HighPayRecord) that;
return (this.getPayRecordId() == null ? other.getPayRecordId() == null : this.getPayRecordId().equals(other.getPayRecordId()))
return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
&& (this.getPaySerialNo() == null ? other.getPaySerialNo() == null : this.getPaySerialNo().equals(other.getPaySerialNo()))
&& (this.getSerailState() == null ? other.getSerailState() == null : this.getSerailState().equals(other.getSerailState()))
&& (this.getResType() == null ? other.getResType() == null : this.getResType().equals(other.getResType()))
&& (this.getPayType() == null ? other.getPayType() == null : this.getPayType().equals(other.getPayType()))
&& (this.getPayMoney() == null ? other.getPayMoney() == null : this.getPayMoney().equals(other.getPayMoney()))
&& (this.getPayTime() == null ? other.getPayTime() == null : this.getPayTime().equals(other.getPayTime()))
@ -220,9 +221,9 @@ public class HighPayRecord implements Serializable {
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((getPayRecordId() == null) ? 0 : getPayRecordId().hashCode());
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
result = prime * result + ((getPaySerialNo() == null) ? 0 : getPaySerialNo().hashCode());
result = prime * result + ((getSerailState() == null) ? 0 : getSerailState().hashCode());
result = prime * result + ((getResType() == null) ? 0 : getResType().hashCode());
result = prime * result + ((getPayType() == null) ? 0 : getPayType().hashCode());
result = prime * result + ((getPayMoney() == null) ? 0 : getPayMoney().hashCode());
result = prime * result + ((getPayTime() == null) ? 0 : getPayTime().hashCode());
@ -243,9 +244,9 @@ public class HighPayRecord implements Serializable {
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", payRecordId=").append(payRecordId);
sb.append(", id=").append(id);
sb.append(", paySerialNo=").append(paySerialNo);
sb.append(", serailState=").append(serailState);
sb.append(", resType=").append(resType);
sb.append(", payType=").append(payType);
sb.append(", payMoney=").append(payMoney);
sb.append(", payTime=").append(payTime);

@ -1,5 +1,6 @@
package com.hai.entity;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -125,63 +126,63 @@ public class HighPayRecordExample {
criteria.add(new Criterion(condition, value1, value2));
}
public Criteria andPayRecordIdIsNull() {
addCriterion("pay_record_id is null");
public Criteria andIdIsNull() {
addCriterion("id is null");
return (Criteria) this;
}
public Criteria andPayRecordIdIsNotNull() {
addCriterion("pay_record_id is not null");
public Criteria andIdIsNotNull() {
addCriterion("id is not null");
return (Criteria) this;
}
public Criteria andPayRecordIdEqualTo(Long value) {
addCriterion("pay_record_id =", value, "payRecordId");
public Criteria andIdEqualTo(Long value) {
addCriterion("id =", value, "id");
return (Criteria) this;
}
public Criteria andPayRecordIdNotEqualTo(Long value) {
addCriterion("pay_record_id <>", value, "payRecordId");
public Criteria andIdNotEqualTo(Long value) {
addCriterion("id <>", value, "id");
return (Criteria) this;
}
public Criteria andPayRecordIdGreaterThan(Long value) {
addCriterion("pay_record_id >", value, "payRecordId");
public Criteria andIdGreaterThan(Long value) {
addCriterion("id >", value, "id");
return (Criteria) this;
}
public Criteria andPayRecordIdGreaterThanOrEqualTo(Long value) {
addCriterion("pay_record_id >=", value, "payRecordId");
public Criteria andIdGreaterThanOrEqualTo(Long value) {
addCriterion("id >=", value, "id");
return (Criteria) this;
}
public Criteria andPayRecordIdLessThan(Long value) {
addCriterion("pay_record_id <", value, "payRecordId");
public Criteria andIdLessThan(Long value) {
addCriterion("id <", value, "id");
return (Criteria) this;
}
public Criteria andPayRecordIdLessThanOrEqualTo(Long value) {
addCriterion("pay_record_id <=", value, "payRecordId");
public Criteria andIdLessThanOrEqualTo(Long value) {
addCriterion("id <=", value, "id");
return (Criteria) this;
}
public Criteria andPayRecordIdIn(List<Long> values) {
addCriterion("pay_record_id in", values, "payRecordId");
public Criteria andIdIn(List<Long> values) {
addCriterion("id in", values, "id");
return (Criteria) this;
}
public Criteria andPayRecordIdNotIn(List<Long> values) {
addCriterion("pay_record_id not in", values, "payRecordId");
public Criteria andIdNotIn(List<Long> values) {
addCriterion("id not in", values, "id");
return (Criteria) this;
}
public Criteria andPayRecordIdBetween(Long value1, Long value2) {
addCriterion("pay_record_id between", value1, value2, "payRecordId");
public Criteria andIdBetween(Long value1, Long value2) {
addCriterion("id between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andPayRecordIdNotBetween(Long value1, Long value2) {
addCriterion("pay_record_id not between", value1, value2, "payRecordId");
public Criteria andIdNotBetween(Long value1, Long value2) {
addCriterion("id not between", value1, value2, "id");
return (Criteria) this;
}
@ -255,63 +256,63 @@ public class HighPayRecordExample {
return (Criteria) this;
}
public Criteria andSerailStateIsNull() {
addCriterion("serail_state is null");
public Criteria andResTypeIsNull() {
addCriterion("res_type is null");
return (Criteria) this;
}
public Criteria andSerailStateIsNotNull() {
addCriterion("serail_state is not null");
public Criteria andResTypeIsNotNull() {
addCriterion("res_type is not null");
return (Criteria) this;
}
public Criteria andSerailStateEqualTo(Integer value) {
addCriterion("serail_state =", value, "serailState");
public Criteria andResTypeEqualTo(Integer value) {
addCriterion("res_type =", value, "resType");
return (Criteria) this;
}
public Criteria andSerailStateNotEqualTo(Integer value) {
addCriterion("serail_state <>", value, "serailState");
public Criteria andResTypeNotEqualTo(Integer value) {
addCriterion("res_type <>", value, "resType");
return (Criteria) this;
}
public Criteria andSerailStateGreaterThan(Integer value) {
addCriterion("serail_state >", value, "serailState");
public Criteria andResTypeGreaterThan(Integer value) {
addCriterion("res_type >", value, "resType");
return (Criteria) this;
}
public Criteria andSerailStateGreaterThanOrEqualTo(Integer value) {
addCriterion("serail_state >=", value, "serailState");
public Criteria andResTypeGreaterThanOrEqualTo(Integer value) {
addCriterion("res_type >=", value, "resType");
return (Criteria) this;
}
public Criteria andSerailStateLessThan(Integer value) {
addCriterion("serail_state <", value, "serailState");
public Criteria andResTypeLessThan(Integer value) {
addCriterion("res_type <", value, "resType");
return (Criteria) this;
}
public Criteria andSerailStateLessThanOrEqualTo(Integer value) {
addCriterion("serail_state <=", value, "serailState");
public Criteria andResTypeLessThanOrEqualTo(Integer value) {
addCriterion("res_type <=", value, "resType");
return (Criteria) this;
}
public Criteria andSerailStateIn(List<Integer> values) {
addCriterion("serail_state in", values, "serailState");
public Criteria andResTypeIn(List<Integer> values) {
addCriterion("res_type in", values, "resType");
return (Criteria) this;
}
public Criteria andSerailStateNotIn(List<Integer> values) {
addCriterion("serail_state not in", values, "serailState");
public Criteria andResTypeNotIn(List<Integer> values) {
addCriterion("res_type not in", values, "resType");
return (Criteria) this;
}
public Criteria andSerailStateBetween(Integer value1, Integer value2) {
addCriterion("serail_state between", value1, value2, "serailState");
public Criteria andResTypeBetween(Integer value1, Integer value2) {
addCriterion("res_type between", value1, value2, "resType");
return (Criteria) this;
}
public Criteria andSerailStateNotBetween(Integer value1, Integer value2) {
addCriterion("serail_state not between", value1, value2, "serailState");
public Criteria andResTypeNotBetween(Integer value1, Integer value2) {
addCriterion("res_type not between", value1, value2, "resType");
return (Criteria) this;
}
@ -325,52 +326,52 @@ public class HighPayRecordExample {
return (Criteria) this;
}
public Criteria andPayTypeEqualTo(Long value) {
public Criteria andPayTypeEqualTo(Integer value) {
addCriterion("pay_type =", value, "payType");
return (Criteria) this;
}
public Criteria andPayTypeNotEqualTo(Long value) {
public Criteria andPayTypeNotEqualTo(Integer value) {
addCriterion("pay_type <>", value, "payType");
return (Criteria) this;
}
public Criteria andPayTypeGreaterThan(Long value) {
public Criteria andPayTypeGreaterThan(Integer value) {
addCriterion("pay_type >", value, "payType");
return (Criteria) this;
}
public Criteria andPayTypeGreaterThanOrEqualTo(Long value) {
public Criteria andPayTypeGreaterThanOrEqualTo(Integer value) {
addCriterion("pay_type >=", value, "payType");
return (Criteria) this;
}
public Criteria andPayTypeLessThan(Long value) {
public Criteria andPayTypeLessThan(Integer value) {
addCriterion("pay_type <", value, "payType");
return (Criteria) this;
}
public Criteria andPayTypeLessThanOrEqualTo(Long value) {
public Criteria andPayTypeLessThanOrEqualTo(Integer value) {
addCriterion("pay_type <=", value, "payType");
return (Criteria) this;
}
public Criteria andPayTypeIn(List<Long> values) {
public Criteria andPayTypeIn(List<Integer> values) {
addCriterion("pay_type in", values, "payType");
return (Criteria) this;
}
public Criteria andPayTypeNotIn(List<Long> values) {
public Criteria andPayTypeNotIn(List<Integer> values) {
addCriterion("pay_type not in", values, "payType");
return (Criteria) this;
}
public Criteria andPayTypeBetween(Long value1, Long value2) {
public Criteria andPayTypeBetween(Integer value1, Integer value2) {
addCriterion("pay_type between", value1, value2, "payType");
return (Criteria) this;
}
public Criteria andPayTypeNotBetween(Long value1, Long value2) {
public Criteria andPayTypeNotBetween(Integer value1, Integer value2) {
addCriterion("pay_type not between", value1, value2, "payType");
return (Criteria) this;
}
@ -385,52 +386,52 @@ public class HighPayRecordExample {
return (Criteria) this;
}
public Criteria andPayMoneyEqualTo(Float value) {
public Criteria andPayMoneyEqualTo(BigDecimal value) {
addCriterion("pay_money =", value, "payMoney");
return (Criteria) this;
}
public Criteria andPayMoneyNotEqualTo(Float value) {
public Criteria andPayMoneyNotEqualTo(BigDecimal value) {
addCriterion("pay_money <>", value, "payMoney");
return (Criteria) this;
}
public Criteria andPayMoneyGreaterThan(Float value) {
public Criteria andPayMoneyGreaterThan(BigDecimal value) {
addCriterion("pay_money >", value, "payMoney");
return (Criteria) this;
}
public Criteria andPayMoneyGreaterThanOrEqualTo(Float value) {
public Criteria andPayMoneyGreaterThanOrEqualTo(BigDecimal value) {
addCriterion("pay_money >=", value, "payMoney");
return (Criteria) this;
}
public Criteria andPayMoneyLessThan(Float value) {
public Criteria andPayMoneyLessThan(BigDecimal value) {
addCriterion("pay_money <", value, "payMoney");
return (Criteria) this;
}
public Criteria andPayMoneyLessThanOrEqualTo(Float value) {
public Criteria andPayMoneyLessThanOrEqualTo(BigDecimal value) {
addCriterion("pay_money <=", value, "payMoney");
return (Criteria) this;
}
public Criteria andPayMoneyIn(List<Float> values) {
public Criteria andPayMoneyIn(List<BigDecimal> values) {
addCriterion("pay_money in", values, "payMoney");
return (Criteria) this;
}
public Criteria andPayMoneyNotIn(List<Float> values) {
public Criteria andPayMoneyNotIn(List<BigDecimal> values) {
addCriterion("pay_money not in", values, "payMoney");
return (Criteria) this;
}
public Criteria andPayMoneyBetween(Float value1, Float value2) {
public Criteria andPayMoneyBetween(BigDecimal value1, BigDecimal value2) {
addCriterion("pay_money between", value1, value2, "payMoney");
return (Criteria) this;
}
public Criteria andPayMoneyNotBetween(Float value1, Float value2) {
public Criteria andPayMoneyNotBetween(BigDecimal value1, BigDecimal value2) {
addCriterion("pay_money not between", value1, value2, "payMoney");
return (Criteria) this;
}

@ -0,0 +1,50 @@
package com.hai.service;
import com.hai.entity.HighOrder;
import java.util.List;
import java.util.Map;
/**
* @Auther: 胡锐
* @Description:
* @Date: 2021/3/26 23:04
*/
public interface HighOrderService {
/**
* @Author 胡锐
* @Description 增加订单
* @Date 2021/3/26 23:05
**/
void insertOrder(HighOrder highOrder);
/**
* @Author 胡锐
* @Description 修改订单
* @Date 2021/3/26 23:06
**/
void updateOrder(HighOrder highOrder);
/**
* @Author 胡锐
* @Description 根据id查询
* @Date 2021/3/26 23:06
**/
HighOrder getOrderById(Long id);
/**
* @Author 胡锐
* @Description 根据订单号查询
* @Date 2021/3/27 0:38
**/
HighOrder getOrderByOrderNo(String orderNo);
/**
* @Author 胡锐
* @Description 查询订单列表
* @Date 2021/3/26 23:06
**/
List<HighOrder> getOrderList(Map<String,Object> map);
}

@ -0,0 +1,95 @@
package com.hai.service.impl;
import com.hai.dao.HighChildOrderMapper;
import com.hai.dao.HighOrderMapper;
import com.hai.entity.HighChildOrder;
import com.hai.entity.HighChildOrderExample;
import com.hai.entity.HighOrder;
import com.hai.entity.HighOrderExample;
import com.hai.service.HighOrderService;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
* @Auther: 胡锐
* @Description:
* @Date: 2021/3/26 23:06
*/
@Service("highOrderService")
public class HighOrderServiceImpl implements HighOrderService {
@Resource
private HighOrderMapper highOrderMapper;
@Resource
private HighChildOrderMapper highChildOrderMapper;
@Override
@Transactional(propagation= Propagation.REQUIRES_NEW)
public void insertOrder(HighOrder highOrder) {
highOrderMapper.insert(highOrder);
for (HighChildOrder childOrder : highOrder.getHighChildOrderList()) {
childOrder.setOrderId(highOrder.getId());
highChildOrderMapper.insert(childOrder);
}
}
@Override
public void updateOrder(HighOrder highOrder) {
}
@Override
public HighOrder getOrderById(Long id) {
HighOrder order = highOrderMapper.selectByPrimaryKey(id);
if (order == null) {
return null;
}
HighChildOrderExample example = new HighChildOrderExample();
example.createCriteria().andOrderIdEqualTo(order.getId());
order.setHighChildOrderList(highChildOrderMapper.selectByExample(example));
return order;
}
@Override
public HighOrder getOrderByOrderNo(String orderNo) {
HighOrderExample example = new HighOrderExample();
example.createCriteria().andOrderNoEqualTo(orderNo);
List<HighOrder> list = highOrderMapper.selectByExample(example);
if (list != null && list.size() > 0) {
return getOrderById(list.get(0).getId());
}
return null;
}
@Override
public List<HighOrder> getOrderList(Map<String, Object> map) {
HighOrderExample example = new HighOrderExample();
HighOrderExample.Criteria criteria = example.createCriteria();
if (MapUtils.getLong(map, "memId") != null) {
criteria.andMemIdEqualTo(MapUtils.getLong(map, "memId"));
}
if (MapUtils.getInteger(map, "status") != null) {
criteria.andOrderStatusEqualTo(MapUtils.getInteger(map, "status"));
}
if (MapUtils.getString(map, "orderNo") != null) {
criteria.andOrderNoEqualTo(MapUtils.getString(map, "orderNo"));
}
example.setOrderByClause("create_time desc");
return highOrderMapper.selectByExample(example);
}
}

@ -0,0 +1,30 @@
package com.hai.service.pay;
import java.util.Map;
/**
* @Description 支付宝/微信 支付回调
* @author gongjia
* @date 2020/3/27 15:30
* @Copyright 2019 www.shinwoten.com Inc. All rights reserved.
*/
public interface NotifyService {
/**
*
* @Title alipayNotify
* @Description 支付宝 验签成功后业务调用
* @author gongjia
* @param paramsMap 异步回调返回的参数
*/
String alipayNotify(Map<String, String> paramsMap) throws Exception;
/**
*
* @Title alipayNotify
* @Description 微信 验签成功后业务调用
* @author gongjia
* @param paramsMap 异步回调返回的参数
*/
String wechatNotify(Map<String, String> paramsMap) throws Exception;
}

@ -0,0 +1,30 @@
package com.hai.service.pay;
import com.hai.entity.HighPayRecord;
import java.util.Map;
/**
* @ClassName: PayRecordService
* @Description: 支付纪录
* @author: gongjia
* @date: 2020/3/27 9:48
* @Copyright: 2019 www.shinwoten.com Inc. All rights reserved.
*/
public interface PayRecordService {
/**
*
* @author gongjia
* @param paramsMap 支付纪录信息支付宝或微信回调传回的信息
* @param payType 支付方式Alipay-支付宝 WechatPay-微信
*/
int addPayRecord(Map<String, String> paramsMap, String payType) throws Exception;
/**
* @desc 插入支付纪录
* @author gongjia
*/
int addPayRecord(HighPayRecord payRecord) throws Exception;
}

@ -0,0 +1,21 @@
package com.hai.service.pay;
import java.util.Map;
/**
* @ClassName: PayService
* @Description: 支付完成 不同模块实际的业务处理
* @author: gongjia
* @date: 2020/3/27 16:28
* @Copyright: 2019 www.shinwoten.com Inc. All rights reserved.
*/
public interface PayService {
/**
* @desc 不同模块实际的业务处理
* @param map 支付宝/微信 异步回调返回的参数
* @param payType 支付方式Alipay-支付宝 WechatPay-微信
*/
void paySuccess(Map<String, String> map, String payType) throws Exception;
}

@ -0,0 +1,39 @@
package com.hai.service.pay.impl;
import com.alibaba.fastjson.JSONObject;
import com.hai.entity.HighOrder;
import com.hai.service.HighOrderService;
import com.hai.service.pay.PayService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
* @Auther: 胡锐
* @Description:
* @Date: 2021/3/27 00:35
*/
@Service("goodsOrderService")
public class GoodsOrderServiceImpl implements PayService {
@Resource
private HighOrderService highOrderService;
@Override
public void paySuccess(Map<String, String> map, String payType) throws Exception {
if (payType.equals("Alipay")) {
// 支付宝支付 todo 暂未开发
return;
}
if (payType.equals("WechatPay")) {
HighOrder order = highOrderService.getOrderByOrderNo(map.get("out_trade_no"));
if (order == null) {
}
}
}
}

@ -0,0 +1,121 @@
package com.hai.service.pay.impl;
import com.alibaba.fastjson.JSONObject;
import com.hai.common.pay.entity.OrderType;
import com.hai.common.utils.SpringContextUtil;
import com.hai.service.pay.NotifyService;
import com.hai.service.pay.PayRecordService;
import com.hai.service.pay.PayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Map;
@Service(value = "notifyService")
public class NotifyServiceImpl implements NotifyService {
private static Logger log = LoggerFactory.getLogger(NotifyServiceImpl.class);
@Resource
private PayRecordService payRecordService;
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public String alipayNotify(Map<String, String> params) throws Exception {
String result = "failure";
String trade_status = params.get("trade_status");
if ("TRADE_SUCCESS".equals(trade_status)) {
// 交易支付成功 默认触发
String orderType = params.get("passback_params");
PayService payService = getPayService(orderType);
if (payService != null) {
payService.paySuccess(params, "Alipay"); // 商户内部实际的交易业务处理
log.info("支付宝异步通知 -> 业务处理完成");
result = "success";
} else {
log.info("支付宝异步通知 -> 业务处理:payService获取失败");
}
} else if ("TRADE_CLOSED".equals(trade_status)) {
// 未付款交易超时关闭,或支付完成后全额退款 默认触发
// todo 业务流程
log.info("支付宝异步通知 -> 未付款交易超时关闭,或支付完成后全额退款");
result = "success";
} else if ("WAIT_BUYER_PAY".equals(trade_status)) {
// 交易创建,等待买家付款 默认不触发
// todo 业务流程
log.info("支付宝异步通知 -> 交易创建,等待买家付款");
result = "success";
} else if ("TRADE_FINISHED".equals(trade_status)) {
// 交易结束,不可退款 默认不触发
// todo 业务流程
log.info("支付宝异步通知 -> 交易结束,不可退款");
result = "success";
}
// 增加支付纪录(实际是支付宝回调纪录)
payRecordService.addPayRecord(params, "Alipay");
return result;
}
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public String wechatNotify(Map<String, String> paramsMap) throws Exception {
String resXml = null;
if ("SUCCESS".equals(paramsMap.get("return_code")) && "SUCCESS".equals(paramsMap.get("result_code"))) {
log.info("微信支付 -> 异步通知:支付成功,进入订单处理");
String orderScene = paramsMap.get("attach");
JSONObject object = JSONObject.parseObject(orderScene);
// 订单类型
String orderType = object.getString("orderScene");
PayService payService = getPayService(orderType);
if (payService != null) {
payService.paySuccess(paramsMap, "WechatPay"); // 商户内部实际的交易业务处理
log.info("微信支付 -> 异步通知:订单处理完成");
} else {
log.error("微信支付 -> 异步通知:业务处理,payService获取失败");
}
// 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了
resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
} else {
log.error("微信支付 -> 异步通知:支付失败,错误信息:" + paramsMap.get("err_code_des"));
resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA["
+ paramsMap.get("err_code_des") + "]]></return_msg>" + "</xml> ";
}
if ("SUCCESS".equals(paramsMap.get("return_code"))) {
// 增加支付纪录(实际是微信回调纪录)
payRecordService.addPayRecord(paramsMap, "WechatPay");
}
return resXml;
}
/**
* @desc 根据回调回传参数 选择业务service
* @param orderType 订单类型回传参数
*/
private PayService getPayService(String orderType) throws Exception{
PayService payService = null;
for (OrderType item : OrderType.values()) {
if (item.getModuleCode().equals(orderType)) {
payService = (PayService) SpringContextUtil.getBean(item.getService());
break;
}
}
return payService;
}
}

@ -0,0 +1,60 @@
package com.hai.service.pay.impl;
import com.alibaba.fastjson.JSONObject;
import com.hai.common.utils.DateUtil;
import com.hai.dao.HighPayRecordMapper;
import com.hai.entity.HighPayRecord;
import com.hai.service.pay.PayRecordService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.Map;
@Service(value = "payRecordService")
public class PayRecordServiceImpl implements PayRecordService {
@Resource
private HighPayRecordMapper payRecordMapper;
@Override
public int addPayRecord(Map<String, String> paramsMap, String payType) throws Exception {
HighPayRecord payRecord = new HighPayRecord();
if ("Alipay".equals(payType)) {
payRecord.setPaySerialNo(paramsMap.get("trade_no"));
payRecord.setResType(2);
payRecord.setPayType(1);
payRecord.setPayMoney(new BigDecimal(paramsMap.get("receipt_amount")));
payRecord.setPayTime(DateUtil.StringToDate(paramsMap.get("gmt_payment"), "yyyy-MM-dd HH:mm:ss"));
payRecord.setBodyInfo(JSONObject.toJSONString(paramsMap));
payRecord.setPayResult(paramsMap.get("trade_status"));
} else if ("WechatPay".equals(payType)) {
payRecord.setPaySerialNo(paramsMap.get("transaction_id"));
payRecord.setResType(2);
payRecord.setPayType(2);
payRecord.setPayMoney(new BigDecimal(paramsMap.get("cash_fee")).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
payRecord.setPayTime(DateUtil.StringToDate(paramsMap.get("time_end"), "yyyyMMddHHmmss"));
payRecord.setBodyInfo(JSONObject.toJSONString(paramsMap));
payRecord.setPayResult(paramsMap.get("result_code"));
} else {
return 0;
}
payRecord.setCreateTime(new Date());
return payRecordMapper.insertSelective(payRecord);
}
@Override
public int addPayRecord(HighPayRecord payRecord) throws Exception {
payRecord.setCreateTime(new Date());
return payRecordMapper.insertSelective(payRecord);
}
}

@ -0,0 +1,23 @@
package com.hai.service.pay.impl;
import com.hai.service.pay.PayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service(value = "testPayService")
public class TestPayService implements PayService {
private static Logger log = LoggerFactory.getLogger(TestPayService.class);
@Override
public void paySuccess(Map<String, String> map, String payType) throws Exception {
log.info("AlipayNotify Test --------> start");
System.out.println("\nAlipayNotify Test --------> start");
System.out.println("\nAlipayNotify Test --------> done");
log.info("AlipayNotify Test --------> done");
}
}
Loading…
Cancel
Save