支付功能(未实现)
This commit is contained in:
parent
7976fc79d3
commit
520d91f382
20
pom.xml
20
pom.xml
|
@ -15,6 +15,7 @@
|
||||||
<description>wxapp-server</description>
|
<description>wxapp-server</description>
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
|
<commons.lang>2.6</commons.lang>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -25,6 +26,11 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.auth0</groupId>
|
<groupId>com.auth0</groupId>
|
||||||
<artifactId>java-jwt</artifactId>
|
<artifactId>java-jwt</artifactId>
|
||||||
|
@ -56,13 +62,17 @@
|
||||||
<artifactId>fastjson</artifactId>
|
<artifactId>fastjson</artifactId>
|
||||||
<version>1.2.83</version>
|
<version>1.2.83</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- 微信支付API -->
|
<!--微信支付-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.wxpay</groupId>
|
<groupId>com.github.wechatpay-apiv3</groupId>
|
||||||
<artifactId>wxpay-sdk</artifactId>
|
<artifactId>wechatpay-apache-httpclient</artifactId>
|
||||||
<version>0.0.3</version>
|
<version>0.4.8</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-lang</groupId>
|
||||||
|
<artifactId>commons-lang</artifactId>
|
||||||
|
<version>${commons.lang}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,12 +2,10 @@ package com.bigdata.wxappserver.controller;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.bigdata.wxappserver.result.Result;
|
||||||
import com.bigdata.wxappserver.service.OrderService;
|
import com.bigdata.wxappserver.service.OrderService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created with IntelliJ IDEA.
|
* Created with IntelliJ IDEA.
|
||||||
|
@ -43,4 +41,15 @@ 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,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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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; //退款成功的回调地址
|
||||||
|
|
||||||
|
}
|
|
@ -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; //当前页数据集合
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,6 +9,8 @@ import com.bigdata.wxappserver.entity.Order;
|
||||||
import com.bigdata.wxappserver.entity.User;
|
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.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;
|
||||||
|
@ -16,6 +18,8 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -28,12 +32,14 @@ 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;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
GoodsService goodsService;
|
GoodsService goodsService;
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public JSONObject addOrUpdate(JSONObject jsonObject) {
|
public JSONObject addOrUpdate(JSONObject jsonObject) {
|
||||||
Order order = jsonObject.toJavaObject(Order.class);
|
Order order = jsonObject.toJavaObject(Order.class);
|
||||||
|
@ -50,14 +56,16 @@ public class OrderService extends ServiceImpl<OrderMapper, Order> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSONObject list(JSONObject jsonObject) {
|
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 status = jsonObject.getInteger("status");
|
||||||
// Integer currentPage = jsonObject.getInteger("currentPage");
|
// Integer currentPage = jsonObject.getInteger("currentPage");
|
||||||
// Integer pageSize = jsonObject.getInteger("pageSize");
|
// Integer pageSize = jsonObject.getInteger("pageSize");
|
||||||
// IPage<Order> page = new Page<>(currentPage, pageSize);
|
// IPage<Order> page = new Page<>(currentPage, pageSize);
|
||||||
LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
|
||||||
wrapper.eq(userId != null, Order::getUserId, userId)
|
wrapper.eq(user != null, Order::getUserId, user.getId())
|
||||||
.eq(status!=null,Order::getStatus,status);
|
.eq(status != null, Order::getStatus, status);
|
||||||
// IPage<Order> orderIPage = page(page, wrapper);
|
// IPage<Order> orderIPage = page(page, wrapper);
|
||||||
List<Order> list = list(wrapper);
|
List<Order> list = list(wrapper);
|
||||||
List<OrderDto> orderDtoList = dealList(list);
|
List<OrderDto> orderDtoList = dealList(list);
|
||||||
|
@ -71,15 +79,15 @@ public class OrderService extends ServiceImpl<OrderMapper, Order> {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
List<Goods> goodsList = goodsService.listByIds(records.stream().map(Order::getGoodsId).collect(Collectors.toSet()));
|
List<Goods> goodsList = goodsService.listByIds(records.stream().map(Order::getGoodsId).collect(Collectors.toSet()));
|
||||||
Set<Goods> goodsSet =new HashSet<>(goodsList);
|
Set<Goods> goodsSet = new HashSet<>(goodsList);
|
||||||
List<OrderDto> list =new ArrayList<>();
|
List<OrderDto> list = new ArrayList<>();
|
||||||
for (Order record : records) {
|
for (Order record : records) {
|
||||||
OrderDto orderDto=new OrderDto();
|
OrderDto orderDto = new OrderDto();
|
||||||
record.setStatusDescription(OrderStatusEnum.describe(record.getStatus()));
|
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()))
|
Goods goods = goodsSet.stream().filter(item -> Objects.equals(item.getId(), record.getGoodsId()))
|
||||||
.findFirst().orElse(null);
|
.findFirst().orElse(null);
|
||||||
if(goods!=null){
|
if (goods != null) {
|
||||||
orderDto.setGoodDetail(goods.getGoodDetail());
|
orderDto.setGoodDetail(goods.getGoodDetail());
|
||||||
orderDto.setGoodPrice(goods.getGoodPrice());
|
orderDto.setGoodPrice(goods.getGoodPrice());
|
||||||
orderDto.setGoodImage(goods.getGoodImage());
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,3 +14,15 @@ 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: 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
|
||||||
|
|
|
@ -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-----
|
|
@ -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-----
|
Loading…
Reference in New Issue