diff --git a/mallinkAdmin/src/main/resources/db/migration/V201908221610__POS_CHANGED.sql b/mallinkAdmin/src/main/resources/db/migration/V201908221610__POS_CHANGED.sql new file mode 100644 index 000000000..ec829c8eb --- /dev/null +++ b/mallinkAdmin/src/main/resources/db/migration/V201908221610__POS_CHANGED.sql @@ -0,0 +1,2 @@ +alter table wx_pos_order +add `remain_amount` int(11) default NULL COMMENT '支付金额:允许有负数,退款时为负值。核销时,金额可以不填写' after `payment`; \ No newline at end of file diff --git a/mallinkBApi/src/main/java/com/iformall/controller/PosController.java b/mallinkBApi/src/main/java/com/iformall/controller/PosController.java index 5b722b755..57a89fcbb 100644 --- a/mallinkBApi/src/main/java/com/iformall/controller/PosController.java +++ b/mallinkBApi/src/main/java/com/iformall/controller/PosController.java @@ -59,7 +59,7 @@ public class PosController extends BaseController { return posService.getQrCode(getTenantId()); } - @ApiOperation(value = "券独立核销检查", notes = "{\"couponOrderId\":\"string\"}") + @ApiOperation(value = "券独立核销-1-检查", notes = "{\"couponOrderId\":\"string\"}") @PostMapping("checkCouponOrderForIndepentVerify") public ResultData checkCouponOrderForIndepentVerify(@RequestBody Map params) { WxMerchantBUser user = getUser(); @@ -74,7 +74,7 @@ public class PosController extends BaseController { return posService.checkCouponOrderForIndepentVerify(user, verifyType, couponOrderIdStr); } - @ApiOperation(value = "券独立核销", notes = "{\"couponOrderId\":\"string\", \"payment\":\"string(单位:分)\"}") + @ApiOperation(value = "券独立核销-2-核销", notes = "{\"couponOrderId\":\"string\", \"payment\":\"string(单位:分)\"}") @PostMapping("posVerifyIndepent") public ResultData posVerifyIndepent(@RequestBody Map params) { WxMerchantBUser user = getUser(); @@ -88,7 +88,7 @@ public class PosController extends BaseController { return posService.posVerifyIndepent(user, couponOrderId, payment); } - @ApiOperation(value = "会员识别", notes = "{\"mem_id\":\"string(可选)\",\"mem_phone\":\"string(可选)\",\"pos_order_id\":\"string(必填)\",\"pos_amount\":\"string(单位:分)(必填)\"}") + @ApiOperation(value = "会员支付-1-会员识别", notes = "{\"mem_id\":\"string(可选)\",\"mem_phone\":\"string(可选)\",\"pos_order_id\":\"string(必填)\",\"pos_amount\":\"string(单位:分)(必填)\"}") @PostMapping("checkMem") public ResultData checkMem(@RequestBody Map params) { WxMerchantBUser user = getUser(); @@ -116,7 +116,7 @@ public class PosController extends BaseController { return posService.checkMem(user, memIdStr, memPhoneStr, posOrderIdStr, posAmountStr); } - @ApiOperation(value = "券交易核销检查", notes = "{\"coupon_order_id\":\"string(必填)\",\"pos_order_id\":\"string(必填)\",\"pos_amount\":\"string(必填)\"}") + @ApiOperation(value = "会员支付-2-交易核销检查", notes = "{\"coupon_order_id\":\"string(必填)\",\"pos_order_id\":\"string(必填)\",\"pos_amount\":\"string(必填)\"}") @PostMapping("checkCouponOrderForPayVerify") public ResultData checkCouponOrderForPayVerify(@RequestBody Map params) { WxMerchantBUser user = getUser(); @@ -143,11 +143,12 @@ public class PosController extends BaseController { return posService.checkCouponOrderForPayVerify(user, verifyType, couponOrderIdStr, posOrderIdStr, posAmountStr); } - @ApiOperation(value = "券预核销", notes = "{\"coupon_order_id\":\"string(必填)\",\"pos_order_id\":\"string(必填)\",\"pos_amount\":\"string(必填)\"}") + @ApiOperation(value = "会员支付-3-券预核销", notes = "{\"coupon_order_id\":\"string(必填)\",\"deduct_amount\":\"string(必填)\",\"pos_order_id\":\"string(必填)\",\"pos_amount\":\"string(必填)\"}") @PostMapping("couponOrderPreVerify") public ResultData couponOrderPreVerify(@RequestBody Map params) { WxMerchantBUser user = getUser(); String couponOrderIdStr = params.get(WxPayConstant.COUPON_ORDER_ID); // 券包ID + String deductAmountStr = params.get(WxPayConstant.DEDUCT_AMOUNT); // 扣减金额 String posOrderIdStr = params.get(WxPayConstant.POS_ORDER_ID); // POS订单ID String posAmountStr = params.get(WxPayConstant.POS_AMOUNT); // POS订单金额(单位:分) @@ -156,6 +157,11 @@ public class PosController extends BaseController { logger.error(errMessage); throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage); } + if (StringUtils.isBlank(deductAmountStr)) { + String errMessage = "request params[deduct_amount] error."; + logger.error(errMessage); + throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage); + } if (StringUtils.isBlank(posOrderIdStr)) { String errMessage = "request params[pos_order_id] error."; logger.error(errMessage); @@ -166,10 +172,28 @@ public class PosController extends BaseController { logger.error(errMessage); throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage); } - return posService.couponOrderPreVerify(user, couponOrderIdStr, posOrderIdStr, posAmountStr); + return posService.couponOrderPreVerify(user, couponOrderIdStr, deductAmountStr, posOrderIdStr, posAmountStr); + } + + + @ApiOperation(value = "会员支付-4-支付完成", notes = "{\"pos_order_id\":\"string\"}") + @PostMapping("posOrderFinished") + public ResultData posOrderFinished(@RequestBody Map params) { + WxMerchantBUser user = getUser(); + String posOrderIdStr = params.get(WxPayConstant.POS_ORDER_ID); // POS订单ID + if (StringUtils.isBlank(posOrderIdStr)) { + String errMessage = "request params[pos_order_id] error."; + logger.error(errMessage); + throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage); + } + // 1. 获取订单信息 + // 2. 获取所有的支付订单信息 + // 3. 同步给FMPOS + + return new ResultData(); } - @ApiOperation(value = "券预核销取消", notes = "{\"coupon_order_id\":\"string(必填)\",\"pos_order_id\":\"string(必填)\",\"pos_amount\":\"string(必填)\"}") + @ApiOperation(value = "会员支付-10-券预核销取消", notes = "{\"coupon_order_id\":\"string(必填)\",\"pos_order_id\":\"string(必填)\",\"pos_amount\":\"string(必填)\"}") @PostMapping("couponOrderPreVerifyCancel") public ResultData couponOrderPreVerifyCancel(@RequestBody Map params) { WxMerchantBUser user = getUser(); @@ -195,14 +219,4 @@ public class PosController extends BaseController { return posService.couponOrderPreVerifyCancel(user, couponOrderIdStr, posOrderIdStr, posAmountStr); } - @ApiOperation(value = "核销接口", notes = "{\"couponOrderId\":\"string\"}") - @PostMapping("verifyForPos") - public ResultData verifyForPos(@RequestBody Map paramMap) { - // 0. 获取dev信息, tenantId信息 - // 1. check 查询 - // 2. create order - // 3. 独立核销 - - return new ResultData(); - } } diff --git a/mallinkBApi/src/main/java/com/iformall/service/PosBrunService.java b/mallinkBApi/src/main/java/com/iformall/service/PosBrunService.java index db6f75a95..c39122786 100644 --- a/mallinkBApi/src/main/java/com/iformall/service/PosBrunService.java +++ b/mallinkBApi/src/main/java/com/iformall/service/PosBrunService.java @@ -1,6 +1,7 @@ package com.iformall.service; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.iformall.common.ErrorCode; import com.iformall.common.Result; @@ -8,9 +9,7 @@ import com.iformall.common.ResultData; import com.iformall.domain.po.PosOrder; import com.iformall.domain.po.PosPayOrder; import com.iformall.domain.po.WxMerchantBUser; -import com.iformall.enums.EnumPosOrderStatus; -import com.iformall.enums.EnumPosOrderType; -import com.iformall.enums.EnumPosPayType; +import com.iformall.enums.*; import com.iformall.exception.MallinkException; import com.iformall.pay.WxPayConstant; import com.iformall.pay.WxPayment; @@ -23,6 +22,7 @@ import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.RequestBody; import java.util.Date; +import java.util.List; import java.util.Map; @Service @@ -273,8 +273,44 @@ public class PosBrunService { * @return */ public ResultData couponOrderPreVerify(WxMerchantBUser user, - String couponOrderIdStr, + String couponOrderIdStr, String deductAmountStr, String posOrderIdStr, String posAmountStr) { + Integer deductAmount, posAmount; + Long posOrderId; + try { + deductAmount = Integer.valueOf(deductAmountStr); + posAmount = Integer.valueOf(posAmountStr); + posOrderId = Long.valueOf(posOrderIdStr); + } catch (NumberFormatException e) { + logger.error(ErrorCode.SYS_PARAMETER_CAST_ERROR.getMessage()); + return new ResultData(ErrorCode.SYS_PARAMETER_CAST_ERROR); + } + // 1. 创建支付订单 + Date curDate = new Date(); + PosPayOrder posPayOrder = new PosPayOrder(); + posPayOrder.setTenantId(user.getTenantId()); + posPayOrder.setCreateTime(curDate); + posPayOrder.setUpdateTime(curDate); + posPayOrder.setOrderId(posOrderId); + posPayOrder.setBuUserId(user.getId()); + posPayOrder.setType(2); + posPayOrder.setPayFrom(10); + posPayOrder.setPayAmount(deductAmount); + posPayOrder.setPayTimeStart(curDate); + posPayOrder.setPayTimeEnd(curDate); + posPayOrder.setPayOrderStatus(EnumPayStatus.PAY_STATUS_WAIT.getCode()); + posPayOrder.setShare(0); + try { + posPayOrderService.saveOrUpdate(posPayOrder); + } catch (MallinkException e) { + logger.error(e.getMessage()); + return new ResultData(e.getErrorCode(), e.getMessage()); + } catch (Exception e) { + logger.error(e.getMessage()); + return new ResultData(Result.ERROR, e.getMessage()); + } + + // 2. POS预核销 try { String resStr = posUtil.couponOrderPreVerify(posUrl, posDevId, posReqKey, user.getTenantId(), String.valueOf(user.getMerchantId()), String.valueOf(user.getId()), @@ -285,7 +321,65 @@ public class PosBrunService { if (!WxPayment.verifyNotifyHMAC(options, posResKey)) { return new ResultData(ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR); } else { - return new ResultData(resStr); + if (retObj.getString(WxPayConstant.RETURN_CODE).equalsIgnoreCase(WxPayConstant.RET_SUCCESS) && + retObj.getString(WxPayConstant.RESULT_CODE).equalsIgnoreCase(WxPayConstant.RET_SUCCESS)) { + Integer remainAmount = posAmount; + // 获取 返回值 + JSONArray retArr = retObj.getJSONArray(WxPayConstant.RET); + for (int i = 0; i > retArr.size(); i++) { + JSONObject couponObj = retArr.getJSONObject(i); + if (couponObj == null) { + continue; + } + String deductAmountOfCouponStr = couponObj.getString(WxPayConstant.DEDUCT_AMOUNT); + Integer deductAmountofCoupon = Integer.valueOf(deductAmountOfCouponStr); + // 新 支付订单状态 + PosPayOrder updatePayOrder = new PosPayOrder(); + updatePayOrder.setId(Long.valueOf(couponObj.getLong(WxPayConstant.ID))); + updatePayOrder.setPayAmount(deductAmountofCoupon); + updatePayOrder.setPayOrderStatus(EnumPayStatus.PAY_STATUS_SUCCESS.getCode()); + updatePayOrder.setPayTimeEnd(new Date()); + try { + posPayOrderService.saveOrUpdate(updatePayOrder); + } catch (MallinkException e) { + logger.error(e.getMessage()); + return new ResultData(e.getErrorCode(), e.getMessage()); + } catch (Exception e) { + logger.error(e.getMessage()); + return new ResultData(Result.ERROR, e.getMessage()); + } + String remainAmountStr = couponObj.getString(WxPayConstant.REMAIN_AMOUNT); + Integer remainAmountofCoupon = Integer.valueOf(remainAmountStr); + remainAmount = remainAmountofCoupon; + } + // 更新 订单状态 + PosOrder updateOrder = new PosOrder(); + updateOrder.setId(posOrderId); + updateOrder.setRemainAmount(remainAmount); + updateOrder.setUpdateDate(new Date()); + if (remainAmount.equals(0)) { + updateOrder.setOrderStatus(EnumPosOrderStatus.PAYMENT_SUCCESS.getCode()); + retObj.put(WxPayConstant.ORDER_STATUS, EnumPosOrderStatus.PAYMENT_SUCCESS.getCode()); + retObj.put(WxPayConstant.DEDUCT_AMOUNT, 0); + } else { + updateOrder.setOrderStatus(EnumPosOrderStatus.PENDING.getCode()); + retObj.put(WxPayConstant.ORDER_STATUS, EnumPosOrderStatus.PENDING.getCode()); + retObj.put(WxPayConstant.DEDUCT_AMOUNT, remainAmount); + } + try { + posOrderService.saveOrUpdate(updateOrder); + } catch (MallinkException e) { + logger.error(e.getMessage()); + return new ResultData(e.getErrorCode(), e.getMessage()); + } catch (Exception e) { + logger.error(e.getMessage()); + return new ResultData(Result.ERROR, e.getMessage()); + } + return new ResultData(JSON.toJSONString(retObj)); + } else { + logger.error(resStr); + return new ResultData(Result.ERROR, retObj.getString(WxPayConstant.ERR_CODE_DESC)); + } } } else { return new ResultData(Result.ERROR, "无返回值"); @@ -446,6 +540,17 @@ public class PosBrunService { logger.error(e.getMessage()); return new ResultData(Result.ERROR, e.getMessage()); } + // 5. 同步给fm pos进程 + // 5.1 posOrder信息 + PosOrder syncOrder = posOrderService.getById(posOrder.getId()); + if (syncOrder != null) { + // 5.2 posPayOrder信息 + PosPayOrder q = new PosPayOrder(); + q.setOrderId(posOrder.getId()); + List posPayOrders = posPayOrderService.getList(q); + + } + return new ResultData(); } } diff --git a/mallinkService/src/main/java/com/iformall/domain/po/PosOrder.java b/mallinkService/src/main/java/com/iformall/domain/po/PosOrder.java index d1fe3ec3f..ffb669e1d 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/PosOrder.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/PosOrder.java @@ -33,6 +33,8 @@ public class PosOrder implements Serializable { private Integer paymentType; @io.swagger.annotations.ApiModelProperty(value="支付金额:允许有负数,退款时为负值。核销时,金额可以不填写",name="paymentType") private Integer payment; + @io.swagger.annotations.ApiModelProperty(value="支付剩余金额",name="remainAmount") + private Integer remainAmount; @io.swagger.annotations.ApiModelProperty(value="创建时间",name="createDate") private Date createDate; @io.swagger.annotations.ApiModelProperty(value="更新时间",name="updateDate") diff --git a/mallinkService/src/main/java/com/iformall/enums/EnumPosOrderStatus.java b/mallinkService/src/main/java/com/iformall/enums/EnumPosOrderStatus.java index 3d5db965c..7c9608948 100644 --- a/mallinkService/src/main/java/com/iformall/enums/EnumPosOrderStatus.java +++ b/mallinkService/src/main/java/com/iformall/enums/EnumPosOrderStatus.java @@ -8,15 +8,19 @@ package com.iformall.enums; public enum EnumPosOrderStatus { PENDING_PAYMENT(0, "待付款"), - PAYMENT_SUCCESS(1, "已支付"), - OVERTIME_CANCEL(2, "已取消"), - PENDING_REFUND(3, "待退款"), - REFUND_SUCCESS(4,"已退款"), - REFUND_FAILD(5, "退款失败"), + PENDING(1, "支付中"), + PAYMENT_SUCCESS(2, "已支付"), + OVERTIME_CANCEL(3, "已取消"), + PENDING_REFUND(4, "待退款"), + REFUNDING(5, "退款中"), + REFUND_SUCCESS(6,"已退款"), + REFUND_FAILD(7, "退款失败"), PENDING_VERIFY(10, "待核销"), - VERIFY_SUCCESS(11, "已核销"), - VERIFY_CANCEL(12, "核销待退"), - VERIFY_CANCELED(13, "核销已退") + VERIFING(11, "核销中"), + VERIFY_SUCCESS(12, "已核销"), + VERIFY_CANCEL(13, "核销待退"), + VERIFY_CANCELING(14, "核销退中"), + VERIFY_CANCELED(15, "核销已退") ; diff --git a/mallinkService/src/main/java/com/iformall/pay/WxPayConstant.java b/mallinkService/src/main/java/com/iformall/pay/WxPayConstant.java index 8d2cf8628..fa755b23a 100644 --- a/mallinkService/src/main/java/com/iformall/pay/WxPayConstant.java +++ b/mallinkService/src/main/java/com/iformall/pay/WxPayConstant.java @@ -64,6 +64,7 @@ public class WxPayConstant { public final static String DEDUCT_AMOUNT = "deduct_amount"; public final static String REMAIN_AMOUNT = "remain_amount"; + public final static String ORDER_STATUS = "order_status"; public final static String REAL_AMOUNT = "real_amount"; public final static String SALE_PRICE = "sale_price"; diff --git a/mallinkService/src/main/java/com/iformall/service/PosPayOrderService.java b/mallinkService/src/main/java/com/iformall/service/PosPayOrderService.java index 823e36ab3..dd64c4aa9 100644 --- a/mallinkService/src/main/java/com/iformall/service/PosPayOrderService.java +++ b/mallinkService/src/main/java/com/iformall/service/PosPayOrderService.java @@ -1,9 +1,10 @@ package com.iformall.service; -import java.util.*; import com.github.pagehelper.PageInfo; import com.iformall.domain.po.PosPayOrder; +import java.util.List; + public interface PosPayOrderService { /** @@ -15,6 +16,14 @@ public interface PosPayOrderService { * @return */ PageInfo listAsPage(PosPayOrder record, Integer pageIndex, Integer pageSize); + + /** + * 根据实体查询列表 + * + * @param record + * @return + */ + List getList(PosPayOrder record); /** * 根据Id获得实体 diff --git a/mallinkService/src/main/java/com/iformall/service/impl/PosOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/PosOrderServiceImpl.java index a26f7ccb6..8f831f748 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/PosOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/PosOrderServiceImpl.java @@ -32,6 +32,9 @@ public class PosOrderServiceImpl implements PosOrderService { final IdWorker idWorker = IdWorker.get(); record.setId(idWorker.nextId()); record.setPosOrderNo(String.valueOf(record.getId())); + if (record.getPayment() != null) { + record.setRemainAmount(record.getPayment()); + } posOrderMapper.insertSelective(record); } else { posOrderMapper.updateByPrimaryKeySelective(record); diff --git a/mallinkService/src/main/java/com/iformall/service/impl/PosPayOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/PosPayOrderServiceImpl.java index 457077ccb..f29dfd866 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/PosPayOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/PosPayOrderServiceImpl.java @@ -22,6 +22,11 @@ public class PosPayOrderServiceImpl implements PosPayOrderService { return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> posPayOrderMapper.findList(record)); } + @Override + public List getList(PosPayOrder record) { + return posPayOrderMapper.findList(record); + } + @Override public PosPayOrder getById(Long id) { return posPayOrderMapper.selectByPrimaryKey(id); @@ -33,6 +38,7 @@ public class PosPayOrderServiceImpl implements PosPayOrderService { //record.setId(UUID.randomUUID().toString().replaceAll("-", "")); final IdWorker idWorker = IdWorker.get(); record.setId(idWorker.nextId()); + record.setPayOrderNo(String.valueOf(record.getId())); posPayOrderMapper.insertSelective(record); } else { posPayOrderMapper.updateByPrimaryKeySelective(record);