企业付款到个人(提现),更加详细内容请参阅官方文档
package com.jkkj.util;
import com.jkkj.entity.tool.EnterprisesPayment;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import javax.net.ssl.SSLContext;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* @program: jianyi
* @description:
* @author: Mr.Jkx
* @create: 2020/7/13 17:15
*/
public class JkxTest {
/**
* 企业付款到个人请求路径
*/
private static final String WX_PAY_COMPANY_TO_USER_UEL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
public static void main(String[] args) throws Exception {
EnterprisesPayment enterprisesPayment = new EnterprisesPayment();
// 小程序appid
enterprisesPayment.setMch_appid("mch_appid");
// 商户号mchid
enterprisesPayment.setMchid("1573074201");
// 商户平台支付秘钥
enterprisesPayment.setPay_key("pay_key");
enterprisesPayment.setNonce_str(UUIDUtil.getUUID());
enterprisesPayment.setPartner_trade_no(UUIDUtil.getUUID());
// 关注小程序用户openid
enterprisesPayment.setOpenid("openid");
enterprisesPayment.setCheck_name("NO_CHECK");
enterprisesPayment.setAmount(100);
enterprisesPayment.setDesc("企业付款到个人描述");
// Ip地址 该IP同在商户平台设置的IP白名单中的IP没有关联,该IP可传用户端或者服务端的IP。
enterprisesPayment.setSpbill_create_ip("spbill_create_ip");
Map<String, Object> map = wxWithdraw(enterprisesPayment, "C:/file/refund/apiclient_cert.p12");
System.out.println(map);
}
public static Map<String, Object> wxWithdraw(EnterprisesPayment enterprisesPayment, String certificatepath) throws Exception {
String mchid = enterprisesPayment.getMchid();
//生成的随机字符串
String stringA = "amount=" + enterprisesPayment.getAmount()
+ "&check_name=" + enterprisesPayment.getCheck_name()
+ "&desc=" + enterprisesPayment.getDesc()
+ "&mch_appid=" + enterprisesPayment.getMch_appid()
+ "&mchid=" + mchid
+ "&nonce_str=" + enterprisesPayment.getNonce_str()
+ "&openid=" + enterprisesPayment.getOpenid()
+ "&partner_trade_no=" + enterprisesPayment.getPartner_trade_no()
+ "&spbill_create_ip=" + enterprisesPayment.getSpbill_create_ip()
+ "&key=" + enterprisesPayment.getPay_key();
String sign = Md5Util.md5(stringA).toUpperCase();
String xml = "" +
"" + enterprisesPayment.getAmount() + "" +
"" + enterprisesPayment.getCheck_name() + "" +
"" + enterprisesPayment.getDesc() + "" +
"" + enterprisesPayment.getMch_appid() + "" +
"" + mchid + "" +
"" + enterprisesPayment.getNonce_str() + "" +
"" + enterprisesPayment.getOpenid() + "" +
"" + enterprisesPayment.getPartner_trade_no() + "" +
"" + enterprisesPayment.getSpbill_create_ip() + "" +
"" + sign + "" +
"";
System.out.println("调试模式_提现接口 请求XML数据:" + xml);
//调用统一下单接口,并接受返回的结果
String result = payOfCertificate(WX_PAY_COMPANY_TO_USER_UEL, xml, certificatepath, mchid);
// 将解析结果存储在HashMap中
Map map = doXMLParse(result);
return map;
}
/**
* @Description: 加载证书 发送请求
* @Author: Mr.Jkx
* @date: 2020/3/23 16:06
* url:退款请求地址
* data:请求数据
* certificatepath:证书路径
* mch_id:商品平台mch_id
*/
public static String payOfCertificate(String url, String data, String certificatepath, String mch_id) throws Exception {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream is = new FileInputStream(new File(certificatepath));
try {
keyStore.load(is, mch_id.toCharArray());
} finally {
is.close();
}
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mch_id.toCharArray()).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[]{"TLSv1"},
null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
);
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
try {
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);
try {
HttpEntity entity = response.getEntity();
String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
EntityUtils.consume(entity);
return jsonStr;
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
/**
* 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
*
* @param strxml
* @return
*/
public static Map doXMLParse(String strxml) throws Exception {
if (null == strxml || "".equals(strxml)) {
return null;
}
Map m = new HashMap();
InputStream in = String2Inputstream(strxml);
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(in);
Element root = doc.getRootElement();
List list = root.getChildren();
Iterator it = list.iterator();
while (it.hasNext()) {
Element e = (Element) it.next();
String k = e.getName();
String v = "";
List children = e.getChildren();
if (children.isEmpty()) {
v = e.getTextNormalize();
} else {
v = getChildrenText(children);
}
m.put(k, v);
}
//关闭流
in.close();
return m;
}
/**
* 获取子结点的xml
*
* @param children
* @return String
*/
public static String getChildrenText(List children) {
StringBuffer sb = new StringBuffer();
if (!children.isEmpty()) {
Iterator it = children.iterator();
while (it.hasNext()) {
Element e = (Element) it.next();
String name = e.getName();
String value = e.getTextNormalize();
List list = e.getChildren();
sb.append("<" + name + ">");
if (!list.isEmpty()) {
sb.append(getChildrenText(list));
}
sb.append(value);
sb.append("" + name + ">");
}
}
return sb.toString();
}
public static InputStream String2Inputstream(String str) {
return new ByteArrayInputStream(str.getBytes());
}
}
package com.jkkj.entity.tool;
public class EnterprisesPayment {
/**
* 商户账号appid
* 申请商户号的appid或商户号绑定的appid
*/
private String mch_appid;
/**
* 商户号 微信支付分配的商户号
*/
private String mchid;
/**
* 支付秘钥
*/
private String payKey;
/**
* 设备号013467007045764
* 微信支付分配的终端设备号
*/
private String device_info;
/**
* 随机字符串 5K8264ILTKCH16CQ2502SI8ZNMTM67VS
* 随机字符串,不长于32位
*/
private String nonce_str;
/**
* 签名 C380BEC2BFD727A4B6845133519F3AD6
*/
private String sign;
/**
* 商户订单号 商户订单号,需保持唯一性(只能是字母或者数字,不能包含有符号)
*/
private String partner_trade_no;
/**
* 用户openid 商户appid下,某用户的openid
*/
private String openid;
/**
* 校验用户姓名选项 不校验真实姓名 NO_CHECK:不校验真实姓名 FORCE_CHECK:强校验真实姓名
*/
private String check_name;
/**
* 收款用户姓名 收款用户真实姓名。 如果check_name设置为FORCE_CHECK,则必填用户真实姓名
*/
private String re_user_name;
/**
* 金额 企业付款金额,单位为分
*/
private Integer amount;
/**
* 企业付款描述信息 理赔 企业付款操作说明信息
*/
private String desc;
/**
* Ip地址 该IP同在商户平台设置的IP白名单中的IP没有关联,该IP可传用户端或者服务端的IP。
*/
private String spbill_create_ip;
/**
* 微信支付秘钥
*/
private String pay_key;
/**
* get,set略。。。
*/
}