- 微信提现到零钱代码,可直接运行,代码如下:
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
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;
import org.junit.Test;
import com.github.wxpay.sdk.MD5Util;
/**
* @ClassName: [WeiXinCashTest]
* @Description: [微信提现到零钱]
* @Author: [songdx]
* @CreateDate: [2018年11月11日 下午4:32:24]
* @Version: [v1.0]
*/
public class WeiXinCashTest {
@Test
public void OldBook(){
//1.0 封装参数
String appid = \"wx**************\"; //微信公众号的appid
String mch_id = \"***********\"; //商户号
String nonce_str = \"******************\"; //生成随机数
String partner_trade_no = \"******************\"; //生成商户订单号
String openid = \"**********************\"; // 支付给用户openid
String check_name = \"NO_CHECK\"; //是否验证真实姓名呢
String re_user_name = \"小宋\"; //收款用户姓名
String amount = \"100\"; //企业付款金额,单位为分
String desc = \"测试开发,稍后会还给公司的\"; //企业付款操作说明信息。必填。
String spbill_create_ip = \"127.0.0.1\"; //
//2.0 生成map集合
SortedMap<String, String> packageParams = new TreeMap<String, String>();
packageParams.put(\"mch_appid\", appid); //微信公众号的appid
packageParams.put(\"mchid\", mch_id); //商务号
packageParams.put(\"nonce_str\",nonce_str); //随机生成后数字,保证安全性
packageParams.put(\"partner_trade_no\",partner_trade_no); //生成商户订单号
packageParams.put(\"openid\",openid); // 支付给用户openid
packageParams.put(\"check_name\",check_name); //是否验证真实姓名呢
packageParams.put(\"re_user_name\",re_user_name);//收款用户姓名
packageParams.put(\"amount\",amount); //企业付款金额,单位为分
packageParams.put(\"desc\",desc); //企业付款操作说明信息。必填。
packageParams.put(\"spbill_create_ip\",spbill_create_ip); //调用接口的机器Ip地址
//3.0 生成签名
String sign = createSign(\"UTF-8\",packageParams,\"************************************\");
//4.0 封装退款对象
packageParams.put(\"sign\", sign);
//5.0将当前的map结合转化成xml格式
String reuqestXml = getRequestXml(packageParams);
//6.0获取需要发送的url地址
String wxUrl = \"https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers\"; //获取退款的api接口
try {
String weixinPost = doRefund(wxUrl, reuqestXml).toString();
//7.0 解析返回的xml数据
//得到解析数据后根据返回内容自行解析下即可
System.out.println(\"解析返回的数据:\"+weixinPost);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @Description: 封装为xml
* @param @param parameters
* @param @return
* @return String
* @throws
* @author songdx
* @date 2018年11月11日
*/
public static String getRequestXml(SortedMap<String,String> parameters){
StringBuffer sb = new StringBuffer();
sb.append(\"<xml>\");
Set es = parameters.entrySet();
Iterator it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
String v = (String)entry.getValue();
if (\"attach\".equalsIgnoreCase(k)||\"body\".equalsIgnoreCase(k)||\"sign\".equalsIgnoreCase(k)) {
sb.append(\"<\"+k+\">\"+\"<![CDATA[\"+v+\"]]></\"+k+\">\");
}else {
sb.append(\"<\"+k+\">\"+v+\"</\"+k+\">\");
}
}
sb.append(\"</xml>\");
return sb.toString();
}
/**
* @Description: 发起退款请求
* @param @param url
* @param @param data
* @param @return
* @param @throws Exception
* @return String
* @throws
* @author songdx
* @date 2018年11月11日
*/
public String doRefund(String url,String data) throws Exception {
char[] password = \"**********\".toCharArray();
KeyStore keyStore = KeyStore.getInstance(\"PKCS12\");
FileInputStream instream = new FileInputStream(new File(\"D://apiclient_cert.p12\"));//P12文件目录
try {
keyStore.load(instream, password);//这里写密码
} finally {
instream.close();
}
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, password)//这里也是写密码的
.build();
// Allow TLSv1 protocol only
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\"));
System.out.println(\"请求的内容:\"+data);
CloseableHttpResponse response = httpclient.execute(httpost);
try {
HttpEntity entity = response.getEntity();
String jsonStr = EntityUtils.toString(response.getEntity(), \"UTF-8\");
System.out.println(\"微信返回的内容:\"+jsonStr);
EntityUtils.consume(entity);
return jsonStr;
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
/**
* 微信支付签名算法sign
* @param characterEncoding
* @param parameters
* @return
*/
@SuppressWarnings(\"unchecked\")
public static String createSign(String characterEncoding,SortedMap<String,String> parameters,String key){
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=\" + key);
System.out.println(\"parameters=\" + parameters);
System.out.println(\"key=\" + key);
System.out.println(\"===========================================\");
System.out.println(\"===========================================\");
String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
System.out.println(\"================sign:\"+sign+\"=======================\");
return sign;
}
}
注意事项:
在开发微信提现时也遇到很多坑和注意的地方,比如签名问题,NO_AUTH | 产品权限验证问题
1. 开通条件:入驻满90天,截止今日往回推30天连续不间断保持有交易(每天可交易一分钱)
2. 登录微信支付平台,地址:https://pay.weixin.qq.com/index.php
3. 开通地址需前往【商户平台】->【产品中心】申请开通
4. 签名错误格式和顺序问题,参照上面签名代码即可(加密形式需要注意下或采用默认)
5. 提现会从“运营账户”扣款,操作时需要保证账户余额有钱,否则提示余额不足情况
版权声明
本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。


