携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第21天,点击查看活动详情
在很多涉及到支付的业务中,有用户向平台付款,也有平台向用户付款(提现等),今天要学习的是微信支付企业付款到零钱。
开通条件
微信必须注册为商户号,商户号已入驻90日且截止今日回推30天商户号保持连续不间断的交易。
登录微信支付商户平台,开通付款到零钱。
登录微信商户平台,在【产品中心】-【我的产品】下可以找到企业付款到零钱。
这里有个小技巧:当我们的商户号刚开通,还没有流水的时候,这个时候可以每天通过我们的商户平台进行付一笔款来刷一下流水。
代码实现
在进行代码开发之前,还有一个很重要的文件:商户证书,因为调用企业付款接口是需要传入证书的。这里需要将商户证书进行下载下来,放到服务器或本地的某个目录,在项目代码执行时要进行使用。
付款给用户是要获取到该用户小程序的openid,该openid是微信用户在公众账号下的唯一用户标识。
private static String wechatPath;
@Value("${wechat.path}")
private void setReplacePath(String path){
wechatPath = path;
}
public static Object[] payToUser(String orderNo, String weixinOpenId, String realname
, BigDecimal payAmount, String desc, String ip) {
// File pkcFile = new File("E:\apiclient_cert.p12");
File pkcFile = new File(wechatPath);
Map<String, String> paramMap = new HashMap<String, String>();
// 公众账号appid[必填]
paramMap.put("mch_appid", PaymentConfig.appid);
// 微信支付分配的商户号 [必填]
paramMap.put("mchid", PaymentConfig.mch_id);
// 终端设备号(门店号或收银设备ID),注意:PC网页或公众号内支付请传"WEB" [非必填]
paramMap.put("device_info", "WEB");
// 随机字符串,不长于32位。 [必填]
paramMap.put("nonce_str", RandomStringUtils.random(16, Num62.N62_CHARS));
// 商户订单号,需保持唯一性[必填]
paramMap.put("partner_trade_no", orderNo);
// 商户appid下,某用户的openid[必填]
paramMap.put("openid", weixinOpenId);
//校验用户姓名选项 NO_CHECK:不校验真实姓名 FORCE_CHECK:强校验真实姓名
// paramMap.put("check_name", "OPTION_CHECK");
paramMap.put("check_name", "NO_CHECK");
//收款用户姓名,如果check_name设置为FORCE_CHECK,则必填用户真实姓名
// paramMap.put("re_user_name", realname);
// 企业付款金额,金额必须为整数 单位为分 [必填]
paramMap.put("amount", PayUtil.changeY2F(payAmount));
// 企业付款描述信息 [必填]
paramMap.put("desc", desc);
// 调用接口的机器Ip地址[必填]
paramMap.put("spbill_create_ip", ip);
// 根据微信签名规则,生成签名
paramMap.put("sign", PayUtil.createSign(paramMap, PaymentConfig.appKey));
// 把参数转换成XML数据格式
String xmlWeChat = PayUtil.assembParamToXml(paramMap);
String resXml = "";
boolean postError = false;
try {
resXml = ClientCustomSSL.getInSsl(PaymentConfig.pay_url, pkcFile, PaymentConfig.mch_id
, xmlWeChat, "application/xml");
} catch (Exception e1) {
postError = true;
e1.printStackTrace();
}
Object[] result = new Object[2];
result[0] = postError;
result[1] = resXml;
return result;
}