微信支付超过2000元配置

本文涉及的产品
.cn 域名,1个 12个月
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 导入依赖、微信工具类、请求示例、超过2000元转账参数、姓名加密、请求参数、微信支付平台证书序列号、Wechatpay-Serial

微信支付超过2000元配置

📔 千寻简笔记介绍

千寻简笔记已开源,Gitee与GitHub搜索chihiro-notes,包含笔记源文件.md,以及PDF版本方便阅读,且是用了精美主题,阅读体验更佳,如果文章对你有帮助请帮我点一个Star

更新:支持在线阅读文章,根据发布日期分类。

@[toc]

简介

微信转账大于等于2000元需要携带收款人的姓名,建议大家使用官方示例中的方法进行转账,由于我的项目比较老,属于二开所以我重新写了一个工具类,用于获取平台证书,大家根据自己的需求去做参考,文章仅做参考,不承担任何责任。如有疑问请留言讨论,文章有误欢迎指正,感谢您的观看。

发起商家转账

更新时间:2023.06.06

发起商家转账接口。商户可以通过该接口同时向多个用户微信零钱进行转账操作。请求消息中应包含商家批次单号、转账名称、appid、转账总金额、转账总笔数、转账openid、收款用户姓名等信息。注意受理成功将返回批次单号,此时并不代表转账成功,请通过查单接口查询单据的付款状态。

接口说明

支持商户:【普通商户】

请求方式:【POST】/v3/transfer/batches

请求域名:

  • 【主域名】https: //api.mch.weixin.qq.com 使用该域名将访问就近的接入点
  • 【备域名】https: //api2.mch.weixin.qq.com 使用该域名将访问异地的接入点 ,指引点击查看

本文关键词

导入依赖微信工具类请求示例超过2000元转账参数姓名加密请求参数微信支付平台证书序列号Wechatpay-Serial

官方示例

1 导入依赖

        <!--        微信支付所需依赖-->
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.9.3</version>
        </dependency>
        <dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-java</artifactId>
            <version>0.2.10</version>
        </dependency>
        <!--        微信支付所需依赖end-->

2 请求参数

2.1【Header】HTTP头参数

  • Authorization必填string

    请参考 签名认证 生成认证信息

  • Accept必填string

    请设置为 application/json

  • Content-Type必填string

    请设置为 application/json

  • Wechatpay-Serial必填string

    【微信支付平台证书序列号】 请求参数中的敏感字段,需要使用微信支付平台证书公钥加密。请设置为该证书的证书序列号。详见敏感信息加解密

2.2【Body】包体参数

  • appid必填string(32)

    【商户appid】 申请商户号的appid或商户号绑定的appid(企业号corpid即为此appid)

  • out_batch_no必填string(32)

    【商家批次单号】 商户系统内部的商家批次单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一

  • batch_name必填string(32)

    【批次名称】 该笔批量转账的名称

  • batch_remark必填string(32)

    【批次备注】 转账说明,UTF8编码,最多允许32个字符

  • total_amount必填integer

    【转账总金额】 转账金额单位为“分”。转账总金额必须与批次内所有明细转账金额之和保持一致,否则无法发起转账操作

  • total_num必填integer

    【转账总笔数】 一个转账批次单最多发起一千笔转账。转账总笔数必须与批次内所有明细之和保持一致,否则无法发起转账操作

  • transfer_detail_list必填array[TransferDetailInput]

    【转账明细列表】 发起批量转账的明细列表,最多一千笔

    • out_detail_no必填string(32)

      【商家明细单号】 商户系统内部区分转账批次单下不同转账明细单的唯一标识,要求此参数只能由数字、大小写字母组成

    • transfer_amount必填integer

      【转账金额】 转账金额单位为“分”

    • transfer_remark必填string(32)

      【转账备注】 单条转账备注(微信用户会收到该备注),UTF8编码,最多允许32个字符

    • openid必填string(64)

      【收款用户openid】 商户appid下,某用户的openid

    • user_name选填string(1024)

      【收款用户姓名】 收款方真实姓名。支持标准RSA算法和国密算法,公钥由微信侧提供
      明细转账金额<0.3元时,不允许填写收款用户姓名
      明细转账金额 >= 2,000元时,该笔明细必须填写收款用户姓名
      同一批次转账明细中的姓名字段传入规则需保持一致,也即全部填写、或全部不填写
      若商户传入收款用户姓名,微信支付会校验用户openID与姓名是否一致,并提供电子回单

  • transfer_scene_id选填string(36)

    【转账场景ID】 该批次转账使用的转账场景,如不填写则使用商家的默认场景,如无默认场景可为空,可前往“商家转账到零钱-前往功能”中申请。
    如:1001-现金营销

3 请求示例

  • config.createEncryptor().encrypt("张三");:方法可以使用平台证书帮我们对姓名进行加密
package com.ruoyi.project;

import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.cipher.PrivacyEncryptor;
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.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

public class WeChatPayTest {

    /** 商户号 */
    public static String merchantId = "190000****";
    /** 商户API私钥路径   */

    public static String privateKeyPath = "/Users/yourname/your/path/apiclient_key.pem";

    /** 商户证书序列号 */
    public static String merchantSerialNumber = "5157F09EFDC096DE15EBE81A47057A72********";

    /** 商户APIV3密钥   */
    public static String apiV3Key = "...";
    public static TransferBatchService service;

    public static void main1(String[] args) {
        Config config = new RSAAutoCertificateConfig.Builder()
            .merchantId(merchantId)
            .privateKeyFromPath(privateKeyPath)
            .merchantSerialNumber(merchantSerialNumber)
            .apiV3Key(apiV3Key)
            .build();
        service = new TransferBatchService.Builder().config(config).build();

        //【Body】包体参数
        InitiateBatchTransferRequest initiateBatchTransferRequest = new InitiateBatchTransferRequest();
        initiateBatchTransferRequest.setAppid("wxf636efh567hg4356");
        initiateBatchTransferRequest.setOutBatchNo("plfk2020042013");
        initiateBatchTransferRequest.setBatchName("2019年1月深圳分部报销单");
        initiateBatchTransferRequest.setBatchRemark("2019年1月深圳分部报销单");
        initiateBatchTransferRequest.setTotalAmount(4000000L);
        initiateBatchTransferRequest.setTotalNum(200);
        {
            List<TransferDetailInput> transferDetailListList = new ArrayList<>();
            {
                TransferDetailInput transferDetailInput = new TransferDetailInput();
                transferDetailInput.setOutDetailNo("x23zy545Bd5436");
                transferDetailInput.setTransferAmount(200000L);
                transferDetailInput.setTransferRemark("2020年4月报销");
                transferDetailInput.setOpenid("o-MYE42l80oelYMDE34nYD456Xoy");
                // 官方例子:
                // transferDetailInput.setUserName("757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45");
                
                // 转账金额大于等于两千元,需要携带收款用户姓名
                if (initiateBatchTransferRequest.getTotalAmount().longValue() >= 200000){
                    /**
                     * Config config = new RSAAutoCertificateConfig.Builder()
                     * 具有自动下载并更新平台证书能力的RSA配置类。 每次构造,都会立即使用传入的商户参数下载微信支付平台证书。 如果下载成功,SDK 会将商户参数注册或更新至
                     * AutoCertificateService。若下载失败,将会抛出异常。 为了提高性能,建议将配置类作为全局变量,减少不必要的证书下载,避免资源浪费
                     * ----------------------------------------------------------------
                     * 我们直接通过config获取到加密的方法encryptor.encrypt("张三")。对姓名进行加密,
                     * 平台证书序列号在service.initiateBatchTransfer(initiateBatchTransferRequest);中会帮我们增加。
                     * */
                    PrivacyEncryptor encryptor = config.createEncryptor();
                    transferDetailInput.setUserName(encryptor.encrypt("张三"));
                }
                
                transferDetailListList.add(transferDetailInput);
            }
            initiateBatchTransferRequest.setTransferDetailList(transferDetailListList);
        }
        initiateBatchTransferRequest.setTransferSceneId("1000");
        InitiateBatchTransferResponse response = service.initiateBatchTransfer(initiateBatchTransferRequest);
    }
}

4 应答参数

  • 200 OK
  • out_batch_no必填string(32)

    【商家批次单号】 商户系统内部的商家批次单号,在商户系统内部唯一

  • batch_id必填string(64)

    【微信批次单号】 微信批次单号,微信商家转账系统返回的唯一标识

  • create_time必填string(32)

    【批次创建时间】 批次受理成功时返回,按照使用rfc3339所定义的格式,格式为YYYY-MM-DDThh:mm:ss+TIMEZONE

  • batch_status选填string

    【批次状态】

    • ACCEPTED:已受理。批次已受理成功,若发起批量转账的30分钟后,转账批次单仍处于该状态,可能原因是商户账户余额不足等。商户可查询账户资金流水,若该笔转账批次单的扣款已经发生,则表示批次已经进入转账中,请再次查单确认
    • PROCESSING:转账中。已开始处理批次内的转账明细单
    • FINISHED:已完成。批次内的所有转账明细单都已处理完成
    • CLOSED:已关闭。可查询具体的批次关闭原因确认

5 应答示例

{
  "out_batch_no" : "plfk2020042013",
  "batch_id" : "1030000071100999991182020050700019480001",
  "create_time" : "2015-05-20T13:29:35.120+08:00",
  "batch_status" : "ACCEPTED"
}

6 错误码

6.1 公共错误码

状态码 错误码 描述 解决方案
400 PARAM_ERROR 参数错误 请根据错误提示正确传入参数
400 INVALID_REQUEST HTTP 请求不符合微信支付 APIv3 接口规则 请参阅 接口规则(opens new window)
401 SIGN_ERROR 验证不通过 请参阅 签名常见问题(opens new window)
500 SYSTEM_ERROR 系统异常,请稍后重试 请稍后重试

6.2 业务错误码

状态码 错误码 描述 解决方案
400 INVALID_REQUEST 请求参数符合参数格式,但不符合业务规则 根据错误提示,传入正确参数
400 INVALID_REQUEST 创建订单冲突,请勿并发调用 根据错误提示调整调用策略
400 INVALID_REQUEST 对应单号已超出重试期,请查单确认后决定是否换单请求 根据错误提示调整调用策略
400 INVALID_REQUEST 此IP地址不允许调用该接口 请在商户平台-商家转账产品详情-转账发起方式-API发起-接口安全 中配置发起转账的IP地址
400 INVALID_REQUEST API通道未开启 请在商户平台-商家转账产品设置中配置API发起转账
400 INVALID_REQUEST 产品权限异常 请在商户平台-商家转账产品设置中开通产品权限
400 INVALID_REQUEST 超出商户单日转账额度,请核实产品设置是否准确 请在商户平台-商家转账产品设置中配置转账日限额
400 INVALID_REQUEST 你尚未获取该转账场景 请在商户平台-商家转账产品设置中申请该场景
400 INVALID_REQUEST 未配置收款用户列表 请前往商户平台-商家转账到零钱-转账场景中添加
400 PARAM_ERROR 参数错误 根据错误提示,传入正确参数
400 PARAM_ERROR 单批次明细笔数不合法,最高支持1000笔明细用 根据错误提示调整策略
401 APPID_MCHID_NOT_MATCH 商户号和appid没有绑定关系 商户号和appid没有绑定关系
403 ACCOUNTERROR 商户账户付款受限 可前往商户平台-违约记录获取解除功能限制指引
403 NO_AUTH 商户信息不合法 登录商户平台核对,传入正确信息
403 NOT_ENOUGH 资金不足 商户账户资金不足,请充值后原单重试,请勿更换商家转账批次单号
429 FREQUENCY_LIMITED 频率超限 该笔请求未受理,请降低频率后原单重试,请勿更换商家转账批次单号
500 SYSTEM_ERROR 系统错误 请勿更换商家转账批次单号,请使用相同参数再次调用API。否则可能造成资金损失

自定义工具类

如果不使用wechatpay-java依赖(推荐使用,方便),只是用wechatpay-apache-httpclient可以参考下面的方式。

        <!--        微信支付所需依赖-->
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.9.3</version>
        </dependency>
        <dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-apache-httpclient</artifactId>
            <version>0.4.8</version>
        </dependency>
        <!--        微信支付所需依赖end-->

1 微信工具类

WeChatPayUtils.java

  • 帮助获取维护证书。
  /**
     * 获取平台证书
     * @param certificateSerialNo 商户API证书序列号serial_no
     * @param mchId 发起请求的商户(包括直连商户、服务商或渠道商)的商户号
     * @param apiV3KeyParam API v3密钥
     * @return
     */
    public static X509Certificate getWechatpaySerial(String certificateSerialNo, String mchId, String apiV3KeyParam){
        // 设置请求头
        Map<String, String> headers = new TreeMap<>();
        headers.put("Accept", "application/json");
        headers.put("User-Agent", "application/json");
        HttpUrl httpUrl = HttpUrl.parse("https://api.mch.weixin.qq.com/v3/certificates");

        LOG.info("开始获取平台证书");
        try {
            String authHeader = getToken(
                "GET",
                httpUrl,
                certificateSerialNo,
                "",
                mchId
            );

            headers.put("Authorization", authHeader);
            String res = HttpUtil.createGet("https://api.mch.weixin.qq.com/v3/certificates").addHeaders(headers).execute().body();
            LOG.info("获取平台证书返回结果:" + res);

            // 处理返回的结果
            cn.hutool.json.JSONArray data = JSONUtil.parseObj(res).getJSONArray("data");
            cn.hutool.json.JSONObject encryptCertificate = data.getJSONObject(0).getJSONObject("encrypt_certificate");
            String ciphertext = encryptCertificate.getStr("ciphertext");
            String associatedDataStr = encryptCertificate.getStr("associated_data");
            String nonceStr = encryptCertificate.getStr("nonce");

            LOG.info("================================");
            LOG.info("加密的平台证书:{}", ciphertext);
            // 这里填写你的apiV3Key
            byte[] apiV3Key = apiV3KeyParam.getBytes();
            //附加数据包(可能为空)
            byte[] associatedData = associatedDataStr.getBytes();
            //加密使用的随机串初始化向量)
            byte[] nonce = nonceStr.getBytes();
            com.wechat.pay.contrib.apache.httpclient.util.AesUtil aesUtil = new com.wechat.pay.contrib.apache.httpclient.util.AesUtil(apiV3Key);
            String ciphertextDecrypt = aesUtil.decryptToString(associatedData, nonce, ciphertext);
            LOG.info("解密后的平台证书:{}", ciphertextDecrypt);

            // 获取证书工厂实例
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

            // 将证书字符串解析为证书对象
            InputStream inputStream = new ByteArrayInputStream(ciphertextDecrypt.getBytes());
            Certificate certificate = certificateFactory.generateCertificate(inputStream);

            return (X509Certificate) certificate;
        } catch (Exception e) {
            throw new ServerException("获取平台证书失败:" + e);
        }
    }

2 携带参数

设置请求头Wechatpay-Serial和使用平台证书加密姓名

    public static void main(String[] args) {
        X509Certificate certificate= new WeChatPayUtils.getWechatpaySerial(certificateSerialNo, mchId, wxMerchantConfig.getWechatKey());
        // 微信平台证书的序列号(Wechatpay-Serial)
        header.put("Wechatpay-Serial", certificate.getSerialNumber().toString(16));
        // 收款用户姓名,使用平台证书进行加密
        String userName = WeChatUtils.rsaEncryptOAEP(wxTransferView.getName(), certificate);
    }
目录
相关文章
|
6月前
|
JSON 小程序 数据格式
微信小程序的tabbar怎么配置
微信小程序的tabbar怎么配置
480 2
|
7月前
|
小程序 开发工具 git
【微信小程序】-- uni-app 项目--- 购物车 -- 配置 tabBar 效果(五十一)
【微信小程序】-- uni-app 项目--- 购物车 -- 配置 tabBar 效果(五十一)
|
3月前
|
iOS开发 开发者
iOS微信分享配置universal links步骤
iOS微信分享配置universal links步骤
1392 58
|
2月前
|
存储 小程序 安全
微信的开发管理都需要配置什么?
【10月更文挑战第17天】微信的开发管理都需要配置什么?
39 0
|
4月前
|
Linux 网络安全 API
企业微信自定义应用 企业可信IP配置 企业可信ip怎么设置
企业微信自定义应用 企业可信IP配置 企业可信ip怎么设置
|
7月前
|
开发框架 移动开发 小程序
【微信小程序】-- 配置uni-app的开发环境(四十八)
【微信小程序】-- 配置uni-app的开发环境(四十八)
|
5月前
|
小程序 JavaScript 前端开发
【微信小程序-原生开发】实用教程06-轮播图、分类页签 tab 、成员列表(含Tdesign升级,切换调试基础库,设置全局样式,配置组件按需注入,添加图片素材,wx:for,生命周期 onLoad)
【微信小程序-原生开发】实用教程06-轮播图、分类页签 tab 、成员列表(含Tdesign升级,切换调试基础库,设置全局样式,配置组件按需注入,添加图片素材,wx:for,生命周期 onLoad)
178 0
|
5月前
|
小程序 开发工具 开发者
【微信小程序-原生开发】实用教程02-添加全局页面配置、页面、底部导航
【微信小程序-原生开发】实用教程02-添加全局页面配置、页面、底部导航
70 0
|
6月前
微信登陆报错:redirect_uri域名与后台配置不一致,错误码:10003 微信支付报错 微信登录报错 微信开发
微信登陆报错:redirect_uri域名与后台配置不一致,错误码:10003 微信支付报错 微信登录报错 微信开发
97 0
|
7月前
|
JSON 小程序 安全
微信小程序介绍、账号申请、开发者工具目录结构详解及小程序配置
微信小程序介绍、账号申请、开发者工具目录结构详解及小程序配置