微信小程序退款【证书的使用】

2,在官方文档中给出了证书使用的链接,如下:

[其实只有证书的获取,选择。具体的证书怎么在代码中使用,文档中并没有给出说明]

3,第一步准备请求的参数,里面只有五个是参数是有点特殊的

(1)随机数。官方文档里面给出了说明【这里】

  /**
     * StringUtils工具类方法 获取一定长度的随机字符串,范围0-9,a-z
     * 
     * @param length:指定字符串长度
     * @return 一定长度的随机字符串
     */
    public static String getRandomStringByLength(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

(2)微信订单号(这个是在支付的时候产生的,需要在支付的回调函数中就将其保存在订单表中,待退款时使用)

(3)签名:这个在官方文档中也给出了说明

String mysign = PayUtil.sign(prestr, WxPayConfig.key, "utf-8").toUpperCase();
    /**
     * 签名字符串
     * 
     * @param text需要签名的字符串
     * @param key               密钥
     * @param input_charset编码格式
     * @return 签名结果
     */
    public static String sign(String text, String key, String input_charset) {
        text = text + "&key=" + key;
        return DigestUtils.md5Hex(getContentBytes(text, input_charset));
    }
 public static String md5Hex(final byte[] data) {
        return Hex.encodeHexString(md5(data));
    }
 public static String encodeHexString(final byte[] data) {
        return new String(encodeHex(data));
    }
 public static char[] encodeHex(final byte[] data) {
        return encodeHex(data, true);
    }
public static char[] encodeHex(final byte[] data, final boolean toLowerCase) {
        return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
    }
    protected static char[] encodeHex(final byte[] data, final char[] toDigits) {
        final int l = data.length;
        final char[] out = new char[l << 1];
        // two characters form the hex value.
        for (int i = 0, j = 0; i < l; i++) {
            out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
            out[j++] = toDigits[0x0F & data[i]];
        }
        return out;
    }

(4)两个整形的参数(一定要注意类型【否则报参数格式错误】)

这两个参数是取得订单类的属性,在订单类中,这两个参数我是定义的Double的类型,单位:元。传的参数是以分为单位的整形,因此就需要乘100。

还有一点需要注意的是,举个例子吧:

  在这里我测试的是0.01(一分)直接乘100,他的结果是1.0,这个结果是不对的,需要把后面的".0"去掉,

4,所有参数准备好之后就是发顺宏请求了,这里比较特殊的就是他需要证书,然而官方文档只给了证书的获取方式,以及不同语言的选择,并没有告诉我们怎么用。

下面就是本篇最重要的地方

public static void  refund(Order order) throws Exception {
        try {
            KeyStore clientStore = KeyStore.getInstance("PKCS12");
            // 读取本机存放的PKCS12证书文件
            FileInputStream instream = new FileInputStream("****\apiclient_cert.p12");
            try {
                // 指定PKCS12的密码(商户ID)
                clientStore.load(instream, "***".toCharArray());
            } finally {
                instream.close();
            }
            SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(clientStore, "***".toCharArray()).build();
            // 指定TLS版本
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null,
                    SSLConnectionSocketFactory.getDefaultHostnameVerifier());
            // 设置httpclient的SSLSocketFactory
            CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
            try {
                HttpPost httpost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund"); // 设置响应头信息
//                httpost.addHeader("Connection", "keep-alive");
//                httpost.addHeader("Accept", "*/*");
//                httpost.addHeader("Content-Type", CONTENT_TYPE_FORM.toString());
//                httpost.addHeader("X-Requested-With", "XMLHttpRequest");
//                httpost.addHeader("Cache-Control", "max-age=0");
//                httpost.addHeader("User-Agent", DEFAULT_USER_AGENT);
                httpost.setEntity(new StringEntity(getXmlStr(order), "UTF-8"));
                CloseableHttpResponse response = httpclient.execute(httpost);
                try {
                    HttpEntity entity = response.getEntity();
                    String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
                    EntityUtils.consume(entity);
                    System.out.println(jsonStr);
                } finally {
                    response.close();
                }
            } finally {
                httpclient.close();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

测试类

public static void main(String[] args) throws Exception {
        Order order = new Order();
        refund(order);
    }

原文地址:https://www.cnblogs.com/excellencesy/p/10194329.html