订单接口修改
This commit is contained in:
parent
fccdb9c8ed
commit
ab8a2f0714
24
pom.xml
24
pom.xml
|
@ -62,30 +62,6 @@
|
||||||
<artifactId>fastjson</artifactId>
|
<artifactId>fastjson</artifactId>
|
||||||
<version>1.2.83</version>
|
<version>1.2.83</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--微信支付-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.wechatpay-apiv3</groupId>
|
|
||||||
<artifactId>wechatpay-apache-httpclient</artifactId>
|
|
||||||
<version>0.4.8</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- 引入jar包-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.squareup.okhttp3</groupId>
|
|
||||||
<artifactId>okhttp</artifactId>
|
|
||||||
<version>3.5.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.wechatpay-apiv3</groupId>
|
|
||||||
<artifactId>wechatpay-java</artifactId>
|
|
||||||
<version>0.2.14</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- 微信支付API -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.binarywang</groupId>
|
|
||||||
<artifactId>weixin-java-pay</artifactId>
|
|
||||||
<version>4.1.0</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-lang</groupId>
|
<groupId>commons-lang</groupId>
|
||||||
<artifactId>commons-lang</artifactId>
|
<artifactId>commons-lang</artifactId>
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
package com.bigdata.wxappserver.config;
|
|
||||||
|
|
||||||
import com.bigdata.wxappserver.properties.WeChatProperties;
|
|
||||||
import com.github.binarywang.wxpay.config.WxPayConfig;
|
|
||||||
import com.github.binarywang.wxpay.service.WxPayService;
|
|
||||||
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created with IntelliJ IDEA.
|
|
||||||
*
|
|
||||||
* @Author: Cool
|
|
||||||
* @Date: 2024/09/03/22:19
|
|
||||||
* @Description:
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@ConditionalOnClass(WxPayService.class)
|
|
||||||
public class MyWxPayConfig {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private WeChatProperties properties;
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnMissingBean
|
|
||||||
public WxPayService wxService() {
|
|
||||||
WxPayConfig payConfig = new WxPayConfig();
|
|
||||||
payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId()));
|
|
||||||
payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));
|
|
||||||
payConfig.setMchKey(StringUtils.trimToNull(this.properties.getSecret()));
|
|
||||||
payConfig.setApiV3Key(StringUtils.trimToNull(this.properties.getApiV3Key()));
|
|
||||||
payConfig.setPrivateKeyPath(StringUtils.trimToNull(this.properties.getPrivateKeyFilePath()));
|
|
||||||
payConfig.setPrivateCertPath(StringUtils.trimToNull(this.properties.getWeChatPayCertFilePath()));
|
|
||||||
// payConfig.setPrivateKeyPath();
|
|
||||||
// 可以指定是否使用沙箱环境
|
|
||||||
payConfig.setUseSandboxEnv(false);
|
|
||||||
|
|
||||||
WxPayService wxPayService = new WxPayServiceImpl();
|
|
||||||
wxPayService.setConfig(payConfig);
|
|
||||||
return wxPayService;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -22,7 +22,7 @@ public class OrderController {
|
||||||
OrderService orderService;
|
OrderService orderService;
|
||||||
|
|
||||||
@RequestMapping("addOrUpdate")
|
@RequestMapping("addOrUpdate")
|
||||||
public JSONObject addOrUpdate(@RequestBody JSONObject jsonObject){
|
public Result addOrUpdate(@RequestBody JSONObject jsonObject){
|
||||||
return orderService.addOrUpdate(jsonObject);
|
return orderService.addOrUpdate(jsonObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,15 +41,4 @@ public class OrderController {
|
||||||
return orderService.delete(id);
|
return orderService.delete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单支付
|
|
||||||
*
|
|
||||||
* @param
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@PutMapping("/payment")
|
|
||||||
public Result payment(@RequestBody JSONObject jsonObject) throws Exception {
|
|
||||||
return orderService.payment(jsonObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,118 +0,0 @@
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package com.bigdata.wxappserver.controller;
|
|
||||||
|
|
||||||
import com.bigdata.wxappserver.result.Result;
|
|
||||||
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
|
|
||||||
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
|
|
||||||
import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
|
|
||||||
import com.github.binarywang.wxpay.service.WxPayService;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created with IntelliJ IDEA.
|
|
||||||
*
|
|
||||||
* @Author: Cool
|
|
||||||
* @Date: 2024/09/03/22:25
|
|
||||||
* @Description:
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
@Slf4j
|
|
||||||
public class TestController {
|
|
||||||
@Autowired
|
|
||||||
private WxPayService wxService;
|
|
||||||
|
|
||||||
|
|
||||||
@PostMapping("/unifiedOrder")
|
|
||||||
public Result unifiedOrder() throws Exception {
|
|
||||||
String orderCode = UUID.randomUUID().toString().replace("-", "");
|
|
||||||
WxPayUnifiedOrderV3Request wxPayUnifiedOrderRequest = new WxPayUnifiedOrderV3Request();
|
|
||||||
|
|
||||||
wxPayUnifiedOrderRequest.setDescription("商品描述");
|
|
||||||
wxPayUnifiedOrderRequest.setOutTradeNo(orderCode);
|
|
||||||
wxPayUnifiedOrderRequest.setNotifyUrl("https://49.233.248.140:8082/order/loadData");
|
|
||||||
|
|
||||||
WxPayUnifiedOrderV3Request.Amount amount = new WxPayUnifiedOrderV3Request.Amount();
|
|
||||||
amount.setTotal(100); // 订单总金额,单位为分
|
|
||||||
wxPayUnifiedOrderRequest.setAmount(amount);
|
|
||||||
WxPayUnifiedOrderV3Request.Payer payer = new WxPayUnifiedOrderV3Request.Payer();
|
|
||||||
payer.setOpenid(UUID.randomUUID().toString().replace("-", "")); // 需要获取用户的OpenID
|
|
||||||
wxPayUnifiedOrderRequest.setPayer(payer);
|
|
||||||
wxService.createOrderV3(TradeTypeEnum.JSAPI, wxPayUnifiedOrderRequest);
|
|
||||||
return Result.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/queryOrder")
|
|
||||||
public Result queryOrder(String outTradeNo) throws Exception {
|
|
||||||
WxPayOrderQueryResult wxPayOrderQueryResult = wxService.queryOrder(null, outTradeNo);
|
|
||||||
log.info(wxPayOrderQueryResult.toString());
|
|
||||||
return Result.success(wxPayOrderQueryResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -21,8 +21,8 @@ public class Order extends Base {
|
||||||
|
|
||||||
private Integer userId;
|
private Integer userId;
|
||||||
private Integer goodsId;
|
private Integer goodsId;
|
||||||
|
private String orderCode;
|
||||||
private String address;
|
private String address;
|
||||||
private LocalDateTime deliveryTime;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单状态 @see
|
* 订单状态 @see
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
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; //退款成功的回调地址
|
|
||||||
|
|
||||||
}
|
|
|
@ -10,7 +10,6 @@ import com.bigdata.wxappserver.entity.User;
|
||||||
import com.bigdata.wxappserver.enums.OrderStatusEnum;
|
import com.bigdata.wxappserver.enums.OrderStatusEnum;
|
||||||
import com.bigdata.wxappserver.mapper.OrderMapper;
|
import com.bigdata.wxappserver.mapper.OrderMapper;
|
||||||
import com.bigdata.wxappserver.result.Result;
|
import com.bigdata.wxappserver.result.Result;
|
||||||
import com.bigdata.wxappserver.utils.WeChatPayUtil;
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
@ -19,7 +18,6 @@ import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -32,8 +30,6 @@ import java.util.stream.Collectors;
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class OrderService extends ServiceImpl<OrderMapper, Order> {
|
public class OrderService extends ServiceImpl<OrderMapper, Order> {
|
||||||
@Autowired
|
|
||||||
private WeChatPayUtil weChatPayUtil;
|
|
||||||
@Autowired
|
@Autowired
|
||||||
UserService userService;
|
UserService userService;
|
||||||
|
|
||||||
|
@ -41,18 +37,26 @@ public class OrderService extends ServiceImpl<OrderMapper, Order> {
|
||||||
GoodsService goodsService;
|
GoodsService goodsService;
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public JSONObject addOrUpdate(JSONObject jsonObject) {
|
public Result addOrUpdate(JSONObject jsonObject) {
|
||||||
Order order = jsonObject.toJavaObject(Order.class);
|
Order order = jsonObject.toJavaObject(Order.class);
|
||||||
if (order == null) {
|
if (order == null) {
|
||||||
return new JSONObject().fluentPut("success", false).fluentPut("message", "参数错误");
|
return Result.error("参数错误");
|
||||||
}
|
}
|
||||||
if (!StringUtils.hasLength(order.getAddress())) {
|
if (!StringUtils.hasLength(order.getAddress())) {
|
||||||
User user = userService.getById(order.getUserId());
|
User user = userService.getById(order.getUserId());
|
||||||
order.setAddress(user.getAddress());
|
order.setAddress(user.getAddress());
|
||||||
}
|
}
|
||||||
// TODO 判空
|
if (order.getUserId() == null || order.getAddress() == null || order.getNum() == null || order.getGoodsId() == null) {
|
||||||
|
return Result.error("请携带完整的参数");
|
||||||
|
}
|
||||||
|
String orderCode = UUID.randomUUID().toString().replace("-", "");
|
||||||
|
order.setOrderCode(orderCode);
|
||||||
boolean success = saveOrUpdate(order);
|
boolean success = saveOrUpdate(order);
|
||||||
return new JSONObject().fluentPut("message", "success").fluentPut("success", success);
|
if(success){
|
||||||
|
return Result.success(orderCode);
|
||||||
|
}else {
|
||||||
|
return Result.error("未知错误,请联系管理员!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSONObject list(JSONObject jsonObject) {
|
public JSONObject list(JSONObject jsonObject) {
|
||||||
|
@ -131,39 +135,5 @@ public class OrderService extends ServiceImpl<OrderMapper, Order> {
|
||||||
saveOrUpdate(order);
|
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,138 +0,0 @@
|
||||||
package com.bigdata.wxappserver.utils;
|
|
||||||
|
|
||||||
import okhttp3.HttpUrl;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.NoSuchPaddingException;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.security.*;
|
|
||||||
import java.security.spec.InvalidKeySpecException;
|
|
||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created with IntelliJ IDEA.
|
|
||||||
*
|
|
||||||
* @Author: Cool
|
|
||||||
* @Date: 2024/09/03/20:34
|
|
||||||
* @Description:
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class SignV3Util{
|
|
||||||
//V3主商户ID
|
|
||||||
private static String merchantId;
|
|
||||||
//微信商户平台APIv3证书序列号
|
|
||||||
private static String certificateSerialNo;
|
|
||||||
//私钥(不要把私钥文件暴露在公共场合,如上传到Github,写在客户端代码等。)
|
|
||||||
private static String privateKey;
|
|
||||||
|
|
||||||
//配置文件配置好主商户号
|
|
||||||
@Value("${dx.wechat.mchid}")
|
|
||||||
public void setMerchantId(String merchantId) {
|
|
||||||
SignV3Util.merchantId = merchantId;
|
|
||||||
}
|
|
||||||
|
|
||||||
//配置文件配置好序列号
|
|
||||||
@Value("${dx.wechat.mchSerialNo}")
|
|
||||||
public void setCertificateSerialNo(String certificateSerialNo) {
|
|
||||||
SignV3Util.certificateSerialNo = certificateSerialNo;
|
|
||||||
}
|
|
||||||
|
|
||||||
//配置文件配置好私钥
|
|
||||||
@Value("${dx.wechat.apiV3Key}")
|
|
||||||
public void setPrivateKey(String privateKey) {
|
|
||||||
SignV3Util.privateKey = privateKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用方法
|
|
||||||
*
|
|
||||||
* @param method 请求方法
|
|
||||||
* @param url 请求url
|
|
||||||
* @param body 请求内容
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static HashMap<String, String> getSignMap(String method, String url, String body) throws InvalidKeySpecException, NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException, SignatureException {
|
|
||||||
String authorization = getSign(method, url, body);
|
|
||||||
|
|
||||||
HashMap<String, String> headsMap = new HashMap<>();
|
|
||||||
headsMap.put("Authorization", authorization);
|
|
||||||
headsMap.put("Content-Type", "application/json");
|
|
||||||
headsMap.put("Accept", "application/json");
|
|
||||||
|
|
||||||
return headsMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getSign(String method, String url, String body) throws NoSuchAlgorithmException, SignatureException, InvalidKeySpecException, InvalidKeyException, UnsupportedEncodingException {
|
|
||||||
return "WECHATPAY2-SHA256-RSA2048 " + getToken(method, HttpUrl.parse(url), body);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getToken(String method, HttpUrl url, String body) throws UnsupportedEncodingException, SignatureException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
|
|
||||||
String nonceStr = nonceString();
|
|
||||||
long timestamp = System.currentTimeMillis() / 1000;
|
|
||||||
String message = buildMessage(method, url, timestamp, nonceStr, body);
|
|
||||||
String signature = sign(message.getBytes("utf-8"));
|
|
||||||
return "mchid=\"" + merchantId + "\","
|
|
||||||
+ "nonce_str=\"" + nonceStr + "\","
|
|
||||||
+ "timestamp=\"" + timestamp + "\","
|
|
||||||
+ "serial_no=\"" + certificateSerialNo + "\","
|
|
||||||
+ "signature=\"" + signature + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sign(byte[] message) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
|
|
||||||
Signature sign = Signature.getInstance("SHA256withRSA");
|
|
||||||
sign.initSign(getPKCS8PrivateKey(privateKey));
|
|
||||||
sign.update(message);
|
|
||||||
|
|
||||||
return Base64.getEncoder().encodeToString(sign.sign());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {
|
|
||||||
String canonicalUrl = url.encodedPath();
|
|
||||||
if (url.encodedQuery() != null) {
|
|
||||||
canonicalUrl += "?" + url.encodedQuery();
|
|
||||||
}
|
|
||||||
|
|
||||||
return method + "\n"
|
|
||||||
+ canonicalUrl + "\n"
|
|
||||||
+ timestamp + "\n"
|
|
||||||
+ nonceStr + "\n"
|
|
||||||
+ body + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static PrivateKey getPKCS8PrivateKey(String strPk) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
|
||||||
String realPK = strPk.replaceAll("-----END PRIVATE KEY-----", "")
|
|
||||||
.replaceAll("-----BEGIN PRIVATE KEY-----", "")
|
|
||||||
.replaceAll("\n", "");
|
|
||||||
|
|
||||||
byte[] b1 = Base64.getDecoder().decode(realPK);
|
|
||||||
|
|
||||||
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(b1);
|
|
||||||
|
|
||||||
KeyFactory kf = KeyFactory.getInstance("RSA");
|
|
||||||
|
|
||||||
return kf.generatePrivate(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String nonceString() {
|
|
||||||
|
|
||||||
String currTime = String.format("%d", (long) System.currentTimeMillis() / 1000);
|
|
||||||
|
|
||||||
String strTime = currTime.substring(8, currTime.length());
|
|
||||||
|
|
||||||
Random random = new Random();
|
|
||||||
int num = (int) (random.nextDouble() * (1000000 - 100000) + 100000);
|
|
||||||
String code = String.format("%06d", num);
|
|
||||||
|
|
||||||
String nonce_str = currTime.substring(2) + code;
|
|
||||||
return nonce_str;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,233 +0,0 @@
|
||||||
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.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信支付工具类
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class WeChatPayUtil {
|
|
||||||
|
|
||||||
//微信支付下单接口地址
|
|
||||||
public static final String PAY_API = "https://api.mch.weixin.qq.com/pay/unifiedorder";
|
|
||||||
|
|
||||||
//申请退款接口地址
|
|
||||||
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("nonce_str", UUID.randomUUID().toString());
|
|
||||||
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(PAY_API, 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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,14 +14,4 @@ mybatis-plus:
|
||||||
mapper-locations: classpath*:/mapper/*Mapper.xml
|
mapper-locations: classpath*:/mapper/*Mapper.xml
|
||||||
configuration:
|
configuration:
|
||||||
map-underscore-to-camel-case: true
|
map-underscore-to-camel-case: true
|
||||||
dx:
|
|
||||||
wechat:
|
|
||||||
appId: wx865aefa5a7115ae0
|
|
||||||
secret: df0817d59696a6160de2770222d8ec53
|
|
||||||
mchId: 1684540409
|
|
||||||
mchSerialNo: 1E860B81D50719F1AA6AB92F00033A222F81C72C
|
|
||||||
privateKeyFilePath: classpath:template/wechatpay_429733475DFDCEBE2A6135485F984EE337297F4F.pem
|
|
||||||
apiV3Key: d5a58d44588b42cbbe01daa5cfa4e792
|
|
||||||
weChatPayCertFilePath: classpath:template/wechatpay_429733475DFDCEBE2A6135485F984EE337297F4F.pem
|
|
||||||
notifyUrl: https://www.weixin.qq.com/wxpay/pay.php
|
|
||||||
refundNotifyUrl: https://www.weixin.qq.com/wxpay/pay.php
|
|
||||||
|
|
Binary file not shown.
|
@ -1,28 +0,0 @@
|
||||||
-----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-----
|
|
|
@ -1,4 +1,3 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIEFDCCAvygAwIBAgIUQpczR139zr4qYTVIX5hO4zcpf08wDQYJKoZIhvcNAQEL
|
MIIEFDCCAvygAwIBAgIUQpczR139zr4qYTVIX5hO4zcpf08wDQYJKoZIhvcNAQEL
|
||||||
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
|
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
|
||||||
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
|
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
|
||||||
|
@ -21,4 +20,3 @@ IRlGr714v8WoudsIwuT7U6t4rws6mekrPrh9tTtDr6xpEuuLaYe0gJrpFM0UbryO
|
||||||
H20I1g2mxzmXl3MuGq8zB+fGQUy+MIO4EoUGIIEM6q7HzcCAPIVn+Qb/MCto56Ne
|
H20I1g2mxzmXl3MuGq8zB+fGQUy+MIO4EoUGIIEM6q7HzcCAPIVn+Qb/MCto56Ne
|
||||||
YPr5a+w7g6u4UZ+sVix2AddlOnqJPBIv/t91sQtFSzew9yztW/r2b1AyUHAsYa0n
|
YPr5a+w7g6u4UZ+sVix2AddlOnqJPBIv/t91sQtFSzew9yztW/r2b1AyUHAsYa0n
|
||||||
76QTS6cjmV/Ee726l9d6tYGhF/NR9lUcXK7hr4JzA9e0zKr0JnAy8Q==
|
76QTS6cjmV/Ee726l9d6tYGhF/NR9lUcXK7hr4JzA9e0zKr0JnAy8Q==
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,19 +1,8 @@
|
||||||
package com.bigdata.wxappserver;
|
package com.bigdata.wxappserver;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.bigdata.wxappserver.utils.SignV3Util;
|
|
||||||
import org.apache.http.HttpEntity;
|
|
||||||
import org.apache.http.client.HttpClient;
|
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
|
||||||
import org.apache.http.client.methods.HttpPost;
|
|
||||||
import org.apache.http.entity.StringEntity;
|
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
|
||||||
import org.apache.http.impl.client.HttpClients;
|
|
||||||
import org.apache.http.util.EntityUtils;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -25,35 +14,5 @@ class WxappServerApplicationTests {
|
||||||
void contextLoads() {
|
void contextLoads() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test() throws Exception {
|
|
||||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
|
||||||
//处理请求参数
|
|
||||||
String param = JSON.toJSONString("请求参数");
|
|
||||||
//获取签名请求头
|
|
||||||
HashMap<String, String> heads = SignV3Util.getSignMap("POST", "https://api.mch.weixin.qq.com/pay/unifiedorder", param);
|
|
||||||
//请求微信接口
|
|
||||||
HttpPost post = new HttpPost("https://api.mch.weixin.qq.com/pay/unifiedorder");
|
|
||||||
for (Map.Entry<String, String> entry : heads.entrySet()) {
|
|
||||||
post.addHeader(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
// 设置请求参数
|
|
||||||
StringEntity entity = new StringEntity(JSON.toJSONString("请求参数"), "UTF-8");
|
|
||||||
post.setEntity(entity);
|
|
||||||
|
|
||||||
// 发送POST请求
|
|
||||||
CloseableHttpResponse response = httpClient.execute(post);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 获取响应实体
|
|
||||||
HttpEntity responseEntity = response.getEntity();
|
|
||||||
|
|
||||||
if (responseEntity != null) {
|
|
||||||
// 打印响应内容
|
|
||||||
System.out.println("Response content: " + EntityUtils.toString(responseEntity, "UTF-8"));
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
response.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue