0


【微信支付】springboot-java接入微信支付-JSAPI支付/查单/退款/发送红包(四)---发送红包

微信api发送微信红包

一、准备工作

微信红包文档:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_3&index=2

1.开通现金红包权限

注意: 根据监管要求,新申请商户号使用现金红包需要满足两个条件:

◆ 商户号已入驻90日且截止今日回推30天商户号保持连续不间的交易;
◆ 保持正常健康交易:

在使用现金红包之前,请前往开通现金红包功能。操作路径:【登录微信支付商户平台——>产品中心——>现金红包——>开通】
在这里插入图片描述

注意⚠️:在开通时请如实选择你的使用场景,且在红包的发放过程中如实上报你的场景,如有作假,微信支付将有权根据《微信支付商户平台使用协议》对你的商户号做出处理。

2.下载API证书

商户调用微信红包接口时,微信支付服务器会进行证书验证,请现在商户平台下载证书

3.充值

在发放现金红包之前,请确保你的资金充足。如若不足,请充值。操作路径:【登录商户平台——>交易中心——>资金管理——>充值】

4.获取openid

目前支持向指定微信用户的openid发放指定金额红包。(获取openid参见微信公众平台开发者文档:网页授权获取用户基本信息)

5.相关参数设置

和红包相关的参数,你可以在页面上自主设置和更改。操作路径如下:【登录商户平台——>产品中心——>现金红包——>产品设置】

注:“产品设置”操作按钮仅当你开通现金红包功能之后才会出现。

说明

    ◆ 调用IP地址:设置之后,仅有已设置的IP地址可以调用,其余的IP调用会报错,最多支持10个
    ◆ 单日发送金额上限:该商户一天允许发放的红包总金额上限;
    ◆ 单用户单日领取上限:限制同一openid同一日领取该商户的个数上限;
    ◆ 单用户单日领取金额上限:限制同一openid同一日领取该商户的红包金额上限
    ◆ 防刷等级:防刷是指微信风控针对微信小号、僵尸号、机器号等的拦截,你可以通过更改防刷等级控制防刷的强度(0级为关闭,1到3逐级递增安全等级);
    ◆ 同时,你也可以申请更改红包额度。若超过所选使用场景的默认额度,则需要经过审核,审核通过之后才会生效;

二、开始开发

WxpayConfig.java以及实体类Entity.java文件请查看博主【微信支付】springboot-java接入微信支付-JSAPI支付/查单/退款/发送红包(一)—JSAPI支付

发送红包接口 同样在QuickStart.java文件中继续编写
完整接口代码:

@PostMapping("/send_redPack")publicMap<String,String>send_redPack(@RequestBodyOrderDao orderDao,@RequestParamInteger rebate_price)throwsException{Map<String,String> map =newHashMap<>();String noncestr =WXPayUtil.generateNonceStr();// 生成随机字符串SortedMap<String,String> requestMap =newTreeMap();
        requestMap.put("mch_billno", orderDao.getOrder_no());// 商户订单号
        requestMap.put("mch_id", wxPayConfig.getMchId());// 商户号
        requestMap.put("wxappid", wxPayConfig.getAppid());// appid
        requestMap.put("send_name","*****");// 商户名称
        requestMap.put("re_openid", orderDao.getOpenid());// 发送红包给用户,用户的openid
        requestMap.put("total_amount", rebate_price.toString());// 发送金额,这里接口传入的是单位为分的整数,需转化为string类型存入
        requestMap.put("total_num","1");//红包发送总人数
        requestMap.put("wishing", orderDao.getDescription());// 红包祝福语
        requestMap.put("client_ip","127.0.0.1");// Ip地址,填写在商户平台设置的IP白名单中的ip
        requestMap.put("act_name", orderDao.getActivity_name());// 活动名称
        requestMap.put("nonce_str", noncestr);//随机字符串String s =WXPayUtil.generateSignature(requestMap, wxPayConfig.getApiV2Key());// 这里注意,发送红包接口使用的是V2版本的密钥//这里使用最简单的构建请求参数的方式,直接拼接String postXml ="<xml>\n"+"<sign><![CDATA["+ s +"]]></sign>\n"+"<mch_billno><![CDATA["+ orderDao.getOrder_no()+"]]></mch_billno>\n"+"<mch_id><![CDATA["+ wxPayConfig.getMchId()+"]]></mch_id>\n"+"<wxappid><![CDATA["+ wxPayConfig.getAppid()+"]]></wxappid>\n"+"<send_name><![CDATA["+"*****"+"]]></send_name>\n"+"<re_openid><![CDATA["+ orderDao.getOpenid()+"]]></re_openid>\n"+"<total_amount><![CDATA["+ rebate_price +"]]></total_amount>\n"+"<total_num><![CDATA["+"1"+"]]></total_num>\n"+"<wishing><![CDATA["+ orderDao.getDescription()+"]]></wishing>\n"+"<client_ip><![CDATA["+"127.0.0.1"+"]]></client_ip>\n"+"<act_name><![CDATA["+ orderDao.getActivity_name()+"]]></act_name>\n"+"<nonce_str><![CDATA["+ noncestr +"]]></nonce_str>\n"+"</xml>";HttpPost httpPost =newHttpPost("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack");

        httpPost.setHeader("Accept","application/json;charset=utf-8");String result =SSLUtil.ssl("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack",postXml);// 请求发送红包接口需要证书,所以利用SSL发送请求并获取结果String info  =WXPayUtil.xmlToMap(result).get("return_msg");//微信支付系统返回的应答参数是xml,使用微信sdk自带的泪转化并提取内容
        map.put("code","200");// 返回状态这里直接写了200,大家需要的话自行修改
        map.put("data",result);
        map.put("info",info);return map;}

SSLUtil.java:

importlombok.extern.slf4j.Slf4j;importorg.apache.http.HttpEntity;importorg.apache.http.client.methods.CloseableHttpResponse;importorg.apache.http.client.methods.HttpPost;importorg.apache.http.conn.ssl.SSLConnectionSocketFactory;importorg.apache.http.entity.StringEntity;importorg.apache.http.impl.client.CloseableHttpClient;importorg.apache.http.impl.client.HttpClients;importorg.apache.http.ssl.SSLContexts;importorg.apache.http.util.EntityUtils;importorg.springframework.core.io.ClassPathResource;importjavax.net.ssl.SSLContext;importjava.io.*;importjava.security.KeyStore;@Slf4jpublicclassSSLUtil{// 微信支付的商户idprivatestaticfinalString mch_id ="********";publicstaticStringssl(String url,String data){StringBuffer message =newStringBuffer();try{KeyStore keyStore  =KeyStore.getInstance("PKCS12");/**
             *
             *重要:将API证书 apiclient_cert.p12 放到resource目录下
             *
             */ClassPathResource cl =newClassPathResource("apiclient_cert.p12");//证书,商户号
            keyStore.load(cl.getInputStream(),mch_id.toCharArray());// 信任自己的 CA 和所有自签名证书SSLContext sslcontext =SSLContexts.custom().loadKeyMaterial(keyStore, mch_id.toCharArray()).build();// 仅允许 TLSv1 协议SSLConnectionSocketFactory sslsf =newSSLConnectionSocketFactory(
                    sslcontext,newString[]{"TLSv1"},null,SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);CloseableHttpClient httpclient =HttpClients.custom().setSSLSocketFactory(sslsf).build();HttpPost httpost =newHttpPost(url);
            httpost.addHeader("Connection","keep-alive");
            httpost.addHeader("Accept","*/*");
            httpost.addHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
            httpost.addHeader("Host","api.mch.weixin.qq.com");
            httpost.addHeader("X-Requested-With","XMLHttpRequest");
            httpost.addHeader("Cache-Control","max-age=0");
            httpost.addHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
            httpost.setEntity(newStringEntity(data,"UTF-8"));System.out.println("executing request"+ httpost.getRequestLine());CloseableHttpResponse response = httpclient.execute(httpost);try{HttpEntity entity = response.getEntity();System.out.println("----------------------------------------");System.out.println(response.getStatusLine());if(entity !=null){System.out.println("Response content length: "+ entity.getContentLength());BufferedReader bufferedReader =newBufferedReader(newInputStreamReader(entity.getContent(),"UTF-8"));String text;while((text = bufferedReader.readLine())!=null){
                        message.append(text);}}EntityUtils.consume(entity);}catch(IOException e){
                e.printStackTrace();}finally{
                response.close();}}catch(Exception e1){
            e1.printStackTrace();}return message.toString();}}

三、测试结果

在这里插入图片描述在这里插入图片描述在这里插入图片描述

data内是微信支付系统返回的xml类型的返回参数,info中是使用微信工具类将xml转化为map后提取的return_msg中的内容

四、附:

各种失败的场景解释

  • 证书错误![证书错误](https://img-blog.csdnimg.cn/direct/9c661c3e8fc542e48d6615e0c1e09c9f.png

一般证书未读取到证书会抛出异常,而不会返回200;这种情况是因为发起请求时,没有携带证书发送。微信支付文档中明确表示,接口调用需要证书。
使用SSLUtil工具类发起请求携带证书

  • 订单号过长订单号过长
  • xml参数格式错误

xml参数错误

  • 签名错误(这个应该是最常出现的错误)签名错误开发文档中还有很多错误,都一一对应,返回参数对照文档可以快速定位问题所在,具体请查看现金红包开发者文档。

至此,整个微信支付的教程基本结束了,如果有小伙伴有其他问题,欢迎留言或者私信。

标签: java 微信 spring boot

本文转载自: https://blog.csdn.net/ssdadasd15623/article/details/135470966
版权归原作者 看海O.o 所有, 如有侵权,请联系我们删除。

“【微信支付】springboot-java接入微信支付-JSAPI支付/查单/退款/发送红包(四)---发送红包”的评论:

还没有评论