springboot整合最新版微信小程序支付 的工具类

public class WxPayUtil {

    private CloseableHttpClient httpClient;
    private String mchid;
    private String appid;
    private Signature sign;
    private String mchSerialNo;
    private String apiV3Key;
    PrivateKey merchantPrivateKey ;
    AesUtil aesUtil ;
    /**
     *
     * @param privateKeyPath 商户私钥 路径
     * @param mchId 商户号
     * @param mchSerialNo 商户证书序列号
     * @param apiV3Key
     */
    public WxPayUtil(HttpClientConnectionManager poolingHttpClientConnectionManager, String privateKeyPath,
                     String mchId,
                     String mchSerialNo,
                     String apiV3Key,
                     String appid
                     ) {
        System.out.println("初始化微信支付工具");

        merchantPrivateKey = PemUtil.loadPrivateKey(this.getClass().getResourceAsStream(privateKeyPath));
        System.out.println(poolingHttpClientConnectionManager);
        //建立微信连接
        this.httpClient  = WechatPayHttpClientBuilder.create()
                .withMerchant(mchId, mchSerialNo, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(getVerifier(mchId,mchSerialNo,apiV3Key,merchantPrivateKey)))
                .setConnectionManager(poolingHttpClientConnectionManager)
                .build();
        this.mchid=mchId;
        this.appid=appid;
        this.mchSerialNo=mchSerialNo;
        this.apiV3Key=apiV3Key;
        aesUtil=new AesUtil(apiV3Key.getBytes(StandardCharsets.UTF_8));
        try {
            this.sign = Signature.getInstance("SHA256withRSA");
            sign.initSign(merchantPrivateKey);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
        }


    }
    private AutoUpdateCertificatesVerifier getVerifier(String mchId, String mchSerialNo,String apiV3Key,PrivateKey merchantPrivateKey){
        return new AutoUpdateCertificatesVerifier(
                new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),
                apiV3Key.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 预下单
     * @param description 商品描述
     * @param orderId 订单id
     * @param totalMoney 总金额
     * @param openid 用户的openid
     * @param wx_callback_url 回调地址
     * @return
     * @throws IOException
     * @throws SignatureException
     */
    public String createPreOrder (String description, String orderId, Integer totalMoney, String openid,String wx_callback_url) throws IOException {
        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
        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",mchid)
                .put("appid", appid)
                .put("description", description)
                .put("notify_url", wx_callback_url)
                .put("out_trade_no", orderId);
        rootNode.putObject("amount")
                .put("total", totalMoney);//totalMoney  !!!!!!!先写死1分钱
        rootNode.putObject("payer")
                .put("openid", openid);
        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());
        JsonNode node=objectMapper.readTree(bodyAsString);
        JsonNode prepayId = node.get("prepay_id");
        if (prepayId==null){
            //预下单为空 处理  返回报错
            System.out.println(bodyAsString);
            return null;
        }
        return prepayId.asText();


    }
    //下单
    public Map<String, Object> createOrder(String prepayId) throws SignatureException {
        //拿到预下单
        StringBuilder builder = new StringBuilder();
        //        小程序appId
        String timestamp=System.currentTimeMillis()/1000+"";//          时间戳 单位秒

        String nonce= RandomUtils.getRandomStr()+RandomUtils.getRandomStr();  //32 位随机字符串

        builder.append(appid).append("\n");
        builder.append(timestamp).append("\n");
        builder.append(nonce).append("\n");

        builder.append("prepay_id=").append(prepayId).append("\n");//订单详情扩展字符串 预付款id
//        System.out.println("明文"+builder);
        //立志"prepay_id=wx201410272009395522657a690389285100"
        String paySign = this.paySign(builder.toString().getBytes()); //签名
        Map<String, Object> result = new HashMap<>();
        result.put("timeStamp",timestamp);
        result.put("nonceStr",nonce);
        result.put("package","prepay_id="+prepayId);
        result.put("signType","RSA");
        result.put("paySign",paySign);
        return result;
    }

    private String paySign(byte[] message) throws  SignatureException {
        if (sign!=null){
            sign.update(message);
            return Base64.getEncoder().encodeToString(sign.sign());
        }
        return null;
    }
    //验签
    public Boolean checkSign(HttpServletRequest request,String body){
        String wxTimestamp=request.getHeader("Wechatpay-Timestamp"); //时间戳
        String wxNonce=request.getHeader("Wechatpay-Nonce"); //随机字符串
        String wxSignture=request.getHeader("Wechatpay-Signature"); //签名
        String wxSerial=request.getHeader("Wechatpay-Serial"); //序列号
        if (wxTimestamp==null||wxNonce==null||wxSignture==null||wxSerial==null){
            return false;
        }
        System.out.println("请求头都有数据");
        StringBuilder signStr=new StringBuilder();
        signStr.append(wxTimestamp).append("\n");
        signStr.append(wxNonce).append("\n");
        signStr.append(body).append("\n");
       return getVerifier(mchid,mchSerialNo,apiV3Key,merchantPrivateKey).verify(wxSerial, signStr.toString().getBytes(StandardCharsets.UTF_8), wxSignture);
    }

    //回调解密
    public String decode(Map<String,Object> body){
        Object resource = body.get("resource");
        if (resource==null){
            return null;
        }
        Map<String, Object> map = (Map)resource;
        Object ciphertext = map.get("ciphertext");
        Object associatedData = map.get("associated_data");
        Object nonce = map.get("nonce");
        String json = null;
        try {
            //解密
            json = this.aesUtil.decryptToString(associatedData.toString().getBytes(StandardCharsets.UTF_8),
                    nonce.toString().getBytes(StandardCharsets.UTF_8),
                    ciphertext.toString());
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return json;
    }

    public int  closeOrder(String orderId) throws IOException {
        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/"+orderId+"/close");
        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",mchid);
        objectMapper.writeValue(bos, rootNode);
        httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
        CloseableHttpResponse response = httpClient.execute(httpPost);
        return response.getStatusLine().getStatusCode();
    }
}
上一篇:python取出frozenset中的元素存到列表list


下一篇:cxgrid属性说明