diff --git a/pom.xml b/pom.xml index 95047d9..620afd0 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,11 @@ org.springframework.cloud spring-cloud-starter-openfeign - + + com.github.wechatpay-apiv3 + wechatpay-java + 0.2.11 + junit diff --git a/src/main/java/com/yxt/pay/api/refund/Refund.java b/src/main/java/com/yxt/pay/api/refund/Refund.java new file mode 100644 index 0000000..6423c1e --- /dev/null +++ b/src/main/java/com/yxt/pay/api/refund/Refund.java @@ -0,0 +1,8 @@ +package com.yxt.pay.api.refund; + +/** + * @author wangpengfei + * @date 2024/3/25 15:03 + */ +public class Refund { +} diff --git a/src/main/java/com/yxt/pay/api/refund/RefundOrder.java b/src/main/java/com/yxt/pay/api/refund/RefundOrder.java new file mode 100644 index 0000000..500d62c --- /dev/null +++ b/src/main/java/com/yxt/pay/api/refund/RefundOrder.java @@ -0,0 +1,43 @@ +package com.yxt.pay.api.refund; + +import com.yxt.common.base.utils.StringRandom; +import com.yxt.common.core.domain.BaseEntity; +import lombok.Data; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @author wangpengfei + * @date 2024/3/28 9:47 + */ +@Data +public class RefundOrder extends BaseEntity { + private String outTradeNo;//订单编号 + private int source;//来源 0云菜窖 + private String name;//商品名 + private String amount;//金额 + private String openId;// + private String returnUrl;//业务回调 + private String orderSid;//支付订单sid + private String reason;//退款原因 + + + public String getTime() { + SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); + return format.format(new Date()); + } + + public RefundOrder(int source) { + String Randomstr = StringRandom.getRandomString(15); + if (source == 0) {//云菜窖 + outTradeNo = "YCJ" + getTime() + Randomstr; + + } else if (source == 1) { + + } else if (source == 2) { + + } + this.source = source; + } +} diff --git a/src/main/java/com/yxt/pay/api/refund/RefundOrderDto.java b/src/main/java/com/yxt/pay/api/refund/RefundOrderDto.java new file mode 100644 index 0000000..8fce446 --- /dev/null +++ b/src/main/java/com/yxt/pay/api/refund/RefundOrderDto.java @@ -0,0 +1,20 @@ +package com.yxt.pay.api.refund; + +import lombok.Data; + +/** + * @author wangpengfei + * @date 2024/3/28 9:57 + */ +@Data +public class RefundOrderDto { + private String outTradeNo;//订单编号 + private int source;//来源 0云菜窖 + private String name;//商品名 + private String amount;//金额 + private String openId;// + private String returnUrl;//业务回调 + private String orderSid;//支付订单sid + private String reason;//退款原因 + private String state;//1退款申请 2退款通过 +} diff --git a/src/main/java/com/yxt/pay/api/refund/RefundOrderVo.java b/src/main/java/com/yxt/pay/api/refund/RefundOrderVo.java new file mode 100644 index 0000000..2a645f5 --- /dev/null +++ b/src/main/java/com/yxt/pay/api/refund/RefundOrderVo.java @@ -0,0 +1,19 @@ +package com.yxt.pay.api.refund; + +import lombok.Data; + +/** + * @author wangpengfei + * @date 2024/3/28 9:57 + */ +@Data +public class RefundOrderVo { + private String outTradeNo;//订单编号 + private String source;//来源 0云菜窖 + private String name;//商品名 + private String amount;//金额 + private String openId;// + private String returnUrl;//业务回调 + private String orderSid;//支付订单sid + private String reason;//退款原因 +} diff --git a/src/main/java/com/yxt/pay/api/refund/WXRefundOrderReqVo.java b/src/main/java/com/yxt/pay/api/refund/WXRefundOrderReqVo.java new file mode 100644 index 0000000..3152833 --- /dev/null +++ b/src/main/java/com/yxt/pay/api/refund/WXRefundOrderReqVo.java @@ -0,0 +1,53 @@ +package com.yxt.pay.api.refund; + +import lombok.Data; + +/** + * @author wangpengfei + * @date 2024/3/25 15:49 + */ +@Data +public class WXRefundOrderReqVo { + /** + * 微信支付订单号,微信支付订单号和商家订单号二选一 + */ +// @Schema(description = "微信支付订单号") + private String transactionId; + + /** + * 商家订单号,对应 out_trade_no, + */ +// @Schema(description = "商家订单号") + private String orderId; + + /** + * 商户退款单号,对应out_refund_no + */ +// @Schema(description = "商户退款单号") + private String outRefundNo; + + /** + * 退款原因,选填 + */ +// @Schema(description = "退款原因") + private String reason; + + /** + * 回调地址 + */ +// @Schema(description = "回调地址") + private String notify; + + /** + * 退款金额 + */ +// @Schema(description = "退款金额") + private Integer refundMoney; + + /** + * 原订单金额,必填 + */ +// @Schema(description = "原订单金额") + private Integer totalMoney; + +} diff --git a/src/main/java/com/yxt/pay/api/refund/WXRefundOrderRespVo.java b/src/main/java/com/yxt/pay/api/refund/WXRefundOrderRespVo.java new file mode 100644 index 0000000..df6b167 --- /dev/null +++ b/src/main/java/com/yxt/pay/api/refund/WXRefundOrderRespVo.java @@ -0,0 +1,71 @@ +package com.yxt.pay.api.refund; + +import lombok.Data; + +/** + * @author wangpengfei + * @date 2024/3/25 15:51 + */ +@Data +public class WXRefundOrderRespVo { + /** + * 微信支付退款号 + */ +// @Schema(description = "微信支付退款号") + private String refundId; + + /** + * 商户退款单号 + */ +// @Schema(description = "商户退款单号") + private String outRefundNo; + + /** + * 微信支付订单号 + */ +// @Schema(description = "微信支付订单号") + private String transactionId; + + /** + * 商户订单号 + */ +// @Schema(description = "商户订单号") + private String outTradeNo; + + /** + * 退款渠道 + */ +// @Schema(description = "退款渠道") + private String channel; + + /** + * 退款入账账户 + */ +// @Schema(description = "退款入账账户") + private String userReceivedAccount; + + /** + * 退款成功时间 + */ +// @Schema(description = "退款成功时间") + private String successTime; + + /** + * 退款创建时间 + */ +// @Schema(description = "退款创建时间") + private String createTime; + + /** + * 退款状态 + */ +// @Schema(description = "退款状态") + private String status; + + /** + * 资金账户 + */ +// @Schema(description = "资金账户") + private String fundsAccount; + +} diff --git a/src/main/java/com/yxt/pay/biz/refund/WxRefundMapper.java b/src/main/java/com/yxt/pay/biz/refund/WxRefundMapper.java new file mode 100644 index 0000000..ced96bb --- /dev/null +++ b/src/main/java/com/yxt/pay/biz/refund/WxRefundMapper.java @@ -0,0 +1,13 @@ +package com.yxt.pay.biz.refund; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yxt.pay.api.refund.RefundOrder; +import org.apache.ibatis.annotations.Mapper; + +/** + * @author wangpengfei + * @date 2024/3/25 15:02 + */ +@Mapper +public interface WxRefundMapper extends BaseMapper { +} diff --git a/src/main/java/com/yxt/pay/biz/refund/WxRefundMapper.xml b/src/main/java/com/yxt/pay/biz/refund/WxRefundMapper.xml new file mode 100644 index 0000000..29fd460 --- /dev/null +++ b/src/main/java/com/yxt/pay/biz/refund/WxRefundMapper.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/yxt/pay/biz/refund/WxRefundRest.java b/src/main/java/com/yxt/pay/biz/refund/WxRefundRest.java new file mode 100644 index 0000000..f90cb3b --- /dev/null +++ b/src/main/java/com/yxt/pay/biz/refund/WxRefundRest.java @@ -0,0 +1,49 @@ +package com.yxt.pay.biz.refund; + +import com.yxt.common.core.domain.BaseEntity; +import com.yxt.common.core.result.ResultBean; +import com.yxt.pay.api.refund.RefundOrder; +import com.yxt.pay.api.refund.RefundOrderDto; +import com.yxt.pay.api.refund.WXRefundOrderReqVo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author wangpengfei + * @date 2024/3/25 15:02 + */ +@RestController +@RequestMapping("refund") +public class WxRefundRest { + @Autowired + WxRefundService refundService; + + + + @PostMapping("/createRefundOrder" ) + public ResultBean createRefundOrder(@RequestBody RefundOrderDto refundOrderDto) { + return refundService.createRefundOrder(refundOrderDto); + } + + + + @PostMapping("/reviewRefund" ) + public ResultBean reviewRefundById(@RequestParam String orderSid) throws Exception { + return refundService.refund(orderSid); + } + /** + * 微信退款回调 + * @return R + */ +// @Operation(summary = "微信退款回调" , description = "微信退款回调" ) +// @SysLog("微信退款回调" ) + @PostMapping("/payNotify") + public ResultBean refundPayNotify(HttpServletRequest request) throws Exception { + ResultBean rb=new ResultBean(); + refundService.refundNotify(request);//注意:回调接口需要暴露到公网上,且要放开token验证 + return rb.success(); + } + +} diff --git a/src/main/java/com/yxt/pay/biz/refund/WxRefundService.java b/src/main/java/com/yxt/pay/biz/refund/WxRefundService.java new file mode 100644 index 0000000..ed97fbc --- /dev/null +++ b/src/main/java/com/yxt/pay/biz/refund/WxRefundService.java @@ -0,0 +1,365 @@ +package com.yxt.pay.biz.refund; +import cn.hutool.core.bean.BeanUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.RSAAutoCertificateConfig; +import com.wechat.pay.java.core.exception.ServiceException; +import com.wechat.pay.java.core.notification.NotificationConfig; +import com.wechat.pay.java.core.notification.NotificationParser; +import com.wechat.pay.java.core.notification.RequestParam; +import com.wechat.pay.java.service.partnerpayments.app.model.Transaction; +import com.wechat.pay.java.service.refund.RefundService; +import com.wechat.pay.java.service.refund.model.*; +import com.yxt.common.base.service.MybatisBaseService; +import com.yxt.common.core.result.ResultBean; +import com.yxt.pay.api.order.PayOrder; +import com.yxt.pay.api.refund.RefundOrder; +import com.yxt.pay.api.refund.RefundOrderDto; +import com.yxt.pay.api.refund.WXRefundOrderReqVo; +import com.yxt.pay.api.refund.WXRefundOrderRespVo; +import com.yxt.pay.api.wxpay.WxPayVo; +import com.yxt.pay.biz.order.OrderService; +import com.yxt.pay.utils.UrlComponent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.HashMap; +import java.util.Map; + +import static com.wechat.pay.java.core.http.Constant.*; + +/** + * @author wangpengfei + * @date 2024/3/25 15:02 + */ +@Service +@Slf4j +public class WxRefundService extends MybatisBaseService { + + @Autowired + private UrlComponent urlComponent; + @Autowired + private OrderService orderService; + @Value("${wx.api-key}") + String apiKey; + @Value("${wx.mch-serial-no}") + String mchSerialNo; + @Value("${wx.key-path}") + String keyPath; + @Value("${wx.mch-id}") + String mchId; + + public static int source; + + + + public ResultBean createRefundOrder(RefundOrderDto refundOrderDto){ + ResultBean rb=new ResultBean(); + RefundOrder refundOrder=new RefundOrder(refundOrderDto.getSource()); + BeanUtil.copyProperties(refundOrderDto,refundOrder,"id","sid"); + baseMapper.insert(refundOrder); + return rb.success().setData(refundOrder); + + } + /** + * 功能描述: + * 〈微信退款〉 + * @Param: [req] + * @Return: [void] + * @Author: whl + * @Date: 2023/10/12 15:46 + */ + public ResultBean refund(String orderSid) throws Exception { + ResultBean rb = ResultBean.fireFail(); + try { + PayOrder payOrder=orderService.getOne(new QueryWrapper().eq("sid",orderSid)); + WxPayVo wxPayVo=new WxPayVo(payOrder.getSource()); + source=payOrder.getSource(); + // 使用自动更新平台证书的RSA配置 + // 一个商户号只能初始化一个配置,否则会因为重复的下载任务报错 + Config config = + new RSAAutoCertificateConfig.Builder() + .merchantId(mchId) + //使用 SDK 不需要计算请求签名和验证应答签名 + // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名 + .privateKeyFromPath(keyPath) + .merchantSerialNumber(mchSerialNo) + .apiV3Key(apiKey) + .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().eq("sid",orderSid)); + RefundOrder refundOrder=baseMapper.selectOne(new QueryWrapper().eq("orderSid",payOrder.getSid())); + //退款金额 + amountReq.setRefund(Long.valueOf(payOrder.getTotalTee())); +// amountReq.setRefund(Long.valueOf("1")); + //原订单金额 + amountReq.setTotal(Long.valueOf(payOrder.getTotalTee())); +// amountReq.setTotal(Long.valueOf("1")); + //货币类型(默认人民币) + amountReq.setCurrency("CNY"); + request.setAmount(amountReq); + //商户退款单号 + request.setOutRefundNo(String.valueOf(payOrder.getOutTradeNo())); +// request.setOutRefundNo(String.valueOf("ceshi")); + request.setOutTradeNo(refundOrder.getOutTradeNo()); +// request.setOutTradeNo("ceshi"); + request.setReason(refundOrder.getReason()); +// request.setReason("ceshi"); + //退款通知回调地址 +// request.setNotifyUrl(wxPayV3Bean.getRefundNotifyUrl()); + request.setNotifyUrl(urlComponent.getDoMainUrl() + "order/payNotify"); + // 调用退款方法,得到应答 + // 调用微信sdk接口 + Refund refund = service.create(request); + //接收退款返回参数 + Refund refundResponse = new Refund(); + refundResponse.setStatus(refund.getStatus()); + System.out.println(refund);; + if (refundResponse.getStatus().equals(Status.SUCCESS)){ + //说明退款成功,开始接下来的业务操作 +// WXRefundOrderRespVo refundOrderRespVO = new WXRefundOrderRespVo(); + //你的业务代码 + return rb.success().setData(refund); + }else{ + + return rb.setMsg("申请退款失败").setData(refund); + } + }catch (Exception e){ + e.printStackTrace(); + return rb.setMsg("退款失败,error=" + e.getMessage()); +// throw new ResultException(ResultEnum.ERROR,e.toString()); + } + } + + /** + * 功能描述: + * 〈微信退款回调〉 + * @Param: [request, response] + * @Return: [void] + * @Author: whl + * @Date: 2023/10/13 10:46 + */ + public void refundNotify(HttpServletRequest request) 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(); + 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); + // 如果已经初始化了 RSAAutoCertificateConfig,可直接使用 + // 没有的话,则构造一个 +// log.error(JSON.toJSONString(wxPayV3Bean)); + NotificationConfig config = new RSAAutoCertificateConfig.Builder() + .merchantId(mchId) + .privateKeyFromPath(keyPath) + .merchantSerialNumber(mchSerialNo) + .apiV3Key(apiKey) + .build(); + // 初始化 NotificationParser + NotificationParser parser = new NotificationParser(config); + RequestParam requestParam=new RequestParam.Builder() + .serialNumber(serialNo) + .nonce(nonce) + .signature(signature) + .timestamp(timestamp) + // 若未设置signType,默认值为 WECHATPAY2-SHA256-RSA2048 + .signType(signType) + .body(s1) + .build(); + RefundNotification parse = parser.parse(requestParam, RefundNotification.class); + System.out.println("退款回调结果: " + parse); + //parse.getRefundStatus().equals("SUCCESS");说明退款成功 + if (parse.getRefundStatus().equals(Transaction.TradeStateEnum.SUCCESS)){ + //你的业务代码 + + }else{ + + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + + + +// //url 微信退款请求地址 data 请求参数 +// public static String doRefund(String url, String data) throws Exception { +// +// KeyStore keyStore = KeyStore.getInstance("PKCS12"); +// // 指定证书路径 +// String path = "/cert/apiclient_cert.p12"; +// ClassPathResource classPathResource = new ClassPathResource(path); +// +// //读取项目存放的PKCS12证书文件 +// InputStream stream = classPathResource.getInputStream(); +// String mchId = "自己的商户id"; +// try { +// //指定PKCS12的初始密码为商户ID +// keyStore.load(stream, mchId.toCharArray()); +// } finally { +// stream.close(); +// } +// SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchId.toCharArray()).build(); +// //指定TLS版本 +// SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext,new String[] { "TLSv1"},null,SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); +// //设置httpclient的SSLSocketFactory +// CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); +// try { +// HttpPost httpost = new HttpPost(url); // 设置响应头信息 +// httpost.addHeader("Connection", "keep-alive"); +// httpost.addHeader("Accept", "*/*"); +// httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); +// httpost.addHeader("Host", "api.mch.weixin.qq.com"); +// httpost.addHeader("X-Requested-With", "XMLHttpRequest"); +// httpost.addHeader("Cache-Control", "max-age=0"); +// httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) "); +// httpost.setEntity(new StringEntity(data, "UTF-8")); +// CloseableHttpResponse response = httpclient.execute(httpost); +// try { +// HttpEntity entity = response.getEntity(); +// String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8"); +// EntityUtils.consume(entity); +// return jsonStr; +// } finally { +// response.close(); +// } +// } finally { +// httpclient.close(); +// } +// } +// /** +// * 退款 +// * @param orderPrice 订单金额(分) +// * @param refundPrice 退款金额(分) +// * @param refundMark 退款备注 +// * @param out_trade_no 退款商家订单号 +// * @return +// * @throws Exception +// */ +// public static String refund(Integer orderPrice,Integer refundPrice,String refundMark,String out_trade_no) throws Exception { +// Map params = new HashMap<>(); +// +// String outRefundNo = GenerateNum.getInstance().GenerateOrder();//可以自定义一个类来随机生成退款单号等等 +// +// params.put("appid", "小程序Appid"); +// params.put("mch_id", "商户号"); +// //商户订单号 +// params.put("out_trade_no", out_trade_no); +// //商户退款单号 +// params.put("out_refund_no", outRefundNo); +// //总金额 +// params.put("total_fee", String.valueOf(orderPrice)); +// //退款金额 +// params.put("refund_fee", String.valueOf(refundPrice)); +// //退款原因 +// params.put("refund_desc", refundMark); +// //退款结果回调地址 +// params.put("notify_url", "回调域名"); +// //随机字符串 +// params.put("nonce_str", WXPayUtil.generateNonceStr());//使用微信随机字符串生成 +// //生成sign +// String sign = WXPayUtil.generateSignature(params, "自己的商户密钥"); +// params.put("sign", sign); +// //微信申请退款接口 +// String wx_refund_url = "https://api.mch.weixin.qq.com/secapi/pay/refund"; +// +// String xmlStr = WXPayUtil.mapToXml(params);//转换成xml格式 +// System.out.println(xmlStr); +// //发送双向证书请求给微信 +// String resultXmlStr = doRefund(wx_refund_url, xmlStr); +// System.out.println(resultXmlStr); +// // 将返回的字符串转成Map集合 +// Map resultMap = WXPayUtil.xmlToMap(resultXmlStr);//转成map格式 +// +// Map map = new HashMap<>(); +// if ("SUCCESS".equalsIgnoreCase(resultMap.get("result_code"))) { +// System.out.println("------申请退款成功,正在退款中----"); +// //申请微信退款接口返回success,但是退款到账还需要时间; +// map.put("success", "REFUNDS"); +// return "1"; +// } else { +// map.put("success", resultMap.get("err_code_des")); +// System.out.println("-------------退款失败-------------------" + resultMap.get("err_code_des")); +// return "2"; +// } +// } +// /* +// * 退款订单结果查询 +// * 生成签名的xml +// * @return +// * */ +// public static String selRefundOrder(String out_trade_no) { +// // 封装需要的信息 +// Map payMap = new HashMap(); +// String nonceStr = WXPayUtil.generateNonceStr(); +// try { +// // 1. 拼接下单地址参数 +// Map param = new HashMap(); +// param.put("appid", "小程序appid"); +// param.put("mch_id", "商户id"); +// param.put("out_trade_no", out_trade_no); // 随机字符串 +// param.put("nonce_str", nonceStr); // 账单类型 +// param.put("sign_type", "MD5"); // 签名类型 +// // 生成签名,官方默认MD5+商户秘钥+参数信息 +// String sign = WXPayUtil.generateSignature(param, "商户密钥"); +// param.put("sign", sign); +// // 将所有参数转换为xml形式 +// String xmlParam = WXPayUtil.mapToXml(param); +// +// // 2. 发送请求 +// HttpClient1 httpClient1 = new HttpClient1("https://api.mch.weixin.qq.com/pay/refundquery"); +// httpClient1.setHttps(true);// https协议 +// httpClient1.setXmlParam(xmlParam); +// httpClient1.post(); +// // 获取结果 +// String xmlResult = httpClient1.getContent(); +// System.out.println(xmlResult); +// if (xmlResult.indexOf("SUCCESS") != -1) { // 只要执行了下单接口,都会包含SUCCESS的 +// Map map = WXPayUtil.xmlToMap(xmlResult); +// if (map.get("refund_fee").equals(map.get("total_fee"))){ +// System.out.println(out_trade_no+"退款"+map.get("refund_fee")+"成功到"+map.get("refund_recv_accout_0")); +// return "1"; +// }else { +// System.out.println(out_trade_no+"退款"+map.get("refund_fee")+"部分到"+map.get("refund_recv_accout_0")); +// return "2"; +// } +// +// }else { +// System.out.println(out_trade_no+"退款失败,不存在"); +// return "3"; +// } +// +// } catch (Exception e) { +// e.printStackTrace(); +// payMap.put("msg", out_trade_no+"签名生成错误"); +// return "签名失败"; +// } +// } + +} diff --git a/src/main/resources/cert/apiclient_cert.p12 b/src/main/resources/cert/apiclient_cert.p12 new file mode 100644 index 0000000..9af0641 Binary files /dev/null and b/src/main/resources/cert/apiclient_cert.p12 differ diff --git a/src/main/resources/cert/apiclient_cert.pem b/src/main/resources/cert/apiclient_cert.pem new file mode 100644 index 0000000..c6fc7ee --- /dev/null +++ b/src/main/resources/cert/apiclient_cert.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIUdOW9WmRaHsToJigg4eKlKS20i50wDQYJKoZIhvcNAQEL +BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT +FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg +Q0EwHhcNMjQwMzI2MDI1OTA0WhcNMjkwMzI1MDI1OTA0WjCBijETMBEGA1UEAwwK +MTY2NDg4Mjc2NTEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMTYwNAYDVQQL +DC3lrofkv6HpgJrliJvmlrDmioDmnK/vvIjmsrPljJfvvInmnInpmZDlhazlj7gx +CzAJBgNVBAYTAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANVl55NDuqDEvx/zQdaCn4WKUC8wLUVEYWKLMlChSZer +VQuQpRlC2lKDW03hKB6cAYH+jQg/pmBQnWbIjiBggyA41EUrCY2ps+CWI77fIAVk +wPxKz1/gk4xoYKbKvnDsSW6A0yWBvma4ZVLt3O2JTEPVo9xaM6/+oWCs4An654rx +ZBwnxb7mzVCXWJeTldWLtjwjby0Y6fvR7wrj2QhSPocz171bQhi1fF8JuQPWyIp/ +XkRRbVWjVIsEv/re80mhTH16ktJf6MhCtEM5l15+GWP8rjIDP2qqhn1m0nIRPTVy +Ut9SZS/bBCm9/Cywtw+C238mvjmItEH+uhK66L6PLzkCAwEAAaOBuTCBtjAJBgNV +HRMEAjAAMAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGHhoGEaHR0 +cDovL2V2Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0MjIw +RTUwREJDMDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0NzFCNjU0 +MjJFMTJCMjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3DQEBCwUA +A4IBAQAgxASDSwdZ8aIVMKha7LJQu3UTGtseO+q8VvfQMmBCN+eB20b+NOLHvfTi +ijEl+x7UBFk7kCbKWPlxL6Osqe8npIxWbLolZfqxi1d+UzokmpkjXYyKtsZnWDPZ +B6Y1Bc/J7khma7GzuEa/d29Z+si+eeiyNHdZUwZUZi/PFwO61KbGP2r11AuXa6W5 +ZYgQBw5sSfOxceoYBCIKTUO79hAOisSuGxP7yFqSalGYd85XG6t5UH5p224VHxVs +Dm+BoD1+w2jtBcAcdwrc3FGvR1mac1pd/LwMSYwfmDTHACWvCV88uN9TNvfbelHy +9f+Y8m563NzVPeWCD2sMqOJs6Ug5 +-----END CERTIFICATE----- diff --git a/src/main/resources/cert/apiclient_key.pem b/src/main/resources/cert/apiclient_key.pem new file mode 100644 index 0000000..dc97089 --- /dev/null +++ b/src/main/resources/cert/apiclient_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDVZeeTQ7qgxL8f +80HWgp+FilAvMC1FRGFiizJQoUmXq1ULkKUZQtpSg1tN4SgenAGB/o0IP6ZgUJ1m +yI4gYIMgONRFKwmNqbPgliO+3yAFZMD8Ss9f4JOMaGCmyr5w7ElugNMlgb5muGVS +7dztiUxD1aPcWjOv/qFgrOAJ+ueK8WQcJ8W+5s1Ql1iXk5XVi7Y8I28tGOn70e8K +49kIUj6HM9e9W0IYtXxfCbkD1siKf15EUW1Vo1SLBL/63vNJoUx9epLSX+jIQrRD +OZdefhlj/K4yAz9qqoZ9ZtJyET01clLfUmUv2wQpvfwssLcPgtt/Jr45iLRB/roS +uui+jy85AgMBAAECggEAaL85mY6wSAPrMNqt4YaCmQEYdOE4B30WNFHRI8TXo8wk +1aVtdOXc1o3FvoebstKu5sk1HuxnVXWcnXwqT3gwRRvADiee69t2APKRnzpUtHEN +TYnHGu/YXR5K+vQf4LwLG2O+wPVbqX4vtjIttKclOVLfuOTJ5ESfoB2bZyqyhv8p +//odyC6+ryOs7+PbcDjChTjHkANT2y0JsQhkjgw9WmqjyrNH3BNAZ8djV4ilSJhz +XYiM+bkjwHEHwbQUJxhCUC0hKNNpxfxRC90J4ZNSJchqQdxG/zmn8Mw1rh239ydt +XXrs7Zeayx7mcr9UBBAjDDYBv+HAiHmieiNueg9wFQKBgQD92x1cOLzBD7YiGfvp +jmKsGZfAYmQQXCsP5thinPG95v5hR5LNoB6lZf27GhpdukKG58vsmJBW5iawF4ex +7SRBHWLEnTlP7SRpuycK0vrGzXkP5ohyR60bw5Sn5DYXokttiPxNYH6trFscGXb+ +CiMJmz/Y04a/QG5loO3viERPVwKBgQDXM0/vWdWLEIxRDMAEa3qaV2yJeHg6MIsh +ltyZ8sJ2Pk9XJIwnKBHPeedqghVhgCyz6q7xpu0dcoj1OyBk6obqwpfe1xM06qK6 +Omr64qSpJ2iNjpnWqpSiCcHxrxHHESOxTwtjZg57YI6TcVB5+Y40vcx51uMyOZgz +X3137Ear7wKBgGU9strpwdWZR4EYLdB6ub17Q3s1gkTIDWB9J0VE5GBhNIhlfBXH +yxEZuPSat3Mz6n5VCY4lVkNh7IIEEFkUg4X4i0Bwl7/ZitEkE7EMbXlFzwdZYId7 +MH3HJY1DxZLtZfmcTUsqtbrb50YwnbU5I7ocEX2O9sllj+G2Kc6C4QNnAoGBAIjl +MWJXSUqPmlMswzGMlY99MaQ5qHGL09XoPCkKjr3dYWdT7nwyNzI+oAHXAnblrIo/ +Lk63G3tyEsG9fRv1PSI165psQuGUqTPCWa+DYa/hS9dQ8XfnR2nUvzVZYvu5YXU3 +jU0L7QZ7I/eTS9hr8hSG8H5JPnoCvVlg01XoTgStAoGAIw+E7j74n8LTx8xp7O38 +QkUQhDs1ajOR3+Ct9VlhIgJ4khVADP550NLruPRO/E//gOWbOpqHNRkAXTJfJ04C +FHCxrhdv6nqaKH86AzazVaE9UH8nPtmoiiit1jLBXanqxZyOglog2PRcUReVfjzQ +uKWacPtR4jyQwZVIWdEbddg= +-----END PRIVATE KEY-----