微信提现(企业付款到个人含demo)
https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2 企业付款文档
```
public class Configure {
// 商户密钥
public static String key = "这里是你的商户秘钥";
private static String appID="应用ID 也就是APPID";
private static String mch_id="这是你的商户号";
//1.本地测试 (这里写了3个url 根据你本身的环境来定 这里配置的是你的证书路径 路径一定要写对 不然各种报错)
//private static String url = "\\apiclient_cert.p12";
//2.这是window环境上的测试路径
//private static String url = "C:\\Users\\THINK\\Desktop\\apiclient_cert.p12";
//3.这是linux环境下测试的路径
//private static String url = "\\usr\\local\\apache-tomcat-8.5.16\\webapps\\apiclient_cert.p12";
public static String getKey() {
return key;
}
public static void setKey(String key) {
Configure.key = key;
}
public static String getAppID() {
return appID;
}
public static void setAppID(String appID) {
Configure.appID = appID;
}
public static String getMch_id() {
return mch_id;
}
public static void setMch_id(String mch_id) {
Configure.mch_id = mch_id;
}
public static String getUrl() {
return url;
}
}
这里可以看到必填项肯定是要填写的塞,其他按照自己的需求而定,我示例的是不要求用户为真实姓名自己```
//如上图根据实际需求填写 我这里是不校验用户真实姓名为例
//openid值某用户的openid amoun指要体现的金额
@ResponseBody
@RequestMapping("/weixinWithdraw")
public Map<String, Object> weixinTransfers(String openid, Integer amount) throws IllegalAccessException {
Map<String, Object> map = new HashMap<String, Object>();
try {
log.info(">>>>>>>>>>>企业微信提现start");
//这里省略对金额的校验 比如不能小于为0 以及负数 单笔不能超过多少啥的.....
// 提现金额
amount = amount * 100;
if (!openid.equals("") || !openid.equals(null)) {
String url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; // 接口链接
InetAddress ia = InetAddress.getLocalHost();
String ip = ia.getHostAddress(); // 获取本机IP地址
String nonce_str = PayCommonUtil.CreateNoncestr();// 随机获取随机字符串
String appid = Configure.getAppID();// APPID
String mchid = Configure.getMch_id();// 微信支付分配的商户号
// 获取订单号
WithdrawCashVo list = homeService.getOderNo();
if (list != null) {
String partner_trade_no = list.getOderNo();
log.info("订单号>>>>>>>>>>>>>>>>>>>>>>>" + partner_trade_no);
String desc = "企业付款描述信息"; // 企业付款描述信息 自己填写的哈
// 设置支付参数
SortedMap<Object, Object> signParams = new TreeMap<Object, Object>();
signParams.put("mch_appid", appid); // 微信分配的公众账号ID(企业号corpid即为此appId)
signParams.put("mchid", mchid);// 微信支付分配的商户号
signParams.put("nonce_str", nonce_str); // 随机字符串,不长于32位
signParams.put("partner_trade_no", partner_trade_no); // 商户订单号,需保持唯一性
signParams.put("openid", openid); // 商户appid下,某用户的openid
signParams.put("check_name", "NO_CHECK"); // 我这里填写的是NO_CHECK:不校验真实姓名
signParams.put("amount", amount); // 企业付款金额,单位为分
signParams.put("desc", desc); // 企业付款操作说明信息。必填。
signParams.put("spbill_create_ip", ip); // 调用接口的机器Ip地址
// 生成支付签名,要采用URLENCODER的原始值进行MD5算法!
String sign = WXSignUtils.createSign("UTF-8", signParams);
String data = "<xml><mch_appid>";
data += appid + "</mch_appid><mchid>"; // APPID
data += mchid + "</mchid><nonce_str>"; // 商户ID
data += nonce_str + "</nonce_str><partner_trade_no>"; // 随机字符串
data += partner_trade_no + "</partner_trade_no><openid>"; // 订单号
data += openid + "</openid><check_name>NO_CHECK</check_name><amount>"; // 是否强制实名验证
data += amount + "</amount><desc>"; // 企业付款金额,单位为分
data += desc + "</desc><spbill_create_ip>"; // 企业付款操作说明信息。必填。
data += ip + "</spbill_create_ip><sign>";// 调用接口的机器Ip地址
data += sign + "</sign></xml>";// 签名
//System.out.println(data);
/// 加载证书
// 获取证书,发送POST请求;
KeyStore keyStore = KeyStore.getInstance("PKCS12");
System.out.println(Configure.getUrl().replaceAll("\\\\", "/"));
FileInputStream instream = new FileInputStream(
new File(Configure.getUrl().replaceAll("\\\\", "/"))); // 从配置文件里读取证书的路径信息
keyStore.load(instream, mchid.toCharArray());// 证书密码是商户ID
instream.close();
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchid.toCharArray()).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,
new String[] { "TLSv1" }, null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
HttpPost httpost = new HttpPost(url); //
httpost.addHeader("Connection", "keep-alive");
httpost.addHeader("Accept", "*/*");
httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
httpost.addHeader("Host", "api.mch.weixin.qq.com");
httpost.addHeader("X-Requested-With", "XMLHttpRequest");
httpost.addHeader("Cache-Control", "max-age=0");
httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
httpost.setEntity(new StringEntity(data, "UTF-8"));
CloseableHttpResponse response = httpclient.execute(httpost);
HttpEntity entity = response.getEntity();
String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
System.out.println("请求微信零钱提现返回的数据为:\n" + jsonStr);
EntityUtils.consume(entity);
// 把返回的字符串解释成DOM节点
Document dom = DocumentHelper.parseText(jsonStr);
Element root = dom.getRootElement();
String returnCode = root.element("result_code").getText(); // 获取返回代码
//----------------分割线---------------------------
//这里便是写提现成功后的操作啦
if (StringUtils.equals(returnCode, "SUCCESS")) { // 判断返回码为成功还是失败
String payment_no = root.element("payment_no").getText(); // 获取支付流水号
String payment_time = root.element("payment_time").getText(); // 获取支付时间
PayEntityUtil util = new PayEntityUtil();
util.setPayment_no(payment_no);
util.setPayment_time(payment_time);
util.setReturnCode(returnCode);
// 到了这步就是做 提现成功后修改提现状态啦
homeService.updateStateByTX(partner_trade_no);
//返回信息
map.put("State", true);
map.put("Message", util);
map.put("Time", String.valueOf(System.currentTimeMillis()));
return map;
} else {
String err_code = root.element("err_code").getText(); // 获取错误代码
String err_code_des = root.element("err_code_des").getText();// 获取错误描述
PayEntityErrorUtil utils = new PayEntityErrorUtil();
utils.setErr_code(err_code);
utils.setErr_code_des(err_code_des);
//返回错误信息
map.put("State", false);
map.put("Message", utils);
map.put("Time", String.valueOf(System.currentTimeMillis()));
}
}
} else {
map.put("State", false);
map.put("Message", "抱歉没有获得openid。");
map.put("Time", String.valueOf(System.currentTimeMillis()));
return map;
}
} catch (Exception e) {
map.put("State", false);
map.put("Message", "企业付款异常");
map.put("Time", String.valueOf(System.currentTimeMillis()));
return map;
}
return map;
}