java开发微信提现_java 微信提现至零钱
需要用户绑定微信,获取用户openid,通过openid调取微信接口企业付款到零钱接口:
package com.framework.loippi.plugins.wxapppay.withdrawal;
import com.framework.loippi.cache.ConfigCache;
import com.framework.loippi.plugins.wxapppay.MD5;
import com.framework.loippi.plugins.wxapppay.MD5Util;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
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.jdom.Document;
import org.jdom.input.SAXBuilder;
import org.springframework.util.ResourceUtils;
import javax.net.ssl.SSLContext;
import java.io.*;
import java.math.BigDecimal;
import java.security.KeyStore;
import java.util.*;
public class WeChatWithdrawalUtil {
private static final String TRANS_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
// 微信商户appkey
private static String appKey = ConfigCache.getConfig("wx.pay.key");
// 微信商户证书路径
private static String certPath = ConfigCache.getConfig("wx.pay.ssl.pkcs12File");
// 与商户号关联应用(如微信公众号/小程序)的APPID
private static String mchAppId = ConfigCache.getConfig("wx.app.appId");
// 微信支付分配的商户号
private static String mchId = ConfigCache.getConfig("wx.pay.mchId");
// 商户名称, 如'XXX服务号'
private static String mchName = "顺路汽车养护平台";
//证书密码
private static String sslPassword = ConfigCache.getConfig("wx.pay.ssl.password");
// 请求器的配置
private static RequestConfig requestConfig;
// 连接超时时间,默认10秒
private static int socketTimeout = 10000;
// 传输超时时间,默认30秒
private static int connectTimeout = 30000;
/**
*微信提现
* @param partnerTradeNo 商户订单号,需保持唯一性(只能是字母或者数字,不能包含有其他字符) 必填
* @param openid 用户的openid 必填 用户提现需要判断是小程序还是APP,小程序传小程序openid,app传微信openId(app登录使用)
* @param amount 付款金额 单位为元 必填
* @param desc 付款备注 必填
* @return result 返回结果列子(是一个xml字符串):
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* 判断 失败:result.contains("CDATA[FAIL]") 返回true 失败 false成功
* SAXBuilder saxBuilder = new SAXBuilder();
* Document doc = saxBuilder.build(new StringReader(result));
* 获取错误原因:return doc.getRootElement().getChild("err_code_des").getValue();
* 成功 获取交易单号:return doc.getRootElement().getChild("payment_no").getValue();
*/
public static String doTransfers(String partnerTradeNo, String openid, BigDecimal amount, String desc){
String result ="success";
try
{
String nonceStr = genNonceStr();
// 1.计算参数签名
SortedMap parameters = new TreeMap();
parameters.put("amount", amount.multiply(new BigDecimal("100")).intValue()+"");
parameters.put("check_name", "NO_CHECK");
parameters.put("desc", desc);
parameters.put("mchid", mchId);
parameters.put("mch_appid", mchAppId);
parameters.put("nonce_str", nonceStr);
parameters.put("openid", openid);
parameters.put("partner_trade_no", partnerTradeNo);
parameters.put("sign", createSign(parameters, appKey));
String data = SortedMaptoXml(parameters);
// data = new String(data.getBytes("gbk"), "utf-8");
// 3.加载证书请求接口
System.out.println(data);
result = weChatWithdrawal(data);
System.out.println(result);
if(result.contains("CDATA[FAIL]")){
SAXBuilder saxBuilder = new SAXBuilder();
Document doc = saxBuilder.build(new StringReader(result));
return doc.getRootElement().getChild("err_code_des").getValue();
}
}
catch (Exception e)
{
e.printStackTrace();
return "微信提现失败";
}
return result;
}
private static String createLinkString(String partnerTradeNo, String openid, BigDecimal amount, String desc, String nonceStr)
{
// 微信签名规则 https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=4_3
Map paramMap = new HashMap();
paramMap.put("mch_appid", mchAppId);
paramMap.put("mchid", mchId);
paramMap.put("openid", openid);
paramMap.put("amount", amount);
paramMap.put("check_name", "NO_CHECK");
paramMap.put("desc", desc);
paramMap.put("partner_trade_no", partnerTradeNo);
paramMap.put("nonce_str", nonceStr);
List keys = new ArrayList(paramMap.keySet());
Collections.sort(keys);
String prestr = "";
for (int i = 0; i < keys.size(); i++ )
{
String key = keys.get(i);
Object value = (Object)paramMap.get(key);
if (i == keys.size() - 1)
{// 拼接时,不包括最后一个&字符
prestr = prestr + key + "=" + value;
}
else
{
prestr = prestr + key + "=" + value + "&";
}
}
return prestr;
}
/**
* 证书使用
* 微信提现
*/
@SuppressWarnings("deprecation")
public static String weChatWithdrawal(String data) throws Exception {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
StringBuffer pkcsPath = new StringBuffer();
pkcsPath.append("classpath:").append(certPath);
System.out.println("certPath"+certPath);
InputStream instream = null;
try {
instream = ResourceUtils.getURL(pkcsPath.toString()).openStream();
} catch (IOException var10) {
}
if (instream == null) {
return null;
}
String result = "";
try {
keyStore.load(instream, sslPassword.toCharArray());
} finally {
instream.close();
}
// Trust own CA and all self-signed certs
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, sslPassword.toCharArray())
.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 httppost = new HttpPost("https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers");
StringEntity entitys = new StringEntity(data,"UTF-8");
httppost.setEntity((HttpEntity) entitys);
// 根据默认超时限制初始化requestConfig
requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();
// 设置请求器的配置
httppost.setConfig(requestConfig);
CloseableHttpResponse response = httpclient.execute(httppost);
try {
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity,"UTF-8");
} finally {
response.close();
}
} finally {
httpclient.close();
}
return result;
}
/**
* 生成32位随机数字
*/
public static String genNonceStr() {
Random random = new Random();
return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
}
/**
* 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
*/
public static String createSign(SortedMap packageParams, String AppKey) {
StringBuffer sb = new StringBuffer();
Set es = packageParams.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 (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + AppKey);
String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
return sign;
}
/**
* @param params
* @Author: WQY
* @Description:请求值转换为xml格式 SortedMap转xml
* @Date: 2017-9-7 17:18
*/
private static String SortedMaptoXml(SortedMap params) {
StringBuilder sb = new StringBuilder();
Set es = params.entrySet();
Iterator it = es.iterator();
sb.append("\n");
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
Object v = entry.getValue();
sb.append("");
sb.append(v);
sb.append("" + k + ">\n");
}
sb.append("");
return sb.toString();
}
public static void main(String[] args) {
try {
String results = WeChatWithdrawalUtil.doTransfers("20200921111523187","oZb9e5YIbMnqN1bSDoOVY3O7ITLY",new BigDecimal("1"),"");
System.out.println(results);
}catch(Exception e){
e.printStackTrace();
}
}
}
java开发微信提现_java 微信提现至零钱相关推荐
- 微信公众号Java开发-笔记01【微信公众号介绍、开发环境搭建】
学习网址:哔哩哔哩网站 微信公众号开发-Java版 微信公众号Java开发-笔记01[微信公众号介绍.开发环境搭建] 微信公众号Java开发-笔记02[] 微信公众号Java开发-笔记03[] 微信公 ...
- java调用微信加密_java微信消息加解密
今天心血来潮就信手拈来学了下微信消息加解密的知识,忽然觉得微信真的好强大.可能在大部分项目微信消息的加解密都用不上,但是仍然不排除有使用到的情况,如涉及金钱方面的微信应用包括商城类.金融类还有其他安全 ...
- java 开发环境配置_Java 开发环境配置
在本章节中我们将为大家介绍如何搭建Java开发环境.Windows 上安装开发环境 Linux 上安装开发环境 安装 Eclipse 运行 Java window系统安装java 下载JDK 首先我们 ...
- java开发后台技术_java开发后台的技术
1 java开发后台的技术 java,互联网发展出来的产物,如今变成了屈指可数的几大编程语言之一,他的未来是不可限量的.因此很多人都想要学会这门技术,希望在以后能有他的一席之地.那么下面小编给大家说说 ...
- java开发程序员_Java大牛给入门Java开发程序员的10个学习建议
Java的知识点其实非常多,并且有些知识点比较难以理解,有时候我们自以为理解了某些内容,其实可能只是停留在表面上,没有理解其底层实现原理. 纸上得来终觉浅,绝知此事要躬行. 学习Java基础的时候,应 ...
- java 开发人员工具_Java开发人员应该知道的5种错误跟踪工具
java 开发人员工具 随着Java生态系统的发展,可满足不断增长的请求和用户对高性能需求的Web应用程序成为了新型的现代开发工具. 具有快速新部署的快速节奏环境需要跟踪错误,并以传统方法无法维持的水 ...
- java 开发人员工具_Java开发人员应该知道的7种新工具
java 开发人员工具 通过快速浏览一些最新的,创新的工具,准备好锁定和加载. 万一您错过了它,RebelLabs最近发布了Java工具和技术前景的全球调查结果 . 除了著名的工具和成熟的工具之外,市 ...
- java 开发人员工具_Java开发人员的5种工具
java 开发人员工具 改善我们编写的Java代码的一种方法是使用最好的工具. 因此,让我们看看IDR Solutions建议使用的5种最常用的工具来帮助Java开发人员编写更好的代码. 查找错误 F ...
- java 开发环境配置文件_Java 开发环境配置
在本章节中我们将为大家介绍如何搭建Java开发环境.Windows 上安装开发环境 Linux 上安装开发环境 安装 Eclipse 运行 Java window系统安装java 下载JDK 首先我们 ...
- java开发怎么包装_Java开发知识之Java的包装类
Java开发知识之Java的包装类 一丶什么是包装类 包装类的意思就是对基本数据类型封装成一个类.这些类都是Number的子类.区别就是封装数据类型不同.包含的方法基本相同. 具体可以查询JAVA A ...
最新文章
- 自定义WPF窗体形状
- 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用
- Android界面编程--使用活动条(ActionBar)--通过ActionBar菜单改变TextView的字体和颜色...
- C,C++中使用可变参数
- Oracle 20c 新特性:基础级内存数据库免费功能 In-Memory Base Level
- elasticsearch的一个bug总结
- 微信小程序 3 岁:日活超 3 亿,交易额超 8000 亿
- C# 委托/Func() 中 GetInvocationList() 方法的使用 | 接收委托多个返回值
- 【租房必看】有了这份租房指南,再也不怕被坑了!(建议收藏)
- linux环境下安装mencoder转码工具
- 单片机音频信号分析仪
- python手机桌面开发_将Android手机打造成你的Python开发者桌面#华为云·寻找黑马程序员#...
- 定义图书类Book,具有属性账号id,铭name.作者author和价格price,在创建图书对象时要求通过构造器进行创建,- -次性将四个属性全部赋值
- [亲测可用] Mac PS CC2019软件下载详细安装教程
- 苹果关闭iOS 16.1.2 验证通道,iPhone升级 iOS 16.2 后无法降级
- 如何使用Python抓取移动端APP的评论(小白篇)
- Matlab/Simulink仿真问题及技巧汇总【持续更新】
- 将顺序表中非零元素移动到顺序表的前面
- Office Tips 3 - 如何设置电脑屏幕背景色为淡绿色
- MySQL DBA必读:万字归总表设计与SQL编写技巧