|
|
@ -19,7 +19,11 @@ import com.yxt.pay.api.order.PayOrder; |
|
|
|
import com.yxt.pay.api.refund.*; |
|
|
|
import com.yxt.pay.api.wxpay.WxPayVo; |
|
|
|
import com.yxt.pay.biz.order.OrderService; |
|
|
|
import com.yxt.pay.utils.TrustEveryone; |
|
|
|
import com.yxt.pay.utils.UrlComponent; |
|
|
|
import com.yxt.pay.utils.wx.HttpKit; |
|
|
|
import com.yxt.pay.utils.wx.SignType; |
|
|
|
import com.yxt.pay.utils.wx.WxPayKit; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.beans.factory.annotation.Value; |
|
|
@ -30,9 +34,12 @@ import org.springframework.web.client.RestTemplate; |
|
|
|
|
|
|
|
import javax.servlet.ServletInputStream; |
|
|
|
import javax.servlet.http.HttpServletRequest; |
|
|
|
import javax.servlet.http.HttpServletResponse; |
|
|
|
import java.io.BufferedReader; |
|
|
|
import java.io.InputStream; |
|
|
|
import java.io.InputStreamReader; |
|
|
|
import java.math.BigDecimal; |
|
|
|
import java.util.Date; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.Map; |
|
|
|
|
|
|
@ -68,7 +75,9 @@ public class WxRefundService extends MybatisBaseService<WxRefundMapper,RefundOrd |
|
|
|
public ResultBean createRefundOrder(RefundOrderDto refundOrderDto){ |
|
|
|
ResultBean rb=new ResultBean(); |
|
|
|
RefundOrder refundOrder=new RefundOrder(refundOrderDto.getSource()); |
|
|
|
BeanUtil.copyProperties(refundOrderDto,refundOrder,"id","sid","outTradeNo"); |
|
|
|
PayOrder payOrder=orderService.getOne(new QueryWrapper<PayOrder>().eq("sid",refundOrderDto.getOrderSid())); |
|
|
|
BeanUtil.copyProperties(refundOrderDto,refundOrder,"id","sid"); |
|
|
|
refundOrder.setOutTradeNo(payOrder.getOutTradeNo()); |
|
|
|
baseMapper.insert(refundOrder); |
|
|
|
return rb.success().setData(refundOrder); |
|
|
|
|
|
|
@ -84,9 +93,9 @@ public class WxRefundService extends MybatisBaseService<WxRefundMapper,RefundOrd |
|
|
|
@Transactional |
|
|
|
public ResultBean refund(String orderSid) throws Exception { |
|
|
|
ResultBean rb = ResultBean.fireFail(); |
|
|
|
PayOrder payOrder=orderService.getOne(new QueryWrapper<PayOrder>().eq("sid",orderSid)); |
|
|
|
RefundOrder refundOrder=baseMapper.selectOne(new QueryWrapper<RefundOrder>().eq("orderSid",payOrder.getSid()).eq("state","1")); |
|
|
|
try { |
|
|
|
PayOrder payOrder=orderService.getOne(new QueryWrapper<PayOrder>().eq("sid",orderSid)); |
|
|
|
WxPayVo wxPayVo=new WxPayVo(payOrder.getSource()); |
|
|
|
source=payOrder.getSource(); |
|
|
|
// 使用自动更新平台证书的RSA配置
|
|
|
|
// 一个商户号只能初始化一个配置,否则会因为重复的下载任务报错
|
|
|
@ -101,58 +110,48 @@ public class WxRefundService extends MybatisBaseService<WxRefundMapper,RefundOrd |
|
|
|
.build(); |
|
|
|
// 构建退款service
|
|
|
|
RefundService service = new RefundService.Builder().config(config).build(); |
|
|
|
// request.setXxx(val)设置所需参数,具体参数可见Request定义
|
|
|
|
//构建退款请求
|
|
|
|
CreateRequest request = new CreateRequest(); |
|
|
|
//构建订单金额信息
|
|
|
|
AmountReq amountReq = new AmountReq(); |
|
|
|
// PayOrder payOrder=orderService.getOne(new QueryWrapper<PayOrder>().eq("sid",orderSid));
|
|
|
|
RefundOrder refundOrder=baseMapper.selectOne(new QueryWrapper<RefundOrder>().eq("orderSid",payOrder.getSid())); |
|
|
|
BigDecimal b=new BigDecimal(refundOrder.getAmount()); |
|
|
|
BigDecimal a =new BigDecimal(100); |
|
|
|
String aoum=String.valueOf(b.multiply(a).setScale(0,ROUND_DOWN)); |
|
|
|
String aoum=String.valueOf(refundOrder.getAmount().multiply(a).setScale(0,ROUND_DOWN)); |
|
|
|
//退款金额
|
|
|
|
amountReq.setRefund(Long.valueOf(aoum)); |
|
|
|
// amountReq.setRefund(Long.valueOf("1"));
|
|
|
|
//原订单金额
|
|
|
|
amountReq.setTotal(Long.valueOf(aoum)); |
|
|
|
// amountReq.setTotal(Long.valueOf("1"));
|
|
|
|
//货币类型(默认人民币)
|
|
|
|
amountReq.setCurrency("CNY"); |
|
|
|
request.setAmount(amountReq); |
|
|
|
//商户退款单号
|
|
|
|
request.setOutRefundNo(refundOrder.getOutTradeNo()); |
|
|
|
// request.setOutRefundNo(String.valueOf("ceshi"));
|
|
|
|
request.setOutTradeNo(payOrder.getOutTradeNo()); |
|
|
|
// request.setOutTradeNo("ceshi");
|
|
|
|
request.setReason(refundOrder.getReason()); |
|
|
|
// request.setReason("ceshi");
|
|
|
|
//退款通知回调地址
|
|
|
|
// request.setNotifyUrl(wxPayV3Bean.getRefundNotifyUrl());
|
|
|
|
request.setNotifyUrl(urlComponent.getDoMainUrl() + "order/payNotify"); |
|
|
|
request.setNotifyUrl(urlComponent.getDoMainUrl() + "refund/refundNotify"); |
|
|
|
// 调用退款方法,得到应答
|
|
|
|
// 调用微信sdk接口
|
|
|
|
Refund refund = service.create(request); |
|
|
|
System.out.println(refund); |
|
|
|
//接收退款返回参数
|
|
|
|
Refund refundResponse = new Refund(); |
|
|
|
refundResponse.setStatus(refund.getStatus()); |
|
|
|
System.out.println(refund);; |
|
|
|
if (refundResponse.getStatus().equals(Status.SUCCESS)){ |
|
|
|
//说明退款成功,开始接下来的业务操作
|
|
|
|
// WXRefundOrderRespVo refundOrderRespVO = new WXRefundOrderRespVo();
|
|
|
|
payOrder.setState(2); |
|
|
|
orderService.updateById(payOrder); |
|
|
|
refundOrder.setState(2); |
|
|
|
baseMapper.updateById(refundOrder); |
|
|
|
//你的业务代码
|
|
|
|
return rb.success().setData(refund); |
|
|
|
}else if(refundResponse.getStatus().equals(Status.PROCESSING)){ |
|
|
|
return rb.success().setMsg("退款申请处理中,请稍等").setData(refund); |
|
|
|
}else{ |
|
|
|
payOrder.setState(3); |
|
|
|
payOrder.setState(4); |
|
|
|
orderService.updateById(payOrder); |
|
|
|
return rb.setMsg("申请退款失败").setData(refund); |
|
|
|
refundOrder.setState(3); |
|
|
|
baseMapper.updateById(refundOrder); |
|
|
|
return rb.setCode("500").setMsg("申请退款失败").setData(refund); |
|
|
|
} |
|
|
|
}catch (Exception e){ |
|
|
|
e.printStackTrace(); |
|
|
|
refundOrder.setState(3); |
|
|
|
baseMapper.updateById(refundOrder); |
|
|
|
return rb.setMsg("退款失败,error=" + e.getMessage()); |
|
|
|
// throw new ResultException(ResultEnum.ERROR,e.toString());
|
|
|
|
} |
|
|
@ -166,25 +165,20 @@ public class WxRefundService extends MybatisBaseService<WxRefundMapper,RefundOrd |
|
|
|
* @Author: whl |
|
|
|
* @Date: 2023/10/13 10:46 |
|
|
|
*/ |
|
|
|
public void refundNotify(HttpServletRequest request) throws Exception { |
|
|
|
public void refundNotify(HttpServletRequest request,HttpServletResponse response) throws Exception { |
|
|
|
try { |
|
|
|
WxPayVo wxPayVo=new WxPayVo(0); |
|
|
|
//读取请求体的信息
|
|
|
|
ServletInputStream inputStream = request.getInputStream(); |
|
|
|
StringBuffer stringBuffer = new StringBuffer(); |
|
|
|
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); |
|
|
|
String s; |
|
|
|
//读取回调请求体
|
|
|
|
while ((s = bufferedReader.readLine()) != null) { |
|
|
|
stringBuffer.append(s); |
|
|
|
} |
|
|
|
String s1 = stringBuffer.toString(); |
|
|
|
log.info("退款回调"+s1); |
|
|
|
String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP); |
|
|
|
String nonce = request.getHeader(WECHAT_PAY_NONCE); |
|
|
|
String signType = request.getHeader("Wechatpay-Signature-Type"); |
|
|
|
String serialNo = request.getHeader(WECHAT_PAY_SERIAL); |
|
|
|
String signature = request.getHeader(WECHAT_PAY_SIGNATURE); |
|
|
|
String xmlMsg = HttpKit.readData(request); |
|
|
|
log.info("退款回调"+xmlMsg); |
|
|
|
request.setCharacterEncoding("UTF-8"); |
|
|
|
response.setCharacterEncoding("UTF-8"); |
|
|
|
response.setContentType("application/json;charset=utf-8"); |
|
|
|
String nonceStr = request.getHeader("Wechatpay-Nonce"); |
|
|
|
//微信传递过来的签名
|
|
|
|
String signature = request.getHeader("Wechatpay-Signature"); |
|
|
|
//证书序列号(微信平台)
|
|
|
|
String serialNo = request.getHeader("Wechatpay-Serial"); |
|
|
|
//时间戳
|
|
|
|
String timestamp = request.getHeader("Wechatpay-Timestamp"); |
|
|
|
// 如果已经初始化了 RSAAutoCertificateConfig,可直接使用
|
|
|
|
// 没有的话,则构造一个
|
|
|
|
// log.error(JSON.toJSONString(wxPayV3Bean));
|
|
|
@ -198,37 +192,96 @@ public class WxRefundService extends MybatisBaseService<WxRefundMapper,RefundOrd |
|
|
|
NotificationParser parser = new NotificationParser(config); |
|
|
|
RequestParam requestParam=new RequestParam.Builder() |
|
|
|
.serialNumber(serialNo) |
|
|
|
.nonce(nonce) |
|
|
|
.nonce(nonceStr) |
|
|
|
.signature(signature) |
|
|
|
.timestamp(timestamp) |
|
|
|
// 若未设置signType,默认值为 WECHATPAY2-SHA256-RSA2048
|
|
|
|
.signType(signType) |
|
|
|
.body(s1) |
|
|
|
.body(xmlMsg) |
|
|
|
.build(); |
|
|
|
RefundNotification parse = parser.parse(requestParam, RefundNotification.class); |
|
|
|
RefundOrder refundOrder=baseMapper.selectOne(new QueryWrapper<RefundOrder>().eq("outRefundNo",parse.getOutRefundNo())); |
|
|
|
System.out.println("退款回调结果: " + parse); |
|
|
|
RefundOrder refundOrder=baseMapper.selectOne(new QueryWrapper<RefundOrder>().eq("outTradeNo",parse.getOutTradeNo())); |
|
|
|
PayOrder payOrder=orderService.getOne(new QueryWrapper<PayOrder>().eq("sid",refundOrder.getOrderSid())); |
|
|
|
//parse.getRefundStatus().equals("SUCCESS");说明退款成功
|
|
|
|
RefundBusinessQuery query=new RefundBusinessQuery(); |
|
|
|
Map<String, Object> map = new HashMap<>(); |
|
|
|
if (parse.getRefundStatus().equals(Transaction.TradeStateEnum.SUCCESS)){ |
|
|
|
if (parse.getRefundStatus().toString().equals(Transaction.TradeStateEnum.SUCCESS.toString())){ |
|
|
|
//你的业务代码
|
|
|
|
map.put("mainSid",refundOrder.getOrderSid()); |
|
|
|
map.put("aBoolean",true); |
|
|
|
System.out.println("退款回调结果: " + parse); |
|
|
|
map.put("code",true); |
|
|
|
refundOrder.setState(2); |
|
|
|
baseMapper.updateById(refundOrder); |
|
|
|
payOrder.setState(6); |
|
|
|
orderService.updateById(payOrder); |
|
|
|
System.out.println(parse.getRefundStatus()); |
|
|
|
}else{ |
|
|
|
map.put("mainSid",refundOrder.getOrderSid()); |
|
|
|
map.put("aBoolean",false); |
|
|
|
System.out.println("退款回调结果: " + parse); |
|
|
|
map.put("code",false); |
|
|
|
refundOrder.setState(3); |
|
|
|
baseMapper.updateById(refundOrder); |
|
|
|
payOrder.setState(5); |
|
|
|
orderService.updateById(payOrder); |
|
|
|
System.out.println(parse.getRefundStatus()); |
|
|
|
} |
|
|
|
TrustEveryone.trustEveryone(); |
|
|
|
ResponseEntity<ResultBean> postForEntity = new RestTemplate().postForEntity(refundOrder.getReturnUrl(),map, ResultBean.class); |
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
e.printStackTrace(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// public void weixinRefundNotify(String body, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
|
|
|
// //获取报文
|
|
|
|
// //随机串
|
|
|
|
// String nonceStr = request.getHeader("Wechatpay-Nonce");
|
|
|
|
// //微信传递过来的签名
|
|
|
|
// String signature = request.getHeader("Wechatpay-Signature");
|
|
|
|
// //证书序列号(微信平台)
|
|
|
|
// String serialNo = request.getHeader("Wechatpay-Serial");
|
|
|
|
// //时间戳
|
|
|
|
// String timestamp = request.getHeader("Wechatpay-Timestamp");
|
|
|
|
// InputStream is = null;
|
|
|
|
// try {
|
|
|
|
// is = request.getInputStream();
|
|
|
|
// // 构造 RequestParam
|
|
|
|
// com.wechat.pay.java.core.notification.RequestParam requestParam = new com.wechat.pay.java.core.notification.RequestParam.Builder()
|
|
|
|
// .serialNumber(serialNo)
|
|
|
|
// .nonce(nonceStr)
|
|
|
|
// .signature(signature)
|
|
|
|
// .timestamp(timestamp)
|
|
|
|
// .body(body)
|
|
|
|
// .build();
|
|
|
|
// // 如果已经初始化了 RSAAutoCertificateConfig,可以直接使用 config
|
|
|
|
// // 初始化 NotificationParser
|
|
|
|
// // 验签、解密并转换成 Transaction
|
|
|
|
// RefundNotification refundNotification = notificationParser.parse(requestParam, RefundNotification.class);
|
|
|
|
// String orderNo = refundNotification.getOutTradeNo();
|
|
|
|
// //记录日志信息
|
|
|
|
// System.out.println("订单号:" + orderNo);
|
|
|
|
// if (SUCCESS.equals(refundNotification.getRefundStatus().SUCCESS)) {
|
|
|
|
// System.out.println("退款成功");
|
|
|
|
// //TODO------
|
|
|
|
// //根据自己的需求处理相应的业务逻辑,异步
|
|
|
|
// JSONObject jsonObject = JSONObject.parseObject(refundNotification.toString());
|
|
|
|
// System.out.println("微信退款回调信息:" + jsonObject);
|
|
|
|
// JSONObject resultJson = new JSONObject();
|
|
|
|
// resultJson.put("out_trade_no", jsonObject.getString("out_trade_no"));
|
|
|
|
// resultJson.put("refund_status", jsonObject.getString("refund_status"));
|
|
|
|
// //业务处理
|
|
|
|
// //通知微信回调成功
|
|
|
|
// response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>");
|
|
|
|
// } else {
|
|
|
|
// System.out.println("微信回调失败,JsapiPayController.payNotify.transaction:" + refundNotification.toString());
|
|
|
|
// //通知微信回调失败
|
|
|
|
// response.getWriter().write("<xml><return_code><![CDATA[FAIL]]></return_code></xml>");
|
|
|
|
// }
|
|
|
|
// } catch (Exception e) {
|
|
|
|
// e.printStackTrace();
|
|
|
|
// } finally {
|
|
|
|
// is.close();
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// //url 微信退款请求地址 data 请求参数
|
|
|
|