需要用户绑定微信,获取用户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 微信提现至零钱相关推荐

  1. 微信公众号Java开发-笔记01【微信公众号介绍、开发环境搭建】

    学习网址:哔哩哔哩网站 微信公众号开发-Java版 微信公众号Java开发-笔记01[微信公众号介绍.开发环境搭建] 微信公众号Java开发-笔记02[] 微信公众号Java开发-笔记03[] 微信公 ...

  2. java调用微信加密_java微信消息加解密

    今天心血来潮就信手拈来学了下微信消息加解密的知识,忽然觉得微信真的好强大.可能在大部分项目微信消息的加解密都用不上,但是仍然不排除有使用到的情况,如涉及金钱方面的微信应用包括商城类.金融类还有其他安全 ...

  3. java 开发环境配置_Java 开发环境配置

    在本章节中我们将为大家介绍如何搭建Java开发环境.Windows 上安装开发环境 Linux 上安装开发环境 安装 Eclipse 运行 Java window系统安装java 下载JDK 首先我们 ...

  4. java开发后台技术_java开发后台的技术

    1 java开发后台的技术 java,互联网发展出来的产物,如今变成了屈指可数的几大编程语言之一,他的未来是不可限量的.因此很多人都想要学会这门技术,希望在以后能有他的一席之地.那么下面小编给大家说说 ...

  5. java开发程序员_Java大牛给入门Java开发程序员的10个学习建议

    Java的知识点其实非常多,并且有些知识点比较难以理解,有时候我们自以为理解了某些内容,其实可能只是停留在表面上,没有理解其底层实现原理. 纸上得来终觉浅,绝知此事要躬行. 学习Java基础的时候,应 ...

  6. java 开发人员工具_Java开发人员应该知道的5种错误跟踪工具

    java 开发人员工具 随着Java生态系统的发展,可满足不断增长的请求和用户对高性能需求的Web应用程序成为了新型的现代开发工具. 具有快速新部署的快速节奏环境需要跟踪错误,并以传统方法无法维持的水 ...

  7. java 开发人员工具_Java开发人员应该知道的7种新工具

    java 开发人员工具 通过快速浏览一些最新的,创新的工具,准备好锁定和加载. 万一您错过了它,RebelLabs最近发布了Java工具和技术前景的全球调查结果 . 除了著名的工具和成熟的工具之外,市 ...

  8. java 开发人员工具_Java开发人员的5种工具

    java 开发人员工具 改善我们编写的Java代码的一种方法是使用最好的工具. 因此,让我们看看IDR Solutions建议使用的5种最常用的工具来帮助Java开发人员编写更好的代码. 查找错误 F ...

  9. java 开发环境配置文件_Java 开发环境配置

    在本章节中我们将为大家介绍如何搭建Java开发环境.Windows 上安装开发环境 Linux 上安装开发环境 安装 Eclipse 运行 Java window系统安装java 下载JDK 首先我们 ...

  10. java开发怎么包装_Java开发知识之Java的包装类

    Java开发知识之Java的包装类 一丶什么是包装类 包装类的意思就是对基本数据类型封装成一个类.这些类都是Number的子类.区别就是封装数据类型不同.包含的方法基本相同. 具体可以查询JAVA A ...

最新文章

  1. 自定义WPF窗体形状
  2. 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用
  3. Android界面编程--使用活动条(ActionBar)--通过ActionBar菜单改变TextView的字体和颜色...
  4. C,C++中使用可变参数
  5. Oracle 20c 新特性:基础级内存数据库免费功能 In-Memory Base Level
  6. elasticsearch的一个bug总结
  7. 微信小程序 3 岁:日活超 3 亿,交易额超 8000 亿
  8. C# 委托/Func() 中 GetInvocationList() 方法的使用 | 接收委托多个返回值
  9. 【租房必看】有了这份租房指南,再也不怕被坑了!(建议收藏)
  10. linux环境下安装mencoder转码工具
  11. 单片机音频信号分析仪
  12. python手机桌面开发_将Android手机打造成你的Python开发者桌面#华为云·寻找黑马程序员#...
  13. 定义图书类Book,具有属性账号id,铭name.作者author和价格price,在创建图书对象时要求通过构造器进行创建,- -次性将四个属性全部赋值
  14. [亲测可用] Mac PS CC2019软件下载详细安装教程
  15. 苹果关闭iOS 16.1.2 验证通道,iPhone升级 iOS 16.2 后无法降级
  16. 如何使用Python抓取移动端APP的评论(小白篇)
  17. Matlab/Simulink仿真问题及技巧汇总【持续更新】
  18. 将顺序表中非零元素移动到顺序表的前面
  19. Office Tips 3 - 如何设置电脑屏幕背景色为淡绿色
  20. MySQL DBA必读:万字归总表设计与SQL编写技巧

热门文章

  1. 团队作业2 需求分析与原型设计
  2. N76E003的学习之路(一)
  3. 46.@弹出点击次数
  4. 一些常见技术问题提问方式
  5. 用Java实现HTTP Multipart的服务端和客户端
  6. LinkButton中添加删除确认框
  7. ASP.NET后台注册javascript脚本方法
  8. 自动化Ansible常见命令
  9. shell编写监控httpd服务80端口脚本.间隔3秒监控端口如果服务关闭自动重启
  10. CENTOS 7 YUM 没有可用的软件包 NGINX