IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> SpringBoot整合微信支付V3版本APP支付 -> 正文阅读

[网络协议]SpringBoot整合微信支付V3版本APP支付

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

话不多说直接上代码。

一、下单

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

 /**
     * 商户号
     */
    private String mchId;
    /**
     * 商户证书序列号
     */
    private String mchSerialNo;

    /**
     * apiV3密钥
     */
    private String apiV3key;
    /**
     * APP ID
     */
    private String  appId;

    /**
     * 回调通知路径
     */
    private String  notifyUrl;

    /**
     * 支付url
     */
    private  String  payUrl;

    /**
     * 查询支付Url
     */
    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、计算签名方法

   /**
     * 计算签名
     * @param message
     * @param yourPrivateKey
     * @return
     */
 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、验证签名

/**
     * 验证签名
     *
     * @param serial
     * @param message
     * @param signture
     * @return
     * @throws UnsupportedEncodingException
     */
    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、解密回调通知密文

  /**
     * 解密回调通知密文
     * @param body
     * @return
     */
    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  "";
    }

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-11-22 12:42:59  更:2021-11-22 12:43:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:38:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码