最近接了微信的现金红包功能,遇到了一些问题,相信是共性的问题,写篇文章记录下,希望能帮助到遇到同样问题的小伙伴。
老规矩,先看一下文章的目录。
文章目录
1、微信现金红包产品官方文档
https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_1
2、现金红包的发放形式
现金红包是商户通过公众号或者服务通知向用户发放现金红包。这个是有别于"小程序红包"的,小程序红包是微信支付的另一款产品。这里要注意下。接着说我们的现金红包。
如果用户关注了公众号,那现金红包就是以公众号消息的方式下发,如图一。
图一:
如果用户没有关注商户的公众号,那用户收到的现金红包消息是服务通知的形式,如图二:
图二:
用户点击消息,就会看到如下的红包,点开红包,红包就会进入零钱。
这里有一个很重要的点:用户没有关注公众号,我们也是可以通过微信提供的SDK获取到用户在微信上的信息,比如:用户在当前这个公众号的openId,然后通过这个openId给用户发红包,只不过红包消息不是以公众号的方式发出的,而是以服务通知的方式。所以,如果确定使用这个产品,务必和业务同事说清楚红包发放的形式。
3、申请现金红包权限准备事项
需要登录微信支付的后台,填写一些信息,开通现金红包。微信支付会在7个工作日以内审核通过,注意是工作日,不是自然日。我申请这个功能时,是等了6个工作日。所以如果确定要用这个产品,一定要早点申请,否则你就干等着吧。
审核通过,微信会给商户在微信支付的后台发一条站内信,通知你审核通过。
这里要注意:填写审核信息的时候,务必多检查几遍你填写的信息。如果填写错了,微信审核失败,重新申请,等的时间会比首次申请更久,这句话不是我说的,是微信官方说的,所以确保第一次申请填写的信息是正确的。
4、代码开发
代码开发时,尽量不要自己造轮子,用成熟的框架,要不然真的会被微信支付给玩死。这里推荐两个。
IJPay、WxJava
IJPay代码库地址
https://github.com/Javen205/IJPay.git
WxJava的代码库地址
https://github.com/binarywang/WxJava.git
我们的系统用的是IJPay,这个框架,在支付和退款等模块的集成还挺好,但是对现金红包这个产品的集成就不是很好,需要用户处理一些东西,比如:签名。接过微信支付产品的同学都知道,如果第一次接入微信,真的会被微信的签名搞到抓狂。这一点上,WxJava就好一点,我没有在生产用过,但是看过这个框架对现金红包集成的测试用例,入参的签名和出参的验签,框架都替业务做了,业务侧只需要关注业务逻辑就行了,很是省事,所以如果项目里没有集成微信支付的框架时,可以考虑用WxJava。
因为我的环境用的是IJPay,所以我给出的示例代码,也是IJPay的。
4.1、构建发送现金红包的入参
private Map<String, String> buildSendPackageParamMap(SendRedPackageReq sendRedPackageReq) {
Map<String, String> sendParamMap = new HashMap<>();
//使用IJPay的工具类生成nonce_str
sendParamMap.put("nonce_str", WxPayKit.generateStr());
//现金红包商户单号,可以随机生成,但需要确保系统内唯一
sendParamMap.put("mch_billno", "18405894839121");
//10位的数字
sendParamMap.put("mch_id", "1510998812");
//微信分配给公众号的appId
sendParamMap.put("wxappid", "wx3688891010919401");
sendParamMap.put("send_name", "红包发送者名称");
//用户在当前公众号的openId
sendParamMap.put("re_openid", "omPxS0dPPZAAZEES3PFFKfufC6ik");
//红包金额,单位:分
sendParamMap.put("total_amount", 100);
//发送的红包个数
sendParamMap.put("total_num", "1");
//红包祝福语
sendParamMap.put("wishing", "红包祝福语");
//红包发送者IP,这个IP,微信不会做强校验,只要格式对就行,可以随便填
sendParamMap.put("client_ip", "192.168.11.21");
//活动名称,可以根据业务情况,随意填写
sendParamMap.put("act_name", "活动名称");
//红包备注,可以根据业务情况,随意填写
sendParamMap.put("remark", "发红包的备注");
//生成请求的签名.这里调用IJPay的工具类生成签名。注意:生成签名的第二个参数是微信支付的V2秘钥,不是V3秘钥。很多人都卡在这个地方,所以秘钥一定要确认是正确的V2秘钥,否则你就会得到签名错误的响应
String sign = WxPayKit.createSign(sendParamMap, "UJfuyirofjfsun109981", SignType.MD5);
sendParamMap.put("sign", sign);
return sendParamMap;
}
4.2、发送现金红包
//获取P12证书。微信官方给了如何获取这个证书的方式,这里不多介绍
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("cert/apiclient_cert.p12");
//调用IJPay的发送现金红包的API发送现金红包,这里注意方法的第三个参数,这个参数是P12证书的秘钥,P12证书的秘钥,是那个10位的商户号
String sendStr = WxPayApi.sendRedPack(sendRedPackageParamMap, inputStream,"1510998812");
5、可能遇到的问题
5.1、签名错误
如果你调用微信支付API发送现金红包时,一直报错:签名错误,可以用微信支付官方提供的这个验证签名是否正确的工具来验证下你的入参是否正确。
工具地址:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=20_1
工具截图如下:
微信现金红包的入参是XML格式。如果你的代码一直报错:签名错误,可以先尝试把你生成的XML入参拿到这个地方验证一下。
这里要注意:这个工具只能验证你的XML参数拼接顺序正确,并不能说明你的秘钥是正确的
以上就是微信现金红包接入的一个流程说明,如果你接入遇到了问题,可以留言,我看到了,会协助处理。
5.2、该场景未开通
发送现金红包的入参里有一个参数是scene_id,这个参数是非必填的。
官方文档对这个参数的说明是:
其实这里是有个坑的。官方文档这里写的是小于1元时必传。
但是如果你在微信支付后台,将红包的最小金额,设置成小于1元,这个scene_id参数并不是必填。感觉官方文档这个地方没有写清楚。感觉不是啥坑是吧?接着往下看。
如果你设置了这个值,官方可能会响应:
该场景未开通:请登录商户平台,产品中心-现金红包-产品设置-使用场景进行开通
然后你就会发现,根本找不到设置的地方。。。。。
这算坑吧?🐶。
所以,就直接不填这个参数就行了。
但是也有可能是我找的地不对😂,如果有老哥知道在哪设置,麻烦评论区指导一下,感谢。