当前位置: 代码网 > it编程>编程语言>Java > 微信商家转账常见的一些问题汇总(附Java调用示例)

微信商家转账常见的一些问题汇总(附Java调用示例)

2025年12月21日 Java 我要评论
前言官方也汇总了一个qa,常见问题_商家转账|微信支付商户文档中心大家可以直接看官方的。我这边是我自己遇到的就蛮记录下来,相比官网的更口语化一点。1,此ip地址不允许调用接口,请按开发指引设置{&qu

前言

官方也汇总了一个qa,常见问题_商家转账|微信支付商户文档中心

大家可以直接看官方的。

我这边是我自己遇到的就蛮记录下来,相比官网的更口语化一点。

1,此ip地址不允许调用接口,请按开发指引设置

{
    "code": "invalid_request",
    "message": "此ip地址不允许调用接口,请按开发指引设置"
}

这个就是要设置一下白名单,扫码登陆商户平台

产品中心 -> 运营工具 -> 商家转账 -> 前往功能 ->安全能力-> 点击「接口ip」

按需选择场景就好,关键是ip要添加一下开发者和服务器的ip就行了。

有ipv6的话记得也得填。

2,appid不存在

{
    "code": "invalid_request",
    "message": "appid不存在"
}

这个是你得把你要调用的这个小程序或者公众号啥的关联到这个商户号上。

打开产品中心 -> appid账号管理 -> 账号关联

进入授权申请页面;

可以看看官方文档:appid授权管理功能介绍 - 微信支付商户平台

授权完之后要到微信公众平台那边点击接受,就可以了。 

3,你尚未获取该转账场景

{
    "code": "invalid_request",
    "message": "你尚未获取该转账场景"
}

转账场景说白了就是你转账的用途。后面的接口调用全都需要跟你的场景挂钩,不同场景的参数都是不同的。

打开:产品中心 > 运营工具 > 商家转账到零钱 > 前往功能 > 转账场景。

然后就是选择、申请、等审核。

4,暂不支持展示当前传入的用户收款感知

{
    "code": "invalid_request",
    "message": "暂不支持展示当前传入的用户收款感知"
}

用户收款感知 说白了就是当微信把钱打给用户时,在用户微信里展示一些“这是什么钱”的提示。对应字段:user_recv_perception

比如:

  • “现金奖励”

  • “拉新红包”

  • “活动奖励”

每个转账场景要填的内容都不一样。各场景展示的默认内容和支持传入的内容详见官方文档:
现金营销_商家转账|微信支付商户文档中心:https://pay.weixin.qq.com/doc/v3/merchant/4013774588在左侧可以选场景:

举个例子,比如上图的 佣金报酬(transfer_scene_id = 1005) 场景下,你只能支持这几个:【劳务报酬】、【报销款】、【企业补贴】、【开工利是】,不传则默认展示【劳务报酬】。

你如果填了别的,就会报这个 “暂不支持...” 这个错。

所以按文档和你的转账场景填就行了。

5,未传入完整且对应的转账场景报备信息,请根据接口文档检查

{
    "code": "param_error",
    "message": "未传入完整且对应的转账场景报备信息,请根据接口文档检查"
}

转账场景报备信息 说白了就是给微信审核用的,告诉微信 “我这个转账是什么用途”,符合政策才允许转账。对应字段:transfer_scene_report_infos

比如:

  • 转账原因

  • 场景说明

  • 奖励类型

每个场景要传的参数都不同。具体每个场景要传的参数可以在这里看:现金营销_商家转账|微信支付商户文档中心:https://pay.weixin.qq.com/doc/v3/merchant/4013774588
在左侧可以选场景:

以佣金报酬为例,如上图,他这里写着了 必须要岗位类型和报酬说明,那调用时就这样:

就可以了。

6,商户运营账户资金不足,充值后可以原单号发起重试,请勿更换商户单号

{
    "code": "not_enough",
    "message": "商户运营账户资金不足,充值后可以原单号发起重试,请勿更换商户单号"
}

很明显,要充钱。不过记得是要充到运营账户里面,不是这个基本账户:

java的调用示例:

package co.yixiang.modules.transfertouser.utils;

import com.google.gson.annotations.serializedname;
import lombok.data;
import okhttp3.*;

import java.io.ioexception;
import java.io.uncheckedioexception;
import java.security.privatekey;
import java.util.arraylist;
import java.util.list;

/**
 * 发起转账
 */
public class transfertouser {
    private static string host = "https://api.mch.weixin.qq.com";
    private static string method = "post";
    private static string path = "/v3/fund-app/mch-transfer/transfer-bills";

    public static void main(string[] args) {
        // todo: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/v3/merchant/4013070756
        transfertouser client = new transfertouser(
                "12321321",                    // 商户号,是由微信支付系统生成并分配给每个商户的唯一标识符,商户号获取方式参考 https://pay.weixin.qq.com/doc/v3/merchant/4013070756
                "12321321321321312",         // 商户api证书序列号,如何获取请参考 https://pay.weixin.qq.com/doc/v3/merchant/4013053053
                "e:\\java_project_self\privatekey.pem"     // 商户api证书私钥文件路径,本地文件路径
        );

        transfertouserrequest request = new transfertouserrequest();
        request.appid = "wx213123213";
        request.outbillno = "plfk212ds" + system.currenttimemillis();
        request.transfersceneid = "1005";
        request.openid = "21321321321213";
        request.transferamount = 10l;
        request.transferremark = "佣金提现到账";
        request.notifyurl = "https://www.weixin.qq.com/wxpay/pay.php";

        list<transferscenereportinfo> list = new arraylist<>();

        transferscenereportinfo info1 = new transferscenereportinfo();
        info1.infotype = "岗位类型";
        info1.infocontent = "分享有礼";
        list.add(info1);

        transferscenereportinfo info2 = new transferscenereportinfo();
        info2.infotype = "报酬说明";
        info2.infocontent = "用户推广获得佣金";
        list.add(info2);

        request.userrecvperception = "劳务报酬";
        request.transferscenereportinfos = list;

        try {
            transfertouserresponse response = client.run(request);
            // todo: 请求成功,继续业务逻辑
            system.out.println(response);
        } catch (exception e) {
            // todo: 请求失败,根据状态码执行不同的逻辑
            e.printstacktrace();
        }
    }

    public transfertouserresponse run(transfertouserrequest request) {
        string uri = path;
        string reqbody = wxpayutility.tojson(request);

        request.builder reqbuilder = new request.builder().url(host + uri);
        reqbuilder.addheader("accept", "application/json");

        reqbuilder.addheader("authorization", wxpayutility.buildauthorization(mchid, certificateserialno, privatekey, method, uri, reqbody));
        reqbuilder.addheader("content-type", "application/json");
        requestbody requestbody = requestbody.create(mediatype.parse("application/json; charset=utf-8"), reqbody);
        reqbuilder.method(method, requestbody);
        request httprequest = reqbuilder.build();

        // 发送http请求
        okhttpclient client = new okhttpclient.builder().build();
        try (response httpresponse = client.newcall(httprequest).execute()) {
            string respbody = wxpayutility.extractbody(httpresponse);
            if (httpresponse.code() >= 200 && httpresponse.code() < 300) {
                // 2xx 成功,验证应答签名
//                wxpayutility.validateresponse(this.wechatpaypublickeyid, this.wechatpaypublickey,
//                        httpresponse.headers(), respbody);

                // 从http应答报文构建返回数据
                return wxpayutility.fromjson(respbody, transfertouserresponse.class);
            } else {
                throw new wxpayutility.apiexception(httpresponse.code(), respbody, httpresponse.headers());
            }
        } catch (ioexception e) {
            throw new uncheckedioexception("sending request to " + uri + " failed.", e);
        }
    }

    private final string mchid;
    private final string certificateserialno;
    private final privatekey privatekey;

    public transfertouser(string mchid, string certificateserialno, string privatekeyfilepath) {
        this.mchid = mchid;
        this.certificateserialno = certificateserialno;
        this.privatekey = wxpayutility.loadprivatekeyfrompath(privatekeyfilepath);
    }

    @data
    public static class transfertouserrequest {
        @serializedname("appid")
        public string appid;

        @serializedname("out_bill_no")
        public string outbillno;

        @serializedname("transfer_scene_id")
        public string transfersceneid;

        @serializedname("openid")
        public string openid;

        @serializedname("user_name")
        public string username;

        @serializedname("transfer_amount")
        public long transferamount;

        @serializedname("transfer_remark")
        public string transferremark;

        @serializedname("notify_url")
        public string notifyurl;

        @serializedname("user_recv_perception")
        public string userrecvperception;

        @serializedname("transfer_scene_report_infos")
        public list<transferscenereportinfo> transferscenereportinfos = new arraylist<transferscenereportinfo>();
    }

    @data
    public static class transfertouserresponse {
        @serializedname("out_bill_no")
        public string outbillno;

        @serializedname("transfer_bill_no")
        public string transferbillno;

        @serializedname("create_time")
        public string createtime;

        @serializedname("state")
        public transferbillstatus state;

        @serializedname("package_info")
        public string packageinfo;
    }

    @data
    public static class transferscenereportinfo {
        @serializedname("info_type")
        public string infotype;

        @serializedname("info_content")
        public string infocontent;
    }

    public enum transferbillstatus {
        @serializedname("accepted")
        accepted,
        @serializedname("processing")
        processing,
        @serializedname("wait_user_confirm")
        wait_user_confirm,
        @serializedname("transfering")
        transfering,
        @serializedname("success")
        success,
        @serializedname("fail")
        fail,
        @serializedname("canceling")
        canceling,
        @serializedname("cancelled")
        cancelled
    }

}

总结 

到此这篇关于微信商家转账常见的一些问题汇总的文章就介绍到这了,更多相关微信商家转账常见问题java内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com