lwhhszx преди 1 година
родител
ревизия
f18e6847c4

+ 28 - 0
pom.xml

@@ -284,6 +284,34 @@
             <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
             <version>1.1.0</version>
         </dependency>
+        <dependency>
+
+            <groupId>com.github.wechatpay-apiv3</groupId>
+
+            <artifactId>wechatpay-java</artifactId>
+
+            <version>0.2.6</version>
+
+        </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk15on</artifactId>
+            <version>1.65</version>
+        </dependency>
+
+        <!-- Feb, 2011 -->
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcpg-jdk16</artifactId>
+            <version>1.46</version>
+        </dependency>
+        <!-- Oct, 2019 -->
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcpkix-jdk15on</artifactId>
+            <version>1.65</version>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 18 - 0
src/main/java/com/example/xiaoshiweixinback/business/utils/RandomUtil.java

@@ -1,5 +1,7 @@
 package com.example.xiaoshiweixinback.business.utils;
 
+import java.util.Random;
+
 public class RandomUtil {
 
     /**
@@ -9,4 +11,20 @@ public class RandomUtil {
     public static String getSixRandom(){
         return String.valueOf((int) ((Math.random() * 9 + 1) * Math.pow(10, 5)));
     }
+    private static String[] STR_ARR = new String[] { "a", "b", "c", "d", "e",
+            "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r",
+            "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E",
+            "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
+            "S", "T", "U", "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5",
+            "6", "7", "8", "9", "0" };
+    public static String generateRandomString(int length) {
+        StringBuilder sb = new StringBuilder();
+        Random rand = new Random();
+        for (int i = 0; i < length; i++) {
+            sb.append(STR_ARR[rand.nextInt(STR_ARR.length)]);
+        }
+        return sb.toString();
+    }
+
+
 }

+ 57 - 0
src/main/java/com/example/xiaoshiweixinback/controller/PayController.java

@@ -0,0 +1,57 @@
+package com.example.xiaoshiweixinback.controller;
+
+import com.example.xiaoshiweixinback.business.common.Constants;
+import com.example.xiaoshiweixinback.business.common.Response;
+import com.example.xiaoshiweixinback.business.common.base.Records;
+import com.example.xiaoshiweixinback.entity.weixinPay.GetPayTicketVO;
+import com.example.xiaoshiweixinback.service.VipService;
+import com.example.xiaoshiweixinback.service.weixinpay.WeixinPayService;
+import io.swagger.v3.oas.annotations.Operation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+@RequestMapping(Constants.XIAOSHI_WEIXINBACK + "/weixinpay")
+@RestController
+public class PayController {
+    @Autowired
+    private WeixinPayService weixinPayService;
+
+    @Operation(summary = "回调成功")
+    @PostMapping("/success")
+    private String success() {
+        System.out.println("success");
+        return "success";
+    }
+
+
+    @Operation(summary = "下单并获取订单信息")
+    @GetMapping("/getPayTickets")
+    private Response getPayTickets() {
+        Records records = new Records();
+        try {
+            GetPayTicketVO getPayTicketVO = weixinPayService.getPayTickets();
+            records.setData(getPayTicketVO);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return Response.success(records);
+    }
+
+
+    @Operation(summary = "回调成功")
+    @PostMapping("/testAuthorization")
+    private String testAuthorization() {
+        try {
+//            String a = weixinPayService.testAuthorization();
+//            System.out.println(a);
+        } catch (Exception e) {
+
+        }
+
+        return "success";
+    }
+}

+ 11 - 0
src/main/java/com/example/xiaoshiweixinback/entity/weixinPay/GetAuthorizationVO.java

@@ -0,0 +1,11 @@
+package com.example.xiaoshiweixinback.entity.weixinPay;
+
+import lombok.Data;
+
+@Data
+public class GetAuthorizationVO {
+    private String authorization;
+    private long timestamp;
+    private String signature;
+    private String nonceStr;
+}

+ 13 - 0
src/main/java/com/example/xiaoshiweixinback/entity/weixinPay/GetPayTicketVO.java

@@ -0,0 +1,13 @@
+package com.example.xiaoshiweixinback.entity.weixinPay;
+
+import lombok.Data;
+
+@Data
+public class GetPayTicketVO {
+    private String prepayId;
+    private long timestamp;
+    private String signature;
+    private String nonceStr;
+    private String appId;
+    private String signType;
+}

+ 28 - 0
src/main/java/com/example/xiaoshiweixinback/entity/weixinPay/JsApiDTO.java

@@ -0,0 +1,28 @@
+package com.example.xiaoshiweixinback.entity.weixinPay;
+
+import lombok.Data;
+import org.joda.time.DateTime;
+import org.springframework.stereotype.Service;
+
+@Data
+public class JsApiDTO {
+    private String appid;
+    private String mchid;
+    private String description;
+    private String out_trade_no;
+    private String notify_url;
+    private Amount amount;
+    private Payer payer;
+
+    @Data
+    public static class Amount {
+        private Integer total;
+        private String currency;
+    }
+
+    @Data
+    public static class Payer {
+        private String openid;
+    }
+}
+

+ 0 - 2
src/main/java/com/example/xiaoshiweixinback/service/LoginService.java

@@ -78,7 +78,6 @@ public class LoginService {
      */
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
     public LoginVO loginByPhone(LoginDTO dto) throws Exception {
-        LogHelper.log("登录开始");
         //获取缓存中验证码
         Object codeObj = redisService.get(AppCacheKeyUtil.getLoginMessageCode(dto.getPhoneNum()));
         if (ToolUtil.isEmpty(codeObj)) {
@@ -124,7 +123,6 @@ public class LoginService {
         loginVO.setToken(jwtTokenUtil.createToken());
 //        redisService.set(AppCacheKeyUtil.getUserIdToken(loginVO.getId()), AppCacheKeyUtil.getTokenUserInfo(loginVO.getToken()));
         redisService.set(loginVO.getToken(), loginVO.getId());
-        LogHelper.log("登陆结束");
         return loginVO;
     }
 

+ 146 - 0
src/main/java/com/example/xiaoshiweixinback/service/weixinpay/AuthorizationService.java

@@ -0,0 +1,146 @@
+package com.example.xiaoshiweixinback.service.weixinpay;
+
+import com.alibaba.druid.sql.ast.statement.SQLForeignKeyImpl;
+import com.example.xiaoshiweixinback.business.utils.RandomUtil;
+import com.example.xiaoshiweixinback.entity.weixinPay.GetAuthorizationVO;
+import okhttp3.HttpUrl;
+import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.openssl.PEMParser;
+import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
+import org.springframework.stereotype.Service;
+
+import java.io.FileReader;
+import java.security.PrivateKey;
+import java.security.Security;
+import java.security.Signature;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+public class AuthorizationService {
+    /**
+     * 商户号
+     */
+
+    public static String merchantId = "1673179188";
+
+    /**
+     * 商户API私钥路径
+     */
+
+    public static String privateKeyPath = "C:\\Users\\admin\\Desktop\\小程序证书\\1673179188_20240408_cert\\apiclient_key.pem";
+
+    /**
+     * 商户证书序列号
+     */
+
+    public static String merchantSerialNumber = "794F7C195E3CEA0C926B5E8B425D8F5B03DFA049";
+
+    /**
+     * 商户APIV3密钥
+     */
+
+    public static String apiV3key = "wL3g4tAlOFe72gAd1THRqNPQsHIVxsYih6s20gN035oKRM3IBcd4c747zlQ1fLu8NrPCvGCo01Ox2jbDwkHJNaS9Yyn2R1NsTgoGWPObH6DWajwNBMrM3hjSC92XV3hJGfO7dkOsikNtHCigwFZk3DAXQmW6JLcl";
+
+//    public String getToken(String method, S, String body) throws Exception {
+//
+//        String nonceStr = "593BEC0C930BF1AFEB40B4A08C8FB242";
+//
+//        long timestamp = System.currentTimeMillis() / 1000;
+//
+//        String message = buildMessage(timestamp, nonceStr);
+//
+//        String signature = sign(message.getBytes("utf-8"));
+//
+//        return "mchid=\"" + merchantId + "\","
+//
+//                + "nonce_str=\"" + nonceStr + "\","
+//
+//                + "timestamp=\"" + timestamp + "\","
+//
+//                + "serial_no=\"" + merchantSerialNumber + "\","
+//
+//                + "signature=\"" + signature + "\"";
+//
+//    }
+
+//    public Map<String, Object> getSignature() throws Exception {
+//        Map<String, Object> map = new HashMap<>();
+//        String nonceStr = RandomUtil.generateRandomString(31);
+//
+//        long timestamp = System.currentTimeMillis() / 1000;
+//
+//        String message = buildMessage(timestamp, nonceStr);
+//
+//        String signature = sign(message.getBytes("utf-8"));
+//        map.put("signature", signature);
+//        map.put("timestamp", timestamp);
+//        map.put("nonceStr", nonceStr);
+//        return map;
+//
+//    }
+
+    public GetAuthorizationVO getAuthorization(String type, String url, String body) throws Exception {
+       GetAuthorizationVO getAuthorizationVO =new GetAuthorizationVO();
+        String re = "WECHATPAY2-SHA256-RSA2048 ";
+        re += "mchid=" + "\"" + merchantId + "\"";
+        Map<String, Object> map = new HashMap<>();
+        String nonceStr = RandomUtil.generateRandomString(32);
+        long timestamp = System.currentTimeMillis() / 1000;
+        String message = buildMessage(type,url,timestamp, nonceStr, body);
+        String signature = sign(message.getBytes("utf-8"));
+        re += ",nonce_str=" + "\"" + nonceStr + "\"";
+        re += ",signature=" + "\"" + signature + "\"";
+        re += ",timestamp=" + "\"" + timestamp + "\"";
+        re += ",serial_no=" + "\"" + merchantSerialNumber + "\"";
+        getAuthorizationVO.setAuthorization(re);
+        getAuthorizationVO.setSignature(signature);
+        getAuthorizationVO.setTimestamp(timestamp);
+        getAuthorizationVO.setNonceStr(nonceStr);
+        return getAuthorizationVO;
+
+
+    }
+
+    String sign(byte[] message) throws Exception {
+
+        Signature sign = Signature.getInstance("SHA256withRSA");
+        // 添加Bouncy Castle作为安全提供者
+        Security.addProvider(new BouncyCastleProvider());
+
+
+        // 使用PEMParser读取PEM文件
+        try (FileReader fileReader = new FileReader(privateKeyPath);
+             PEMParser pemParser = new PEMParser(fileReader)) {
+
+            // 使用JcaPEMKeyConverter将PEM对象转换为PrivateKey
+            JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
+            PrivateKey privateKey = converter.getPrivateKey((PrivateKeyInfo) pemParser.readObject());
+            sign.initSign(privateKey);
+
+            sign.update(message);
+
+            return Base64.getEncoder().encodeToString(sign.sign());
+
+        }
+    }
+
+    String buildMessage(String type,String url,long timestamp, String nonceStr, String body) {
+
+        String re = type + "\n"
+
+                + url + "\n"
+
+                + timestamp + "\n"
+
+                + nonceStr + "\n";
+        if (body != null) {
+            re += body;
+        }
+        re += "\n";
+        return re;
+    }
+
+}

+ 91 - 0
src/main/java/com/example/xiaoshiweixinback/service/weixinpay/WeixinPayService.java

@@ -0,0 +1,91 @@
+package com.example.xiaoshiweixinback.service.weixinpay;
+
+import com.alibaba.fastjson.JSONObject;
+import com.example.xiaoshiweixinback.business.config.XDns;
+import com.example.xiaoshiweixinback.business.utils.BatchNoUtil;
+import com.example.xiaoshiweixinback.business.utils.FormatUtil;
+import com.example.xiaoshiweixinback.entity.weixinPay.GetAuthorizationVO;
+import com.example.xiaoshiweixinback.entity.weixinPay.GetPayTicketVO;
+import com.example.xiaoshiweixinback.entity.weixinPay.JsApiDTO;
+import com.google.gson.Gson;
+import okhttp3.*;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+@Service
+public class WeixinPayService {
+    /**
+     * 商户号
+     */
+    @Autowired
+    private AuthorizationService authorizationService;
+    public static String merchantId = "1673179188";
+    /**
+     * appId
+     */
+    public static String appId = "wxaefb842bd0b93ff0";
+    public static String signType = "RSA";
+
+    /**
+     * 下订单接口
+     *
+     * @return
+     * @throws Exception
+     */
+    public GetPayTicketVO getPayTickets() throws Exception {
+        GetPayTicketVO getPayTicketVO = new GetPayTicketVO();
+        String url = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
+        JsApiDTO jsApiDTO = new JsApiDTO();
+        jsApiDTO.setAppid(appId);
+        jsApiDTO.setDescription("会员");
+        jsApiDTO.setMchid(merchantId);
+        String tradeNo = BatchNoUtil.getBatchNo();
+        jsApiDTO.setOut_trade_no(tradeNo);
+        JsApiDTO.Amount amount = new JsApiDTO.Amount();
+        amount.setCurrency("CNY");
+        amount.setTotal(100);
+        jsApiDTO.setAmount(amount);
+        JsApiDTO.Payer payer = new JsApiDTO.Payer();
+        jsApiDTO.setNotify_url("https://xsip.cn/xiaoshi-weixinback/weixinpay/success");
+        payer.setOpenid("oM10C7USCn1yqeZTrRVwnfMnrxzE");
+        jsApiDTO.setPayer(payer);
+        OkHttpClient okHttpClient = new OkHttpClient();
+        String param = new Gson().toJson(jsApiDTO);
+        GetAuthorizationVO authorizationVO = authorizationService.getAuthorization("POST", "/v3/pay/transactions/jsapi", param);
+        BeanUtils.copyProperties(authorizationVO, getPayTicketVO);
+        getPayTicketVO.setAppId(appId);
+        getPayTicketVO.setSignType(signType);
+        String authorization = authorizationVO.getAuthorization();
+        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), param);
+        Request request = new Request.Builder()
+                .addHeader("Authorization", authorization)
+                .addHeader("Accept", "*/*")
+                .url(url)
+                .post(requestBody)
+                .build();
+        // 发送请求获取响应
+        try {
+            Response response = okHttpClient.newCall(request).execute();
+            // 判断请求是否成功
+            if (response.isSuccessful()) {
+                // 打印服务端返回结果
+                String a = Objects.requireNonNull(response.body()).string();
+                JSONObject jsonObject = JSONObject.parseObject(a);
+                getPayTicketVO.setPrepayId(jsonObject.get("prepay_id").toString());
+                return getPayTicketVO;
+            }
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+}

+ 2 - 2
src/main/resources/application-prodNetIn.yml

@@ -67,8 +67,8 @@ PCSUrl: http://localhost:8871
 OPSUrl: http://139.224.24.90:5001
 PASUrl: http://localhost:8877
 FMSUrl: http://localhost:8801
-FileSource: 3
-
+FileSource: 5
+VectorUrl: http://192.168.1.6:8000
 ##################  短信 ####################
 SMS:
   regionId: cn-shanghai