文章目录

  • 一、引入jar包
  • 二、yml里面配置支付
  • 三、java 实现支付的步骤
  • (1)在controller里面写一个支付接口
  • (2) EntPayReq 的实体类对象
  • (3)业务层 WxEntPayService
  • (4) RandomUtil方法
  • (5) 业务层 WxEntPayServiceImpl 实现方法


基于新创建的企业微信支付号,企业支付到零钱的功能改成了企业转账到零钱的功能,我们来实践操作一下,下面上步骤。

一、引入jar包

<dependency>
            <groupId>com.github.binarywang</groupId>
            <artifactId>wx-java-pay-spring-boot-starter</artifactId>
            <version>4.3.7.B</version>
        </dependency>

二、yml里面配置支付

wx:
  # 微信公众号
  mp:
    app-id: 微信公众号appid
    secret: 微信公众号密钥
    token: arecatoken
  # 微信企业支付
  pay:
    appId: 微信公众号appid
    mchId: 微信企业商户号
    apiv3-key: api3key密钥
    private-key-path: 证书apiclient_key
    private-cert-path: 证书apiclient_cert

三、java 实现支付的步骤

**该案例是微信公众号+微信支付,切齐一定要微信公众号关联微信商户号才可以**

(1)在controller里面写一个支付接口

public class WxEntPayController {

    @Autowired
    private WxEntPayService wxEntPayService;

    /**
     * 支付接口
     *
     * @param entPayReq
     * @return
     */
    @AutoLog(value = "支付接口")
    @ApiOperation(value = "支付接口", notes = "支付接口")
    @PostMapping(value = "/entPay")
    public Result<?> entPay(@RequestBody EntPayReq entPayReq) {
        wxEntPayService.entPay(entPayReq);
        return Result.OK("支付成功!");
    }
}

(2) EntPayReq 的实体类对象

@ApiModel("企业支付请求")
@Data
public class EntPayReq {
    /**
     * <pre>
     * 字段名:金额.
     * 变量名:amount
     * 是否必填:是
     * 示例值:10099
     * 类型:int
     * 描述:企业付款金额, 单位为分
     * </pre>
     */
    @NotNull(message = "金额不能为空")
    @Min(value = 30, message = "最小金额30分")
    @ApiModelProperty(value = "金额(单位分)", required = true)
    private Integer amount;

    /**
     * <pre>
     * 字段名:校验用户姓名选项.
     * 变量名:check_name
     * 是否必填:是
     * 示例值:OPTION_CHECK
     * 类型:String
     * 描述:NO_CHECK:不校验真实姓名 
     * FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账) 
     * OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功)
     * </pre>
     */
    @ApiModelProperty(value = "校验用户姓名选项 [NO_CHECK:不校验真实姓名,FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账),OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功)]")
    private String checkName;

    /**
     * <pre>
     * 字段名:收款用户姓名.
     * 变量名:re_user_name
     * 是否必填:可选
     * 示例值:马花花
     * 类型:String
     * 描述:收款用户真实姓名。
     * 如果check_name设置为FORCE_CHECK或OPTION_CHECK,  则必填用户真实姓名
     * </pre>
     */
    @ApiModelProperty("收款用户真实姓名")
    private String reUserName;

    /**
     * <pre>
     * 字段名:设备号.
     * 变量名:device_info
     * 是否必填:否
     * 示例值:13467007045764
     * 类型:String(32)
     * 描述:微信支付分配的终端设备号
     * </pre>
     */
    @ApiModelProperty("设备号")
    private String deviceInfo;

    /**
     * <pre>
     * 字段名:Ip地址.
     * 变量名:spbill_create_ip
     * 是否必填:是
     * 示例值:192.168.0.1
     * 类型:String(32)
     * 描述:调用接口的机器Ip地址
     * </pre>
     */
    @NotBlank(message = "不能为空")
    @ApiModelProperty(value = "Ip地址", required = true)
    private String spbillCreateIp;

    /**
     * 支付订单号
     */
    @ApiModelProperty(value = "支付订单号[非必填]")
    private String partnerTradeNo;

    /**
     * 批次订单号
     */
    @ApiModelProperty(value = "批次订单号")
    private String batchTradeNo;
}

(3)业务层 WxEntPayService

public interface WxEntPayService {
    /**
     * 微信支付
     *
     * @param entPayReq
     */
    void entPay(EntPayReq entPayReq);
}

(4) RandomUtil方法

import org.apache.commons.lang3.RandomStringUtils;

public class RandomUtil
{
    private static char[] chars  = new char[]{'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e',
            'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
            'V', 'W', 'X', 'Y', 'Z'};

    private static char[] nubers = new char[]{'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};

    /**
     * 生成随机字符串,包含数字和字母
     * @param length 长度
     * @return
     * @author zmr
     */
    public static String randomStr(int length)
    {
        return RandomStringUtils.random(length, chars);
    }

    /**
     * 生成随机字符串,只包含数字
     * @param length 长度
     * @return
     * @author zmr
     */
    public static String randomInt(int length)
    {
        return RandomStringUtils.random(length, nubers);
    }
}

(5) 业务层 WxEntPayServiceImpl 实现方法

@Service
@Slf4j
public class WxEntPayServiceImpl implements WxEntPayService {

    @Autowired
    private WxPayService wxPayService;
    /**
     * 不校验真实姓名.
     */
    public static final String NO_CHECK = "NO_CHECK";

    /**
     * 微信支付
     *
     * @param req
     */
    @Override
    public void entPay(EntPayReq req) {
        log.info("开始企业支付到零钱 [req:{}]",req);
        req.setCheckName(StringUtils.isBlank(req.getCheckName()) ? NO_CHECK : req.getCheckName());
        //商户订单号
        String partnerTradeNo = StringUtils.isNotBlank(req.getPartnerTradeNo()) ? req.getPartnerTradeNo() : RandomUtil.randomInt(20);
        req.setPartnerTradeNo(partnerTradeNo);
        //随机获取批次号  切记仅用于测试
        String s =  RandomNumber.GetRandom();
        req.setBatchTradeNo(s);
        TransferService transferService = wxPayService.getTransferService();
        //获取appId
        String appId = wxPayService.getConfig().getAppId();
        //创建批次对象
        TransferBatchesRequest transferBatchesRequest=new TransferBatchesRequest();
        transferBatchesRequest.setAppid(appId);
        //设置批次名称 可不写
        transferBatchesRequest.setBatchName("测试批次");
        //设置批次备注 可不写
        transferBatchesRequest.setBatchRemark("测试");
        //设置该批次编号
        transferBatchesRequest.setOutBatchNo(s);
        //设置该批次总个数
        transferBatchesRequest.setTotalNum(1);
        //设置该批次总金额
        transferBatchesRequest.setTotalAmount(req.getAmount());
        //创建收款人请求对象
        ArrayList<TransferBatchesRequest.TransferDetail> transferDetails = new ArrayList<>();
        TransferBatchesRequest.TransferDetail transferDetail=new TransferBatchesRequest.TransferDetail();
        //转账的编号
        transferDetail.setOutDetailNo(req.getPartnerTradeNo());
        //转账的金额
        transferDetail.setTransferAmount(req.getAmount());
        //转账的注释
        transferDetail.setTransferRemark("转账金额");
        //以实际微信公众号那边的openid为准
        transferDetail.setOpenid("获取到用户的openid");
        //把收款人对象放到批次里面
        transferDetails.add(transferDetail);
        transferBatchesRequest.setTransferDetailList(transferDetails);
        TransferBatchesResult transferBatchesResult=null;
        try {
            transferBatchesResult = transferService.transferBatches(transferBatchesRequest);
            log.info("企业支付完成:[msg:{}]",transferBatchesResult);
        } catch (WxPayException e) {
            e.printStackTrace();
            log.info("企业支付失败:[msg:{}]",e.getMessage());
        }

    }

这样就可以实现单个人转账到零钱,该方法仅用于测试
批量转账到零钱是为了实现一批次转账到多个账户的方法,这里我只用了一个用户转账。