附官方地址:
微信官方api 微信公众号获取用户openid
微信api说明,请求需要双向证书。 所以需要去商户管理后台下载api证书 微信支付平台
在支付平台->账户中心->api安全 下载证书 并设置秘钥
然后在营销中心->支付后配置 查看发起提现公众号的appid 此appid一定要和获取用户openid的appid一致
将上图这个id记住 这是商户号
从微信支付平台中我们要下载证书,设置秘钥,确保appid一致,获取商户号
api具体请求就不分析了 有文档 直接上代码
package com.liuyb.model;
/**
* @Auther: liuyubo
* @Date: 2018/8/10 20:30
* @Description:实体类
*/
public class EnterprisesPayment {
/**
* 商户账号appid
* 申请商户号的appid或商户号绑定的appid
*/
private String mch_appid;
/**
* 商户号 微信支付分配的商户号
*/
private String mchid;
/**
*设备号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;
public String getMch_appid() {
return mch_appid;
}
public void setMch_appid(String mch_appid) {
this.mch_appid = mch_appid;
}
public String getDevice_info() {
return device_info;
}
public void setDevice_info(String device_info) {
this.device_info = device_info;
}
public String getNonce_str() {
return nonce_str;
}
public void setNonce_str(String nonce_str) {
this.nonce_str = nonce_str;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getPartner_trade_no() {
return partner_trade_no;
}
public void setPartner_trade_no(String partner_trade_no) {
this.partner_trade_no = partner_trade_no;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getCheck_name() {
return check_name;
}
public void setCheck_name(String check_name) {
this.check_name = check_name;
}
public String getRe_user_name() {
return re_user_name;
}
public void setRe_user_name(String re_user_name) {
this.re_user_name = re_user_name;
}
public Integer getAmount() {
return amount;
}
public void setAmount(Integer amount) {
this.amount = amount;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getSpbill_create_ip() {
return spbill_create_ip;
}
public void setSpbill_create_ip(String spbill_create_ip) {
this.spbill_create_ip = spbill_create_ip;
}
public String getMchid() {
return mchid;
}
public void setMchid(String mchid) {
this.mchid = mchid;
}
}
package com.liuyb.util;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import javax.net.ssl.SSLContext;
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.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
/**
* @Auther: liuyubo
* @Date: 2018/8/10 20:39
* @Description: 加载证书 发送请求
*/
public class ClientCustomSSL {
public static String doRefund(String url,String xmlData) throws Exception {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(new File(""));//P12文件目录 写证书的项目路径
try {
keyStore.load(instream, "xxxx".toCharArray());//这里写密码..默认是你的MCHID 证书密码
} finally {
instream.close();
}
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, "xxxx".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 returnMessage = EntityUtils.toString(response.getEntity(), "UTF-8");
EntityUtils.consume(entity);
return returnMessage; //返回后自己解析结果
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
}
/**
* @Auther: liuyubo
* @Date: 2018/8/10 20:46
* @Description: 微信提现 xml数据 签名等
*/
public class WeixinpayUtil {
private static final Logger LOG = Logger.getLogger(WeixinpayUtil.class);
public static String createDocumentForEnterprisesPayment(EnterprisesPayment enterprisesPayment) {
final StringBuffer result = new StringBuffer();
result.append("");
result.append("" + enterprisesPayment.getMch_appid() + " ");
result.append("" + enterprisesPayment.getMchid() + " ");
result.append("" + enterprisesPayment.getNonce_str() + " ");
result.append("" + enterprisesPayment.getPartner_trade_no() + " ");
result.append("" + enterprisesPayment.getOpenid() + " ");
result.append("" + enterprisesPayment.getCheck_name() + " ");
result.append("" + enterprisesPayment.getRe_user_name() + " ");
result.append("" +enterprisesPayment.getAmount()+ " ");
result.append("" + enterprisesPayment.getDesc() + " ");
result.append("" + enterprisesPayment.getSpbill_create_ip() + " ");
result.append("" + enterprisesPayment.getSign() + " ");
result.append(" ");
return result.toString();
}
public static String getSignCode(Map map,String keyValue) {
String result = "";
try {
List> infoIds = new ArrayList>(map.entrySet());
// 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)
Collections.sort(infoIds, new Comparator>() {
public int compare(Map.Entry o1, Map.Entry o2) {
return (o1.getKey()).toString().compareTo(o2.getKey());
}
});
// 构造签名键值对的格式
StringBuilder sb = new StringBuilder();
for (Map.Entry item : infoIds) {
if (item.getKey() != null || item.getKey() != "") {
String key = item.getKey();
String val = item.getValue();
if (!(val == "" || val == null)) {
sb.append(key + "=" + val + "&");
}
}
}
sb.append("key="+keyValue);
result = sb.toString();
//进行MD5加密
result = WeixinpayUtil.md5(result).toUpperCase();
} catch (Exception e) {
return null;
}
return result;
}
/**
* 生成32位编码
* @return string
*/
public static String getUUID(){
String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
return uuid;
}
/**
* 生成提现订单号
* @return string
*/
public static String getOrderId() {
int machineId = 1;//最大支持1-9个集群机器部署
int hashCodeV = UUID.randomUUID().toString().hashCode();
if(hashCodeV < 0) {//有可能是负数
hashCodeV = - hashCodeV;
}
return machineId+String.format("%015d", hashCodeV);
}
/**
* md5加密
* @param text
* @return
*/
public static String md5(final String text) {
//自己写一个md5方法 这里我就不写了 记得大写
return Md5Encrypt.md5(text).toUpperCase();
}
}
/**
* @Auther: liuyubo
* @Date: 2018/8/10 20:59
* @Description: test
*/
public class Test {
private SortedMap sortedMap = new TreeMap<>();
public static void main(String[] args) {
String sginCode = getSgin(openid,amount);//获取用户openid 和 用户要提现的金额 拿到签名
EnterprisesPayment enterprisesPayment = addEnterprisesPayment(openid,amount,sginCode);//拿到签名后加密得到要发送到对象数据
String enterprisesPaymentXML = WeixinpayUtil.createDocumentForEnterprisesPayment(enterprisesPayment);
//封装xml 数据发送
String returnXmlData =
ClientCustomSSL.doRefund("url地址",enterprisesPaymentXML);
}
public EnterprisesPayment addEnterprisesPayment(String openid, Integer amount,String sginCode){
EnterprisesPayment enterprisesPayment = new EnterprisesPayment();
enterprisesPayment.setMch_appid("appid");//商户号appid
enterprisesPayment.setMchid("商户号");//商户号
// enterprisesPayment.setDevice_info(null);//设备号 非必填
enterprisesPayment.setNonce_str(sortedMap.get("nonce_str"));//随机字符串
enterprisesPayment.setSign(sginCode);//签名
enterprisesPayment.setPartner_trade_no(sortedMap.get("partner_trade_no"));//商户订单号
enterprisesPayment.setOpenid(openid);
enterprisesPayment.setCheck_name("NO_CHECK");
enterprisesPayment.setRe_user_name(null); 根据checkName字段判断是否需要
enterprisesPayment.setAmount(amount);//金额
enterprisesPayment.setDesc("desc");//描述
enterprisesPayment.setSpbill_create_ip("ip");//ip地址
return enterprisesPayment;
}
public String getSgin(String openid, Integer amount) {
sortedMap.put("mch_appid","appid");
sortedMap.put("mchid","商户号");
sortedMap.put("nonce_str", WeixinpayUtil.getUUID());
sortedMap.put("partner_trade_no", WeixinpayUtil.getOrderId());
sortedMap.put("openid", openid);
sortedMap.put("check_name", "NO_CHECK");
sortedMap.put("amount", amount.toString());
sortedMap.put("desc", "desc");
sortedMap.put("spbill_create_ip", "ip");
sortedMap.put("re_user_name", "null");
return WeixinpayUtil.getSignCode(sortedMap,"api秘钥");
}
}
具体就这些吧 不懂到来问我 q群 8028492