Просмотр исходного кода

[POS][修改]:预核销/核销

release_toaliyun_real
Stormeye Wu 6 лет назад
Родитель
Сommit
6d2289d527
7 измененных файлов: 352 добавлений и 43 удалений
  1. +55
    -14
      mallinkPosApi/src/main/java/com/iformall/controller/PosController.java
  2. +3
    -1
      mallinkPosApi/src/main/java/com/iformall/service/PosService.java
  3. +267
    -23
      mallinkPosApi/src/main/java/com/iformall/service/impl/PosServiceImpl.java
  4. +5
    -1
      mallinkPosApi/src/test/java/com/iformall/pos/test/PosAppTest.java
  5. +4
    -2
      mallinkService/src/main/java/com/iformall/common/ErrorCode.java
  6. +16
    -0
      mallinkService/src/main/java/com/iformall/pay/WxPayConstant.java
  7. +2
    -2
      mallinkService/src/main/resources/mapper/WxCouponOrderMapper.xml

+ 55
- 14
mallinkPosApi/src/main/java/com/iformall/controller/PosController.java Просмотреть файл

@@ -69,7 +69,8 @@ public class PosController extends BaseController {
"\"merchant_id\":\"string(必填)\"," +
"\"mem_id\":\"string(选填)\"," +
"\"mem_phone\":\"string(选填)\"," +
"\"pos_order_id\":\"string(必填)\"" +
"\"pos_order_id\":\"string(必填)\"," +
"\"pos_amount\":\"string(单位:分)(必填)\"," +
"\"nonce_str\":\"string(必填)\"}")
@PostMapping("/checkMem")
public Map<String, String> checkMem(@RequestBody Map<String, String> params) {
@@ -99,14 +100,16 @@ public class PosController extends BaseController {
}
}

@ApiOperation(value = "券是否可以核销", notes = "{" +
@ApiOperation(value = "券核销检查", notes = "{" +
"\"dev_id\":\"string(必填)\"," +
"\"tenant_id\":\"string(必填)\"," +
"\"merchant_id\":\"string(必填)\"," +
"\"bu_user_id\":\"string(必填)\"," +
"\"coupon_order_id\":\"string(必填)\" +" +
"\"nonce_str\":\"string(必填)\" +" +
"\"pos_order_id\":\"string(选填)\" }")
"\"coupon_order_id\":\"string(必填)\"," +
"\"nonce_str\":\"string(必填)\"," +
"\"verify\":\"independent, pay(必填)\"," +
"\"pos_order_id\":\"string(选填)\"," +
"\"pos_amount\":\"单位(分)(选填)\"}")
@PostMapping("/checkCouponOrderForVerify")
public Map<String, String> checkCouponOrderVerify(@RequestBody Map<String, String> params) {
JSONObject payContent = new JSONObject();
@@ -121,7 +124,7 @@ public class PosController extends BaseController {
logger.info("resKey: " + resKey);

try {
retMap = posService.couponOrderVerifyDoSomething(params, EnumVerifyActionType.CHECK);
retMap = posService.couponOrderVerifyDo(params, EnumVerifyActionType.CHECK);
return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "",
WxPayConstant.RET_SUCCESS, null);
} catch (MallinkException e) {
@@ -140,9 +143,10 @@ public class PosController extends BaseController {
"\"tenant_id\":\"string(必填)\"," +
"\"merchant_id\":\"string(必填)\"," +
"\"bu_user_id\":\"string(必填)\"," +
"\"coupon_order_id\":\"string(必填)\" +" +
"\"nonce_str\":\"string(必填)\" +" +
"\"pos_order_id\":\"string(必填)\" }")
"\"coupon_order_id\":\"string(必填)\"," +
"\"nonce_str\":\"string(必填)\"," +
"\"pos_order_id\":\"string(必填)\"," +
"\"pos_amount\":\"string(必填)\"}")
@PostMapping("/couponOrderPreVerify")
public Map<String, String> couponOrderPreVerify(@RequestBody Map<String, String> params) {
JSONObject payContent = new JSONObject();
@@ -157,7 +161,7 @@ public class PosController extends BaseController {
logger.info("resKey: " + resKey);

try {
retMap = posService.couponOrderVerifyDoSomething(params, EnumVerifyActionType.PRE_VERIFY);
retMap = posService.couponOrderVerifyDo(params, EnumVerifyActionType.PRE_VERIFY);
return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "",
WxPayConstant.RET_SUCCESS, null);
} catch (MallinkException e) {
@@ -229,7 +233,7 @@ public class PosController extends BaseController {
logger.info("resKey: " + resKey);

try {
retMap = posService.couponOrderVerifyDoSomething(params, EnumVerifyActionType.VERIFY_INDEPENT);
retMap = posService.couponOrderVerifyDo(params, EnumVerifyActionType.VERIFY_INDEPENT);
return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "",
WxPayConstant.RET_SUCCESS, null);
} catch (MallinkException e) {
@@ -243,7 +247,7 @@ public class PosController extends BaseController {
}
}

@ApiOperation(value = "券交易核销", notes = "{" +
@ApiOperation(value = "券交易核销-单个优惠券接口", notes = "{" +
"\"dev_id\":\"string(必填)\"," +
"\"tenant_id\":\"string(必填)\"," +
"\"merchant_id\":\"string(必填)\"," +
@@ -251,7 +255,7 @@ public class PosController extends BaseController {
"\"coupon_order_id\":\"string(必填)\" +" +
"\"nonce_str\":\"string(必填)\" +" +
"\"pos_order_id\":\"string(必填)\" }")
@PostMapping("/couponOrderPayVerify")
@PostMapping("/couponOrderPayVerifyOne")
public Map<String, String> couponOrderPayVerify(@RequestBody Map<String, String> params) {
JSONObject payContent = new JSONObject();

@@ -265,7 +269,44 @@ public class PosController extends BaseController {
logger.info("resKey: " + resKey);

try {
retMap = posService.couponOrderVerifyDoSomething(params, EnumVerifyActionType.VERIFY_PAY);
retMap = posService.couponOrderVerifyDo(params, EnumVerifyActionType.VERIFY_PAY);
return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "",
WxPayConstant.RET_SUCCESS, null);
} catch (MallinkException e) {
return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "",
WxPayConstant.RET_FAIL,
e.getErrorCode(), e.getMessage());
} catch (Exception e) {
return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "",
WxPayConstant.RET_FAIL,
500, e.getMessage());
}
}

@ApiOperation(value = "券交易核销-优惠券列表接口", notes = "{" +
"\"dev_id\":\"string(必填)\"," +
"\"nonce_str\":\"string(必填)\"" +
"\"tenant_id\":\"string(必填)\"," +
"\"merchant_id\":\"string(必填)\"," +
"\"bu_user_id\":\"string(必填)\"," +
"\"sel_co_list\":\"json array(必填),例[\"1\",\"2\",\"3\"]\"" +
"\"pos_order_id\":\"string(必填)\"" +
"\"pay_amount\":\"单位(分)(必填)\" }")
@PostMapping("/couponOrderPayVerifyList")
public Map<String, String> couponOrderPayVerifyList(@RequestBody Map<String, String> params) {
JSONObject payContent = new JSONObject();

// 1. check sign
Map<String, String> retMap = checkSign(params, payContent);
if (retMap != null) {
// 签名相关异常返回
return retMap;
}
String resKey = payContent.getString("resKey");
logger.info("resKey: " + resKey);

try {
retMap = posService.couponOrderVerifyListDo(params, EnumVerifyActionType.VERIFY_PAY);
return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "",
WxPayConstant.RET_SUCCESS, null);
} catch (MallinkException e) {


+ 3
- 1
mallinkPosApi/src/main/java/com/iformall/service/PosService.java Просмотреть файл

@@ -22,7 +22,9 @@ public interface PosService {
*/
Map<String, String> checkMember(Map<String, String> params) throws MallinkException;

Map<String, String> couponOrderVerifyDoSomething(@RequestBody Map<String, String> params, EnumVerifyActionType actionType) throws MallinkException;
Map<String, String> couponOrderVerifyDo(@RequestBody Map<String, String> params, EnumVerifyActionType actionType) throws MallinkException;

Map<String, String> couponOrderVerifyListDo(@RequestBody Map<String, String> params, EnumVerifyActionType actionType) throws MallinkException;

Map<String, String> couponOrderVerifyCancel(Map<String, String> params, EnumVerifyActionType actionType) throws MallinkException;
}

+ 267
- 23
mallinkPosApi/src/main/java/com/iformall/service/impl/PosServiceImpl.java Просмотреть файл

@@ -1,5 +1,6 @@
package com.iformall.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iformall.common.ErrorCode;
import com.iformall.domain.po.*;
@@ -14,10 +15,12 @@ import com.iformall.mapper.WxOrderMapper;
import com.iformall.pay.WxPayConstant;
import com.iformall.service.*;
import lombok.AllArgsConstructor;
import net.sf.saxon.expr.Component;
import org.apache.commons.lang3.StringUtils;
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 org.springframework.web.bind.annotation.RequestBody;

@@ -25,6 +28,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
@@ -83,11 +87,12 @@ public class PosServiceImpl implements PosService {
Map<String, String> retMap = new HashMap<>();

String nonceStr = params.get(WxPayConstant.NONCE_STR); // 随机数
String tenantId = params.get(WxPayConstant.TENANT_ID); // 租户ID
String merchantIdStr = params.get(WxPayConstant.MERCHANT_ID); // 商户ID
String memIdStr = params.get(WxPayConstant.MEM_ID); // 会员ID
String memPhoneStr = params.get(WxPayConstant.MEM_PHONE); // 会员手机
String posOrderIdStr = params.get(WxPayConstant.POS_ORDER_ID); // POS订单ID
String tenantId = params.get(WxPayConstant.TENANT_ID); // 租户ID
String merchantIdStr = params.get(WxPayConstant.MERCHANT_ID); // 商户ID
String memIdStr = params.get(WxPayConstant.MEM_ID); // 会员ID
String memPhoneStr = params.get(WxPayConstant.MEM_PHONE); // 会员手机
String posOrderIdStr = params.get(WxPayConstant.POS_ORDER_ID); // POS订单ID
String posAmountStr = params.get(WxPayConstant.POS_AMOUNT); // POS订单金额(单位:分)

if (StringUtils.isBlank(tenantId)) {
String errMessage = "request params[tenant_id] error.";
@@ -104,6 +109,11 @@ public class PosServiceImpl implements PosService {
logger.error(errMessage);
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}
if (StringUtils.isBlank(posAmountStr)) {
String errMessage = "request params[pos_amount] error.";
logger.error(errMessage);
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}

if (StringUtils.isBlank(memIdStr) && StringUtils.isBlank(memPhoneStr)) {
String errMessage = "please give one value for mem_id or mem_phone";
@@ -135,9 +145,11 @@ public class PosServiceImpl implements PosService {
}

Long merchantId, posOrderId;
Integer posAmount = 0;
try {
merchantId = Long.valueOf(merchantIdStr);
posOrderId = Long.valueOf(posOrderIdStr);
posAmount = Integer.valueOf(posAmountStr);
} catch (NumberFormatException e) {
logger.error(e.getMessage());
throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR);
@@ -155,24 +167,32 @@ public class PosServiceImpl implements PosService {
level = levelConfig.getLevel();
}
}
Integer discount = 100;
WxLevelMerchant levelMerchant = new WxLevelMerchant();
levelMerchant.setTenantId(tenantId);
levelMerchant.setLevelId(levelId);
levelMerchant.setMerchantId(merchantId);
List<WxLevelMerchantCVo> levelMerchantList = levelConfigService.findListCVo(levelMerchant);
if(levelMerchantList.size() >= 1) {
if (levelMerchantList.size() >= 1) {
WxLevelMerchantCVo levelMerchantCVo = levelMerchantList.get(0);
if(levelMerchantCVo != null) {
retMap.put("discount", levelMerchantCVo.getDiscount().toString());
retMap.put("levelMerchant", levelMerchantCVo.toString());
if (levelMerchantCVo != null) {
discount = levelMerchantCVo.getDiscount();
retMap.put(WxPayConstant.MEM_DISCOUNT, discount.toString());
// retMap.put("levelMerchant", levelMerchantCVo.toString());
}
} else {
retMap.put("discount", "100");
retMap.put(WxPayConstant.MEM_DISCOUNT, "100");
}

retMap.put("id", user.getId().toString());
retMap.put("phone", user.getPhone());
retMap.put("level", level);
Double remainAmountD = posAmount * 1.0D * discount / 100;
long remainAmount = Math.round(remainAmountD);


retMap.put(WxPayConstant.MEM_ID, user.getId().toString());
retMap.put(WxPayConstant.MEM_PHONE, user.getPhone());
retMap.put(WxPayConstant.MEM_LEVEL, level);
retMap.put(WxPayConstant.ORG_AMOUNT, posAmountStr);
retMap.put(WxPayConstant.REMAIN_AMOUNT, String.valueOf(remainAmount));

// 优惠券列表
Map<String, Object> coQ = new HashMap<>();
@@ -181,12 +201,26 @@ public class PosServiceImpl implements PosService {
coQ.put("merchantId", merchantId);
coQ.put("posOrderId", posOrderId);
List<Map> couponOrderList = couponOrderService.findAvailCouponOrder(coQ);
retMap.put("avail_co_list", couponOrderList.toString());
if (couponOrderList.size() > 0) {
retMap.put(WxPayConstant.AVAIL_CO_LIST,
JSONArray.toJSONString(
couponOrderList
.stream()
.filter(co ->
(co.get("type") == EnumCouponType.COUPON_MULTIMCH.getCode() ||
co.get("type") == EnumCouponType.COUPON_MANJIAN.getCode() ||
co.get("type") == EnumCouponType.COUPON_DAIJIN.getCode()
))
.collect(Collectors.toList())
));
} else {
retMap.put(WxPayConstant.AVAIL_CO_LIST, "[]");
}
return retMap;
}

@Override
public Map<String, String> couponOrderVerifyDoSomething(@RequestBody Map<String, String> params, EnumVerifyActionType actionType) throws MallinkException {
public Map<String, String> couponOrderVerifyDo(@RequestBody Map<String, String> params, EnumVerifyActionType actionType) throws MallinkException {
Map<String, String> retMap = new HashMap<>();

String nonceStr = params.get(WxPayConstant.NONCE_STR); // 随机数
@@ -194,7 +228,8 @@ public class PosServiceImpl implements PosService {
String merchantIdStr = params.get(WxPayConstant.MERCHANT_ID); // 商户ID
String buUserIdStr = params.get(WxPayConstant.BUSER_ID); // POS操作员ID
String couponOrderIdStr = params.get(WxPayConstant.COUPON_ORDER_ID); // 券ID
String posOrderIdStr = params.get(WxPayConstant.COUPON_ORDER_ID); // POS订单ID
String posOrderIdStr = params.get(WxPayConstant.POS_ORDER_ID); // POS订单ID
String posAmountStr = params.get(WxPayConstant.POS_AMOUNT); // POS订单总额(单位:分)

if (StringUtils.isBlank(tenantId)) {
String errMessage = "request params[tenant_id] error.";
@@ -214,22 +249,129 @@ public class PosServiceImpl implements PosService {
String errMessage = "request params[coupon_order_id] error.";
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}
if (actionType.equals(EnumVerifyActionType.PRE_VERIFY) ||
actionType.equals(EnumVerifyActionType.VERIFY_INDEPENT) ||
actionType.equals(EnumVerifyActionType.VERIFY_PAY)) {
if (StringUtils.isBlank(posOrderIdStr)) {
String errMessage = "request params[pos_order_id] error.";
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}
}
if (actionType.equals(EnumVerifyActionType.PRE_VERIFY) ||
actionType.equals(EnumVerifyActionType.VERIFY_PAY)) {
if (StringUtils.isBlank(posAmountStr)) {
String errMessage = "request params[pos_amount] error.";
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}
}

Long merchantId, buUserId, posOrderId = 0L;
Integer posAmount = 0;
try {
merchantId = Long.valueOf(merchantIdStr);
buUserId = Long.valueOf(buUserIdStr);
if (actionType.equals(EnumVerifyActionType.PRE_VERIFY) ||
actionType.equals(EnumVerifyActionType.VERIFY_INDEPENT) ||
actionType.equals(EnumVerifyActionType.VERIFY_PAY)) {
posOrderId = Long.valueOf(posOrderIdStr);
}
if (actionType.equals(EnumVerifyActionType.PRE_VERIFY) ||
actionType.equals(EnumVerifyActionType.VERIFY_PAY)) {
posAmount = Integer.valueOf(posAmount);
}
} catch (NumberFormatException e) {
logger.error(e.getMessage());
throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), e.getMessage());
}
// 2. check merchant
WxMerchant merchant = merchantService.getById(merchantId);
if (merchant == null) {
logger.error(ErrorCode.MERCHANT_INFO_NOT_FOUND.getMessage() + ": " + merchantIdStr);
throw new MallinkException(ErrorCode.MERCHANT_INFO_NOT_FOUND);
}
if (merchant.getIsDel().equals(EnumDelStatus.DEL.getCode()) || merchant.getStatus().equals(EnumMerchantStatus.NOT_VALID.getCode())) {
logger.error(ErrorCode.MERCHANT_INFO_NOT_VALID.getMessage() + ": " + merchantIdStr);
throw new MallinkException(ErrorCode.MERCHANT_INFO_NOT_VALID);
}
// 3. check buUser
WxMerchantBUser buUser = merchantBUserService.getById(buUserId);
if (buUser == null) {
logger.error(ErrorCode.USER_IS_EMPTY.getMessage() + ": " + buUserIdStr);
throw new MallinkException(ErrorCode.USER_IS_EMPTY);
}
if (!buUser.getMerchantId().equals(merchantId)) {
logger.error(ErrorCode.VERIFY_BUSER_MERCHANT_NOT_BELONG.getMessage() + ": " + buUserIdStr);
throw new MallinkException(ErrorCode.VERIFY_BUSER_MERCHANT_NOT_BELONG);
}

JSONArray coRetArr = new JSONArray();
if (couponOrderIdStr != null) {
try {
Map<String,String> oneRetMap = doVerifyActionForOneCouponOrder(actionType,
tenantId, merchantIdStr, merchantId,
buUserIdStr, buUserId,
posOrderIdStr, posOrderId, posAmount,
couponOrderIdStr);
coRetArr.add(oneRetMap);
} catch (MallinkException e) {
throw new MallinkException(e.getErrorCode(), e.getMessage());
}
}
retMap.put("ret", coRetArr.toJSONString());
return retMap;
}

@Override
public Map<String, String> couponOrderVerifyListDo(@RequestBody Map<String, String> params, EnumVerifyActionType actionType) throws MallinkException {
Map<String, String> retMap = new HashMap<>();

String nonceStr = params.get(WxPayConstant.NONCE_STR); // 随机数
String tenantId = params.get(WxPayConstant.TENANT_ID); // 租户ID
String merchantIdStr = params.get(WxPayConstant.MERCHANT_ID); // 商户ID
String buUserIdStr = params.get(WxPayConstant.BUSER_ID); // POS操作员ID
String posOrderIdStr = params.get(WxPayConstant.POS_ORDER_ID); // POS订单ID
String posAmountStr = params.get(WxPayConstant.POS_AMOUNT); // POS订单总额(单位:分)
String selCoListStr = params.get(WxPayConstant.SELECTED_COUPON_ORDER_LIST); // 选中的优惠券列表

if (StringUtils.isBlank(tenantId)) {
String errMessage = "request params[tenant_id] error.";
logger.error(errMessage);
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}
if (StringUtils.isBlank(merchantIdStr)) {
String errMessage = "request params[merchant_id] error.";
logger.error(errMessage);
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}
if (StringUtils.isBlank(buUserIdStr)) {
String errMessage = "request params[bu_user_id] error.";
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}
if (StringUtils.isBlank(selCoListStr)) {
String errMessage = "request params[sel_co_list] error.";
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}
if (actionType.equals(EnumVerifyActionType.PRE_VERIFY) || actionType.equals(EnumVerifyActionType.VERIFY_INDEPENT)) {
if (StringUtils.isBlank(posOrderIdStr)) {
String errMessage = "request params[pos_order_id] error.";
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}
if (StringUtils.isBlank(posAmountStr)) {
String errMessage = "request params[pos_amount] error.";
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}
}

Long merchantId, buUserId, couponOrderId, posOrderId = 0L;
Long merchantId, buUserId, posOrderId = 0L;
Integer posAmount = 0;
try {
merchantId = Long.valueOf(merchantIdStr);
buUserId = Long.valueOf(buUserIdStr);
couponOrderId = Long.valueOf(couponOrderIdStr);
if (actionType.equals(EnumVerifyActionType.PRE_VERIFY) ||
actionType.equals(EnumVerifyActionType.VERIFY_INDEPENT) ||
actionType.equals(EnumVerifyActionType.VERIFY_PAY)) {
posOrderId = Long.valueOf(posOrderIdStr);
posAmount = Integer.valueOf(posAmountStr);
}
} catch (NumberFormatException e) {
logger.error(e.getMessage());
@@ -255,6 +397,40 @@ public class PosServiceImpl implements PosService {
logger.error(ErrorCode.VERIFY_BUSER_MERCHANT_NOT_BELONG.getMessage() + ": " + buUserIdStr);
throw new MallinkException(ErrorCode.VERIFY_BUSER_MERCHANT_NOT_BELONG);
}

JSONArray selCoArr = JSONObject.parseArray(selCoListStr);
if (selCoArr.size() <= 0) {
String errMessage = "request params[sel_co_list] error.";
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}

JSONArray coRetArr = new JSONArray();
for(int i=0;i<selCoArr.size();i++) {
String couponOrderIdStr = selCoArr.getString(i);
if (couponOrderIdStr != null) {
try {
Map<String,String> oneRetMap = doVerifyActionForOneCouponOrder(actionType,
tenantId, merchantIdStr, merchantId,
buUserIdStr, buUserId,
posOrderIdStr, posOrderId, posAmount,
couponOrderIdStr);
coRetArr.add(oneRetMap);
} catch (MallinkException e) {
throw new MallinkException(e.getErrorCode(), e.getMessage());
}
}
}
retMap.put("ret", coRetArr.toJSONString());
return retMap;
}

private Map<String, String> doVerifyActionForOneCouponOrder(
EnumVerifyActionType actionType,
String tenantId, String merchantIdStr, Long merchantId,
String buUserIdStr, Long buUserId,
String posOrderIdStr, Long posOrderId, Integer posAmount,
String couponOrderIdStr) {
Map<String, String> retMap = new HashMap<>();
// 4. check couponOrderId
WxCouponOrderCVo couponOrderCVo = couponOrderService.detailCUserVo(couponOrderIdStr);
if (couponOrderCVo == null) {
@@ -262,6 +438,8 @@ public class PosServiceImpl implements PosService {
throw new MallinkException(ErrorCode.COUPON_ORDER_IS_NULL);
}

Long couponOrderId = couponOrderCVo.getId();

// 5. get coupon
WxCoupon wxCoupon = couponMapper.selectByPrimaryKey(couponOrderCVo.getCouponId());
if (wxCoupon == null) {
@@ -281,6 +459,7 @@ public class PosServiceImpl implements PosService {
throw new MallinkException(ErrorCode.COUPON_ORDER_IS_EARLIER_THAN_VALIDDATE);
}
}

// 6. 检查适用门店
WxCouponMerchant wxCouponMerchant = new WxCouponMerchant();
wxCouponMerchant.setProductId(couponOrderCVo.getCouponId());
@@ -334,12 +513,27 @@ public class PosServiceImpl implements PosService {
throw new MallinkException(ErrorCode.VERIFY_PRE_POS_ORDER_NOT_EQUAL);
}
logger.info("券可以被核销: " + couponOrderIdStr);
retMap.put(WxPayConstant.ID, couponOrderIdStr);
retMap.put(WxPayConstant.CHECK, "true");
return retMap;
} else if (couponOrderCVo.getCouponOrderStatus().equals(EnumCouponOrderStatus.COUPON_ORDER_USE_WAIT.getCode())) {
logger.info("券可以被核销: " + couponOrderIdStr);
retMap.put(WxPayConstant.ID, couponOrderIdStr);
retMap.put(WxPayConstant.CHECK, "true");
return retMap;
}
} else if (actionType.equals(EnumVerifyActionType.PRE_VERIFY)) {
if (couponOrderCVo.getPrice() > posAmount) {
logger.error(ErrorCode.VERIFY_PRE_POS_ORDER_PRICE_ISSUE.getMessage());
throw new MallinkException(ErrorCode.VERIFY_PRE_POS_ORDER_PRICE_ISSUE);
}
if (!(couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_MULTIMCH) ||
couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_MANJIAN) ||
couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_DAIJIN)
)) {
logger.error(ErrorCode.VERIFY_COUPON_TYPE_NOT_SUPPORT.getMessage());
throw new MallinkException(ErrorCode.VERIFY_COUPON_TYPE_NOT_SUPPORT);
}
if (couponOrderCVo.getCouponOrderStatus().equals(EnumCouponOrderStatus.POS_PRE_VERIFY.getCode())) {
logger.info("券已被预核销: " + couponOrderIdStr);
if (!couponOrderCVo.getBUserId().equals(buUserId)) {
@@ -357,12 +551,22 @@ public class PosServiceImpl implements PosService {
logger.error(ErrorCode.VERIFY_PRE_POS_ORDER_NOT_EQUAL.getMessage() + ": " + posOrderIdStr);
throw new MallinkException(ErrorCode.VERIFY_PRE_POS_ORDER_NOT_EQUAL);
}
retMap.put(WxPayConstant.ID, couponOrderIdStr);
retMap.put(WxPayConstant.PRE_VERIFY, "true");
retMap.put(WxPayConstant.DEDUCT_AMOUNT, String.valueOf(couponOrderCVo.getPrice()));
retMap.put(WxPayConstant.REMAIN_AMOUNT, String.valueOf(posAmount - couponOrderCVo.getPrice()));
posAmount = posAmount - couponOrderCVo.getPrice();
return retMap;
}
if (couponOrderCVo.getCouponOrderStatus().equals(EnumCouponOrderStatus.COUPON_ORDER_USE_WAIT.getCode())) {
logger.info("券可以被预核销: " + couponOrderIdStr);
try {
doPreVerify(couponOrderCVo, buUserId, posOrderId);
retMap.put(WxPayConstant.ID, couponOrderIdStr);
retMap.put(WxPayConstant.PRE_VERIFY, "true");
retMap.put(WxPayConstant.DEDUCT_AMOUNT, String.valueOf(couponOrderCVo.getPrice()));
retMap.put(WxPayConstant.REMAIN_AMOUNT, String.valueOf(posAmount - couponOrderCVo.getPrice()));
posAmount = posAmount - couponOrderCVo.getPrice();
return retMap;
} catch (MallinkException e) {
logger.error(e.getMessage());
@@ -374,6 +578,29 @@ public class PosServiceImpl implements PosService {
}
} else {
// if (actionType.equals(EnumVerifyActionType.VERIFY_INDEPENT ) ||actionType.equals(EnumVerifyActionType.VERIFY_PAY))
if (actionType.equals(EnumVerifyActionType.VERIFY_INDEPENT)) {
if (!(couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_MULTIMCH.getCode()) ||
couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_LIPIN.getCode()) ||
couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_PRESS.getCode()) ||
couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_GROUP.getCode())
)) {
logger.error(ErrorCode.VERIFY_COUPON_TYPE_NOT_SUPPORT.getMessage());
throw new MallinkException(ErrorCode.VERIFY_COUPON_TYPE_NOT_SUPPORT);
}
}
if (actionType.equals(EnumVerifyActionType.VERIFY_PAY)) {
if (!(couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_MULTIMCH.getCode()) ||
couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_MANJIAN.getCode()) ||
couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_DAIJIN.getCode())
)) {
logger.error(ErrorCode.VERIFY_COUPON_TYPE_NOT_SUPPORT.getMessage());
throw new MallinkException(ErrorCode.VERIFY_COUPON_TYPE_NOT_SUPPORT);
}
if (couponOrderCVo.getPrice() > posAmount) {
logger.error(ErrorCode.VERIFY_PRE_POS_ORDER_PRICE_ISSUE.getMessage());
throw new MallinkException(ErrorCode.VERIFY_PRE_POS_ORDER_PRICE_ISSUE);
}
}
boolean blVerify = false;
if (couponOrderCVo.getCouponOrderStatus().equals(EnumCouponOrderStatus.POS_PRE_VERIFY.getCode())) {
logger.info("券已被预核销: " + couponOrderIdStr);
@@ -381,6 +608,12 @@ public class PosServiceImpl implements PosService {
logger.error(ErrorCode.VERIFY_PRE_BUSER_NOT_EQUAL.getMessage() + ": " + buUserIdStr);
throw new MallinkException(ErrorCode.VERIFY_PRE_BUSER_NOT_EQUAL);
}
if (actionType.equals(EnumVerifyActionType.VERIFY_PAY)) {
if (couponOrderCVo.getPrice() > posAmount) {
logger.error(ErrorCode.VERIFY_PRE_POS_ORDER_PRICE_ISSUE.getMessage());
throw new MallinkException(ErrorCode.VERIFY_PRE_POS_ORDER_PRICE_ISSUE);
}
}
// check pos order是否一致
PosCouponOrderVerify posCouponOrderVerifyQ = new PosCouponOrderVerify();
posCouponOrderVerifyQ.setTenantId(tenantId);
@@ -394,12 +627,23 @@ public class PosServiceImpl implements PosService {
}
blVerify = true;
} else if (couponOrderCVo.getCouponOrderStatus().equals(EnumCouponOrderStatus.COUPON_ORDER_USE_WAIT.getCode())) {
logger.info("券可以被预核销: " + couponOrderIdStr);
if (actionType.equals(EnumVerifyActionType.VERIFY_PAY)) {
if (couponOrderCVo.getPrice() > posAmount) {
logger.error(ErrorCode.VERIFY_PRE_POS_ORDER_PRICE_ISSUE.getMessage());
throw new MallinkException(ErrorCode.VERIFY_PRE_POS_ORDER_PRICE_ISSUE);
}
}
logger.info("券可以被核销: " + couponOrderIdStr);
blVerify = true;
}
if (blVerify) {
try {
doVerify(couponOrderCVo, wxCoupon, merchantId, buUserId, posOrderId, retMap);
retMap.put(WxPayConstant.ID, couponOrderIdStr);
retMap.put(WxPayConstant.VERIFY, "true");
retMap.put(WxPayConstant.DEDUCT_AMOUNT, String.valueOf(couponOrderCVo.getPrice()));
retMap.put(WxPayConstant.REMAIN_AMOUNT, String.valueOf(posAmount - couponOrderCVo.getPrice()));
posAmount = posAmount - couponOrderCVo.getPrice();
return retMap;
} catch (MallinkException e) {
logger.error(e.getMessage());
@@ -410,6 +654,7 @@ public class PosServiceImpl implements PosService {
}
}
}

String errMessage = "核销异常:未知的核销状态-" + couponOrderCVo.getCouponOrderStatus() + ", 核销action-" + actionType.getCode();
logger.error(errMessage);
throw new MallinkException(500, errMessage);
@@ -424,7 +669,7 @@ public class PosServiceImpl implements PosService {
String merchantIdStr = params.get(WxPayConstant.MERCHANT_ID); // 商户ID
String buUserIdStr = params.get(WxPayConstant.BUSER_ID); // POS操作员ID
String couponOrderIdStr = params.get(WxPayConstant.COUPON_ORDER_ID); // 券ID
String posOrderIdStr = params.get(WxPayConstant.COUPON_ORDER_ID); // POS订单ID
String posOrderIdStr = params.get(WxPayConstant.POS_ORDER_ID); // POS订单ID
String forceStr = params.get(WxPayConstant.FORCE); // 是否强制

if (StringUtils.isBlank(tenantId)) {
@@ -455,11 +700,10 @@ public class PosServiceImpl implements PosService {
}
}

Long merchantId, buUserId, couponOrderId, posOrderId = 0L;
Long merchantId, buUserId, posOrderId = 0L;
try {
merchantId = Long.valueOf(merchantIdStr);
buUserId = Long.valueOf(buUserIdStr);
couponOrderId = Long.valueOf(couponOrderIdStr);
posOrderId = Long.valueOf(posOrderIdStr);
} catch (NumberFormatException e) {
logger.error(e.getMessage());
@@ -567,7 +811,7 @@ public class PosServiceImpl implements PosService {
couponOrder.setCouponOrderStatus(EnumCouponOrderStatus.POS_PRE_VERIFY.getCode());
couponOrder.setBUserId(buUserId);
couponOrder.setUpdateDate(new Date());
num = couponOrderMapper.updateVerifyCouponOrderStatus(couponOrder);
num = couponOrderMapper.updateVerifyCouponOrder(couponOrder);
} catch (Exception e) {
logger.error("db failed: couponOrder-" + couponOrderCVo.getId() + ", e:" + e.getMessage());
throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage());


+ 5
- 1
mallinkPosApi/src/test/java/com/iformall/pos/test/PosAppTest.java Просмотреть файл

@@ -109,6 +109,7 @@ public class PosAppTest {
// reqObj.put(WxPayConstant.MEM_ID, "318314000718200832");
reqObj.put(WxPayConstant.MEM_PHONE, "13910154397");
reqObj.put(WxPayConstant.POS_ORDER_ID, "1");
reqObj.put(WxPayConstant.POS_AMOUNT, "100");
reqObj.put(WxPayConstant.SIGN, WxPayment.createSignHMAC(reqObj, devReqKey));
String reqJsonStr = JSONObject.toJSONString(reqObj);
RequestBuilder request = MockMvcRequestBuilders.post("/checkMem")
@@ -135,6 +136,7 @@ public class PosAppTest {
reqObj.put(WxPayConstant.COUPON_ORDER_ID, "318978990426783744");
reqObj.put(WxPayConstant.NONCE_STR, "1");
reqObj.put(WxPayConstant.POS_ORDER_ID, "1");
reqObj.put(WxPayConstant.POS_AMOUNT, "100");
reqObj.put(WxPayConstant.SIGN, WxPayment.createSignHMAC(reqObj, devReqKey));
String reqJsonStr = JSONObject.toJSONString(reqObj);
RequestBuilder request = MockMvcRequestBuilders.post("/checkCouponOrderForVerify")
@@ -213,6 +215,7 @@ public class PosAppTest {
reqObj.put(WxPayConstant.COUPON_ORDER_ID, "318978990426783744");
reqObj.put(WxPayConstant.NONCE_STR, "1");
reqObj.put(WxPayConstant.POS_ORDER_ID, "1");
reqObj.put(WxPayConstant.POS_AMOUNT, "100");
reqObj.put(WxPayConstant.SIGN, WxPayment.createSignHMAC(reqObj, devReqKey));
String reqJsonStr = JSONObject.toJSONString(reqObj);
RequestBuilder request = MockMvcRequestBuilders.post("/couponOrderPreVerify")
@@ -265,9 +268,10 @@ public class PosAppTest {
reqObj.put(WxPayConstant.COUPON_ORDER_ID, "318978990426783744");
reqObj.put(WxPayConstant.NONCE_STR, "1");
reqObj.put(WxPayConstant.POS_ORDER_ID, "1");
reqObj.put(WxPayConstant.POS_AMOUNT, "100");
reqObj.put(WxPayConstant.SIGN, WxPayment.createSignHMAC(reqObj, devReqKey));
String reqJsonStr = JSONObject.toJSONString(reqObj);
RequestBuilder request = MockMvcRequestBuilders.post("/couponOrderPayVerify")
RequestBuilder request = MockMvcRequestBuilders.post("/couponOrderPayVerifyOne")
.contentType(MediaType.APPLICATION_JSON)
.content(reqJsonStr);
MvcResult result = mockMvc.perform(request).andReturn();


+ 4
- 2
mallinkService/src/main/java/com/iformall/common/ErrorCode.java Просмотреть файл

@@ -280,8 +280,10 @@ public enum ErrorCode{
VERIFY_PRE_BUSER_NOT_EQUAL(12051, "预核销操作员不一致,请先取消上次预核销"),
VERIFY_PRE_POS_ORDER_IS_EMPTY(12052, "预核销POS订单ID为空"),
VERIFY_PRE_POS_ORDER_NOT_EQUAL(12053, "预核销POS订单不一致,请先取消上次预核销"),
VERIFY_BUSER_MERCHANT_NOT_BELONG(12054, "核销员不属于此商户"),
VERIFY_POS_ORDER_NOT_EQUAL(12055, "核销POS订单不一致,请先取消上次预核销"),
VERIFY_PRE_POS_ORDER_PRICE_ISSUE(12054, "预核销券金额失败,请确定券金额是否合适"),
VERIFY_BUSER_MERCHANT_NOT_BELONG(12055, "核销员不属于此商户"),
VERIFY_POS_ORDER_NOT_EQUAL(12056, "核销POS订单不一致,请先取消上次预核销"),
VERIFY_COUPON_TYPE_NOT_SUPPORT(12057, "核销不支持此券类型"),
MSG_REPEAT_SEND(12061, "短信重复发送"),
VERIFY_COUPON_ORDER_MERCHANT_IS_NULL(12062, "卡券核销失败,请查看适用门店"),



+ 16
- 0
mallinkService/src/main/java/com/iformall/pay/WxPayConstant.java Просмотреть файл

@@ -22,8 +22,24 @@ public class WxPayConstant {
public final static String MERCHANT_ID = "merchant_id";
public final static String BUSER_ID = "bu_user_id";
public final static String COUPON_ORDER_ID = "coupon_order_id";
public final static String SELECTED_COUPON_ORDER_LIST = "sel_co_list";
public final static String POS_ORDER_ID = "pos_order_id";
public final static String POS_AMOUNT = "pos_amount";
public final static String MEM_ID = "mem_id";
public final static String MEM_PHONE = "mem_phone";
public final static String VERIFY_TYPE = "verify_type";


public final static String MEM_DISCOUNT = "discount";
public final static String MEM_LEVEL = "level";
public final static String AVAIL_CO_LIST = "avail_co_list";
public final static String ID = "id";
public final static String CHECK = "check";
public final static String PRE_VERIFY = "pre_verify";
public final static String VERIFY = "verify";
public final static String DEDUCT_AMOUNT = "deduct_amount";
public final static String REMAIN_AMOUNT = "remain_amount";

public final static String ORG_AMOUNT = "org_amount";

}

+ 2
- 2
mallinkService/src/main/resources/mapper/WxCouponOrderMapper.xml Просмотреть файл

@@ -1044,7 +1044,7 @@
</select>

<select id="findAvailCouponOrder" parameterType="java.util.Map" resultType="hashmap">
select co.id,c.title, co.create_date, co.expired_time, c.price
select co.id, c.title, c.type, co.create_date, co.expired_time, c.price
from wx_coupon_order co
left join wx_coupon_merchant cm on cm.product_id = co.coupon_id
left join wx_coupon c on c.id = co.coupon_id
@@ -1053,7 +1053,7 @@
and cm.merchant_id = #{merchantId}
and co.expired_time > now()
union
select co.id,c.title, co.create_date, co.expired_time, c.price
select co.id,c.title, c.type, co.create_date, co.expired_time, c.price
from wx_coupon_order co
left join wx_coupon_merchant cm on cm.product_id = co.coupon_id
left join wx_coupon c on c.id = co.coupon_id


Загрузка…
Отмена
Сохранить