退款
This commit is contained in:
@@ -4,6 +4,7 @@ import com.yxt.common.base.utils.StringRandom;
|
||||
import com.yxt.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
@@ -17,7 +18,7 @@ public class RefundOrder extends BaseEntity {
|
||||
private String outRefundNo;//订单编号
|
||||
private int source;//来源 0云菜窖
|
||||
private String name;//商品名
|
||||
private String amount;//金额
|
||||
private BigDecimal amount;//金额
|
||||
private String openId;//
|
||||
private String returnUrl;//业务回调
|
||||
private String orderSid;//支付订单sid
|
||||
@@ -31,7 +32,7 @@ public class RefundOrder extends BaseEntity {
|
||||
public RefundOrder(int source) {
|
||||
String Randomstr = StringRandom.getRandomString(15);
|
||||
if (source == 0) {//云菜窖
|
||||
outTradeNo = "YCJ" + getTime() + Randomstr;
|
||||
outRefundNo = "YCJ" + getTime() + Randomstr;
|
||||
|
||||
} else if (source == 1) {
|
||||
|
||||
|
||||
@@ -151,6 +151,7 @@ public class OrderService extends MybatisBaseService<OrderMapper, PayOrder> {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("mainSid", payOrder.getSid());
|
||||
map.put("payTime", date);
|
||||
TrustEveryone.trustEveryone();
|
||||
ResponseEntity<ResultBean> postForEntity = new RestTemplate().postForEntity(payOrder.getPayUrl(), map, ResultBean.class);
|
||||
return rb.success().setData(resultObj);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @author wangpengfei
|
||||
@@ -39,10 +40,10 @@ public class WxRefundRest {
|
||||
*/
|
||||
// @Operation(summary = "微信退款回调" , description = "微信退款回调" )
|
||||
// @SysLog("微信退款回调" )
|
||||
@PostMapping("/payNotify")
|
||||
public ResultBean refundPayNotify(HttpServletRequest request) throws Exception {
|
||||
@PostMapping("/refundNotify")
|
||||
public ResultBean refundPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
ResultBean rb=new ResultBean();
|
||||
refundService.refundNotify(request);//注意:回调接口需要暴露到公网上,且要放开token验证
|
||||
refundService.refundNotify(request,response);//注意:回调接口需要暴露到公网上,且要放开token验证
|
||||
return rb.success();
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
try {
|
||||
PayOrder payOrder=orderService.getOne(new QueryWrapper<PayOrder>().eq("sid",orderSid));
|
||||
WxPayVo wxPayVo=new WxPayVo(payOrder.getSource());
|
||||
RefundOrder refundOrder=baseMapper.selectOne(new QueryWrapper<RefundOrder>().eq("orderSid",payOrder.getSid()).eq("state","1"));
|
||||
try {
|
||||
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 请求参数
|
||||
|
||||
39
src/main/java/com/yxt/pay/utils/TrustEveryone.java
Normal file
39
src/main/java/com/yxt/pay/utils/TrustEveryone.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package com.yxt.pay.utils;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
/**
|
||||
* @author wangpengfei
|
||||
* @date 2024/12/16 15:27
|
||||
*/
|
||||
public class TrustEveryone {
|
||||
public static void trustEveryone() {
|
||||
|
||||
try {
|
||||
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
SSLContext context = SSLContext.getInstance("TLS");
|
||||
context.init(null, new X509TrustManager[]{new X509TrustManager() {
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||
}
|
||||
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||
}
|
||||
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
}}, new SecureRandom());
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user