微信支付-商家转账到零钱开发

上一篇介绍了微信支付-现金红包的开发,这一章聊聊商家转账到零钱的开发细节。我当时调研功能的时候,先调研的其实是这个产品。我们产品上的场景是:用户答题,答题正确,然后给发红包。我到微信开放社区上搜了一下这种类型的开发案例,官方给的回复是:这种场景,使用转账到零钱这个产品更合适。那我为啥最后用了现金红包呢?是因为业务上的一些原因,不说了。产品方面,如果是我这种类型的场景,或者其他类型的,比如:抽奖之类的,最好也都是用这个商家转账到零钱。

1、官方文档

https://pay.weixin.qq.com/doc/v3/merchant/4012716434
这里注意一下,我发的这个文档是“商家转账到零钱的最新版本”,是微信支付团队在2025-01-15这一天最新更新的,但是他们还是保留了之前的版本。你要注意,确保你看到的是最新的开发文档,如果看的是之前的版本,等真正调用的时候就提示你,功能不能用,需要使用最新升级的版本。你就白开发了。

2、开发前的准备事项

提前申请“商家转账到零钱”的产品权限,这个权限,貌似是不用等的,我们是2025-01-15当天申请的,填写完资料,直接就审核通过了,但是不确定后面会不会和现金红包一样,审核要等很久。

3、代码开发

代码开发部分,还是使用了IJPay框架。
因为当时只是进行了调研,所以只是写了一个测试用例

@Test
    public void testProcess() throws Exception {
    	//时间戳
        long timestamp = System.currentTimeMillis() / 1000;
        //加密算法。固定值,目前不支持其他方式
        String authType = "WECHATPAY2-SHA256-RSA2048";
        //生成nonce_str
        String nonceStr = WxPayKit.generateStr();
        //商家转账到零钱的请求地址后缀
        String urlSuffix = "/v3/fund-app/mch-transfer/transfer-bills";
        //发起转账的商户号
        String mchId = "15122xx159";
        //非对称加密,公钥证书的证书序列号
        String serialNo = "54823F07XXXXXXXXXF4FFF455BCB2063";
        //非对称加密的私钥
        String privateKey = "cert/apiclient_key.pem";

        //转账业务信息
        JSONObject rootJSON = baseInfo();
        String body = JSONUtil.toJsonStr(rootJSON);
        System.out.println("入参json:" + body);
        // 调用IJPay框架的工具类生成待签名参数
        String buildSignMessage = PayKit.buildSignMessage(RequestMethod.POST, urlSuffix, timestamp, nonceStr, body);
        //调用IJPay框架的工具类生成签名
        String signature = PayKit.createSign(buildSignMessage, privateKey);
        System.out.println("signature:" + signature);
        // 调用IJPay框架的工具类,根据平台规则生成请求头 authorization
        String authorization = PayKit.getAuthorization(mchId, serialNo, nonceStr, String.valueOf(timestamp), signature, authType);
        System.out.println("Authorization:" + authorization);
        //完整的"商家转账到零钱"的请求链接
        String url = "https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills";
        //调用Hutool包的工具类发起post请求
        HttpResponse httpResponse = HttpRequest.post(url)
                .header("Authorization", authorization)
                .header("Accept", "application/json")
                .header("Wechatpay-Serial", "54823F07XXXXXXXXXF4FFF455BCB2063")
                .header("Content-Type", "application/json")
                .body(body)
                .execute();
        System.out.println("出参json:" + JSON.toJSONString(httpResponse.body()));
    }

//方法里的参数key名称,不要改,这是官方文档的要求。
private JSONObject baseInfo() {
        JSONObject rootJSON = new JSONObject();
        rootJSON.put("appid", "wx16adxxxxxx75f084d");
        //商户单号,随机生成,但需要确保系统内唯一。
        rootJSON.put("out_bill_no", "sdkdemobatXXXXX1736928718526");
        //转账场景id,默认值1000,代表:现金营销。可以到微信支付后台申请开通其他场景
        rootJSON.put("transfer_scene_id", "1000");
        rootJSON.put("openid", "o0HMZAAxXXXXXXCChA-t5uhc2PUS7bE");
        //转账金额,单位:分
        rootJSON.put("transfer_amount", 10L);
        rootJSON.put("transfer_remark", "转账备注1");
        //转账活动备注
        List<JSONObject> childList = getTransferSceneReportInfos();
        rootJSON.put("transfer_scene_report_infos", childList);
        return rootJSON;
    }
    
    private List<JSONObject> getTransferSceneReportInfos() {
        List<JSONObject> childList = new ArrayList<>();
        JSONObject childJSON1 = new JSONObject();
        //注意,注意,注意!!这个info_type的值不能改,只能写:活动名称,否则就会调用失败。
        childJSON1.put("info_type", "活动名称");
        childJSON1.put("info_content", "活动有礼");

        JSONObject childJSON2 = new JSONObject();
        //这个也一样。这个info_type的值也不能改,只能写:奖励说明,否则就会调用失败。
        childJSON2.put("info_type", "奖励说明");
        childJSON2.put("info_content", "活动有礼的奖励说明");
        childList.add(childJSON1);
        childList.add(childJSON2);
        return childList;
    }

4、获取证书序列号

https://myssl.com/cert_decode.html
这是微信支付推荐的,查看证书序列号的网站,大家可以把自己的证书上传到这个网站,查看一下证书的序列化

5、注意事项

转账到零钱,其实没什么接入难度,主要就是按照官方文档的要求入参就行了。

根据引用\[1\]中提到的错误信息"java.io.IOException: Server returned HTTP response code: 400 for URL",这个错误通常表示在与服务器进行通信时发生了问题。HTTP响应代码400表示请求无效,可能是由于请求的URL不正确或请求参数不正确导致的。 根据引用\[2\]中提供的正确的URL示例"https://open.douyin.com/item/comment/list/?open_id=URLEncoder.encode("@8hhauTCnM4ltGM780mDqPP","utf-8")",可以看出正确的URL应该是经过编码的,并且参数应该正确传递。 根据引用\[3\]中提供的代码示例,可以看出在使用org.apache.commons.io.FileUtils进行文件下载时,需要确保URL的正确性,并且需要处理可能的异常情况。 综上所述,根据提供的错误信息"Server returned HTTP response code: 400 for URL: https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi",可能是由于请求的URL不正确或请求参数不正确导致的。您可以检查URL是否正确,并确保请求参数的正确传递。如果问题仍然存在,您可以尝试使用异常处理来捕获可能的异常情况。 #### 引用[.reference_title] - *1* *3* [java.io.IOException: Server returned HTTP response code: 400 for URL 问题定位与解决](https://blog.csdn.net/LS7011846/article/details/84074946)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [java.io.IOException: Server returned HTTP response code: 400 for URL: https://open.douyin.com/](https://blog.csdn.net/weixin_43852094/article/details/115181233)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值