|
|
package com.yohoufo.order.service.impl;
|
|
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.yoho.core.common.utils.DateUtil;
|
|
|
import com.yoho.error.ServiceError;
|
|
|
import com.yoho.error.exception.ServiceException;
|
|
|
import com.yohoufo.common.utils.HttpClient;
|
|
|
import com.yohoufo.common.utils.SignUtils;
|
|
|
import com.yohoufo.dal.order.BuyerOrderMapper;
|
|
|
import com.yohoufo.dal.order.SellerOrderMapper;
|
|
|
import com.yohoufo.dal.order.model.BuyerOrder;
|
|
|
import com.yohoufo.dal.order.model.SellerOrder;
|
|
|
import com.yohoufo.order.common.OrderCodeType;
|
|
|
import com.yohoufo.order.common.OrderStatus;
|
|
|
import com.yohoufo.order.common.Payment;
|
|
|
import com.yohoufo.order.constants.OrderConstant;
|
|
|
import com.yohoufo.order.request.PaymentRequest;
|
|
|
import com.yohoufo.order.response.PrepayResponse;
|
|
|
import com.yohoufo.order.service.IPaymentService;
|
|
|
import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator;
|
|
|
import com.yohoufo.order.service.support.codegenerator.bean.CodeMeta;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.util.Date;
|
|
|
|
|
|
|
|
|
@Service
|
|
|
public class PaymentServiceImpl implements IPaymentService {
|
|
|
|
|
|
private final Logger logger = LoggerFactory.getLogger(getClass());
|
|
|
|
|
|
@Autowired
|
|
|
BuyerOrderMapper buyerOrderMapper;
|
|
|
|
|
|
@Autowired
|
|
|
SellerOrderMapper sellerOrderMapper;
|
|
|
|
|
|
@Value("${unionpay.pay.url}")
|
|
|
private String unionPayUrl;
|
|
|
|
|
|
@Value("${unionpay.pay.callbackUrl}")
|
|
|
private String callbackUrl;
|
|
|
|
|
|
@Value("${unionpay.pay.msgSrc}")
|
|
|
private String msgSrc;
|
|
|
|
|
|
@Value("${unionpay.pay.mid}")
|
|
|
private String mid;
|
|
|
|
|
|
@Value("${unionpay.pay.tid}")
|
|
|
private String tid;
|
|
|
|
|
|
@Value("${unionPay.pay.signKey}")
|
|
|
private String signKey;
|
|
|
|
|
|
@Autowired
|
|
|
HttpClient httpClient;
|
|
|
|
|
|
/**
|
|
|
* 机构商户号
|
|
|
*/
|
|
|
public static final String INST_MID = "APPDEFAULT";
|
|
|
|
|
|
@Autowired
|
|
|
OrderCodeGenerator orderCodeGenerator;
|
|
|
|
|
|
/**
|
|
|
* 支付
|
|
|
* @param request
|
|
|
* @return
|
|
|
*/
|
|
|
public PrepayResponse payment(PaymentRequest request){
|
|
|
|
|
|
|
|
|
// 入口数据检查
|
|
|
if (request.getUid() < 0
|
|
|
|| request.getOrderCode() < 0){
|
|
|
logger.warn("payment not exist");
|
|
|
throw new ServiceException(ServiceError.ORDER_REQUEST_PARM_IS_EMPTY);
|
|
|
}
|
|
|
|
|
|
// 不存在的支付方式
|
|
|
Payment payment = Payment.getPayment(request.getPayment());
|
|
|
if (payment == null){
|
|
|
logger.warn("payment payment not exist {}, uid is {}, orderCode is {}" ,request.getPayment(),
|
|
|
request.getUid(), request.getOrderCode());
|
|
|
throw new ServiceException(ServiceError.ORDER_PAYMENT_IS_EMPTY);
|
|
|
}
|
|
|
|
|
|
// 卖家or买家订单,支付方式更新,返回实付金额
|
|
|
BigDecimal amount = checkUpdOrderCode(request);
|
|
|
|
|
|
// 生成预支付数据
|
|
|
JSONObject prepayData = buildPrepayData(request, payment.getValue(), amount);
|
|
|
|
|
|
PrepayResponse response = new PrepayResponse();
|
|
|
|
|
|
try{
|
|
|
String result = httpClient.post(unionPayUrl, JSON.toJSONString(prepayData));
|
|
|
JSONObject resultJSON = JSONObject.parseObject(result);
|
|
|
if (resultJSON.containsKey("errCode") && "SUCCESS".equals(resultJSON.getString("errCode"))){
|
|
|
response.setPrepayResult(PrepayResponse.SUCCESS);
|
|
|
response.setJsonObj(resultJSON.getJSONObject("appPayRequest"));
|
|
|
logger.info("payment success orderCode is {}", request.getOrderCode() );
|
|
|
return response;
|
|
|
}else {
|
|
|
response.setPrepayResult(PrepayResponse.FAILED);
|
|
|
response.setJsonObj(resultJSON);
|
|
|
logger.warn("payment fail, orderCode is {}, result is {}", request.getOrderCode(), result);
|
|
|
return response;
|
|
|
}
|
|
|
}catch (Exception e) {
|
|
|
logger.warn("payment error orderCode is {}, e is {}", request.getOrderCode());
|
|
|
}
|
|
|
response.setPrepayResult(PrepayResponse.FAILED);
|
|
|
return response;
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 生成预支付数据
|
|
|
* @param request
|
|
|
* @param paymentVal
|
|
|
* @return
|
|
|
*/
|
|
|
private JSONObject buildPrepayData(PaymentRequest request, String paymentVal, BigDecimal amount) {
|
|
|
JSONObject prepayData = new JSONObject();
|
|
|
prepayData.put("msgSrc", msgSrc);
|
|
|
prepayData.put("msgType", paymentVal);
|
|
|
prepayData.put("requestTimestamp", DateUtil.date2String(new Date(), OrderConstant.DATE_FORMAT));
|
|
|
prepayData.put("merOrderId", OrderConstant.ORDER_CODE_PRE + request.getOrderCode());
|
|
|
prepayData.put("mid", mid);
|
|
|
prepayData.put("tid", tid);
|
|
|
prepayData.put("instMid", INST_MID);
|
|
|
prepayData.put("notifyUrl", callbackUrl);
|
|
|
// 单位分 存在点,则签名失败,不支持1.0这种
|
|
|
prepayData.put("totalAmount", amount.multiply(new BigDecimal(100)).setScale( 0, BigDecimal.ROUND_DOWN ).longValue());
|
|
|
|
|
|
prepayData.put("sign", SignUtils.getSign(prepayData, signKey));
|
|
|
return prepayData;
|
|
|
}
|
|
|
|
|
|
private BigDecimal checkUpdOrderCode(PaymentRequest request) {
|
|
|
// 根据订单号 反解:买家订单号 or 卖家订单号
|
|
|
CodeMeta codeMeta = orderCodeGenerator.expId(request.getOrderCode());
|
|
|
if (!OrderCodeType.isExistOrderCodeType(codeMeta.getType())) {
|
|
|
logger.warn("payment orderCode invalidate {}, uid is {}, codeMeta is {}", request.getOrderCode(), request.getUid(), codeMeta.getType());
|
|
|
throw new ServiceException(ServiceError.ORDER_ORDER_CODE_IS_EMPTY);
|
|
|
}
|
|
|
|
|
|
logger.info("payment orderCode is {} ,uid is {}, type is {}",request.getOrderCode(), request.getUid(), codeMeta.getType());
|
|
|
|
|
|
// 卖家订单号
|
|
|
if (codeMeta.getType() == OrderCodeType.BUYER_TYPE.getType()){
|
|
|
return checkUpdBuyerOrderCode(request);
|
|
|
}else{
|
|
|
return checkUpdSellerOrderCode(request);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
private BigDecimal checkUpdSellerOrderCode(PaymentRequest request) {
|
|
|
// 订单状态
|
|
|
SellerOrder sellerOrder = sellerOrderMapper.selectByOrderCode(request.getOrderCode());
|
|
|
if (sellerOrder == null){
|
|
|
logger.warn("payment orderCode not exist, orderCode is {}", request.getOrderCode(), request.getUid());
|
|
|
throw new ServiceException(ServiceError.ORDER_NULL);
|
|
|
}
|
|
|
|
|
|
// 订单不是未付款的状态
|
|
|
if (sellerOrder.getStatus() == null || sellerOrder.getStatus().intValue() != OrderStatus.WAITING_PAY.getCode()){
|
|
|
logger.warn("payment status not allow {}, orderCode is {}, uid is {}", sellerOrder.getStatus(), request.getOrderCode(), request.getUid());
|
|
|
throw new ServiceException(ServiceError.ORDER_PAY_NOT_ALLOW);
|
|
|
}
|
|
|
|
|
|
// 检查实付金额 TODO
|
|
|
// 更新预支付方式
|
|
|
sellerOrder.setPayment((byte)request.getPayment());
|
|
|
sellerOrder.setUpdateTime(DateUtil.getCurrentTimeSecond());
|
|
|
sellerOrderMapper.updateByPrimaryKey(sellerOrder);
|
|
|
|
|
|
return sellerOrder.getIncome();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 检查买家订单状态,更新支付方式
|
|
|
* @param request
|
|
|
*/
|
|
|
private BigDecimal checkUpdBuyerOrderCode(PaymentRequest request) {
|
|
|
// 订单状态
|
|
|
BuyerOrder buyerOrder = buyerOrderMapper.selectByOrderCode(request.getOrderCode());
|
|
|
if (buyerOrder == null){
|
|
|
logger.warn("payment orderCode not exist, orderCode is {}", request.getOrderCode(), request.getUid());
|
|
|
throw new ServiceException(ServiceError.ORDER_NULL);
|
|
|
}
|
|
|
|
|
|
// 订单不是未付款的状态
|
|
|
if (buyerOrder.getStatus() == null || buyerOrder.getStatus().intValue() != OrderStatus.WAITING_PAY.getCode()){
|
|
|
logger.warn("payment status not allow {}, orderCode is {}, uid is {}", buyerOrder.getStatus(), request.getOrderCode(), request.getUid());
|
|
|
throw new ServiceException(ServiceError.ORDER_PAY_NOT_ALLOW);
|
|
|
}
|
|
|
|
|
|
// 检查实付金额 TODO
|
|
|
|
|
|
// 更新预支付方式
|
|
|
buyerOrder.setPayment((byte)request.getPayment());
|
|
|
buyerOrder.setUpdateTime(DateUtil.getCurrentTimeSecond());
|
|
|
buyerOrderMapper.updateByPrimaryKey(buyerOrder);
|
|
|
|
|
|
return buyerOrder.getAmount();
|
|
|
}
|
|
|
} |
...
|
...
|
|