PostSale 表
用户Id,订单Id,机器Id,订单,用户备注,机器备注,图片,售后状态
@OneToOne
@JoinColumn(name = "orderId"
,updatable = false
,insertable = false)
private StoreOrder order;
通过注解关联订单Id和订单
private Status status = Status.CREATED;
public enum Status{
CREATED, //等待商家处理 - 商家处理中
CANCELED, //用户取消 - 已取消
FINISHED, //商家同意售后 - 已完成
REJECTED //商家驳回售后 - 已完成
}
枚举类型 enum Status
继承一个通用的BaseEntity,包含自动生成的表Id,
Timestamp类型的时间,通过注解实现正反的序列化
@Id
@GeneratedValue(
strategy = GenerationType.AUTO
)
protected Integer id;
@CreationTimestamp
@JsonSerialize(
using = TimestampSerializer.class
)
@JsonDeserialize(
using = TimestampDeserializer.class
)
@Column(
updatable = false
)
protected Timestamp createTime;
@UpdateTimestamp
@JsonSerialize(
using = TimestampSerializer.class
)
@JsonDeserialize(
using = TimestampDeserializer.class
)
protected Timestamp updateTime;
Controller
@RequestBody 接受传递过来的json实体对象
@PostMapping("/post_sale/refund_order")
public API<PostSale> refundOrder(@RequestBody @Valid PostSale postSale){
return API.ok(mOrderManageService.refundOrder(postSale));
}
PostSaleService
public PostSale refundOrder(PostSale postSale) {
StoreOrder order = orderRepository.findItemById(postSale.getOrderId());
mPayService.refundOrder(order.getNo(),order.getPrice(),order.getPayMethod());
postSale.setStatus(PostSale.Status.FINISHED);
return postSaleRepository.save(postSale);
}
通过postSale实体类中的订单Id查找出订单数据,进行退款操作,退款成功后更改售后状态
PayService
传递订单中的编号,价格,订单支付日志中的支付方式
public void refundOrder(String no, BigDecimal refundPrice, PayLog.PayMethod payMethod) {
getPayService(payMethod).refundOrder(no,refundPrice);
}
抽出getPayService方法.获得支付类型
public PayService getPayService(PayLog.PayMethod payMethod){
if (PayLog.PayMethod.WECHAT.equals(payMethod)){
return mWechatPayService;
}
if (PayLog.PayMethod.ROYAL_PAY.equals(payMethod)){
return mRoyalPayService;
}
APIError.CUSTOM.set(400,"暂不支持该支付方式").expose();
return null;
}
WechatPayService
申请退款
public void refundOrder(String orderNo,BigDecimal refundPrice) {
PayLog log = checkIfCanRefund(orderNo);
WxPayRefundRequest refundQueryRequest = new WxPayRefundRequest();
refundQueryRequest.setTransactionId(log.getTransactionId());
refundQueryRequest.setOutRefundNo(generateRefundId());
refundQueryRequest.setRefundFee(transformPrice(refundPrice));
refundQueryRequest.setTotalFee(transformPrice(log.getPrice()));
refundQueryRequest.setNotifyUrl(String.format("http://%s/pay/wechat/%srefund",mBasicConfigService.getConfig().getDomain(),callbackPrefix));
try {
WxPayRefundResult data = mWxPayService.refund(refundQueryRequest);
log.setRefundId(data.getRefundId());
log.setRefundPrice(refundPrice);
log.setStatus(PayLog.PayStatus.REFUNDING);
log.setRefundTransactionId(data.getRefundId());
log.setRefundApplyTime(new Timestamp(System.currentTimeMillis()));
mPayLogRepository.save(log);
} catch (WxPayException e) {
mLogger.warning("refund apply error:"+e.getMessage());
APIError.CUSTOM.set(500,"退款失败:"+e.getMessage()).expose();
}
}
PayLog log = checkIfCanRefund(orderNo); 检查是否可以退款
protected PayLog checkIfCanRefund(String orderNo){
PayLog log = getPayLog(orderNo);
if (log == null){
APIError.CUSTOM.set(404,"订单不存在").expose();
}
if (!PayLog.PayStatus.SUCCESS.equals(log.getStatus())){
APIError.CUSTOM.set(404,"当前订单不可退款").expose();
}
return log;
}
WxPayRefundRequest refundQueryRequest = new WxPayRefundRequest();
创建一个微信退款xml实体,满足微信商户申请退款接口中要求的数据
<xml>
<appid>wx2421b1c4370ec43b</appid>
<mch_id>10000100</mch_id>
<nonce_str>6cefdb308e1e2e8aabd48cf79e546a02</nonce_str>
<out_refund_no>1415701182</out_refund_no>
<out_trade_no>1415757673</out_trade_no>
<refund_fee>1</refund_fee>
<total_fee>1</total_fee>
<transaction_id></transaction_id>
<sign>FE56DD4AA85C0EECA82C35595A69E153</sign>
</xml>
WxPayRefundRequest 导入jar包
package com.github.binarywang.wxpay.bean.request;
refundQueryRequest.setTransactionId(log.getTransactionId());
通过支付日志获取交易号
设置商户自己内部的退款单号
refundQueryRequest.setOutRefundNo(generateRefundId());
@Override
public String generateRefundId() {
return UUID.randomUUID().toString().replaceAll("-","");
}
设置退款结果通知url.
refundQueryRequest.setNotifyUrl(String.format(“http://%s/pay/wechat/%srefund",mBasicConfigService.getConfig().getDomain(),callbackPrefix));