一、微信付款接口可参考:付款到零钱:
二、企业微信发红包## 标题main方法,调用发红包接口
public static void main (String[] args) throws IOException{ String url="https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack"; String wx_appid="wx1be1xxxxxxx"; String wx_mchid="1555xxxxx"; String wx_mchkey="Thxxxxxxxxxxxxxxxx"; String wxCertPath="E:\\cert\\apiclient_cert.p12"; String logNo="xxxx2019091019933ddd"; SortedMap<String,Object> map =new TreeMap<String,Object>(); map.put("nonce_str", "ASDXCV");//可以写死 map.put("mch_billno", logNo); map.put("mch_id", wx_mchid); map.put("wxappid", wx_appid); map.put("send_name", "测试红包"); map.put("re_openid", "oKvRh5ljxxxxxx"); map.put("total_amount", 30); map.put("total_num", "1"); map.put("wishing", "祝福红包"); map.put("client_ip", "127.0.0.1"); map.put("act_name", "祝福红包二"); map.put("remark", "祝福红包描述"); map.put("scene_id", "PRODUCT_1"); String sign=createSignBalance("utf-8", map, wx_mchkey); map.put("sign", sign); String rest=WXHttpClient.postData(url, XmlParse.mapToXml(map, "xml"), wx_mchid, wxCertPath); System.out.println("http请求结果:"+rest); } /** * 支付签名算法sign * @param characterEncoding 编码集 UTF-8 * @param parameters 传入的有序map * @param key 传入的秘钥 * @return */ @SuppressWarnings({ "rawtypes" }) public static String createSignBalance(String characterEncoding,SortedMap<String,Object> parameters,String pkey){ StringBuffer sb = new StringBuffer(); Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序) Iterator it = es.iterator(); while(it.hasNext()) { Map.Entry entry = (Map.Entry)it.next(); String k = (String)entry.getKey(); Object v = entry.getValue(); if(null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { sb.append(k + "=" + v + "&"); } } sb.append("key=" + pkey); String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase(); return sign; }
MD5Util类
package com.sanxia.common.utils; import java.security.MessageDigest; public class MD5Util { private static String byteArrayToHexString(byte b[]) { StringBuffer resultSb = new StringBuffer(); for (int i = 0; i < b.length; i++) resultSb.append(byteToHexString(b[i])); return resultSb.toString(); } private static String byteToHexString(byte b) { int n = b; if (n < 0) n += 256; int d1 = n / 16; int d2 = n % 16; return hexDigits[d1] + hexDigits[d2]; } public static String MD5Encode(String origin, String charsetname) { String resultString = null; try { resultString = new String(origin); MessageDigest md = MessageDigest.getInstance("MD5"); if (charsetname == null || "".equals(charsetname)) resultString = byteArrayToHexString(md.digest(resultString .getBytes())); else resultString = byteArrayToHexString(md.digest(resultString .getBytes(charsetname))); } catch (Exception exception) { } return resultString; } /** * Convert byte[] to hex string.这里我们可以将byte转换成int,然后利用Integer.toHexString(int)来转换成16进制字符串。 * @param src * @return */ public static String bytesToHexString(byte[] src){ StringBuilder stringBuilder = new StringBuilder(""); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }; }
WXHttpClient类
@SuppressWarnings("deprecation") public class WXHttpClient { private static int socketTimeout = 10000;// 连接超时时间,默认10秒 private static int connectTimeout = 30000;// 传输超时时间,默认30秒 private static RequestConfig requestConfig;// 请求器的配置 private static CloseableHttpClient httpClient;// HTTP请求器 /** * 通过Https往API post xml数据 * * @param url API地址 * @param xmlObj 要提交的XML数据对象 * @param mchId 商户ID * @param certPath 证书位置 * @return */ public static String postData(String url, String xmlObj, String mchId, String certPath) { // 加载证书 try { initCert(mchId, certPath); } catch (Exception e) { e.printStackTrace(); } String result = null; HttpPost httpPost = new HttpPost(url); // 得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别 StringEntity postEntity = new StringEntity(xmlObj, "UTF-8"); httpPost.addHeader("Content-Type", "text/xml"); httpPost.setEntity(postEntity); // 根据默认超时限制初始化requestConfig requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build(); // 设置请求器的配置 httpPost.setConfig(requestConfig); try { HttpResponse response = null; try { response = httpClient.execute(httpPost); } catch (IOException e) { e.printStackTrace(); } HttpEntity entity = response.getEntity(); try { result = EntityUtils.toString(entity, "UTF-8"); } catch (IOException e) { e.printStackTrace(); } } finally { httpPost.abort(); } return result; } /** * 加载证书 * * @param mchId 商户ID * @param certPath 证书位置 * @throws Exception */ private static void initCert(String mchId, String certPath) throws Exception { // 证书密码,默认为商户ID String key = mchId; // 证书的路径 String path = certPath; // 指定读取证书格式为PKCS12 KeyStore keyStore = KeyStore.getInstance("PKCS12"); // 读取本机存放的PKCS12证书文件 FileInputStream instream = new FileInputStream(new File(path)); try { // 指定PKCS12的密码(商户ID) keyStore.load(instream, key.toCharArray()); } finally { instream.close(); } SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build(); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] {"TLSv1"}, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); } }