积分模块相关代码

This commit is contained in:
谭凯凯
2024-11-01 16:31:44 +08:00
committed by Tankaikai
parent a9bfd9b93b
commit 41edba65fc
10 changed files with 516 additions and 75 deletions

View File

@@ -1,11 +1,14 @@
package com.chaozhanggui.system.cashierservice.controller;
import cn.hutool.core.map.MapProxy;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.chaozhanggui.system.cashierservice.entity.TbPointsExchangeRecord;
import com.chaozhanggui.system.cashierservice.interceptor.RequestWrapper;
import com.chaozhanggui.system.cashierservice.service.PayService;
import com.chaozhanggui.system.cashierservice.service.TbPointsExchangeRecordService;
import com.chaozhanggui.system.cashierservice.sign.Result;
import com.chaozhanggui.system.cashierservice.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
@@ -24,10 +27,12 @@ import java.util.Map;
public class NotifyController {
@Autowired
PayService payService;
@Autowired
private TbPointsExchangeRecordService tbPointsExchangeRecordService;
@RequestMapping("memberInCallBack")
public String memberInCallBack(HttpServletRequest request) {
@@ -47,20 +52,20 @@ public class NotifyController {
@RequestMapping("fstmemberInCallBack")
public String fstmemberInCallBack(HttpServletRequest request) throws Exception {
Map<String, Object> map= getParameterMap(request);
log.info("fstmemberInCallBack回调返回信息:{}",JSONUtil.toJsonStr(map));
if(ObjectUtil.isNotEmpty(map)&&map.containsKey("code")&&"000000".equals(map.get("code")+"")){
Map<String, Object> map = getParameterMap(request);
log.info("fstmemberInCallBack回调返回信息:{}", JSONUtil.toJsonStr(map));
if (ObjectUtil.isNotEmpty(map) && map.containsKey("code") && "000000".equals(map.get("code") + "")) {
// Map<String,Object> object=(Map)map.get("bizData");
JSONObject object=JSONUtil.parseObj(map.get("bizData").toString());
if(ObjectUtil.isNotEmpty(object)&&object.containsKey("state")){
if("TRADE_SUCCESS".equals(object.get("state").toString())){
String orderNo=object.get("mchOrderNo").toString();
String tradeNo=object.get("payOrderId").toString();
String payType=object.getStr("payType");
return payService.fstMemberInSuccess(orderNo,tradeNo, payType);
}
JSONObject object = JSONUtil.parseObj(map.get("bizData").toString());
if (ObjectUtil.isNotEmpty(object) && object.containsKey("state")) {
if ("TRADE_SUCCESS".equals(object.get("state").toString())) {
String orderNo = object.get("mchOrderNo").toString();
String tradeNo = object.get("payOrderId").toString();
String payType = object.getStr("payType");
return payService.fstMemberInSuccess(orderNo, tradeNo, payType);
}
}
}
return null;
@@ -68,18 +73,18 @@ public class NotifyController {
}
@RequestMapping("notifyCallBack")
public String notifyCallBack(HttpServletRequest request){
public String notifyCallBack(HttpServletRequest request) {
Map<String, Object> map= getParameterMap(request);
log.info("回调返回信息:{}",JSONUtil.toJsonStr(map));
if(ObjectUtil.isNotEmpty(map)&&map.containsKey("code")&&"200".equals(map.get("code")+"")){
JSONObject object=JSONUtil.parseObj(map.get("data"));
if(ObjectUtil.isNotEmpty(object)
Map<String, Object> map = getParameterMap(request);
log.info("回调返回信息:{}", JSONUtil.toJsonStr(map));
if (ObjectUtil.isNotEmpty(map) && map.containsKey("code") && "200".equals(map.get("code") + "")) {
JSONObject object = JSONUtil.parseObj(map.get("data"));
if (ObjectUtil.isNotEmpty(object)
&& object.containsKey("status")
&& "1".equals(object.getStr("status"))
&& !"0100".equals(object.getStr("payType"))
){
String orderNo=object.getStr("orderNumber");
) {
String orderNo = object.getStr("orderNumber");
return payService.callBackPay(orderNo);
}
@@ -90,6 +95,7 @@ public class NotifyController {
/**
* 支付取消
*
* @return 影响数量
*/
@PostMapping("cancel")
@@ -99,21 +105,21 @@ public class NotifyController {
@RequestMapping("notifyfstCallBack")
public String notifyfstCallBack(HttpServletRequest request){
public String notifyfstCallBack(HttpServletRequest request) {
Map<String, Object> map= getParameterMap(request);
log.info("notifyfstCallBack回调返回信息:{}",JSONUtil.toJsonStr(map));
if(ObjectUtil.isNotEmpty(map)&&map.containsKey("code")&&"000000".equals(map.get("code")+"")){
Map<String, Object> map = getParameterMap(request);
log.info("notifyfstCallBack回调返回信息:{}", JSONUtil.toJsonStr(map));
if (ObjectUtil.isNotEmpty(map) && map.containsKey("code") && "000000".equals(map.get("code") + "")) {
JSONObject object=JSONUtil.parseObj(map.get("bizData").toString());
if(ObjectUtil.isNotEmpty(object)&&object.containsKey("state")){
if("TRADE_SUCCESS".equals(object.get("state").toString())){
String orderNo=object.get("mchOrderNo").toString();
String tradeNo=object.get("payOrderId").toString();
String payType=object.getStr("payType");
return payService.callBackPayFST(tradeNo,payType);
}else {
String tradeNo=object.get("payOrderId").toString();
JSONObject object = JSONUtil.parseObj(map.get("bizData").toString());
if (ObjectUtil.isNotEmpty(object) && object.containsKey("state")) {
if ("TRADE_SUCCESS".equals(object.get("state").toString())) {
String orderNo = object.get("mchOrderNo").toString();
String tradeNo = object.get("payOrderId").toString();
String payType = object.getStr("payType");
return payService.callBackPayFST(tradeNo, payType);
} else {
String tradeNo = object.get("payOrderId").toString();
return String.valueOf(payService.activateOrder(tradeNo));
}
}
@@ -123,15 +129,15 @@ public class NotifyController {
}
@RequestMapping("notifyCallBackGroupYsk")
public String notifyCallBackGroupYsk(HttpServletRequest request){
Map<String, Object> map= getParameterMap(request);
log.info("团购卷回调返回信息:{}",JSONUtil.toJsonStr(map));
if(ObjectUtil.isNotEmpty(map)&&map.containsKey("code")&&"200".equals(map.get("code")+"")){
JSONObject object=JSONUtil.parseObj(map.get("data"));
if(ObjectUtil.isNotEmpty(object)&&object.containsKey("status")&&"1".equals(object.getStr("status"))){
String orderNo=object.getStr("orderNumber");
public String notifyCallBackGroupYsk(HttpServletRequest request) {
Map<String, Object> map = getParameterMap(request);
log.info("团购卷回调返回信息:{}", JSONUtil.toJsonStr(map));
if (ObjectUtil.isNotEmpty(map) && map.containsKey("code") && "200".equals(map.get("code") + "")) {
JSONObject object = JSONUtil.parseObj(map.get("data"));
if (ObjectUtil.isNotEmpty(object) && object.containsKey("status") && "1".equals(object.getStr("status"))) {
String orderNo = object.getStr("orderNumber");
String payTime = object.getStr("payTime");
return payService.callBackGroupPay(orderNo,payTime);
return payService.callBackGroupPay(orderNo, payTime);
}
}
return null;
@@ -153,6 +159,7 @@ public class NotifyController {
/**
* 点歌支付回调
*
* @param request
* @return
*/
@@ -163,7 +170,7 @@ public class NotifyController {
if (ObjectUtil.isNotEmpty(map) && map.containsKey("code") && "000000".equals(map.get("code") + "")) {
JSONObject object = JSONUtil.parseObj(map.get("bizData"));
if (ObjectUtil.isNotEmpty(object) && object.containsKey("state") && "TRADE_SUCCESS".equals(object.getStr("state"))) {
String tradeNo=object.get("payOrderId").toString();
String tradeNo = object.get("payOrderId").toString();
String orderNo = object.getStr("mchOrderNo");
return payService.songOrderSuccess(orderNo, tradeNo);
}
@@ -171,13 +178,48 @@ public class NotifyController {
return null;
}
@RequestMapping("pointsGoodsOrderCallBack")
public String pointsGoodsOrderCallBack(HttpServletRequest request, @RequestBody Map<String, Object> params) {
log.info("积分商城订单支付回调返回信息:{}", JSONUtil.toJsonStr(params));
//Map<String, Object> params = getParameterMap(request);
log.info("积分商城订单支付回调返回信息:{}", JSONUtil.toJsonStr(params));
MapProxy proxy = MapProxy.create(params);
String code = proxy.getStr("code");
String msg = proxy.getStr("msg");
if (!"000000".equals(code)) {
log.error("支付失败:{}", msg);
return "FAIL";
}
String bizData = proxy.getStr("bizData");
JSONObject data = JSONUtil.parseObj(bizData);
String state = data.getStr("state");
if (!"TRADE_SUCCESS".equals(state)) {
log.error("支付失败:{}", state);
return "FAIL";
}
String payOrderId = data.getStr("payOrderId");
String channelTradeNo = data.getStr("channelTradeNo");
Date payTime = data.getDate("payTime", new Date());
TbPointsExchangeRecord record = new TbPointsExchangeRecord();
record.setPayOrderId(payOrderId);
record.setChannelTradeNo(channelTradeNo);
record.setPayTime(payTime);
try {
tbPointsExchangeRecordService.callback(record);
} catch (Exception e) {
log.error("支付失败:{}", e);
return "FAIL";
}
return "SUCCESS";
}
private Map getParameterMap(HttpServletRequest request) {
RequestWrapper requestWrapper = new RequestWrapper(request);
String body = requestWrapper.getBody();
if (ObjectUtil.isNotEmpty(body)) {
return JSONUtil.toBean(body, Map.class);
}else {
} else {
Map<String, String[]> parameterMap = request.getParameterMap();
return parameterMap;
}

View File

@@ -4,10 +4,12 @@ import com.chaozhanggui.system.cashierservice.entity.TbPointsExchangeRecord;
import com.chaozhanggui.system.cashierservice.service.TbPointsExchangeRecordService;
import com.chaozhanggui.system.cashierservice.sign.CodeEnum;
import com.chaozhanggui.system.cashierservice.sign.Result;
import com.chaozhanggui.system.cashierservice.util.IpUtil;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@@ -60,18 +62,57 @@ public class TbPointsExchangeRecordController {
return Result.success(CodeEnum.SUCCESS);
}
/**
* 兑换
* 创建订单
*
* @param record
* @return
*/
@PostMapping("exchange")
public Result exchange(@RequestBody TbPointsExchangeRecord record) {
TbPointsExchangeRecord data = tbPointsExchangeRecordService.exchange(record);
@PostMapping("create")
public Result create(@RequestBody TbPointsExchangeRecord record) {
TbPointsExchangeRecord data = tbPointsExchangeRecordService.create(record);
return Result.successWithData(data);
}
/**
* 支付
*
* @param record
* @return
*/
@PostMapping("pay")
public Result pay(HttpServletRequest request, @RequestBody TbPointsExchangeRecord record) {
String ip = IpUtil.getIpAddr(request);
record.setIp(ip);
TbPointsExchangeRecord data = tbPointsExchangeRecordService.pay(record);
return Result.successWithData(data);
}
/**
* 取消
*
* @param record
* @return
*/
@PostMapping("cancel")
public Result cancel(@RequestBody TbPointsExchangeRecord record) {
tbPointsExchangeRecordService.cancel(record);
return Result.success(CodeEnum.SUCCESS);
}
/**
* 退单
*
* @param record
* @return
*/
@PostMapping("refund")
public Result exchange(@RequestBody TbPointsExchangeRecord record) {
tbPointsExchangeRecordService.refund(record);
return Result.success(CodeEnum.SUCCESS);
}
/**
* 统计
*

View File

@@ -2,6 +2,8 @@ package com.chaozhanggui.system.cashierservice.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -78,9 +80,38 @@ public class TbPointsExchangeRecord {
*/
private String couponCode;
/**
* 状态 waiting-待自取 done-已完成
* 支付平台订单号
*/
private String payOrderId;
/**
* 渠道订单号(微信/支付宝订单号)
*/
private String channelTradeNo;
/**
* 支付方式 积分支付/积分+微信/积分+支付宝
*/
private String payMethod;
/**
* 支付类型 POINTS-积分 WECHAT-微信 ALIPAY-支付宝 UNIONPAY-银联云闪付
*/
private String payType;
/**
* 状态 unpaid-待支付 waiting-待自取 done-已完成 cancel-已取消
*/
private String status;
/**
* 取消/退款原因
*/
private String cancelOrRefundReason;
/**
* 取消/退款时间
*/
private Date cancelOrRefundTime;
/**
* 实际支付时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date payTime;
/**
* 创建时间(下单时间)
*/
@@ -97,4 +128,18 @@ public class TbPointsExchangeRecord {
@TableField(value = "sum(extra_payment_amount)", select = false, insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
private BigDecimal totalAmount;
/**
* 用户ip
*/
@JsonIgnore
@TableField(exist = false)
private String ip;
/**
* 微信openId/支付完userId
*/
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@TableField(exist = false)
private String openId;
}

View File

@@ -20,7 +20,15 @@ public interface TbPointsExchangeRecordService extends IService<TbPointsExchange
void checkout(String couponCode);
TbPointsExchangeRecord exchange(TbPointsExchangeRecord record);
TbPointsExchangeRecord create(TbPointsExchangeRecord record);
TbPointsExchangeRecord pay(TbPointsExchangeRecord record);
void callback(TbPointsExchangeRecord record);
void cancel(TbPointsExchangeRecord record);
void refund(TbPointsExchangeRecord record);
Map<String, Object> total(Map<String, Object> params);
}

View File

@@ -5,19 +5,26 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.map.MapProxy;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chaozhanggui.system.cashierservice.dao.TbMerchantThirdApplyMapper;
import com.chaozhanggui.system.cashierservice.entity.*;
import com.chaozhanggui.system.cashierservice.exception.MsgException;
import com.chaozhanggui.system.cashierservice.mapper.*;
import com.chaozhanggui.system.cashierservice.service.TbPointsExchangeRecordService;
import com.chaozhanggui.system.cashierservice.thirdpay.resp.OrderReturnResp;
import com.chaozhanggui.system.cashierservice.thirdpay.resp.PublicResp;
import com.chaozhanggui.system.cashierservice.thirdpay.resp.WxScanPayResp;
import com.chaozhanggui.system.cashierservice.thirdpay.service.ThirdPayService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -37,6 +44,17 @@ import java.util.Map;
@Primary
public class TbPointsExchangeRecordServiceImpl extends ServiceImpl<TbPointsExchangeRecordMapper, TbPointsExchangeRecord> implements TbPointsExchangeRecordService {
private static final Map<String, String> payMethod = MapUtil.builder("POINTS", "积分支付")
.put("WECHAT", "积分+微信")
.put("ALIPAY", "积分+支付宝")
.build();
@Value("${thirdPay.url}")
private String thirdUrl;
@Value("${thirdPay.pointsGoodsOrderCallBack}")
private String pointsGoodsOrderCallBack;
@Autowired
private TbPointsBasicSettingMapper tbPointsBasicSettingMapper;
@@ -49,6 +67,15 @@ public class TbPointsExchangeRecordServiceImpl extends ServiceImpl<TbPointsExcha
@Autowired
private TbMemberPointsLogMapper tbMemberPointsLogMapper;
@Autowired
private MpShopInfoMapper mpShopInfoMapper;
@Autowired
private TbMerchantThirdApplyMapper tbMerchantThirdApplyMapper;
@Autowired
private ThirdPayService thirdPayService;
private LambdaQueryWrapper<TbPointsExchangeRecord> getWrapper(Map<String, Object> params) {
MapProxy mapProxy = MapProxy.create(params);
String keywords = mapProxy.getStr("keywords");
@@ -91,6 +118,7 @@ public class TbPointsExchangeRecordServiceImpl extends ServiceImpl<TbPointsExcha
}
@Override
@Transactional(rollbackFor = Exception.class)
public void checkout(String couponCode) {
if (StrUtil.isBlank(couponCode)) {
throw new MsgException("兑换券券码不能为空");
@@ -102,11 +130,18 @@ public class TbPointsExchangeRecordServiceImpl extends ServiceImpl<TbPointsExcha
entity.setStatus("done");
entity.setUpdateTime(new Date());
super.updateById(entity);
TbPointsGoodsSetting goods = tbPointsGoodsSettingMapper.selectById(entity.getPointsGoodsId());
if (goods == null) {
throw new MsgException("积分商品不存在");
}
// 更新累计兑换数量
goods.setTotalExchangeCount(goods.getTotalExchangeCount() + 1);
goods.setUpdateTime(new Date());
tbPointsGoodsSettingMapper.updateById(goods);
}
@Override
@Transactional(rollbackFor = Exception.class)
public TbPointsExchangeRecord exchange(TbPointsExchangeRecord record) {
private void verify(TbPointsExchangeRecord record, TbPointsBasicSetting basic, TbPointsGoodsSetting goods, TbMemberPoints memberPoints) {
try {
Assert.notNull(record.getShopId(), "{}({})不能为空", "店铺id", "shopId");
Assert.notNull(record.getPointsGoodsId(), "{}({})不能为空", "积分商品id", "pointsGoodsId");
@@ -117,14 +152,14 @@ public class TbPointsExchangeRecordServiceImpl extends ServiceImpl<TbPointsExcha
} catch (IllegalArgumentException e) {
throw new MsgException(e.getMessage());
}
TbPointsBasicSetting basic = tbPointsBasicSettingMapper.selectOne(Wrappers.<TbPointsBasicSetting>lambdaQuery().eq(TbPointsBasicSetting::getShopId, record.getShopId()));
basic = tbPointsBasicSettingMapper.selectOne(Wrappers.<TbPointsBasicSetting>lambdaQuery().eq(TbPointsBasicSetting::getShopId, record.getShopId()));
if (basic == null) {
throw new MsgException("未配置积分锁客基本设置");
throw new MsgException("商家未配置积分锁客基本设置");
}
if (basic.getEnablePointsMall() != 1) {
throw new MsgException("积分商城未开启");
}
TbPointsGoodsSetting goods = tbPointsGoodsSettingMapper.selectById(record.getPointsGoodsId());
goods = tbPointsGoodsSettingMapper.selectById(record.getPointsGoodsId());
if (goods == null) {
throw new MsgException("兑换的商品信息不存在");
}
@@ -142,26 +177,183 @@ public class TbPointsExchangeRecordServiceImpl extends ServiceImpl<TbPointsExcha
if (quantity <= 0) {
throw new MsgException("兑换的商品库存不足");
}
TbMemberPoints memberPoints = tbMemberPointsMapper.selectOne(Wrappers.<TbMemberPoints>lambdaQuery().eq(TbMemberPoints::getMemberId, record.getMemberId()));
memberPoints = tbMemberPointsMapper.selectOne(Wrappers.<TbMemberPoints>lambdaQuery().eq(TbMemberPoints::getMemberId, record.getMemberId()));
if (memberPoints == null) {
throw new MsgException("会员积分不足无法兑换这个商品");
throw new MsgException("会员积分不足无法兑换商品");
}
Integer accountPoints = memberPoints.getAccountPoints();
Integer requiredPoints = goods.getRequiredPoints();
if (accountPoints < requiredPoints) {
throw new MsgException("会员积分不足无法兑换这个商品");
throw new MsgException("会员积分不足无法兑换商品");
}
BigDecimal extraPrice = goods.getExtraPrice();
record.setExtraPaymentAmount(extraPrice);
record.setSpendPoints(requiredPoints);
}
@Override
public TbPointsExchangeRecord create(TbPointsExchangeRecord record) {
TbPointsBasicSetting basic = null;
TbPointsGoodsSetting goods = null;
TbMemberPoints memberPoints = null;
verify(record, basic, goods, memberPoints);
record.setExtraPaymentAmount(goods.getExtraPrice());
record.setSpendPoints(goods.getRequiredPoints());
Snowflake seqNo = IdUtil.getSnowflake(0, 0);
String orderNo = DateUtil.format(new Date(), "yyyyMMddHH") + StrUtil.subSuf(seqNo.nextIdStr(), -12);
record.setOrderNo(orderNo);
record.setCouponCode(IdUtil.getSnowflakeNextIdStr());
record.setStatus("waiting");
record.setStatus("unpaid");
record.setCreateTime(new Date());
// 生成订单
super.save(record);
return record;
}
@Override
@Transactional(rollbackFor = Exception.class)
public TbPointsExchangeRecord pay(TbPointsExchangeRecord record) {
if (record.getId() == null) {
throw new MsgException("订单ID不能为空");
}
TbPointsExchangeRecord entity = super.getById(record.getId());
if (entity == null) {
throw new MsgException("订单不存在");
}
TbPointsBasicSetting basic = null;
TbPointsGoodsSetting goods = null;
TbMemberPoints memberPoints = null;
try {
verify(entity, basic, goods, memberPoints);
} catch (Exception e) {
throw new MsgException(e.getMessage().concat(",请您取消订单"));
}
if (!"unpaid".equals(record.getStatus())) {
throw new MsgException("订单状态异常,请刷新后重试");
}
if (StrUtil.isBlank(record.getPayType())) {
throw new MsgException("支付方式不能为空");
}
entity.setPayType(record.getPayType().toUpperCase());
if (!payMethod.keySet().contains(record.getPayType().toUpperCase())) {
throw new MsgException("支付方式不合法");
}
// 设置支付方式
entity.setPayMethod(payMethod.get(record.getPayType().toUpperCase()));
// 纯积分支付并且商品需要额外支付金额,需要抛出异常
if ("POINTS".equals(entity.getPayType()) && NumberUtil.isGreater(record.getExtraPaymentAmount(), BigDecimal.ZERO)) {
throw new MsgException("此商品需要额外支付金额");
}
if (!"POINTS".equals(entity.getPayType()) && NumberUtil.equals(record.getExtraPaymentAmount(), BigDecimal.ZERO)) {
throw new MsgException("此商品不需要额外支付金额");
}
// 如果不需要额外支付
if (NumberUtil.equals(record.getExtraPaymentAmount(), BigDecimal.ZERO)) {
// 设置核销券码
entity.setCouponCode(IdUtil.getSnowflakeNextIdStr());
entity.setStatus("waiting");
entity.setPayTime(new Date());
super.updateById(entity);
waitingAfter(entity);
return entity;
}
if (StrUtil.isBlank(record.getOpenId())) {
throw new MsgException("openId/userId不能为空");
}
if (StrUtil.isBlank(record.getIp())) {
throw new MsgException("无法获取用户ip地址");
}
// 需要额外支付
TbShopInfo shopInfo = mpShopInfoMapper.selectById(entity.getShopId());
if (shopInfo == null) {
throw new MsgException("店铺信息不存在");
}
TbMerchantThirdApply thirdApply = tbMerchantThirdApplyMapper.selectByPrimaryKey(Integer.valueOf(shopInfo.getMerchantId()));
if (thirdApply == null) {
throw new MsgException("支付通道不存在");
}
if ("alipay".equalsIgnoreCase(entity.getPayType()) && StrUtil.isBlank(thirdApply.getAlipaySmallAppid())) {
throw new MsgException("店铺未配置支付宝小程序appId");
}
// 准备支付参数
// 应用ID
String appId = thirdApply.getAppId();
String appToken = thirdApply.getAppToken();
String storeId = thirdApply.getStoreId();
// 订单标题(商品名称)
String subject = entity.getPointsGoodsName();
// 商品描述
String body = StrUtil.format("兑换商品:{} * {}", entity.getPointsGoodsName(), "1");
// 交易金额 单位分 100 表示1元
long amount = NumberUtil.mul(entity.getExtraPaymentAmount(), new BigDecimal("100")).longValue();
// 支付方式
String payType = entity.getPayType().toUpperCase();
// 子商户APPID
String subAppid = thirdApply.getSmallAppid();
if ("alipay".equalsIgnoreCase(entity.getPayType())) {
subAppid = thirdApply.getAlipaySmallAppid();
}
// 用户唯一标识 微信支付时传入用户的openId支付宝支付和银联支付时传入用户的userId
String openId = record.getOpenId();
// 用户IP
String clientIp = record.getIp();
// 商户订单号 mchOrderNo
String mchOrderNo = IdUtil.getSnowflakeNextIdStr();
// 回调地址
String notifyUrl = pointsGoodsOrderCallBack;
// 支付成功后的跳转页面
String returnUrl = null;
PublicResp<WxScanPayResp> publicResp;
try {
publicResp = thirdPayService.scanpay(thirdUrl, appId, subject, body, amount, payType, subAppid, openId, clientIp, mchOrderNo, storeId, notifyUrl, returnUrl, appToken);
} catch (Exception e) {
log.error("拉起支付失败:", e);
throw new MsgException(StrUtil.format("拉起支付失败:{}", e.getMessage()));
}
if (publicResp == null) {
throw new MsgException("拉起支付失败:无响应");
}
if (!"000000".equals(publicResp.getCode())) {
throw new MsgException(publicResp.getMsg());
}
WxScanPayResp payResp = publicResp.getObjData();
if (!"TRADE_AWAIT".equals(payResp.getState())) {
throw new MsgException(StrUtil.format("拉起支付失败:{}", payResp.getState()));
}
entity.setPayOrderId(payResp.getPayOrderId());
super.updateById(entity);
return entity;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void callback(TbPointsExchangeRecord record) {
TbPointsExchangeRecord entity = baseMapper.selectOne(Wrappers.<TbPointsExchangeRecord>lambdaQuery().eq(TbPointsExchangeRecord::getPayOrderId, record.getPayOrderId()));
if (entity == null) {
throw new MsgException("对应的支付订单不存在");
}
entity.setStatus("waiting");
entity.setPayTime(record.getPayTime());
entity.setChannelTradeNo(record.getChannelTradeNo());
entity.setCouponCode(IdUtil.getSnowflakeNextIdStr());
super.updateById(entity);
waitingAfter(entity);
}
/**
* 支付完成的后续操作
*
* @param entity
*/
private void waitingAfter(TbPointsExchangeRecord entity) {
TbPointsGoodsSetting goods = tbPointsGoodsSettingMapper.selectById(entity.getPointsGoodsId());
if (goods == null) {
throw new MsgException("积分商品不存在");
}
TbMemberPoints memberPoints = tbMemberPointsMapper.selectOne(Wrappers.<TbMemberPoints>lambdaQuery().eq(TbMemberPoints::getMemberId, entity.getMemberId()));
if (memberPoints == null) {
throw new MsgException("会员积分不足无法兑换此商品");
}
Integer quantity = goods.getQuantity();
Integer accountPoints = memberPoints.getAccountPoints();
Integer requiredPoints = goods.getRequiredPoints();
// 扣减积分
memberPoints.setAccountPoints(accountPoints - requiredPoints);
memberPoints.setLastPointsChangeTime(new Date());
@@ -173,21 +365,130 @@ public class TbPointsExchangeRecordServiceImpl extends ServiceImpl<TbPointsExcha
tbPointsGoodsSettingMapper.updateById(goods);
// 记录积分浮动流水
TbMemberPointsLog log = new TbMemberPointsLog();
log.setShopId(record.getShopId());
log.setMemberId(record.getMemberId());
log.setMemberName(record.getMemberName());
log.setMobile(record.getMobile());
log.setAvatarUrl(record.getAvatarUrl());
log.setContent(StrUtil.format("兑换商品:{} * {}", record.getPointsGoodsName(), "1"));
log.setShopId(entity.getShopId());
log.setMemberId(entity.getMemberId());
log.setMemberName(entity.getMemberName());
log.setMobile(entity.getMobile());
log.setAvatarUrl(entity.getAvatarUrl());
log.setContent(StrUtil.format("兑换商品:{} * {}", entity.getPointsGoodsName(), "1"));
log.setFloatType("subtract");
log.setFloatPoints(-requiredPoints);
log.setCreateTime(new Date());
tbMemberPointsLogMapper.insert(log);
// 更新累计兑换数量
goods.setTotalExchangeCount(goods.getTotalExchangeCount() + 1);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void cancel(TbPointsExchangeRecord record) {
if (record.getId() == null) {
throw new MsgException("订单ID不能为空");
}
TbPointsExchangeRecord entity = super.getById(record.getId());
if (entity == null) {
throw new MsgException("订单不存在");
}
if (!"unpaid".equals(entity.getStatus())) {
throw new MsgException("当前订单状态不支持取消");
}
entity.setStatus("cancel");
entity.setCancelOrRefundReason(record.getCancelOrRefundReason());
entity.setCancelOrRefundTime(new Date());
super.updateById(entity);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void refund(TbPointsExchangeRecord record) {
if (record.getId() == null) {
throw new MsgException("订单ID不能为空");
}
TbPointsExchangeRecord entity = super.getById(record.getId());
if (entity == null) {
throw new MsgException("订单不存在");
}
if (!"waiting".equals(entity.getStatus())) {
throw new MsgException("当前订单状态不支持退款");
}
// 先退积分
entity.setStatus("cancel");
entity.setCancelOrRefundReason(record.getCancelOrRefundReason());
entity.setCancelOrRefundTime(new Date());
super.updateById(entity);
TbMemberPoints memberPoints = tbMemberPointsMapper.selectOne(Wrappers.<TbMemberPoints>lambdaQuery().eq(TbMemberPoints::getMemberId, entity.getMemberId()));
if (memberPoints == null) {
throw new MsgException("会员信息不存在");
}
memberPoints.setAccountPoints(memberPoints.getAccountPoints() + entity.getSpendPoints());
memberPoints.setLastPointsChangeTime(new Date());
memberPoints.setLastFloatPoints(entity.getSpendPoints());
tbMemberPointsMapper.updateById(memberPoints);
// 回滚库存
TbPointsGoodsSetting goods = tbPointsGoodsSettingMapper.selectById(entity.getPointsGoodsId());
if (goods == null) {
throw new MsgException("积分商品不存在");
}
goods.setQuantity(goods.getQuantity() + 1);
goods.setUpdateTime(new Date());
tbPointsGoodsSettingMapper.updateById(goods);
return record;
// 记录积分浮动流水
TbMemberPointsLog log = new TbMemberPointsLog();
log.setShopId(entity.getShopId());
log.setMemberId(entity.getMemberId());
log.setMemberName(entity.getMemberName());
log.setMobile(entity.getMobile());
log.setAvatarUrl(entity.getAvatarUrl());
log.setContent(StrUtil.format("(退单)兑换商品:{} * {}", entity.getPointsGoodsName(), "1"));
log.setFloatType("add");
log.setFloatPoints(+entity.getSpendPoints());
log.setCreateTime(new Date());
tbMemberPointsLogMapper.insert(log);
// 如果额外付款了则需要退款
if (NumberUtil.equals(entity.getExtraPaymentAmount(), BigDecimal.ZERO)) {
return;
}
if (StrUtil.isBlank(record.getOpenId())) {
throw new MsgException("openId/userId不能为空");
}
if (StrUtil.isBlank(record.getIp())) {
throw new MsgException("无法获取用户ip地址");
}
// 需要额外支付
TbShopInfo shopInfo = mpShopInfoMapper.selectById(entity.getShopId());
if (shopInfo == null) {
throw new MsgException("店铺信息不存在");
}
TbMerchantThirdApply thirdApply = tbMerchantThirdApplyMapper.selectByPrimaryKey(Integer.valueOf(shopInfo.getMerchantId()));
if (thirdApply == null) {
throw new MsgException("支付通道不存在");
}
if ("alipay".equalsIgnoreCase(entity.getPayType()) && StrUtil.isBlank(thirdApply.getAlipaySmallAppid())) {
throw new MsgException("店铺未配置支付宝小程序appId");
}
// 准备退款参数
// 应用ID
String appId = thirdApply.getAppId();
String appToken = thirdApply.getAppToken();
// 交易金额 单位分 100 表示1元
long amount = NumberUtil.mul(record.getExtraPaymentAmount(), new BigDecimal("100")).longValue();
// 退款订单号
String mchRefundNo = entity.getOrderNo();
PublicResp<OrderReturnResp> publicResp;
try {
publicResp = thirdPayService.returnOrder(thirdUrl, appId, mchRefundNo, entity.getPayOrderId(), null, entity.getCancelOrRefundReason(), amount, null, null, appToken);
} catch (Exception e) {
super.log.error("发起退款失败:", e);
throw new MsgException(StrUtil.format("发起退款失败:{}", e.getMessage()));
}
if (publicResp == null) {
throw new MsgException("拉起支付失败:无响应");
}
if (!"000000".equals(publicResp.getCode())) {
throw new MsgException(publicResp.getMsg());
}
OrderReturnResp returnResp = publicResp.getObjData();
if (!"SUCCESS".equals(returnResp.getState())) {
throw new MsgException(StrUtil.format("退款失败原因:{}",returnResp.getState()));
}
}
@Override

View File

@@ -1,8 +1,6 @@
package com.chaozhanggui.system.cashierservice.thirdpay.service;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.chaozhanggui.system.cashierservice.thirdpay.constants.SignTypeEnum;
import com.chaozhanggui.system.cashierservice.thirdpay.req.*;
import com.chaozhanggui.system.cashierservice.thirdpay.resp.*;
@@ -27,6 +25,8 @@ public class ThirdPayService {
private static String trade="/api/open/query/trade";
private static String refund="/api/open/order/refund";
/**
* 被扫接口
* @param url
@@ -209,7 +209,7 @@ public class ThirdPayService {
param.setSign(sign);
String reqbody = JSONUtil.toJSONString(param);
log.info("请求参数:{}", reqbody);
String response = HttpRequest.post(url.concat(trade)).body(reqbody).execute().body();
String response = HttpRequest.post(url.concat(refund)).body(reqbody).execute().body();
log.info("返回结果:{}", response);
PublicResp<OrderReturnResp> resp =JSONUtil.parseJSONStr2T(response,PublicResp.class);
resp.setObjData(JSONUtil.parseJSONStr2T(resp.getBizData(),OrderReturnResp.class));

View File

@@ -61,6 +61,7 @@ thirdPay:
callInBack: https://wxcashiertest.sxczgkj.cn/cashierService/notify/fstmemberInCallBack
callFSTBack: https://wxcashiertest.sxczgkj.cn/cashierService/notify/notifyfstCallBack
songOrderBack: https://wxcashiertest.sxczgkj.cn/cashierService/notify/songOrderCallBack
pointsGoodsOrderCallBack: https://wxcashiertest.sxczgkj.cn/cashierService/notify/pointsGoodsOrderCallBack
server:
port: 9888
prod: dev1

View File

@@ -54,6 +54,7 @@ thirdPay:
callInBack: https://pre-cashier.sxczgkj.cn/cashierService/notify/fstmemberInCallBack
callFSTBack: https://pre-cashier.sxczgkj.cn/cashierService/notify/notifyfstCallBack
songOrderBack: https://pre-cashier.sxczgkj.cn/cashierService/notify/songOrderCallBack
pointsGoodsOrderCallBack: https://pre-cashier.sxczgkj.cn/cashierService/notify/pointsGoodsOrderCallBack
server:
port: 9888
prod: dev1

View File

@@ -55,6 +55,7 @@ thirdPay:
callInBack: https://cashier.sxczgkj.cn${server.servlet.context-path}notify/fstmemberInCallBack
callFSTBack: https://cashier.sxczgkj.cn${server.servlet.context-path}notify/notifyfstCallBack
songOrderBack: https://cashier.sxczgkj.cn${server.servlet.context-path}notify/songOrderCallBack
pointsGoodsOrderCallBack: https://cashier.sxczgkj.cn${server.servlet.context-path}notify/pointsGoodsOrderCallBack
prod: prod1
queue: cart_queue_putprod1
subscribe:

View File

@@ -55,6 +55,7 @@ thirdPay:
callInBack: https://cashier.sxczgkj.cn${server.servlet.context-path}notify/fstmemberInCallBack
callFSTBack: https://cashier.sxczgkj.cn${server.servlet.context-path}notify/notifyfstCallBack
songOrderBack: https://cashier.sxczgkj.cn${server.servlet.context-path}notify/songOrderCallBack
pointsGoodsOrderCallBack: https://cashier.sxczgkj.cn${server.servlet.context-path}notify/pointsGoodsOrderCallBack
prod: prod2
queue: cart_queue_putprod2