微信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") public Mapsend_redPack(@RequestBody OrderDao orderDao,@RequestParam Integer rebate_price) throws Exception { Map map = new HashMap<>(); String noncestr = WXPayUtil.generateNonceStr(); // 生成随机字符串 SortedMap requestMap = new TreeMap(); 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 = " \n" + " "; HttpPost httpPost = new HttpPost("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; }\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + "
SSLUtil.java:
import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContexts; import org.apache.http.util.EntityUtils; import org.springframework.core.io.ClassPathResource; import javax.net.ssl.SSLContext; import java.io.*; import java.security.KeyStore; @Slf4j public class SSLUtil { // 微信支付的商户id private static final String mch_id = "********"; public static String ssl(String url,String data){ StringBuffer message = new StringBuffer(); try { KeyStore keyStore = KeyStore.getInstance("PKCS12"); /** * *重要:将API证书 apiclient_cert.p12 放到resource目录下 * */ ClassPathResource cl = new ClassPathResource("apiclient_cert.p12"); //证书,商户号 keyStore.load(cl.getInputStream(),mch_id.toCharArray()); // 信任自己的 CA 和所有自签名证书 SSLContext sslcontext = SSLContexts.custom() .loadKeyMaterial(keyStore, mch_id.toCharArray()) .build(); // 仅允许 TLSv1 协议 SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); CloseableHttpClient httpclient = HttpClients.custom() .setSSLSocketFactory(sslsf) .build(); HttpPost httpost = new HttpPost(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(new StringEntity(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 = new BufferedReader(new InputStreamReader(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中的内容
四、附:
各种失败的场景解释
- 证书错误
一般证书未读取到证书会抛出异常,而不会返回200;这种情况是因为发起请求时,没有携带证书发送。微信支付文档中明确表示,接口调用需要证书。
使用SSLUtil工具类发起请求携带证书
-
订单号过长
-
xml参数格式错误
- 签名错误(这个应该是最常出现的错误)
开发文档中还有很多错误,都一一对应,返回参数对照文档可以快速定位问题所在,具体请查看现金红包开发者文档。
至此,整个微信支付的教程基本结束了,如果有小伙伴有其他问题,欢迎留言或者私信。
- 签名错误(这个应该是最常出现的错误)
-
猜你喜欢
网友评论
- 搜索
- 最新文章
- 热门文章