Authored by tanling

支付

package com.yohoufo.dal.order;
import com.yohoufo.dal.order.model.BuyerOrderMeta;
import com.yohoufo.dal.order.model.SellerOrderMeta;
import org.apache.ibatis.annotations.Param;
public interface SellerOrderMetaMapper {
int deleteByPrimaryKey(Integer id);
... ... @@ -14,4 +16,6 @@ public interface SellerOrderMetaMapper {
int updateByPrimaryKeySelective(SellerOrderMeta record);
int updateByPrimaryKey(SellerOrderMeta record);
BuyerOrderMeta selectByMetaKey(@Param("uid") int uid, @Param("orderCode") long orderCode, @Param("metaKey") String metaKey);
}
\ No newline at end of file
... ...
... ... @@ -13,7 +13,7 @@ public class BuyerOrder {
private Integer clientType;
private Byte payment;
private Integer payment;
private Byte paymentType;
... ... @@ -23,7 +23,7 @@ public class BuyerOrder {
private BigDecimal shipFee;
private Byte status;
private Integer status;
private Integer createTime;
... ... @@ -75,11 +75,11 @@ public class BuyerOrder {
this.clientType = clientType;
}
public Byte getPayment() {
public Integer getPayment() {
return payment;
}
public void setPayment(Byte payment) {
public void setPayment(Integer payment) {
this.payment = payment;
}
... ... @@ -115,11 +115,11 @@ public class BuyerOrder {
this.shipFee = shipFee;
}
public Byte getStatus() {
public Integer getStatus() {
return status;
}
public void setStatus(Byte status) {
public void setStatus(Integer status) {
this.status = status;
}
... ...
... ... @@ -7,12 +7,12 @@
<result column="order_code" jdbcType="BIGINT" property="orderCode" />
<result column="seller_uid" jdbcType="INTEGER" property="sellerUid" />
<result column="client_type" jdbcType="INTEGER" property="clientType" />
<result column="payment" jdbcType="TINYINT" property="payment" />
<result column="payment" jdbcType="INTEGER" property="payment" />
<result column="payment_type" jdbcType="TINYINT" property="paymentType" />
<result column="is_cancel" jdbcType="TINYINT" property="isCancel" />
<result column="amount" jdbcType="DECIMAL" property="amount" />
<result column="ship_fee" jdbcType="DECIMAL" property="shipFee" />
<result column="status" jdbcType="TINYINT" property="status" />
<result column="status" jdbcType="INTEGER" property="status" />
<result column="create_time" jdbcType="INTEGER" property="createTime" />
<result column="update_time" jdbcType="INTEGER" property="updateTime" />
<result column="buyer_order_status" jdbcType="INTEGER" property="buyerOrderStatus" />
... ... @@ -92,9 +92,9 @@
status, create_time, update_time,
buyer_order_status, seller_order_status, channel_no)
values (#{uid,jdbcType=INTEGER}, #{orderCode,jdbcType=BIGINT}, #{sellerUid,jdbcType=INTEGER},
#{clientType,jdbcType=INTEGER}, #{payment,jdbcType=TINYINT}, #{paymentType,jdbcType=TINYINT},
#{clientType,jdbcType=INTEGER}, #{payment,jdbcType=INTEGER}, #{paymentType,jdbcType=TINYINT},
#{isCancel,jdbcType=TINYINT}, #{amount,jdbcType=DECIMAL}, #{shipFee,jdbcType=DECIMAL},
#{status,jdbcType=TINYINT}, #{createTime,jdbcType=INTEGER}, #{updateTime,jdbcType=INTEGER},
#{status,jdbcType=INTEGER}, #{createTime,jdbcType=INTEGER}, #{updateTime,jdbcType=INTEGER},
#{buyerOrderStatus,jdbcType=INTEGER}, #{sellerOrderStatus,jdbcType=INTEGER}, #{channelNo,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="com.yohoufo.dal.order.model.BuyerOrder" useGeneratedKeys="true">
... ... @@ -160,7 +160,7 @@
#{clientType,jdbcType=TINYINT},
</if>
<if test="payment != null">
#{payment,jdbcType=TINYINT},
#{payment,jdbcType=INTEGER},
</if>
<if test="paymentType != null">
#{paymentType,jdbcType=TINYINT},
... ... @@ -175,7 +175,7 @@
#{shipFee,jdbcType=DECIMAL},
</if>
<if test="status != null">
#{status,jdbcType=TINYINT},
#{status,jdbcType=INTEGER},
</if>
<if test="createTime != null">
#{createTime,jdbcType=INTEGER},
... ... @@ -210,7 +210,7 @@
client_type = #{clientType,jdbcType=TINYINT},
</if>
<if test="payment != null">
payment = #{payment,jdbcType=TINYINT},
payment = #{payment,jdbcType=INTEGER},
</if>
<if test="paymentType != null">
payment_type = #{paymentType,jdbcType=TINYINT},
... ... @@ -225,7 +225,7 @@
ship_fee = #{shipFee,jdbcType=DECIMAL},
</if>
<if test="status != null">
status = #{status,jdbcType=TINYINT},
status = #{status,jdbcType=INTEGER},
</if>
<if test="createTime != null">
create_time = #{createTime,jdbcType=INTEGER},
... ... @@ -251,12 +251,12 @@
order_code = #{orderCode,jdbcType=BIGINT},
seller_uid = #{sellerUid,jdbcType=INTEGER},
client_type = #{clientType,jdbcType=TINYINT},
payment = #{payment,jdbcType=TINYINT},
payment = #{payment,jdbcType=INTEGER},
payment_type = #{paymentType,jdbcType=TINYINT},
is_cancel = #{isCancel,jdbcType=TINYINT},
amount = #{amount,jdbcType=DECIMAL},
ship_fee = #{shipFee,jdbcType=DECIMAL},
status = #{status,jdbcType=TINYINT},
status = #{status,jdbcType=INTEGER},
create_time = #{createTime,jdbcType=INTEGER},
update_time = #{updateTime,jdbcType=INTEGER},
buyer_order_status = #{buyerOrderStatus,jdbcType=INTEGER},
... ...
... ... @@ -27,6 +27,19 @@
values (#{skup,jdbcType=INTEGER}, #{uid,jdbcType=INTEGER}, #{metaKey,jdbcType=VARCHAR},
#{metaValue,jdbcType=VARCHAR})
</insert>
<select id="selectByMetaKey" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from seller_order_meta
where uid = #{uid,jdbcType=INTEGER}
and order_code = #{orderCode,jdbcType=BIGINT}
and meta_key = #{metaKey,jdbcType=VARCHAR}
limit 1
</select>
<insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="com.yohoufo.dal.order.model.SellerOrderMeta" useGeneratedKeys="true">
insert into seller_order_meta
<trim prefix="(" suffix=")" suffixOverrides=",">
... ...
package com.yohoufo.order.common;
public enum MsgType {
QUERY("query");
String value;
MsgType(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
... ...
... ... @@ -2,7 +2,7 @@ package com.yohoufo.order.common;
public enum SellerOrderStatus {
public enum SellerOrderStatus {
WAITING_PAY(0, "待付保证金", new ButtonShow[]{ButtonShow.PAY_EARNESTMONEY,ButtonShow.NOT_SOLD}),
SELLER_CANCEL_PAY(1, "上架关闭(卖家取消支付)", new ButtonShow[]{ButtonShow.SHOW_DETAIL}),
... ...
package com.yohoufo.order.model;
import com.yohoufo.order.common.OrderCodeType;
import lombok.Data;
import lombok.experimental.Builder;
import java.math.BigDecimal;
@Data
@Builder
public class OrderInfo {
private Integer uid;
private Long orderCode;
private int skup;
private Integer payment;
private Integer status;
private OrderCodeType orderCodeType;
private BigDecimal amount;
private String statusStr;
}
... ...
package com.yohoufo.order.response;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Builder;
@Data
@ToString
@Builder
public class PaymentConfirmRsp {
long orderCode;
String status;
String isPaid;
String isCancle;
}
... ...
package com.yohoufo.order.service;
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.order.common.Payment;
import com.yohoufo.order.constants.OrderConstant;
import com.yohoufo.order.model.OrderInfo;
import com.yohoufo.order.request.PaymentRequest;
import com.yohoufo.order.response.PrepayResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import java.math.BigDecimal;
import java.util.Date;
public abstract class AbstractOrderPaymentService {
private final Logger logger = LoggerFactory.getLogger(getClass());
@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";
/**
* 获取订单信息
* @param request
* @return
*/
public abstract OrderInfo getOrderInfo(PaymentRequest request);
/**
* 检查状态
* @param orderInfo
*/
public abstract void checkOrderStatus(OrderInfo orderInfo);
/**
* 预支付方式更新
* @param orderInfo
*/
public abstract void updatePayment(OrderInfo orderInfo, int payment);
/**
* 获取前回的访问结果
* @param request
* @return
*/
public abstract PrepayResponse getAppPayRequest(PaymentRequest request);
/**
* 保存前回预支付结果
* @param orderInfo
* @param response
*/
public abstract void saveAppPayRequest(OrderInfo orderInfo, PrepayResponse response);
/**
* 订单是否是待支付状态
* @param orderInfo
* @return
*/
public abstract boolean isOrderWaitingPay(OrderInfo orderInfo);
/**
* 检查并更新预支付方式
* @param request
* @return
*/
public BigDecimal checkUpdOrderCodePayment(OrderInfo orderInfo,PaymentRequest request) {
// check 订单状态为非付款的状态
checkOrderStatus(orderInfo);
// check 金额
checkOrderAmount(orderInfo);
// 更新 预支付方式
updatePayment(orderInfo, request.getPayment());
return orderInfo.getAmount();
}
/**
* 请求银联接口
* @param requestObj
* @return
*/
public JSONObject accessUnionPay(JSONObject requestObj){
try{
String result = httpClient.post(unionPayUrl, JSON.toJSONString(requestObj));
return JSONObject.parseObject(result);
}catch (Exception e){
logger.warn("accessUnionPay fail, orderCode is {}, uid is {}");
return null;
}
}
/**
* 生成查询订单支付结果
* @param request
* @param payment
* @return
*/
public JSONObject buildQueryOrderData(PaymentRequest request, Payment payment) {
JSONObject prepayData = buildCommOrderData(request, payment);
prepayData.put("sign", SignUtils.getSign(prepayData, signKey));
return prepayData;
}
/**
* 银联请求共通参数
* @param request
* @param payment
* @return
*/
private JSONObject buildCommOrderData(PaymentRequest request, Payment payment){
JSONObject commData = new JSONObject();
commData.put("msgSrc", msgSrc);
commData.put("msgType", payment.getValue());
commData.put("requestTimestamp", DateUtil.date2String(new Date(), OrderConstant.DATE_FORMAT));
commData.put("merOrderId", getPayOrderCode(request.getOrderCode(), payment));
commData.put("mid", mid);
commData.put("tid", tid);
commData.put("instMid", INST_MID);
return commData;
}
/**
* 生成预支付数据
* @param request
* @param payment
* @return
*/
public JSONObject buildPrepayData(PaymentRequest request, Payment payment, BigDecimal amount) {
JSONObject requestData = buildCommOrderData(request, payment);
requestData.put("notifyUrl", callbackUrl);
// 单位分 存在点,则签名失败,不支持1.0这种
requestData.put("totalAmount", amount.multiply(new BigDecimal(100)).setScale( 0, BigDecimal.ROUND_DOWN ).longValue());
requestData.put("sign", SignUtils.getSign(requestData, signKey));
return requestData;
}
private String getPayOrderCode(long orderCode, Payment payment){
StringBuilder sb = new StringBuilder();
sb.append(OrderConstant.ORDER_CODE_PRE);
sb.append(orderCode);
sb.append(OrderConstant.SPLIT_STR);
sb.append(payment.getCode());
return sb.toString();
}
/**
* 检查金额
* @param orderInfo
* @return
*/
public BigDecimal checkOrderAmount(OrderInfo orderInfo){
// 检查实付金额
if (orderInfo.getAmount() == null || orderInfo.getAmount().compareTo(new BigDecimal(0)) <=0 ){
logger.warn("payment amount null, orderCode is {}", orderInfo.getOrderCode());
throw new ServiceException(ServiceError.ORDER_NULL);
}
return orderInfo.getAmount();
}
}
... ...
package com.yohoufo.order.service;
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.dal.order.BuyerOrderMapper;
import com.yohoufo.dal.order.BuyerOrderMetaMapper;
import com.yohoufo.dal.order.model.BuyerOrder;
import com.yohoufo.dal.order.model.BuyerOrderMeta;
import com.yohoufo.order.common.OrderCodeType;
import com.yohoufo.order.common.OrderStatus;
import com.yohoufo.order.common.SellerOrderStatus;
import com.yohoufo.order.constants.MetaKey;
import com.yohoufo.order.model.OrderInfo;
import com.yohoufo.order.request.PaymentRequest;
import com.yohoufo.order.response.PrepayResponse;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BuyerOrderPaymentService extends AbstractOrderPaymentService {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
BuyerOrderMapper buyerOrderMapper;
@Autowired
BuyerOrderMetaMapper buyerOrderMetaMapper;
/**
* 订单是否是待支付状态
* @param orderInfo
* @return
*/
public boolean isOrderWaitingPay(OrderInfo orderInfo){
if (orderInfo.getStatus() != null && orderInfo.getStatus().intValue() == OrderStatus.WAITING_PAY.getCode()){
return true;
}
return false;
}
/**
* 保存前回预支付结果
* @param orderInfo
* @param response
*/
public void saveAppPayRequest(OrderInfo orderInfo, PrepayResponse response) {
BuyerOrderMeta buyerOrderMeta = new BuyerOrderMeta();
buyerOrderMeta.setUid(orderInfo.getUid());
buyerOrderMeta.setOrderCode(orderInfo.getOrderCode());
buyerOrderMeta.setMetaKey(MetaKey.APP_PAY_REQUEST);
buyerOrderMeta.setMetaValue(JSONObject.toJSONString(response));
// 记录appPayRequest
buyerOrderMetaMapper.insert(buyerOrderMeta);
}
/**
* 获取前回的访问结果
* @param request
* @return
*/
public PrepayResponse getAppPayRequest(PaymentRequest request) {
BuyerOrderMeta buyerOrderMeta = buyerOrderMetaMapper.selectByMetaKey(request.getUid(), request.getOrderCode(), MetaKey.APP_PAY_REQUEST);
if (buyerOrderMeta == null || StringUtils.isEmpty(buyerOrderMeta.getMetaValue())){
return null;
}
try{
PrepayResponse response = JSON.parseObject(buyerOrderMeta.getMetaValue(), PrepayResponse.class);
return response;
}catch (Exception e){
}
return null;
}
/**
* 检查状态
* @param orderInfo
*/
public void checkOrderStatus(OrderInfo orderInfo){
// 订单不是未付款的状态
if (orderInfo.getStatus() == null || orderInfo.getStatus().intValue() != OrderStatus.WAITING_PAY.getCode()){
logger.warn("payment status not allow {}, orderCode is {}, uid is {}", orderInfo.getStatus(),
orderInfo.getOrderCode(), orderInfo.getUid());
throw new ServiceException(ServiceError.ORDER_PAY_NOT_ALLOW);
}
}
/**
* 预支付方式更新
* @param orderInfo
*/
public void updatePayment(OrderInfo orderInfo, int payment){
BuyerOrder buyerOrder = new BuyerOrder();
// 更新预支付方式
buyerOrder.setPayment(orderInfo.getPayment());
buyerOrder.setUpdateTime(DateUtil.getCurrentTimeSecond());
buyerOrderMapper.updateByPrimaryKeySelective(buyerOrder);
}
/**
* 获取订单情报
* @param request
* @return
*/
public OrderInfo getOrderInfo(PaymentRequest request) {
BuyerOrder buyerOrder = buyerOrderMapper.selectByOrderCode(request.getOrderCode(), request.getUid());
if (buyerOrder == null){
logger.warn("getOrderInfo order not exist, orderCode is {}, uid is {}",request.getOrderCode(), request.getUid());
throw new ServiceException(ServiceError.ORDER_NULL);
}
OrderInfo orderInfo = OrderInfo.builder()
.uid(request.getUid())
.orderCode(request.getOrderCode())
.payment(buyerOrder.getPayment())
.status(buyerOrder.getStatus())
.amount(buyerOrder.getAmount())
.orderCodeType(OrderCodeType.BUYER_TYPE)
.build();
return orderInfo;
}
}
... ...
package com.yohoufo.order.service;
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.dal.order.SellerOrderMapper;
import com.yohoufo.dal.order.SellerOrderMetaMapper;
import com.yohoufo.dal.order.model.BuyerOrderMeta;
import com.yohoufo.dal.order.model.SellerOrder;
import com.yohoufo.dal.order.model.SellerOrderMeta;
import com.yohoufo.order.common.OrderCodeType;
import com.yohoufo.order.common.SellerOrderStatus;
import com.yohoufo.order.constants.MetaKey;
import com.yohoufo.order.model.OrderInfo;
import com.yohoufo.order.request.PaymentRequest;
import com.yohoufo.order.response.PrepayResponse;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SellerOrderPaymentService extends AbstractOrderPaymentService {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
SellerOrderMapper sellerOrderMapper;
@Autowired
SellerOrderMetaMapper sellerOrderMetaMapper;
/**
* 订单是否是待支付状态
* @param orderInfo
* @return
*/
public boolean isOrderWaitingPay(OrderInfo orderInfo){
if (orderInfo.getStatus() == null || orderInfo.getStatus().intValue() != SellerOrderStatus.WAITING_PAY.getCode()){
return true;
}
return false;
}
/**
* 保存前回预支付结果
* @param orderInfo
* @param response
*/
public void saveAppPayRequest(OrderInfo orderInfo, PrepayResponse response) {
SellerOrderMeta buyerOrderMeta = new SellerOrderMeta();
buyerOrderMeta.setUid(orderInfo.getUid());
buyerOrderMeta.setSkup(orderInfo.getSkup());
buyerOrderMeta.setMetaKey(MetaKey.APP_PAY_REQUEST);
buyerOrderMeta.setMetaValue(JSONObject.toJSONString(response));
// 记录appPayRequest
sellerOrderMetaMapper.insert(buyerOrderMeta);
}
/**
* 获取前回的访问结果
* @param request
* @return
*/
public PrepayResponse getAppPayRequest(PaymentRequest request) {
BuyerOrderMeta buyerOrderMeta = sellerOrderMetaMapper.selectByMetaKey(request.getUid(), request.getOrderCode(), MetaKey.APP_PAY_REQUEST);
if (buyerOrderMeta == null || StringUtils.isEmpty(buyerOrderMeta.getMetaValue())){
return null;
}
try{
PrepayResponse response = JSON.parseObject(buyerOrderMeta.getMetaValue(), PrepayResponse.class);
return response;
}catch (Exception e){
}
return null;
}
/**
* 预支付方式更新
* @param orderInfo
*/
public void updatePayment(OrderInfo orderInfo, int payment){
SellerOrder sellerOrder = new SellerOrder();
// 更新预支付方式
sellerOrder.setPayment(orderInfo.getPayment());
sellerOrder.setUpdateTime(DateUtil.getCurrentTimeSecond());
sellerOrderMapper.updateByPrimaryKeySelective(sellerOrder);
}
/**
* 检查状态
* @param orderInfo
*/
public void checkOrderStatus(OrderInfo orderInfo){
// 订单不是未付款的状态
if (orderInfo.getStatus() == null || orderInfo.getStatus().intValue() != SellerOrderStatus.WAITING_PAY.getCode()){
logger.warn("payment status not allow {}, orderCode is {}, uid is {}", orderInfo.getStatus(),
orderInfo.getOrderCode(), orderInfo.getUid());
throw new ServiceException(ServiceError.ORDER_PAY_NOT_ALLOW);
}
}
/**
* 获取订单情报
* @param request
* @return
*/
public OrderInfo getOrderInfo(PaymentRequest request) {
SellerOrder sellerOrder = sellerOrderMapper.selectByOrderCode(request.getOrderCode(), request.getUid());
if (sellerOrder == null){
logger.warn("getOrderInfo order not exist, orderCode is {}, uid is {}",request.getOrderCode(), request.getUid());
throw new ServiceException(ServiceError.ORDER_NULL);
}
OrderInfo orderInfo = OrderInfo.builder()
.uid(request.getUid())
.orderCode(request.getOrderCode())
.payment(sellerOrder.getPayment())
.skup(sellerOrder.getSkup())
.status(sellerOrder.getStatus())
.orderCodeType(OrderCodeType.BUYER_TYPE)
.amount(sellerOrder.getEarnestMoney())
.build();
return orderInfo;
}
}
... ...
... ... @@ -13,14 +13,17 @@ import com.yohoufo.dal.order.SellerOrderMapper;
import com.yohoufo.dal.order.model.BuyerOrder;
import com.yohoufo.dal.order.model.BuyerOrderMeta;
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.common.*;
import com.yohoufo.order.constants.MetaKey;
import com.yohoufo.order.constants.OrderConstant;
import com.yohoufo.order.model.OrderInfo;
import com.yohoufo.order.request.PaymentRequest;
import com.yohoufo.order.response.PaymentConfirmRsp;
import com.yohoufo.order.response.PrepayResponse;
import com.yohoufo.order.service.AbstractOrderPaymentService;
import com.yohoufo.order.service.BuyerOrderPaymentService;
import com.yohoufo.order.service.IPaymentService;
import com.yohoufo.order.service.SellerOrderPaymentService;
import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator;
import com.yohoufo.order.service.support.codegenerator.bean.CodeMeta;
import org.apache.commons.lang3.StringUtils;
... ... @@ -39,52 +42,97 @@ public class PaymentServiceImpl implements IPaymentService {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
BuyerOrderMapper buyerOrderMapper;
BuyerOrderMetaMapper buyerOrderMetaMapper;
@Autowired
SellerOrderMapper sellerOrderMapper;
BuyerOrderPaymentService buyerOrderPaymentService;
@Value("${unionpay.pay.url}")
private String unionPayUrl;
@Autowired
SellerOrderPaymentService sellerOrderPaymentService;
@Value("${unionpay.pay.callbackUrl}")
private String callbackUrl;
@Value("${unionpay.pay.msgSrc}")
private String msgSrc;
@Autowired
OrderCodeGenerator orderCodeGenerator;
@Value("${unionpay.pay.mid}")
private String mid;
@Value("${unionpay.pay.tid}")
private String tid;
/**
* 获取主场的订单service
* @param codeMeta
* @param request
* @return
*/
private AbstractOrderPaymentService getOrderPaymentService(CodeMeta codeMeta, PaymentRequest request){
@Value("${unionPay.pay.signKey}")
private String signKey;
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);
}
@Autowired
HttpClient httpClient;
AbstractOrderPaymentService paymentService = null;
@Autowired
BuyerOrderMetaMapper buyerOrderMetaMapper;
// 买家订单
if (codeMeta.getType() == OrderCodeType.BUYER_TYPE.getType()){
paymentService = this.buyerOrderPaymentService;
/**
* 机构商户号
*/
public static final String INST_MID = "APPDEFAULT";
}else{
paymentService = this.sellerOrderPaymentService;
@Autowired
OrderCodeGenerator orderCodeGenerator;
}
return paymentService;
}
public PaymentConfirmRsp payConfirm(PaymentRequest request){
// 入口数据检查
if (request.getUid() < 0
|| request.getOrderCode() < 0){
logger.warn("payConfirm request empty");
throw new ServiceException(ServiceError.ORDER_REQUEST_PARM_IS_EMPTY);
}
// 反解订单号
// 根据订单号 反解:买家订单号 or 卖家订单号
CodeMeta codeMeta = orderCodeGenerator.expId(request.getOrderCode());
// 获取主场的service
AbstractOrderPaymentService paymentService = getOrderPaymentService(codeMeta, request);
// 获取订单信息
OrderInfo orderInfo = paymentService.getOrderInfo(request);
// 已支付的状态,直接返回
// payment!=null && 待付款,其他直接返回
PaymentConfirmRsp paymentConfirmRsp = PaymentConfirmRsp.builder().orderCode(request.getOrderCode()).build();
if (orderInfo.getPayment() == null || !paymentService.isOrderWaitingPay(orderInfo)){
}
// 未支付订单
Payment payment = Payment.getPayment(orderInfo.getPayment());
JSONObject result = paymentService.accessUnionPay(paymentService.buildQueryOrderData(request, payment));
if (result.containsKey("errCode") && "SUCCESS".equals(result.getString("errCode"))){
String stauts = result.getString("status");
if ("TRADE_SUCCESS".equals(stauts)){
public void payConfirm(PaymentRequest request){
// 支付成功 TODO
}
}
//
return paymentConfirmRsp;
}
/**
* 订单退款
* 使用场景: [卖家发布商品]页面的[不卖了],
... ... @@ -113,207 +161,84 @@ public class PaymentServiceImpl implements IPaymentService {
*/
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 = checkPaymentRequest(request);
// 不存在的支付方式
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 卖家订单号
CodeMeta codeMeta = orderCodeGenerator.expId(request.getOrderCode());
// 获取主场的service
AbstractOrderPaymentService paymentService = getOrderPaymentService(codeMeta, request);
// check 订单是否存在
OrderInfo orderInfo = paymentService.getOrderInfo(request);
// 卖家or买家订单,支付方式更新,返回实付金额
BigDecimal amount = checkUpdOrderCode(request);
BigDecimal amount = paymentService.checkUpdOrderCodePayment(orderInfo, request);
// 向银联提下过单的,直接返回结果
PrepayResponse oldAppPayRequest = getAppPayRequest(request);
PrepayResponse oldAppPayRequest = paymentService.getAppPayRequest(request);
if (oldAppPayRequest != null){
logger.info("payment oldAppPayRequest orderCode is {}, uid is {}, oldAppPayRequest is {}",
request.getOrderCode(), request.getUid(), oldAppPayRequest);
logger.info("payment oldAppPayRequest orderCode is {}, uid is {}, oldAppPayRequest is {}",request.getOrderCode(), request.getUid(), oldAppPayRequest);
return oldAppPayRequest;
}
// 生成预支付数据
JSONObject prepayData = buildPrepayData(request, payment, amount);
JSONObject prepayData = paymentService.buildPrepayData(request, payment, 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"));
// 保存支付成功结果
saveAppPayRequest(request, response);
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;
JSONObject resultJSON = paymentService.accessUnionPay(prepayData);
}
if (resultJSON.containsKey("errCode") && "SUCCESS".equals(resultJSON.getString("errCode"))){
response.setPrepayResult(PrepayResponse.SUCCESS);
response.setJsonObj(resultJSON.getJSONObject("appPayRequest"));
/**
* 获取前回的访问结果
* @param request
* @return
*/
private PrepayResponse getAppPayRequest(PaymentRequest request) {
BuyerOrderMeta buyerOrderMeta = buyerOrderMetaMapper.selectByMetaKey(request.getUid(), request.getOrderCode(), getMetaKey(request.getPayment()));
// 保存支付成功结果
paymentService.saveAppPayRequest(orderInfo, response);
if (buyerOrderMeta == null || StringUtils.isEmpty(buyerOrderMeta.getMetaValue())){
return null;
}
try{
PrepayResponse response = JSON.parseObject(buyerOrderMeta.getMetaValue(), PrepayResponse.class);
logger.info("payment success orderCode is {}", request.getOrderCode() );
return response;
}catch (Exception e){
}else{
response.setPrepayResult(PrepayResponse.FAILED);
response.setJsonObj(resultJSON);
return response;
}
return null;
}
private void saveAppPayRequest(PaymentRequest request, PrepayResponse response) {
BuyerOrderMeta buyerOrderMeta = new BuyerOrderMeta();
buyerOrderMeta.setUid(request.getUid());
buyerOrderMeta.setOrderCode(request.getOrderCode());
buyerOrderMeta.setMetaKey(getMetaKey(request.getPayment()));
buyerOrderMeta.setMetaValue(JSONObject.toJSONString(response));
// 记录appPayRequest
buyerOrderMetaMapper.insert(buyerOrderMeta);
}
public String getMetaKey(int payment){
return MetaKey.APP_PAY_REQUEST + OrderConstant.SPLIT_STR +payment;
}
/**
* 生成预支付数据
* 入口数据检查
* @param request
* @param paymentVal
* @return
*/
private JSONObject buildPrepayData(PaymentRequest request, Payment payment, BigDecimal amount) {
JSONObject prepayData = new JSONObject();
prepayData.put("msgSrc", msgSrc);
prepayData.put("msgType", payment.getValue());
prepayData.put("requestTimestamp", DateUtil.date2String(new Date(), OrderConstant.DATE_FORMAT));
prepayData.put("merOrderId", getPayOrderCode(request.getOrderCode(), payment));
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 String getPayOrderCode(long orderCode, Payment payment){
StringBuilder sb = new StringBuilder();
sb.append(OrderConstant.ORDER_CODE_PRE);
sb.append(orderCode);
sb.append(OrderConstant.SPLIT_STR);
sb.append(payment.getCode());
return sb.toString();
}
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);
private Payment checkPaymentRequest(PaymentRequest request) {
// 入口数据检查
if (request.getUid() < 0
|| request.getOrderCode() < 0){
logger.warn("payment request empty");
throw new ServiceException(ServiceError.ORDER_REQUEST_PARM_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);
// 不存在的支付方式
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);
}
return payment;
}
private BigDecimal checkUpdSellerOrderCode(PaymentRequest request) {
// 订单状态
SellerOrder sellerOrder = sellerOrderMapper.selectByOrderCode(request.getOrderCode(), request.getUid());
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);
}
// 检查实付金额
if (sellerOrder.getEarnestMoney() == null || sellerOrder.getEarnestMoney().compareTo(new BigDecimal(0)) <=0 ){
logger.warn("payment amount null, orderCode is {}", request.getOrderCode());
throw new ServiceException(ServiceError.ORDER_NULL);
}
// 更新预支付方式
sellerOrder.setPayment(request.getPayment());
sellerOrder.setUpdateTime(DateUtil.getCurrentTimeSecond());
sellerOrderMapper.updateByPrimaryKey(sellerOrder);
return sellerOrder.getEarnestMoney();
}
/**
* 检查买家订单状态,更新支付方式
* @param request
*/
private BigDecimal checkUpdBuyerOrderCode(PaymentRequest request) {
// 订单状态
BuyerOrder buyerOrder = buyerOrderMapper.selectByOrderCode(request.getOrderCode(), request.getUid());
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);
}
// 检查实付金额
if (buyerOrder.getAmount() == null || buyerOrder.getAmount().compareTo(new BigDecimal(0)) <= 0){
logger.warn("payment amount null, orderCode is {}", request.getOrderCode());
throw new ServiceException(ServiceError.ORDER_NULL);
}
// 更新预支付方式
buyerOrder.setPayment((byte)request.getPayment());
buyerOrder.setUpdateTime(DateUtil.getCurrentTimeSecond());
buyerOrderMapper.updateByPrimaryKey(buyerOrder);
return buyerOrder.getAmount();
}
}
... ...
... ... @@ -161,7 +161,7 @@ public class SubmitOrderServiceImpl implements ISubmitOrderService {
buyerOrder.setClientType(ClientType.getClientType(orderBuilder.getClientType()));
buyerOrder.setCreateTime(now);
buyerOrder.setUpdateTime(now);
buyerOrder.setStatus((byte) OrderStatus.WAITING_PAY.getCode());
buyerOrder.setStatus(OrderStatus.WAITING_PAY.getCode());
buyerOrderMapper.insert(buyerOrder);
}
... ...
... ... @@ -187,7 +187,7 @@ public class PayTest {
// 支付宝
data.put("msgType", "query"); // 微信:wx.unifiedOrder, 支付宝:trade.precreate, 全民付:qmf.order, 银联云闪付:uac.appOrder
data.put("requestTimestamp", DateUtil.date2String(new Date(), "yyyy-MM-dd HH:mm:ss"));
data.put("merOrderId", "319450751581111111");
data.put("merOrderId", "31949756868190273_1");
data.put("mid", "898310148160568"); //商户号 仅用于支付宝和云闪付
data.put("tid","00000001"); //终端号
data.put("instMid", "APPDEFAULT"); // 机构商户号
... ...