栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot整合微信支付V3版本APP支付

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot整合微信支付V3版本APP支付

最近在搞微信支付,V3版本文档对于新手理解起来相对比较绕,最终还是搞起来了。此代码片段只写了下单支付接口,其他接口相对简单就不一一列举出来了。

话不多说直接上代码。

一、下单

1、支付相关参数配置,根据自己相关参数配置

 
    private String mchId;
    
    private String mchSerialNo;

    
    private String apiV3key;
    
    private String  appId;

    
    private String  notifyUrl;

    
    private  String  payUrl;

    
    private  String  queryPayUrl;

2、支付方法(获取支付连接可以封装成工具类)

 AutoUpdateCertificatesVerifier verifier =null;
        CloseableHttpClient httpClient =null;
        PrivateKey merchantPrivateKey =null;
        try{
             merchantPrivateKey =
                    PemUtil.loadPrivateKey(
                            new ByteArrayInputStream(emsWeChatPayConfig.getPrivateKey().getBytes("utf-8")));

            // 使用自动更新的签名验证器,不需要传入证书
             verifier =
                    new AutoUpdateCertificatesVerifier(
                            new WechatPay2Credentials(
                                    emsWeChatPayConfig.getMchId(),
                                    new PrivateKeySigner(emsWeChatPayConfig.getMchSerialNo(), merchantPrivateKey)),
                            emsWeChatPayConfig.getApiV3key().getBytes("utf-8"));

             httpClient =
                    WechatPayHttpClientBuilder.create()
                            .withMerchant(emsWeChatPayConfig.getMchId(), emsWeChatPayConfig.getMchSerialNo(), merchantPrivateKey)
                            .withValidator(new WechatPay2Validator(verifier))
                            .build();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            log.error("【微信下单支付】----初始化连接异常--{}--",e.getMessage());
        }



        HttpPost httpPost = new HttpPost(emsWeChatPayConfig.getPayUrl());
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type", "application/json; charset=utf-8");

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectMapper objectMapper = new ObjectMapper();

        ObjectNode rootNode = objectMapper.createObjectNode();
        rootNode
                .put("mchid", emsWeChatPayConfig.getMchId())
                .put("appid", emsWeChatPayConfig.getAppId())
                .put("description", payInfoVo.getTitle())
                .put("notify_url", emsWeChatPayConfig.getNotifyUrl())
                .put("out_trade_no", payInfoVo.getOutTradeNo());
        rootNode.putObject("amount").put("total", payInfoVo.getPayFree());
        try {
            objectMapper.writevalue(bos, rootNode);

            httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
            CloseableHttpResponse response = httpClient.execute(httpPost);

           String bodyAsString = EntityUtils.toString(response.getEntity());
            int statusCode = response.getStatusLine().getStatusCode();
           log.info("【微信下单返回参数】:状态码:{}  返回内容:{}",statusCode,bodyAsString);
           //微信成功响应
           if (statusCode==200){
               String timestamp = System.currentTimeMillis()/1000+"";
               String nonce = RandomUtil.randomString(32);

               StringBuilder builder = new StringBuilder();
               // Appid
               builder.append(emsWeChatPayConfig.getAppId()).append("n");
               // 时间戳
               builder.append(timestamp).append("n");
               // 随机字符串
               builder.append(nonce).append("n");
               JsonNode jsonNode = objectMapper.readTree(bodyAsString);
               // 预支付会话ID
               builder.append(jsonNode.get("prepay_id").textValue()).append("n");
               // 获取签名
               //String ciphertext = RsaCryptoUtil.encryptOAEP(builder.toString(),verifier.getValidCertificate());
               String sign = this.sign(builder.toString().getBytes("utf-8"), merchantPrivateKey);

               JSonObject jsonMap = new JSonObject();
               jsonMap.put("noncestr", nonce);
               jsonMap.put("timestamp", timestamp);
               jsonMap.put("prepayid", jsonNode.get("prepay_id").textValue());
               jsonMap.put("sign", sign);
               jsonMap.put("package", emsWeChatPayConfig.getPackageStr());
               jsonMap.put("appid", emsWeChatPayConfig.getAppId());
               jsonMap.put("partnerid", emsWeChatPayConfig.getMchId());
               return jsonMap.toJSonString();

2、计算签名方法

   
 private     String sign(byte[] message, PrivateKey yourPrivateKey)  {

        try{
            Signature sign = Signature.getInstance("SHA256withRSA");
            sign.initSign(yourPrivateKey);
            sign.update(message);
            return base64.getEncoder().encodeToString(sign.sign());
        }catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (SignatureException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }

     return "";
    }

3、支付回调通知

 public String callback(HttpServletRequest request) throws IOException {

        log.info("【微信支付结果回调】:回调成功");

        String wechatpayTimestamp = request.getHeader("Wechatpay-Timestamp");
        String wechatpayNonce = request.getHeader("Wechatpay-Nonce");
        String wechatpaySignature = request.getHeader("Wechatpay-Signature");
        String wechatpaySerial = request.getHeader("Wechatpay-Serial");

        BufferedReader reader = request.getReader();
        String str = null;

        StringBuilder builder = new StringBuilder();
        while ((str = reader.readLine()) != null) {
            builder.append(str);
        }

        StringBuilder signStr = new StringBuilder();
        signStr.append(wechatpayTimestamp).append("n");
        signStr.append(wechatpayNonce).append("n");
        signStr.append(builder.toString()).append("n");

        //验证签名
        if (!signVerify(wechatpaySerial, signStr.toString(), wechatpaySignature)) {
            log.error("【微信支付回调】:签名延签错误");

            return  this.resultCallbackJson(Constants.FAIL_CODE,"签名延签错误");
        }
        //解密密文
         String decryptOrder = this.decryptOrder(builder.toString());

        log.info("【微信支付回调】:解密密文:{}",decryptOrder);
          if (StringUtils.isEmpty(decryptOrder)){
              log.error("【微信支付回调】:解密为空");
              return  this.resultCallbackJson(Constants.FAIL_CODE,"解密为空");
          }
         JSonObject resultJson = JSONObject.parseObject(decryptOrder);

          //微信订单号
         String transactionId = resultJson.getString("transaction_id");
         //商户订单号
         String outTradeNo = resultJson.getString("out_trade_no");
         //支付状态
         String tradeState = resultJson.getString("trade_state");

         JSonObject amount = resultJson.getJSonObject("amount");
         //用户支付金额
         int payerTotal = amount.getInteger("payer_total");
         //总金额
         int total = amount.getInteger("total");
         //附加数据
         String attach = amount.getString("attach");

         }

4、验证签名

    public boolean signVerify(String serial, String message, String signture)   throws UnsupportedEncodingException {
 AutoUpdateCertificatesVerifier verifier =null;  
        PrivateKey merchantPrivateKey =null;
        try{
             merchantPrivateKey =
                    PemUtil.loadPrivateKey(
                            new ByteArrayInputStream(emsWeChatPayConfig.getPrivateKey().getBytes("utf-8")));

            // 使用自动更新的签名验证器,不需要传入证书
             verifier =
                    new AutoUpdateCertificatesVerifier(
                            new WechatPay2Credentials(
                                    emsWeChatPayConfig.getMchId(),
                                    new PrivateKeySigner(emsWeChatPayConfig.getMchSerialNo(), merchantPrivateKey)),
                            emsWeChatPayConfig.getApiV3key().getBytes("utf-8"));

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            log.error("【微信下单支付】----初始化连接异常--{}--",e.getMessage());
        }

  return verifier.verify(serial, message.getBytes("utf-8"), signture);
    }

5、解密回调通知密文

  
    private     String   decryptOrder(String  body){

        try {
            AesUtil aesUtil  = new AesUtil(emsWeChatPayConfig.getApiV3key().getBytes("utf-8"));
            ObjectMapper objectMapper  = new ObjectMapper();
            JsonNode jsonNode = objectMapper.readTree(body);
            JsonNode resource = jsonNode.get("resource");
            //数据密文
            String ciphertext = resource.get("ciphertext").textValue();
            String associatedData = resource.get("associated_data").textValue();
            String nonce = resource.get("nonce").textValue();

            return aesUtil.decryptToString(associatedData.getBytes("utf-8"),nonce.getBytes("utf-8"),ciphertext);

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }

        return  "";
    }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/582643.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号