微信转账到零钱2种实现方式,SDK和API对接

您所在的位置:网站首页 微信批量转账的正确方法 微信转账到零钱2种实现方式,SDK和API对接

微信转账到零钱2种实现方式,SDK和API对接

2024-07-08 21:31:02| 来源: 网络整理| 查看: 265

微信官方文档地址

https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter4_3_1.shtml#doc-main

第一种:SDK方式

首先引入微信官方的sdk包

                    com.github.wechatpay-apiv3             wechatpay-java             0.2.11        

核心代码

  import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import com.deliyun.transfer.util.UUIDUtil; import com.deliyun.transfer.util.WechatPayConstant; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.RSAAutoCertificateConfig; import com.wechat.pay.java.service.transferbatch.TransferBatchService; import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferRequest; import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferResponse; import com.wechat.pay.java.service.transferbatch.model.TransferDetailInput;   import java.util.ArrayList; import java.util.List;   public class BatchTransfer {       /**      * 商户号      */     public static String merchantId = "1********";     /**      * 商户API私钥路径      */     public static String privateKeyPath = "F:apiclient_key.pem";     /**      * 商户证书序列号      */     public static String merchantSerialNumber = "3860*********************E7447";     /**      * 商户APIV3密钥      */     public static String apiV3Key = "V**********************************V";     public static TransferBatchService service;       public static void main(String[] args) {           Config config = new RSAAutoCertificateConfig.Builder()                 .merchantId(merchantId)                 .privateKeyFromPath(privateKeyPath)                 .merchantSerialNumber(merchantSerialNumber)                 .apiV3Key(apiV3Key)                 .build();         service = new TransferBatchService.Builder().config(config).build();           String out_batch_no = RandomUtil.randomNumbers(10);         out_batch_no = StrUtil.concat(true, "sc", out_batch_no);           InitiateBatchTransferRequest initiateBatchTransferRequest = new InitiateBatchTransferRequest();         initiateBatchTransferRequest.setAppid(WechatPayConstant.APP_ID);         initiateBatchTransferRequest.setOutBatchNo(out_batch_no);         initiateBatchTransferRequest.setBatchName("2019年1月深圳分部报销单");         initiateBatchTransferRequest.setBatchRemark("2019年1月深圳分部报销单");         initiateBatchTransferRequest.setTotalAmount(100l);         initiateBatchTransferRequest.setTotalNum(1);           List transferDetailListList = new ArrayList();         TransferDetailInput transferDetailInput = new TransferDetailInput();         transferDetailInput.setOutDetailNo(UUIDUtil.getUUID());         transferDetailInput.setTransferAmount(100l);         transferDetailInput.setTransferRemark("2020年4月报销");         transferDetailInput.setOpenid("o_***************************"); //        transferDetailInput.setUserName( //                "757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45");         transferDetailListList.add(transferDetailInput);         initiateBatchTransferRequest.setTransferDetailList(                 transferDetailListList);         initiateBatchTransferRequest.setTransferSceneId("1000");         InitiateBatchTransferResponse response =                 service.initiateBatchTransfer(initiateBatchTransferRequest);         System.out.println(response);     } }

第二种:API方式

协议对象

public class Transfer {     private String appid; // 直连商户的appid       private String out_batch_no; // 商家批次单号     private String batch_name = "分润红包"; // 该笔批量转账的名称:     private String batch_remark = "分润红包"; // 转账说明,UTF8编码,最多允许32个字符       private int total_amount; // 转账总金额:分     private int total_num = 1; // 转账总笔数       private List transfer_detail_list; // 发起批量转账的明细列表,最多三千笔       public Transfer(String appid, String out_batch_no, int total_amount, List transfer_detail_list) {         this.appid = appid;         this.out_batch_no = out_batch_no;         this.total_amount = total_amount;         this.transfer_detail_list = transfer_detail_list;     }       public String getAppid() {         return appid;     }       public void setAppid(String appid) {         this.appid = appid;     }       public String getOut_batch_no() {         return out_batch_no;     }       public void setOut_batch_no(String out_batch_no) {         this.out_batch_no = out_batch_no;     }       public String getBatch_name() {         return batch_name;     }       public void setBatch_name(String batch_name) {         this.batch_name = batch_name;     }       public String getBatch_remark() {         return batch_remark;     }       public void setBatch_remark(String batch_remark) {         this.batch_remark = batch_remark;     }       public int getTotal_amount() {         return total_amount;     }       public void setTotal_amount(int total_amount) {         this.total_amount = total_amount;     }       public int getTotal_num() {         return total_num;     }       public void setTotal_num(int total_num) {         this.total_num = total_num;     }       public List getTransfer_detail_list() {         return transfer_detail_list;     }       public void setTransfer_detail_list(List transfer_detail_list) {         this.transfer_detail_list = transfer_detail_list;     }       public static class TransferDetailList {           private String out_detail_no = UUIDUtil.getUUID(); // 商户系统内部区分转账批次单下不同转账明细单的唯一标识,要求此参数只能由数字、大小写字母组成         private int transfer_amount; // 转账金额单位为分         private String transfer_remark = "分润红包"; //转账备注         private String openid; // 用户在直连商户应用下的用户标示           public TransferDetailList( int transfer_amount, String openid) {             this.transfer_amount = transfer_amount;             this.openid = openid;         }           public String getOut_detail_no() {             return out_detail_no;         }           public void setOut_detail_no(String out_detail_no) {             this.out_detail_no = out_detail_no;         }           public int getTransfer_amount() {             return transfer_amount;         }           public void setTransfer_amount(int transfer_amount) {             this.transfer_amount = transfer_amount;         }           public String getTransfer_remark() {             return transfer_remark;         }           public void setTransfer_remark(String transfer_remark) {             this.transfer_remark = transfer_remark;         }           public String getOpenid() {             return openid;         }           public void setOpenid(String openid) {             this.openid = openid;         }     } }

工具类 CertUtil.java

public class CertUtil {       public static String APICLIENT_KEY = "conf/cert/apiclient_key.pem";     public static String APICLIENT_CERT = "conf/cert/apiclient_cert.pem";       /**      * 获取私钥。      *      * @return 私钥对象      */     public static PrivateKey getPrivateKey() throws IOException {         InputStream instream = CertUtil.class.getClassLoader().getResourceAsStream(APICLIENT_KEY);         String content = new String(ByteStreams.toByteArray(instream), StandardCharsets.UTF_8);   // String content = new String(Files.readAllBytes(Paths.get(APICLIENT_KEY)), StandardCharsets.UTF_8);         try {             String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "").replaceAll("\\s+", "");             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("无效的密钥格式");         }     }       /**      * 获取商户证书。      *      * @return X509证书      */     public static X509Certificate getCertificate() throws IOException { // InputStream fis = new FileInputStream(APICLIENT_CERT);         InputStream fis = CertUtil.class.getClassLoader().getResourceAsStream(APICLIENT_CERT);         ;         try (BufferedInputStream bis = new BufferedInputStream(fis)) {             CertificateFactory cf = CertificateFactory.getInstance("X509");             X509Certificate cert = (X509Certificate) cf.generateCertificate(bis);             cert.checkValidity();             return cert;         } catch (CertificateExpiredException e) {             throw new RuntimeException("证书已过期", e);         } catch (CertificateNotYetValidException e) {             throw new RuntimeException("证书尚未生效", e);         } catch (CertificateException e) {             throw new RuntimeException("无效的证书文件", e);         }     }       /**      * 获取商户证书序列号      *      * @return      * @throws IOException      */     public static String getSerialNo() throws IOException {         X509Certificate certificate = getCertificate();         return certificate.getSerialNumber().toString(16).toUpperCase();     }       public static void main(String[] args) {         try {             System.out.println(CertUtil.getCertificate());         } catch (Exception e) {             e.printStackTrace();         }     } }

HttpUrl工具类

public class HttpUrlUtil {       public static String SCHEMA = "WECHATPAY2-SHA256-RSA2048";     public static String merchantId = WechatPayConstant.MCH_ID; // 服务商       public static String POST = "POST";     public static String GET = "GET";       public static String TRANSFER_URL = "https://api.mch.weixin.qq.com/v3/transfer/batches"; // 转账       public static String postTransfer(String body) {         String authorization = getToken(POST, TRANSFER_URL, body);         String returnMsg = HttpRequest.post(TRANSFER_URL)                 .header("Authorization", authorization)                 .header("Wechatpay-Serial", WechatPayConstant.merchantSerialNumber)                 .body(body)                 .execute().body();         JSONObject returnTransferInfo = JSON.parseObject(returnMsg);         return returnTransferInfo.toJSONString();     }       /**      * 获取加密串      *      * @param method      * @param url      * @param body      * @return      */     public static String getToken(String method, String url, String body) {         String nonceStr = UUIDUtil.getUUID();         long timestamp = System.currentTimeMillis() / 1000;         HttpUrl httpUrl = HttpUrl.parse(url);         String message = buildMessage(method, httpUrl, timestamp, nonceStr, body);         String signature = null;         String certificateSerialNo = null;         try {             signature = sign(message.getBytes("utf-8"));             certificateSerialNo = CertUtil.getSerialNo();         } catch (Exception e) {             e.printStackTrace();         }         return SCHEMA + " mchid=\"" + merchantId + "\"," + "nonce_str=\"" + nonceStr + "\"," + "timestamp=\"" + timestamp + "\"," + "serial_no=\""                 + certificateSerialNo + "\"," + "signature=\"" + signature + "\"";     }       /**      * 得到签名字符串      */     public static String sign(byte[] message) throws Exception {         Signature sign = Signature.getInstance("SHA256withRSA");         PrivateKey privateKey = CertUtil.getPrivateKey();         sign.initSign(privateKey);         sign.update(message);         return Base64.getEncoder().encodeToString(sign.sign());     }       public static String buildMessage(String method, HttpUrl url, 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";     }

UUID工具类

public class UUIDUtil {       public static String getUUID () {         return UUID.randomUUID().toString().replace("-", "");     }       public static void main(String[] args) {         System.out.println(UUIDUtil.getUUID());     } }

常量类 WechatPayConstant.java

public class WechatPayConstant {       /**      * appId      */     public static String APP_ID = "wx64************";       /**      * 商户号      */     public static String MCH_ID = "1***********";       /**      * API_V3密钥      */     public static String API_V3KEY = "V*****************************";       /**      * 证书序列号      */     public static String merchantSerialNumber = "************************************"; }

转账业务类

public class TransferService {       public static void exe(String openId) {           String out_batch_no = RandomUtil.randomNumbers(10);         out_batch_no = StrUtil.concat(true, "sc", out_batch_no);             int transfer_amount = 100;         Transfer.TransferDetailList transferDetailList = new Transfer.TransferDetailList(transfer_amount, openId);         List list = new ArrayList();         list.add(transferDetailList);         Transfer transfer = new Transfer(WechatPayConstant.APP_ID, out_batch_no, transfer_amount, list);         String str = HttpUrlUtil.postTransfer(JSONObject.toJSONString(transfer));         System.out.println("转账结果返回:" + str);     }       public static void main(String[] args) {           String openId = "o_F*******************************";         TransferService.exe(openId);     }   }

执行结果:

{"create_time":"2023-11-22T18:56:39+08:00","batch_id":"131000110008101808*********************3342","batch_status":"ACCEPTED","out_batch_no":"592147839212385514533287"}



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭