支付功能(未实现)

This commit is contained in:
Cool 2024-09-03 00:34:51 +08:00
parent 7976fc79d3
commit 520d91f382
13 changed files with 588 additions and 145 deletions

20
pom.xml
View File

@ -15,6 +15,7 @@
<description>wxapp-server</description>
<properties>
<java.version>1.8</java.version>
<commons.lang>2.6</commons.lang>
</properties>
<dependencies>
<dependency>
@ -25,6 +26,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
@ -56,13 +62,17 @@
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<!-- 微信支付API -->
<!--微信支付-->
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.4.8</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons.lang}</version>
</dependency>
</dependencies>
<build>

View File

@ -1,54 +0,0 @@
package com.bigdata.wxappserver.config;
import com.github.wxpay.sdk.WXPayConfig;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
/**
* Created with IntelliJ IDEA.
*
* @Author: Cool
* @Date: 2024/08/31/20:53
* @Description:
*/
public class WxPayConfig implements WXPayConfig {
private byte[] certData;
public void MyConfig() throws Exception {
//此处暂时用不到这里是读取证书的地方
}
@Override
public String getAppID() {
return "wx865aefa5a7115ae0";
}
@Override
public String getMchID() {
//申请普通商户时分配给你的商户号
return "这里是你的商户号";
}
@Override
public String getKey() {
//这里的key 就是你在支付平台设置的API密钥
return "这是就是你的Key了";
}
@Override
public InputStream getCertStream() {
ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
return certBis;
}
@Override
public int getHttpConnectTimeoutMs() {
return 8000;
}
@Override
public int getHttpReadTimeoutMs() {
return 10000;
}
}

View File

@ -2,12 +2,10 @@ package com.bigdata.wxappserver.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bigdata.wxappserver.result.Result;
import com.bigdata.wxappserver.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
/**
* Created with IntelliJ IDEA.
@ -43,4 +41,15 @@ public class OrderController {
return orderService.delete(id);
}
/**
* 订单支付
*
* @param
* @return
*/
@PutMapping("/payment")
public Result payment(@RequestBody JSONObject jsonObject) throws Exception {
return orderService.payment(jsonObject);
}
}

View File

@ -1,73 +0,0 @@
package com.bigdata.wxappserver.controller;
import com.bigdata.wxappserver.config.WxPayConfig;
import com.github.wxpay.sdk.WXPay;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("pay")
public class PayController {
@RequestMapping("payment")
public Object getPayment(HttpServletRequest request, @RequestParam("totalFee") String totalFee, String tradeno) throws Exception {
// 获取到当前登录用户因为这里我保存了openid , 方法大家可以自己处理这里就不展示了
// User user = User.getCurrentUserInfo().getUser();
//当前就是我们自己配置的支付配置appid 商户号 key 什么的
WxPayConfig config = new WxPayConfig();
//当前类是官方为我们封装的一些使用的方法
WXPay wxpay = new WXPay(config);
//获取到 IP
String clientIp = getIpAddress(request);
System.err.println(clientIp);
//封装请求参数 参数说明看API文档当前就不进行讲解了
Map<String, String> data = new HashMap<>();
data.put("body", "腾讯充值中心-QQ会员充值");
data.put("out_trade_no", "2016090910595900000012");
data.put("device_info", "12345679"); //此处设备或商品编号
data.put("fee_type", "CNY"); // 货币类型 人民币
// 支付中没有小数点起步以分做为单们当前为1 分钱所以自行调整金额 这里可以做为传参
//选取商品金额传到后端来
data.put("total_fee", "1");
data.put("spbill_create_ip", "123.12.12.123");
data.put("notify_url", "http://www.example.com/wxpay/notify");
data.put("trade_type", "JSAPI"); // 此处指定JSAPI
data.put("product_id", "12");
data.put("openid", "这是是登录获取到的openId 必传");
//调用统一下单方法
Map<String, String> order = wxpay.unifiedOrder(data);
//获取到需要的参数返回小程序
return order;
}
// 获取 IP
public static String getIpAddress(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}

View File

@ -0,0 +1,118 @@
package com.bigdata.wxappserver.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bigdata.wxappserver.properties.WeChatProperties;
import com.bigdata.wxappserver.service.OrderService;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
/**
* 支付回调相关接口
*/
@RestController
@RequestMapping("/notify")
@Slf4j
public class PayNotifyController {
@Autowired
private OrderService orderService;
@Autowired
private WeChatProperties weChatProperties;
/**
* 支付成功回调
*
* @param request
*/
@RequestMapping("/paySuccess")
public void paySuccessNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
//读取数据
String body = readData(request);
log.info("支付成功回调:{}", body);
//数据解密
String plainText = decryptData(body);
log.info("解密后的文本:{}", plainText);
JSONObject jsonObject = JSON.parseObject(plainText);
String outTradeNo = jsonObject.getString("out_trade_no");//商户平台订单号
String transactionId = jsonObject.getString("transaction_id");//微信支付交易号
log.info("商户平台订单号:{}", outTradeNo);
log.info("微信支付交易号:{}", transactionId);
//业务处理修改订单状态来单提醒
orderService.paySuccess(outTradeNo);
//给微信响应
responseToWeixin(response);
}
/**
* 读取数据
*
* @param request
* @return
* @throws Exception
*/
private String readData(HttpServletRequest request) throws Exception {
BufferedReader reader = request.getReader();
StringBuilder result = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
if (result.length() > 0) {
result.append("\n");
}
result.append(line);
}
return result.toString();
}
/**
* 数据解密
*
* @param body
* @return
* @throws Exception
*/
private String decryptData(String body) throws Exception {
JSONObject resultObject = JSON.parseObject(body);
JSONObject resource = resultObject.getJSONObject("resource");
String ciphertext = resource.getString("ciphertext");
String nonce = resource.getString("nonce");
String associatedData = resource.getString("associated_data");
AesUtil aesUtil = new AesUtil(weChatProperties.getApiV3Key().getBytes(StandardCharsets.UTF_8));
//密文解密
String plainText = aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),
nonce.getBytes(StandardCharsets.UTF_8),
ciphertext);
return plainText;
}
/**
* 给微信响应
*
* @param response
*/
private void responseToWeixin(HttpServletResponse response) throws Exception {
response.setStatus(200);
HashMap<Object, Object> map = new HashMap<>();
map.put("code", "SUCCESS");
map.put("message", "SUCCESS");
response.setHeader("Content-type", ContentType.APPLICATION_JSON.toString());
response.getOutputStream().write(JSON.toJSONString(map).getBytes(StandardCharsets.UTF_8));
response.flushBuffer();
}
}

View File

@ -0,0 +1,22 @@
package com.bigdata.wxappserver.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "dx.wechat")
@Data
public class WeChatProperties {
private String appid; //小程序的appid
private String secret; //小程序的秘钥
private String mchid; //商户号
private String mchSerialNo; //商户API证书的证书序列号
private String privateKeyFilePath; //商户私钥文件
private String apiV3Key; //证书解密的密钥
private String weChatPayCertFilePath; //平台证书
private String notifyUrl; //支付成功的回调地址
private String refundNotifyUrl; //退款成功的回调地址
}

View File

@ -0,0 +1,22 @@
package com.bigdata.wxappserver.result;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
* 封装分页查询结果
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResult implements Serializable {
private long total; //总记录数
private List records; //当前页数据集合
}

View File

@ -0,0 +1,38 @@
package com.bigdata.wxappserver.result;
import lombok.Data;
import java.io.Serializable;
/**
* 后端统一返回结果
* @param <T>
*/
@Data
public class Result<T> implements Serializable {
private Integer code; //编码1成功0和其它数字为失败
private String msg; //错误信息
private T data; //数据
public static <T> Result<T> success() {
Result<T> result = new Result<T>();
result.code = 1;
return result;
}
public static <T> Result<T> success(T object) {
Result<T> result = new Result<T>();
result.data = object;
result.code = 1;
return result;
}
public static <T> Result<T> error(String msg) {
Result result = new Result();
result.msg = msg;
result.code = 0;
return result;
}
}

View File

@ -9,6 +9,8 @@ import com.bigdata.wxappserver.entity.Order;
import com.bigdata.wxappserver.entity.User;
import com.bigdata.wxappserver.enums.OrderStatusEnum;
import com.bigdata.wxappserver.mapper.OrderMapper;
import com.bigdata.wxappserver.result.Result;
import com.bigdata.wxappserver.utils.WeChatPayUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -16,6 +18,8 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
@ -28,12 +32,14 @@ import java.util.stream.Collectors;
*/
@Service
public class OrderService extends ServiceImpl<OrderMapper, Order> {
@Autowired
private WeChatPayUtil weChatPayUtil;
@Autowired
UserService userService;
@Autowired
GoodsService goodsService;
@Transactional(rollbackFor = Exception.class)
public JSONObject addOrUpdate(JSONObject jsonObject) {
Order order = jsonObject.toJavaObject(Order.class);
@ -50,14 +56,16 @@ public class OrderService extends ServiceImpl<OrderMapper, Order> {
}
public JSONObject list(JSONObject jsonObject) {
Integer userId = jsonObject.getInteger("userId");
String openId = jsonObject.getString("openId");
List<User> userList = userService.list();
User user = userList.stream().filter(e -> Objects.equals(e.getOpenId(), openId)).findFirst().orElse(null);
Integer status = jsonObject.getInteger("status");
// Integer currentPage = jsonObject.getInteger("currentPage");
// Integer pageSize = jsonObject.getInteger("pageSize");
// IPage<Order> page = new Page<>(currentPage, pageSize);
LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(userId != null, Order::getUserId, userId)
.eq(status!=null,Order::getStatus,status);
wrapper.eq(user != null, Order::getUserId, user.getId())
.eq(status != null, Order::getStatus, status);
// IPage<Order> orderIPage = page(page, wrapper);
List<Order> list = list(wrapper);
List<OrderDto> orderDtoList = dealList(list);
@ -71,15 +79,15 @@ public class OrderService extends ServiceImpl<OrderMapper, Order> {
return new ArrayList<>();
}
List<Goods> goodsList = goodsService.listByIds(records.stream().map(Order::getGoodsId).collect(Collectors.toSet()));
Set<Goods> goodsSet =new HashSet<>(goodsList);
List<OrderDto> list =new ArrayList<>();
Set<Goods> goodsSet = new HashSet<>(goodsList);
List<OrderDto> list = new ArrayList<>();
for (Order record : records) {
OrderDto orderDto=new OrderDto();
OrderDto orderDto = new OrderDto();
record.setStatusDescription(OrderStatusEnum.describe(record.getStatus()));
BeanUtils.copyProperties(record,orderDto);
BeanUtils.copyProperties(record, orderDto);
Goods goods = goodsSet.stream().filter(item -> Objects.equals(item.getId(), record.getGoodsId()))
.findFirst().orElse(null);
if(goods!=null){
if (goods != null) {
orderDto.setGoodDetail(goods.getGoodDetail());
orderDto.setGoodPrice(goods.getGoodPrice());
orderDto.setGoodImage(goods.getGoodImage());
@ -114,4 +122,48 @@ public class OrderService extends ServiceImpl<OrderMapper, Order> {
}
}
public void paySuccess(String outTradeNo) {
List<Order> list = list();
Order order = list.stream().filter(e -> Objects.equals(String.valueOf(e.getId()), outTradeNo)).findFirst().orElse(null);
if (order != null) {
order.setStatus(2);
}
saveOrUpdate(order);
}
/**
* 订单支付
*
* @param ordersPaymentDTO
* @return
*/
public Result payment(JSONObject ordersPaymentDTO) throws Exception {
// 当前登录用户id
String openId = ordersPaymentDTO.getString("openId");
String orderCode = ordersPaymentDTO.getString("orderCode");
List<User> userList = userService.list();
User user = userList.stream().filter(e -> Objects.equals(e.getOpenId(), openId)).findFirst().orElse(null);
if (user == null) {
return Result.error("查询不到该用户");
}
//调用微信支付接口生成预支付交易单
JSONObject jsonObject = weChatPayUtil.pay(
orderCode, //商户订单号
new BigDecimal(0.01), //支付金额单位
"Test123", //商品描述
user.getOpenId() //微信用户的openid
);
if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) {
return Result.error("该订单已支付");
}
// OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class);
// vo.setPackageStr(jsonObject.getString("package"));
//
// return vo;
return Result.success();
}
}

View File

@ -0,0 +1,235 @@
package com.bigdata.wxappserver.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bigdata.wxappserver.properties.WeChatProperties;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.math.BigDecimal;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
/**
* 微信支付工具类
*/
@Component
public class WeChatPayUtil {
//微信支付下单接口地址
public static final String JSAPI = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
//申请退款接口地址
public static final String REFUNDS = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
@Autowired
private WeChatProperties weChatProperties;
/**
* 获取调用微信接口的客户端工具对象
*
* @return
*/
private CloseableHttpClient getClient() {
PrivateKey merchantPrivateKey = null;
try {
//merchantPrivateKey商户API私钥如何加载商户API私钥请看常见问题
merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream(new File(weChatProperties.getPrivateKeyFilePath())));
//加载平台证书文件
X509Certificate x509Certificate = PemUtil.loadCertificate(new FileInputStream(new File(weChatProperties.getWeChatPayCertFilePath())));
//wechatPayCertificates微信支付平台证书列表你也可以使用后面章节提到的定时更新平台证书功能而不需要关心平台证书的来龙去脉
List<X509Certificate> wechatPayCertificates = Arrays.asList(x509Certificate);
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(weChatProperties.getMchid(), weChatProperties.getMchSerialNo(), merchantPrivateKey)
.withWechatPay(wechatPayCertificates);
// 通过WechatPayHttpClientBuilder构造的HttpClient会自动的处理签名和验签
CloseableHttpClient httpClient = builder.build();
return httpClient;
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}
/**
* 发送post方式请求
*
* @param url
* @param body
* @return
*/
private String post(String url, String body) throws Exception {
CloseableHttpClient httpClient = getClient();
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.toString());
httpPost.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());
httpPost.addHeader("Wechatpay-Serial", weChatProperties.getMchSerialNo());
httpPost.setEntity(new StringEntity(body, "UTF-8"));
CloseableHttpResponse response = httpClient.execute(httpPost);
try {
String bodyAsString = EntityUtils.toString(response.getEntity());
return bodyAsString;
} finally {
httpClient.close();
response.close();
}
}
/**
* 发送get方式请求
*
* @param url
* @return
*/
private String get(String url) throws Exception {
CloseableHttpClient httpClient = getClient();
HttpGet httpGet = new HttpGet(url);
httpGet.addHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.toString());
httpGet.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());
httpGet.addHeader("Wechatpay-Serial", weChatProperties.getMchSerialNo());
CloseableHttpResponse response = httpClient.execute(httpGet);
try {
String bodyAsString = EntityUtils.toString(response.getEntity());
return bodyAsString;
} finally {
httpClient.close();
response.close();
}
}
/**
* jsapi下单
*
* @param orderNum 商户订单号
* @param total 总金额
* @param description 商品描述
* @param openid 微信用户的openid
* @return
*/
private String jsapi(String orderNum, BigDecimal total, String description, String openid) throws Exception {
JSONObject jsonObject = new JSONObject();
jsonObject.put("appid", weChatProperties.getAppid());
jsonObject.put("mchid", weChatProperties.getMchid());
jsonObject.put("description", description);
jsonObject.put("out_trade_no", orderNum);
jsonObject.put("notify_url", weChatProperties.getNotifyUrl());
JSONObject amount = new JSONObject();
amount.put("total", total.multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).intValue());
amount.put("currency", "CNY");
jsonObject.put("amount", amount);
JSONObject payer = new JSONObject();
payer.put("openid", openid);
jsonObject.put("payer", payer);
String body = jsonObject.toJSONString();
return post(JSAPI, body);
}
/**
* 小程序支付
*
* @param orderNum 商户订单号
* @param total 金额单位
* @param description 商品描述
* @param openid 微信用户的openid
* @return
*/
public JSONObject pay(String orderNum, BigDecimal total, String description, String openid) throws Exception {
//统一下单生成预支付交易单
String bodyAsString = jsapi(orderNum, total, description, openid);
//解析返回结果
JSONObject jsonObject = JSON.parseObject(bodyAsString);
System.out.println(jsonObject);
String prepayId = jsonObject.getString("prepay_id");
if (prepayId != null) {
String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
String nonceStr = RandomStringUtils.randomNumeric(32);
ArrayList<Object> list = new ArrayList<>();
list.add(weChatProperties.getAppid());
list.add(timeStamp);
list.add(nonceStr);
list.add("prepay_id=" + prepayId);
//二次签名调起支付需要重新签名
StringBuilder stringBuilder = new StringBuilder();
for (Object o : list) {
stringBuilder.append(o).append("\n");
}
String signMessage = stringBuilder.toString();
byte[] message = signMessage.getBytes();
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(PemUtil.loadPrivateKey(new FileInputStream(new File(weChatProperties.getPrivateKeyFilePath()))));
signature.update(message);
String packageSign = Base64.getEncoder().encodeToString(signature.sign());
//构造数据给微信小程序用于调起微信支付
JSONObject jo = new JSONObject();
jo.put("timeStamp", timeStamp);
jo.put("nonceStr", nonceStr);
jo.put("package", "prepay_id=" + prepayId);
jo.put("signType", "RSA");
jo.put("paySign", packageSign);
return jo;
}
return jsonObject;
}
/**
* 申请退款
*
* @param outTradeNo 商户订单号
* @param outRefundNo 商户退款单号
* @param refund 退款金额
* @param total 原订单金额
* @return
*/
public String refund(String outTradeNo, String outRefundNo, BigDecimal refund, BigDecimal total) throws Exception {
JSONObject jsonObject = new JSONObject();
jsonObject.put("out_trade_no", outTradeNo);
jsonObject.put("out_refund_no", outRefundNo);
JSONObject amount = new JSONObject();
amount.put("refund", refund.multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).intValue());
amount.put("total", total.multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).intValue());
amount.put("currency", "CNY");
jsonObject.put("amount", amount);
jsonObject.put("notify_url", weChatProperties.getRefundNotifyUrl());
String body = jsonObject.toJSONString();
//调用申请退款接口
return post(REFUNDS, body);
}
}

View File

@ -14,3 +14,15 @@ mybatis-plus:
mapper-locations: classpath*:/mapper/*Mapper.xml
configuration:
map-underscore-to-camel-case: true
dx:
wechat:
appid: wx865aefa5a7115ae0
secret: 3f9849429894435abc935eea88178dfd
mchid: 1684540409
mchSerialNo: 250414966CEADA52CF0A989445FB3190C5A82F40
privateKeyFilePath: template/bddf2dc508484b6bb086fe748e813260.pem
apiV3Key: d5a58d44588b42cbbe01daa5cfa4e792
#未填写及以下
weChatPayCertFilePath: template/wechatpay_429733475DFDCEBE2A6135485F984EE337297F4F.pem
notifyUrl: https://www.weixin.qq.com/wxpay/pay.php
refundNotifyUrl: https://www.weixin.qq.com/wxpay/pay.php

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDE4z0uWRbfuMPP
m19ZOd3CoKmm20Rdp0EJGsYsItxWk1veEUrtUDGUevrBpAWxSW6ka6YRcs3G6nzK
sAkrOzoFOU1xTH4I0qrspIelXwLZMYKZrdR+G+LNS9gmITrvkBKlZsrWTNOxStv1
0CTeWPr3mBUt3SrUOHPX+eY5JR1XgBau8Y/9hd5fiYuPTCoWQsM+IUIXBrWsaEqI
oDrymtFH8Nupgz55g8qgUX0jxb1yjcuenO7jlonqMySIpZuNrAxla4GnfERG7TAL
36VYJ/f4QWiHpa8lg4azq/FgwegL7nVo2wcDoCcqkIjDvyYxTXtwwn7llFSa44B9
abXQ4Ip3AgMBAAECggEBAMCtwcoB1ajLoJUjcIRZZPR7Vou8OYONks/eK+I1m3v+
agFA2xqzSFIOqCeo5QlC28x8rOCWgVsRT17sN4zfQUCre2ZNfWoVAMDlovnrqVX0
ZeMPgsyHbcWLW9S04IBhdl334rkmJmVy5SACupH+clyrsM5Zivh05qmOHgf+kmB1
dpG8oJ+4gaAg5f8YQ0S3q0jJy/Tr2tZRaTU5S1Gaa3xmfDHBvte6bmmSrjF7V56M
hibEOqvjrgK04P20FtFH7Laug4tq5IMyi6L9XVN2tE06c0epN7+Z7oBEzeTuQ+zU
EwEnNwH7GG+JYjUIrxlQMr6XXNEWv/iDhbXKJd5zvoECgYEA/9AFOlQthPdR0dY3
9N9q41jmrxvF0yep+MFw4+X7sEV+gnLLRATQCnsBF+Br3DHdUU2H8DwtOEYD8V9L
Ks8j7B9ivVcbs4KT6iu3ehrQgX2DvnGov+ZlRpVwWV90CppLzubuX++0L8K/dYfF
OPpm128k18BgwWY+4UvD1BClrU8CgYEAxQgqsEysa9RUcKFcPMMkMUG3SDvB0+q3
vkn4EDZVgUoojQnk54vQ4U6pbF4KTPPHvNF4vrmu5DdhSWBBnHAchdLHO7NXVl7n
cIPOHnakzauiS+jZlokpf4bMIECsQMW+n6c2WfT4mhbciCTo4+oLBu/aZ/tS/fUu
EJyW2+/VllkCgYByexSr2toYJFpgbt7R3l5GahWqjeJFMf32DhPIWbb+Vstb86WV
xhWYax29IrkCbOpfpTPNxhBym5rOHVhVSygHVrBojaAfALPTW0ccBP4ExTf9NX5Q
ivoN0Xja9kXHLO/6IwzQsERSD3SBU4ZmjmERznKNf1GNm4VObAqyT9TlLwKBgQCT
R1OBjQ6lW4Xy2urzkHqRRyoVmHV+TskiOHBwzeyEREajhm3QlraAdCg4lOLmOqNn
BL1Y87tDZBIYoxboNPVdIv1CJwB102L0u9Fq/AycoFskmt1qpQScCsqyoSUhFa8z
7+20uGTL6aLXMZ/UHbI4cTm02CxlIMxaJnKt3EyvoQKBgQCeZwTjaqIQmR3fBrNm
MG0qO652ONVLirzEsfn7DpxPC6+ON3MGuPZxaiSaYwAhQq3dqQ/dpJoxrInPMScH
bebJz33OLTH4+1t4NvNDJkauWwuDI46uZhX+MVfIelNC5j5V+qrd1n614nQe9pJJ
UMlUt8FS3+aqnzvtYMOs6MNO9g==
-----END PRIVATE KEY-----

View File

@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIIEFDCCAvygAwIBAgIUQpczR139zr4qYTVIX5hO4zcpf08wDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
Q0EwHhcNMjQwOTAyMDkxNjQ1WhcNMjkwOTAxMDkxNjQ1WjBuMRgwFgYDVQQDDA9U
ZW5wYXkuY29tIHNpZ24xEzARBgNVBAoMClRlbnBheS5jb20xHTAbBgNVBAsMFFRl
bnBheS5jb20gQ0EgQ2VudGVyMQswCQYDVQQGEwJDTjERMA8GA1UEBwwIU2hlblpo
ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDjlZH/RfODPFpUJoQ7
VtfxW+65CSEPwOAlLQvdCELE5Irw8e0kCpmVUw8jKJKr/7yMfOgt4jxHkgZYcXp6
YejRNAXOQi5CKnW1FuJi+gU9CNE+wneG1Yq/9P2LGRpO+uWzYOUKe5G6qja7/y5A
37mgRy1b6EpRjN3cPQxOCwqlU6+ynojM+1ZKBbVmXETwJL3Cet03fb1IR50N/lLt
vRHGEpjLUR991aPBgHCQF+2BmlSlrZyQcfqzvVbRzCLnZtFWVa+yESYF1o3mf7+W
MSKPwrGgyfWw2NpY5Sz3smLUOgqJOooqoYbCf4iW+QceBAdXTixY14MBInS7jHPr
T8MLAgMBAAGjgbkwgbYwCQYDVR0TBAIwADALBgNVHQ8EBAMCA/gwgZsGA1UdHwSB
kzCBkDCBjaCBiqCBh4aBhGh0dHA6Ly9ldmNhLml0cnVzLmNvbS5jbi9wdWJsaWMv
aXRydXNjcmw/Q0E9MUJENDIyMEU1MERCQzA0QjA2QUQzOTc1NDk4NDZDMDFDM0U4
RUJEMiZzZz1IQUNDNDcxQjY1NDIyRTEyQjI3QTlEMzNBODdBRDFDREY1OTI2RTE0
MDM3MTANBgkqhkiG9w0BAQsFAAOCAQEAdhtjpoyuFq7mMOAqWFmdgA+Z9ko8Yu31
iehWhcFaKbhGZ0rvbXUquzQYS8/DYTobCyM1I9+2skKks+bbOC56BrZtduzSqzII
IRlGr714v8WoudsIwuT7U6t4rws6mekrPrh9tTtDr6xpEuuLaYe0gJrpFM0UbryO
H20I1g2mxzmXl3MuGq8zB+fGQUy+MIO4EoUGIIEM6q7HzcCAPIVn+Qb/MCto56Ne
YPr5a+w7g6u4UZ+sVix2AddlOnqJPBIv/t91sQtFSzew9yztW/r2b1AyUHAsYa0n
76QTS6cjmV/Ee726l9d6tYGhF/NR9lUcXK7hr4JzA9e0zKr0JnAy8Q==
-----END CERTIFICATE-----