微信发起商家转账API,以前是企业转账,没有进行微信开发的同学比较头疼,因为微信API太庞大了,慢慢了解下来发现需要看的东西比较多,很多描述的还不是重点,现在记录一下这次转账遇到的问题和整体流程.

第一步需要获取OpenId,获取OpenId需要先拿Core去获取
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=回调域名&response_type=code&scope=snsapi_base&state=STATE

1、域名进入natapp官网下载安装natapp并且申请一个免费隧道或者购买隧道
2、打开cmd进入natapp安装地址,输入natapp -authtoken=(官网获取的token),如果出现以下画面就说明映射成功,此窗口千万千万不能关闭。

配置回调域名 不需要http和https前缀

 回调地址是域名加上自己的方法名获取到OpenId就可以进行下一步了

    @RequestMapping("/getToken")@ResponseBodypublic static void auth(@RequestParam(value="code",defaultValue = "",required = false) String code){String appId = "";String secret = "";String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+appId+"&secret="+secret+"&code="+code+"&grant_type=authorization_code";RestTemplate restTemplate = new RestTemplate();String result = restTemplate.getForObject(url, String.class);System.out.println("result={}"+result);JSONObject json = JSONObject.parseObject(result);String openid = json.getString("openid");}

发起商家转账API

<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.2</version>
</dependency>
import cn.hutool.core.util.IdUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.extern.slf4j.Slf4j;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@Slf4j
public class WechatPay {private static final Gson GSON = new GsonBuilder().create();public static void main(String[] args) throws Exception {//测试微信转账weixinTransferBat();}//请看下面public static String weixinTransferBat() {...};
 public static String weixinTransferBat() throws Exception {//商户号String mchid = "";//申请商户号的appid或商户号绑定的appid(企业号corpid即为此appid)String appId = "";//用户在直连商户应用下的用户标示String openId = "";//商户证书编号String wechatPayserialNo = "";//商户证书路径(在你本机测试时放你本机路径中的就可以)String privatekeypath = "";Map<String, Object> postMap = new HashMap<String, Object>();//商家批次单号 长度 1~32String outNo = IdUtil.getSnowflake(0, 0).nextIdStr();postMap.put("appid", appId);postMap.put("out_batch_no", outNo);//该笔批量转账的名称postMap.put("batch_name", "测试转账");//转账说明,UTF8编码,最多允许32个字符postMap.put("batch_remark", "测试转账");//转账金额单位为“分”。 总金额postMap.put("total_amount", 100);//。转账总笔数postMap.put("total_num", 1);List<Map> list = new ArrayList<>();Map<String, Object> subMap = new HashMap<>(4);//商家明细单号subMap.put("out_detail_no", outNo);//转账金额subMap.put("transfer_amount", 100);//转账备注subMap.put("transfer_remark", "明细备注1");//用户在直连商户应用下的用户标示subMap.put("openid", openId);
//      subMap.put("user_name", RsaCryptoUtil.encryptOAEP(userName, x509Certificate));list.add(subMap);postMap.put("transfer_detail_list", list);//发起转账操作String resStr = HttpUtil.postTransBatRequest("https://api.mch.weixin.qq.com/v3/transfer/batches",GSON.toJson(postMap),wechatPayserialNo,mchid,privatekeypath);
}
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
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;/*** 微信支付专用类 请求操作方法** @author Administrator*/
@Slf4j
public class HttpUtil {/*** 发起批量转账API 批量转账到零钱** @param requestUrl* @param requestJson 组合参数* @param wechatPayserialNo 商户证书序列号* @param mchID4M  商户号 * @param privatekeypath  商户私钥证书路径* @return*/public static String postTransBatRequest(String requestUrl,String requestJson,String wechatPayserialNo,String mchID4M,String privatekeypath) {CloseableHttpClient httpclient = HttpClients.createDefault();CloseableHttpResponse response = null;HttpEntity entity = null;try {//商户私钥证书HttpPost httpPost = new HttpPost(requestUrl);// NOTE: 建议指定charset=utf-8。低于4.4.6版本的HttpCore,不能正确的设置字符集,可能导致签名错误httpPost.addHeader("Content-Type", "application/json");httpPost.addHeader("Accept", "application/json");//"55E551E614BAA5A3EA38AE03849A76D8C7DA735A");httpPost.addHeader("Wechatpay-Serial", wechatPayserialNo);//-------------------------核心认证 start-----------------------------------------------------------------String strToken = VechatPayV3Util.getToken("POST","/v3/transfer/batches",requestJson,mchID4M,wechatPayserialNo, privatekeypath);log.error("微信转账token "+strToken);// 添加认证信息httpPost.addHeader("Authorization","WECHATPAY2-SHA256-RSA2048" + " "+ strToken);//---------------------------核心认证 end---------------------------------------------------------------httpPost.setEntity(new StringEntity(requestJson, "UTF-8"));//发起转账请求response = httpclient.execute(httpPost);entity = response.getEntity();//获取返回的数据log.info("-----getHeaders.Request-ID:"+response.getHeaders("Request-ID"));return EntityUtils.toString(entity);} catch (Exception e) {e.printStackTrace();} finally {// 关闭流}return null;}}

微信转账 token 签名认证


import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Random;import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;import org.springframework.util.StringUtils;@Slf4j
public class VechatPayV3Util {/*** * @param method 请求方法 post* @param canonicalUrl 请求地址* @param body 请求参数* @param merchantId 这里用的商户号* @param certSerialNo 商户证书序列号* @param keyPath 商户证书地址* @return* @throws Exception*/public static String getToken(String method,String canonicalUrl,String body,String merchantId,String certSerialNo,String keyPath) throws Exception {String signStr = "";//获取32位随机字符串String nonceStr = getRandomString(32);//当前系统运行时间long timestamp = System.currentTimeMillis() / 1000;if (StringUtils.isEmpty(body)) {body = "";}//签名操作String message = buildMessage(method, canonicalUrl, timestamp, nonceStr, body);//签名操作String signature = sign(message.getBytes("utf-8"), keyPath);//组装参数signStr = "mchid=\"" + merchantId + "\",timestamp=\"" +  timestamp+ "\",nonce_str=\"" + nonceStr+ "\",serial_no=\"" + certSerialNo + "\",signature=\"" + signature + "\"";return signStr;}public static String buildMessage(String method, String canonicalUrl, long timestamp, String nonceStr, String body) {
//      String canonicalUrl = url.encodedPath();
//      if (url.encodedQuery() != null) {
//          canonicalUrl += "?" + url.encodedQuery();
//      }return method + "\n" + canonicalUrl + "\n" + timestamp + "\n" + nonceStr + "\n" + body + "\n";}public static String sign(byte[] message, String keyPath) throws Exception {Signature sign = Signature.getInstance("SHA256withRSA");sign.initSign(getPrivateKey(keyPath));sign.update(message);return Base64.encodeBase64String(sign.sign());}/*** 微信支付-前端唤起支付参数-获取商户私钥** @param filename 私钥文件路径  (required)* @return 私钥对象*/public static PrivateKey getPrivateKey(String filename) throws IOException {log.error("签名 证书地址是 "+filename);String content = new String(Files.readAllBytes(Paths.get(filename)), "utf-8");try {String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "").replaceAll("\\s+", "");//System.out.println("--------privateKey---------:"+privateKey);KeyFactory kf = KeyFactory.getInstance("RSA");return kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey)));} catch (NoSuchAlgorithmException e) {throw new RuntimeException("当前Java环境不支持RSA", e);} catch (InvalidKeySpecException e) {throw new RuntimeException("无效的密钥格式");}}/*** 获取随机位数的字符串* @param length* @return*/public static String getRandomString(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();}
}

调试中遇到的几个错误问题记录一下:

首先需要开通商家转账到零钱,然后进行产品设置

接口返回:{"code":"NO_AUTH","message":"本商户号未配置API发起能力"}

开启后才可以进行API调用
第二个问题:{"code":"NOT_ENOUGH","message":"账户余额不足,请充值"}

需要给运营账户进行充值,之前的版本是可以直接扣零钱的

整体流程也就这样了,大家遇到问题也可以互相讨论一下

java开发 微信商家转账到零钱,发起商家转账API,微信支付相关推荐

  1. JAVA开发Android聊天APP,实现了类似QQ、微信的即时通讯功能

    视频学习地址 本内容接上篇文章 我的源码: 码云 github 大加有需要可以下载来参照一下. 文章目录 简介: 问题.报错 与视频中有差别的地方 视频的第十九节 视频的第38节,关于长按删除联系人, ...

  2. 微信支付:商家转账到零钱的开发

    主要所需:1.微信商户平台的证书apiclient_cert.pem 2.微信商户平台证书的密钥apiclient_key.pem 3.微信商户平台的证书的序列号 一.转账所需字段 public cl ...

  3. 平台资金提现解决方案之实现微信商家转账到零钱功能

    大家好,我是小悟 使用场景 不管是做APP.电脑网站.手机网站还是小程序,为了推广基本上都离不开用户分佣的场景. 换句话说就是在其平台内为每个用户设置"电子钱包"功能,而电子钱包在 ...

  4. c# 微信支付V3商家转账到零钱避坑宝典(二)

    上篇文章经过开通商家转账到零钱,以及设置安全证书,APIv3密钥,接下来访问接口,获取证书的key,以及密钥. 废话不多说,上酸菜,不对,上代码. 一.首先小程序appid,商户号,证书编号,后台配置 ...

  5. 怎么开通商家转账到零钱?

    目录 定义与场景 开通条件 产品优势 权限申请实操 个人浅谈 定义与场景 商家转账到零钱是微信支付商户平台推出的运营工具,可以为商户提供向一个或者同时向多个用户微信零钱转账的能力,商户可免费使用.商户 ...

  6. 商家转账到零钱快速开通方法

    什么是商家转账到零钱? 商家转账提供商户同时向多个用户微信零钱转账的能力.商户可以使用商家转账用于费用报销.员工福利发放.合作伙伴货款或服务款项支付等场景,提高转账效率. 都知道官网开通这个功能条件有 ...

  7. JAVA微信企业付款到零钱(十分钟搞定),附完整DEMO下载

    最近帮朋友做了一个简单的微分销系统,实现从企业付款到零钱分润的功能,简单记录一下微信提现功能开发的流程, 主要就是按规则封装好请求参数调用微信接口,涉及一些签名校验: A.接口流程 获取用户OPENI ...

  8. 商家转账到零钱场景申请模板有吗

    相信大多在申请开通商家转账到零钱的时候遇到审核不通过的问题,然而腾讯审核标准也在不断变化,被驳回也没有一个很清晰的答复.那么有解决方案吗? 答案是:有的,代申请模式. 什么是商家转账到零钱 商家转账到 ...

  9. java开发常用jar包_Java开发中常用jar包整理及使用

    本文整理了我自己在Java开发中常用的jar包以及常用的API记录. 一.common-lang3 简介:一个现在最为常用的jar包,封装了许多常用的工具包 依赖: org.apache.common ...

  10. 【Java进阶营】2022全栈Java开发工程师要掌握哪些技能?

    如果你希望加快自己的职业生涯,成为一名全栈Java程序员,那么你可以学习以下这些技能,以便将自己与其他程序员区分开来. 1.软件设计与体系结构 软件设计和体系结构可以说是软件开发过程中最重要的阶段.对 ...

最新文章

  1. python数字图像处理(17):边缘与轮廓
  2. nyoj1307Linux的文件权限对不对
  3. 类似excel实现文本中带数字的值进行规律填充[前提:字符串中数字对数相等](-)
  4. 开课吧Java教程:如何用listFiles()方法
  5. 360胡宁:通往CTO的道路上就是四个字
  6. [求助]关于服务器之间的文件拷贝问题,没有头绪,希望大家指点一二
  7. AcWing Django框架课第一节笔记
  8. [深度长文] 996的经济学
  9. 机器学习 Cohen s Kappa,Quadratic Weighted Kappa 详解
  10. 计算机c类地址是什么,ip地址中属于c类地址的是什么
  11. windows源文件名称大于文件系统支持的长度无法删除问题
  12. Excel使用空格/逗号等对数据进行分列
  13. marvin框架_告别开源先驱Marvin Minsky
  14. Android Q版本读取SDcard
  15. 留学地 各国比较2021
  16. 知明:技术 Leader 的思考法
  17. 解决深度Deepin20应用商店闪退
  18. Revit二次开发,新手接入IExternalCommand、IExternalApplication,如何使用它们!
  19. hihoCoder 156周 岛屿
  20. EasyDarwin使用udp方式推流实现摄像头直播代码流程分析

热门文章

  1. 蓝桥杯 ADV-222 7-2求arccos值
  2. c++中arccos()的用法(提醒自己)
  3. Leetcode力扣 MySQL数据库 1194 竞标赛优胜者
  4. Java经验者的面经
  5. 在MAC上如何隐藏文件夹以及查看隐藏文件
  6. Solidity语言详解——view和pure函数的使用区别
  7. Linux系统下启动DB2以及一些常用命令
  8. Java项目:在线bbs论坛系统(java+SSM+JSP+bootstrap+jQuery+mysql)
  9. 利用集成支持向量机模型评估信贷风险
  10. 怎么用ps做一个黑底白字_ps怎么把白底黑字变成黑底白字