首先下载证书,证书下载在商户号平台下载
微信提现的请求地址:WX_WITHDRAW_QPAY_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"
下面是我的post的信息,参数替换成自己的就可以了(其中的一些方法放在文章尾)
private static final String WX_WITHDRAW_QPAY_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
/**
*
*
* @param userId
* @param amount
* 提现金额 单位:分
*/
public int withdrawToUserWallet(long userId, int cfgId, int amount) {
int retErrorCode = 0;
String openid = "我的openid";
if (StringUtils.isEmpty(openid)) {
return -1;
}
String appId = "appid";
String mchId = "商户id";
String tranceDesc = "放置战机提现";
String randomNumberStr = PayUtils.getNonceStr(32);
String wxOpUserId = ComConfigParse.sysPf.WX_OP_USER_ID;
String wxUserPasswd = ComConfigParse.sysPf.WX_OP_USER_PASSWD;
String orderId = PayUtils.getOrderId();
String localIp = PayUtils.getLocalIP();
/**
* ==================================================================================================================
*/
/**
* ==================================================封装提现所需参数================================================
*/
/**
* ==================================================================================================================
*/
Map<String, String> restmap = null;
try {
Map<String, String> parm = new HashMap<String, String>();
// parm.put("input_charset", "UTF-8");
parm.put("mch_appid", appId); // 公众账号appid
parm.put("mchid", mchId); // 商户号
parm.put("desc", tranceDesc); // 企业付款描述信息
parm.put("nonce_str", randomNumberStr); // 随机字符串
parm.put("openid", openid); // 用户openid oCVr20N2YLH9VQztnkZTaCj2aYYY
parm.put("partner_trade_no", orderId); // 商户订单号
parm.put("check_name", "NO_CHECK"); // 校验用户姓名选项 OPTION_CHECK
// parm.put("re_user_name", "安迪"); //check_name设置为FORCE_CHECK或OPTION_CHECK,则必填
parm.put("spbill_create_ip", localIp); // Ip地址
parm.put("amount", amount + ""); // 转账金额
parm.put("sign", PayUtils.getSign(parm, ComConfigParse.sysPf.WX_API_PATERNERKEY));
String xml = XmlUtil.xmlFormat(parm, false);
// String resetxml = HttpUtils.post(QQWithdraw.QQ_WITHDRAW_QPAY_URL,xml,
// "UTF-8");
String resetxml = ClientCustomSSLUtil.postWXCustom(WXWithdraw.WX_WITHDRAW_QPAY_URL, xml);
restmap = XmlUtil.xmlParse(resetxml);
} catch (Exception e) {
//
logger.info(e);
return -1;
}
/**
* =======================================查询提现结果==========================================
*/
if (!CollectionUtils.isEmpty(restmap) && "SUCCESS".equals(restmap.get("result_code"))) {
logger.info("提现成功");
/**
* =======================================提现成功的处理===================================================
*/
retErrorCode = 1;
} else {
if (!CollectionUtils.isEmpty(restmap)) {
logger.info("转账失败:" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
/**
* =======================================提现失败的处理===================================================
*/
switch (restmap.get("err_code")) {
case "AMOUNT_LIMIT": {
retErrorCode = 2;
logger.info("*****************************************************");
logger.info("*********************金额超额********************************");
break;
}
case "PARAM_ERROR": {
// retErrCodr = "请确定收款用户的账号是否正常";
retErrorCode = 3;
logger.info("*****************************************************");
logger.info("*********************参数错误********************************");
break;
}
case "OPENID_ERROR": {
// retErrCodr = "";
retErrorCode = 4;
logger.info("*****************************************************");
logger.info("*********************openid错误********************************");
break;
}
case "NOTENOUGH": {
// retErrCodr = "商户余额不足,请联系客户充值营销账号";
retErrorCode = 5;
logger.info("*****************************************************");
logger.info("*********************商户余额不足,请联系客户充值营销账号********************************");
break;
}
case "TOTAL_FEE_OUT_OF_LIMIT": {
// retErrCodr = "提现金额较低或较高,请切换金额操作";
retErrorCode = 6;
break;
}
case "V2_ACCOUNT_SIMPLE_BAN": {
// retErrCodr = "未实名无法收款,请实名后再试";
retErrorCode = 7;
break;
}
case "CA_ERROR": {
// retErrCodr = "商户证书非法";
retErrorCode = 8;
break;
}
default:
// retErrCodr = "服务器繁忙";
retErrorCode = 8;
break;
}
}
}
return retErrorCode;
}
package com.hpw.minigame.planeKing.withdraw;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import com.hpw.config.ComConfigParse;
import com.hpw.utils.DateUtils;
import com.hpw.utils.MD5Utils;
import com.hpw.utils.StringUtils;
public class PayUtils {
//
public static String getOrderId() {
StringBuilder sb = new StringBuilder();
sb.append(DateUtils.dateToString(new Date(), "yyMMddHHmmss"));
sb.append("g9003s");// gameid (上报gameid) serveridx
sb.append(ComConfigParse.sysGame.game_serverIdx);
sb.append(StringUtils.getUniqueID(13));
return sb.toString();
}
public static String getNonceStr(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();
}
public static String MD5OpUserPasswd(String passwd) {
return MD5Utils.md5(passwd);
}
/**
* 构建签名
*
* @param params
* @param paternerKey
* API密匙
* @return
* @throws UnsupportedEncodingException
*/
public static String getSign(Map<String, String> params, String paternerKey) throws UnsupportedEncodingException {
String srcStr = createSign(params, false) + "&key=" + paternerKey;
return MD5Utils.md5(srcStr).toUpperCase();
}
// /**
// * * 生成 MD5 * * @param data 待处理数据 * @return MD5结果
// */
// public static String MD5(String data) throws Exception {
// MessageDigest md = MessageDigest.getInstance("MD5");
// byte[] array = md.digest(data.getBytes("UTF-8"));
// StringBuilder sb = new StringBuilder();
// for (byte item : array) {
// sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
// }
// return sb.toString().toUpperCase();
// }
/**
* 构造签名
*
* @param params
* @param encode
* @return
* @throws UnsupportedEncodingException
*/
private static String createSign(Map<String, String> params, boolean encode) throws UnsupportedEncodingException {
Set<String> keysSet = params.keySet();
Object[] keys = keysSet.toArray();
Arrays.sort(keys);
StringBuffer temp = new StringBuffer();
boolean first = true;
for (Object key : keys) {
if (key == null || StringUtils.isEmpty(params.get(key))) // 参数为空不参与签名
continue;
if (first) {
first = false;
} else {
temp.append("&");
}
temp.append(key).append("=");
Object value = params.get(key);
String valueStr = "";
if (null != value) {
valueStr = value.toString();
}
if (encode) {
temp.append(URLEncoder.encode(valueStr, "UTF-8"));
} else {
temp.append(valueStr);
}
}
return temp.toString();
}
/**
* 获得本机IP
* */
public static String getLocalIP() {
InetAddress addr = null;
try {
addr = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
byte[] ipAddr = addr.getAddress();
String ipAddrStr = "";
for (int i = 0; i < ipAddr.length; i++) {
if (i > 0) {
ipAddrStr += ".";
}
ipAddrStr += ipAddr[i] & 0xFF;
}
return ipAddrStr;
}
}