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

[POS][修改]:POS交易核销检查

release_toaliyun_real
Stormeye Wu 6 лет назад
Родитель
Сommit
3c42879554
9 измененных файлов: 177 добавлений и 31 удалений
  1. +2
    -0
      mallinkAdmin/src/main/resources/db/migration/V201908221610__POS_CHANGED.sql
  2. +31
    -17
      mallinkBApi/src/main/java/com/iformall/controller/PosController.java
  3. +110
    -5
      mallinkBApi/src/main/java/com/iformall/service/PosBrunService.java
  4. +2
    -0
      mallinkService/src/main/java/com/iformall/domain/po/PosOrder.java
  5. +12
    -8
      mallinkService/src/main/java/com/iformall/enums/EnumPosOrderStatus.java
  6. +1
    -0
      mallinkService/src/main/java/com/iformall/pay/WxPayConstant.java
  7. +10
    -1
      mallinkService/src/main/java/com/iformall/service/PosPayOrderService.java
  8. +3
    -0
      mallinkService/src/main/java/com/iformall/service/impl/PosOrderServiceImpl.java
  9. +6
    -0
      mallinkService/src/main/java/com/iformall/service/impl/PosPayOrderServiceImpl.java

+ 2
- 0
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`;

+ 31
- 17
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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> paramMap) {
// 0. 获取dev信息, tenantId信息
// 1. check 查询
// 2. create order
// 3. 独立核销

return new ResultData();
}
}

+ 110
- 5
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<PosPayOrder> posPayOrders = posPayOrderService.getList(q);

}

return new ResultData();
}
}

+ 2
- 0
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")


+ 12
- 8
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, "核销已退")
;




+ 1
- 0
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";


+ 10
- 1
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<PosPayOrder> listAsPage(PosPayOrder record, Integer pageIndex, Integer pageSize);

/**
* 根据实体查询列表
*
* @param record
* @return
*/
List<PosPayOrder> getList(PosPayOrder record);
/**
* 根据Id获得实体


+ 3
- 0
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);


+ 6
- 0
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<PosPayOrder> 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);


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