微信红包发送关键代码


title: 微信红包发送关键代码
date: 2019-09-21 17:30:13
tags: 微信

微信红包发送主要涉及服务号获取用户openid、发送红包请求两块内容,本文展示这两部分的关键代码。

获取用户openid

1、服务号设置内容链接

​ 笔者维护的服务号使用自定义菜单跳转网页的方式,网页链接格式按照微信公众号开发文档中归档的格式即可,如果只需要获得openid的则按照snsapi_base的格式即可。

2、获取网页授权access_token与openid

获取网页授权access_token部分代码:

 // 拼接请求地址
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
url = url.replace("APPID", appId);
url = url.replace("SECRET", appSecret);
url = url.replace("CODE", code);

Map<String, Object> map = new HashMap<String, Object>();
ObjectMapper mapper = new ObjectMapper();
// 获取网页授权凭证
String result = new WxUtil().getSendResult(url);//该方法发送get请求

try {
  result = new String(result.getBytes("GBK"), "UTF-8");
} catch (UnsupportedEncodingException e1) {
  e1.printStackTrace();
}
System.out.println("result=" + result);

​ 正常获取的json数据格式如下,其中openid 便是用户在这个服务号下的唯一编号,之后便可以与数据库中的用户进行绑定:

{
  "access_token":"ACCESS_TOKEN",
  "expires_in":7200,
  "refresh_token":"REFRESH_TOKEN",
  "openid":"OPENID",
  "scope":"SCOPE" 
}

发送红包

1、获得签名

​ 发送红包请求中需要包含签名,具体生成方法请参考微信商户签名生成方法文档。这个步骤很容易出现错误,比如数值为空的参数也参与了签名算法、key值为空等情况,可参考签名校验工具进行验证。以下为笔者生成签名的部分代码:

//String param = "act_name=ACT_NAME&client_ip=CLIENT_IP&mch_billno=MCH_BILLNO&mch_id=MCH_ID&nonce_str=NONCE_STR&re_openid=RE_OPENID&remark=REMARK&scene_id=SCENE_ID&send_name=SEND_NAME&total_amount=TOTAL_AMOUNT&total_num=TOTAL_NUM&wishing=WISHING&wxappid=WXAPPID&key=KEY";
    	
//不添加场景参数
String param = "act_name=ACT_NAME&client_ip=CLIENT_IP&mch_billno=MCH_BILLNO&mch_id=MCH_ID&nonce_str=NONCE_STR&re_openid=RE_OPENID&remark=REMARK&send_name=SEND_NAME&total_amount=TOTAL_AMOUNT&total_num=TOTAL_NUM&wishing=WISHING&wxappid=WXAPPID&key=KEY";

String act_name = str.get(map, "act_name");//str为笔者系统里的一个工具类
String client_ip = str.get(map, "client_ip");
String mch_billno = str.get(map, "mch_billno");
String mch_id = str.get(map, "mch_id");
String nonce_str = str.get(map, "nonce_str");
String re_openid = str.get(map, "re_openid");
String remark = str.get(map, "remark");
String scene_id = str.get(map, "scene_id");
String send_name = str.get(map, "send_name");
String sign = str.get(map, "sign");
String total_amount = str.get(map, "total_amount");
String total_num = str.get(map, "total_num");
String wishing = str.get(map, "wishing");
String wxappid = str.get(map, "wxappid");

param = param.replace("ACT_NAME", act_name)
  .replace("CLIENT_IP", client_ip)
  .replace("MCH_BILLNO", mch_billno)
  .replace("MCH_ID", mch_id)
  .replace("NONCE_STR", nonce_str)
  .replace("RE_OPENID", re_openid)
  .replace("REMARK", remark)
  .replace("SCENE_ID", scene_id)
  .replace("SEND_NAME", send_name)
  .replace("SIGN", sign)
  .replace("TOTAL_AMOUNT", total_amount)
  .replace("TOTAL_NUM", total_num)
  .replace("WISHING", wishing)
  .replace("WXAPPID", wxappid)
  .replace("KEY", key);
//System.out.println(param);
return new MD5().MD5Encode(param).toUpperCase();

2、发送红包请求

​ 发送请求请按照微信红包发送文档的规定进行发送,请求方式为post,必须得携带api证书进行发送,以下为部分发送代码:

public String sendRedPack(Map<String, Object> packInfo) throws Exception {
		String result = "";
		String url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
		String urlparams = sendRedPackParams();
		
		Set<String> set = packInfo.keySet(); //取出所有的key值
        for (String key:set) {
        	String value = (String)packInfo.get(key);
        	urlparams = urlparams.replace(key.toUpperCase(), value);
        	//log.debug("key="+key+" value="+value);
        }
        
        log.debug("urlparams=" + urlparams);
        
		KeyStore keyStore = KeyStore.getInstance("PKCS12");
		FileInputStream instream = new FileInputStream(new File("apiclient_cert.p12"));
		try {
			keyStore.load(instream, SzdjjhConst.getMch_id().toCharArray());
		} finally {
			instream.close();
		}
		// Trust own CA and all self-signed certs
		SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, SzdjjhConst.getMch_id().toCharArray()).build();
		// Allow TLSv1 protocol only
		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,
				SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
		CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
		
		try {
			HttpPost httpPost = new HttpPost(url);
			log.debug("executing request" + httpPost.getRequestLine());
			//中文不成功是因为没加编码
			StringEntity myEntity = new StringEntity(urlparams, "utf-8");
			httpPost.setEntity(myEntity);
			CloseableHttpResponse response = httpclient.execute(httpPost);
			try {
				HttpEntity entity1 = response.getEntity();
				log.debug("----------------------------------------");
				log.debug(response.getStatusLine());
				if (entity1 != null) {
					log.debug("Response content length: " + entity1.getContentLength());
					BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity1.getContent()));
					String text;
					while ((text = bufferedReader.readLine()) != null) {
						result += text;
						/*result += new String(text.getBytes("gbk"), "utf-8");
						log.debug(new String(text.getBytes("gbk"), "utf-8"));*/
					}
				}
				EntityUtils.consume(entity1);
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				response.close();
			}
		} finally {
			httpclient.close();
		}
		
		return result;
	}

public static String sendRedPackParams(){
  String xmlParams = " <xml>" 
    + "<sign>SIGN</sign>"
    + "<mch_billno>MCH_BILLNO</mch_billno>"
    + "<mch_id>MCH_ID</mch_id>"
    + "<wxappid>WXAPPID</wxappid>"
    + "<send_name>SEND_NAME</send_name>"
    + "<re_openid>RE_OPENID</re_openid>"
    + "<total_amount>TOTAL_AMOUNT</total_amount>"
    + "<total_num>TOTAL_NUM</total_num>"
    + "<wishing>WISHING</wishing>"
    + "<client_ip>CLIENT_IP</client_ip>"
    + "<act_name>ACT_NAME</act_name>"
    + "<remark>REMARK</remark>"
    //+ "<scene_id>SCENE_ID</scene_id>"
    + "<nonce_str>NONCE_STR</nonce_str>" 
    + "</xml>";
  return xmlParams;
}

附上红包发送成功的示例:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值