打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
微信支付v3——批量转账到零钱(提现)
userphoto

2023.06.05 湖南

关注

进入正题之前先吐槽一下微信官方文档吧!一开始在官网上下载了微信支付版本V3的Demo,下载下来基本上难以投入使用,要学会使用的话,就要去看源码,看文档,稍微错过一点就会有一大堆的坑等着你跳,相比之下,阿里的文档就简单易懂,而且官方的文档下载下来之后,稍微改下参数就可以run!!

正文:

批量转账到零钱(服务商)的接入示例:

(微信文档地址:开发文档-微信支付批量转账到零钱)

微信支付V3版本,微信SDK,内部封装了部分方法(微信支付API v3的Apache HttpClient扩展,实现了请求签名的生成和应答签名的验证。)

第一步:在项目中引入Maven

<dependency>

    <groupId>com.github.wechatpay-apiv3</groupId>

    <artifactId>wechatpay-apache-httpclient</artifactId>

    <version>0.4.8</version>

</dependency>

1

2

3

4

5

6

第二步:构造微信接口通讯Client,构造隐私数据加密公钥,每次调用微信V3的接口都需要用Client来发起,敏感数据需通过平台公钥加密。

package cn.schoolgroup.config.until;

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;

import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;

import org.apache.http.impl.client.CloseableHttpClient;

import org.springframework.core.io.ClassPathResource;

import java.io.IOException;

import java.io.InputStream;

import java.security.PrivateKey;

import java.security.cert.X509Certificate;

import java.util.Arrays;

/**

 * @Author lulu

 * @Date 2022/09/07

 */

public class WeChatClient {

    /**

     * 微信通讯client

     * @return CloseableHttpClient 

     * 作者的文件都放在resour文件下的

     */

    public static CloseableHttpClient getClient() throws IOException {

        /**商户私钥文件*/

        ClassPathResource classPathResource = new ClassPathResource("/cert/apiclient_key.pem");

        InputStream mchPrivateKeyInputStream = classPathResource.getInputStream();

        /**微信平台公钥文件*/

        ClassPathResource classPathResource1 = new ClassPathResource("/cert/wechatpay_64124ADAF002CDEEBA0A58215D8572D270F2A854.pem");

        InputStream platformKeyInputStream = classPathResource1.getInputStream();

        PrivateKey mchPrivateKey = PemUtil.loadPrivateKey(mchPrivateKeyInputStream);

        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()

                .withMerchant("自己的商户号", "自己的商户证书序列号", mchPrivateKey)

                .withWechatPay(Arrays.asList(PemUtil.loadCertificate(platformKeyInputStream)));

        CloseableHttpClient httpClient = builder.build();

        return httpClient;

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

第三步:调起商家转账API

需要在《转账到用户零钱》产品的开发设置中,添加安全ip,接口才能访问

/**

     * 发起商家转账API

     *

* @Author lulu

* @Date 2022/07/09

     */

    public static void merchantTransfers() throws IllegalBlockSizeException, IOException {

        CloseableHttpClient httpClient = WeChatClient.getClient();

        Map<String, Object> map = new HashMap<>();

        map.put("appid", "小程序appid");

        map.put("out_batch_no", "zcx04");

        map.put("batch_name", "1元");

        map.put("batch_remark", "1元");

        map.put("total_amount", 100);

        map.put("total_num", 1);

        List<Map> list = new ArrayList<>();

        Map<String, Object> subMap = new HashMap<>(4);

        subMap.put("out_detail_no", "detail1");

        subMap.put("transfer_amount", 100);

        subMap.put("transfer_remark", "1元");

        subMap.put("openid", "用户openid");

        //明细转账金额 >= 2000,收款用户姓名必填

        //subMap.put("user_name", RsaCryptoUtil.encryptOAEP("收款用户姓名", zcx));

        list.add(subMap);

        map.put("transfer_detail_list", list);

        String body = JSONUtil.toJsonStr(map);

        System.out.println("请求参数:" + body);

        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/transfer/batches");

        httpPost.addHeader(ACCEPT, APPLICATION_JSON.toString());

        httpPost.addHeader(CONTENT_TYPE, APPLICATION_JSON.toString());

        httpPost.addHeader("Wechatpay-Serial", "自己的平台证书序列号");

        httpPost.setEntity(new StringEntity(body, "UTF-8"));

        CloseableHttpResponse response = httpClient.execute(httpPost);

        try {

            String result= EntityUtils.toString(response.getEntity());

            System.out.println("返回参数:" + result);

            //业务逻辑自己处理

        } finally {

            response.close();

        }

    }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

第四步:商家批次单号查询批次单API

/**

     * 商家批次单号查询批次单API

     * @throws URISyntaxException

     * @throws IOException

     */

    public static void queryBatch() throws URISyntaxException, IOException {

        CloseableHttpClient httpClient = WeChatClient.getClient();

        //批次号

        String batchCode = "zcx03";

        StringBuilder url = new StringBuilder("https://api.mch.weixin.qq.com/v3/transfer/batches/out-batch-no/");

        url.append(batchCode).append("?need_query_detail=true").append("&detail_status=ALL");

        URIBuilder uriBuilder = new URIBuilder(url.toString());

        HttpGet httpGet = new HttpGet(uriBuilder.build());

        httpGet.addHeader(ACCEPT, APPLICATION_JSON.toString());

        CloseableHttpResponse response = httpClient.execute(httpGet);

        try {

            String bodyAsString = EntityUtils.toString(response.getEntity());

            System.out.println("微信支付查询返回:" + bodyAsString);

            JSONObject jsonObject = JSONUtil.parseObj(bodyAsString);

            if (AjaxResult.me().getCode().equals(response.getStatusLine().getStatusCode())) {

                //转账批次单基本信息

                JSONObject transferBatch = jsonObject.getJSONObject("transfer_batch");

                //批次状态

                String batchStatus = transferBatch.getStr("batch_status");

                System.out.println("交易状态:" + batchStatus);

                //已完成

                if ("FINISHED".equals(batchStatus)){

                    JSONArray transferDetailList = jsonObject.getJSONArray("transfer_detail_list");

                    for (int i = 0; i < transferDetailList.size(); i++){

                        JSONObject detail = (JSONObject) transferDetailList.get(i);

                        //明细单号

                        String outDetailNo = detail.getStr("out_detail_no");

                        //明细状态

                        String detailStatus = detail.getStr("detail_status");

                        System.out.println("交易明细单号:"+ outDetailNo +",明细状态:" + detailStatus);

                    }

                }else if ("CLOSED".equals(batchStatus)){

                    //批次关闭原因

                    String closeReason = transferBatch.getStr("close_reason");

                    System.out.println("交易关闭原因:" + closeReason);

                }

            } else {

                //失败自己处理

            }

        } finally {

            response.close();

        }

    }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

获取平台证书的方法

————————————————

版权声明:本文为CSDN博主「暴脾气_lulu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_49706389/article/details/126754921

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
android以application/json流的方式提交数据
Java 微信支付 发起商家转账API 2022年v3 transfer batches
android与php后台服务的数据交换例子webservice1.php
android发送/接收json数据
java接入钉钉机器人实现告警通知
第三方服务器获取微信公众号图文消息
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服