有了微信支付 的开发做铺垫,相关的微信其他业务处理起来逻辑就能清晰很多。

准备好这两个架包

---------------------------------------------------------------------------------------------------1.微信公众号发红包 开发流程图----------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------2.红包实体-----------------------------------------------------------------------------------------------------

package net.shopxx.wx.redPackage;/*** 微信公众号   发红包实体* @author SXD**/
public class RedPack {/*** 随机字符串* 随机字符串,不长于32位*/private String nonce_str;/*** 签名*/private String sign;/*** 商户订单号* 商户订单号(每个订单号必须唯一。取值范围:0~9,a~z,A~Z)接口根据商户订单号支持重入,如出现超时可再调用。*/private String mch_billno;/*** 商户号* 微信支付分配的商户号*/private String mch_id;/*** 公众账号* 微信分配的公众账号ID(企业号corpid即为此appId)*/private String wxappid;/*** 商户名称* 红包发送者名称*/private String send_name;/*** 用户openid* 接受红包的用户* 用户在wxappid下的openid*/private String re_openid;/*** 付款金额 单位:分* 100 == 1元钱 ,也就是说 这里的 1 相当于1分钱* 微信发送红包不少于1元钱*/private int total_amount;/*** 红包发放总人数*/private int total_num;/*** 红包祝福语*/private String wishing;/*** Ip地址* 调用接口的机器Ip地址*/private String client_ip;/*** 活动名称*/private String act_name;/*** 备注*/private String remark;public String getNonce_str() {return nonce_str;}public void setNonce_str(String nonce_str) {this.nonce_str = nonce_str;}public String getSign() {return sign;}public void setSign(String sign) {this.sign = sign;}public String getMch_billno() {return mch_billno;}public void setMch_billno(String mch_billno) {this.mch_billno = mch_billno;}public String getMch_id() {return mch_id;}public void setMch_id(String mch_id) {this.mch_id = mch_id;}public String getWxappid() {return wxappid;}public void setWxappid(String wxappid) {this.wxappid = wxappid;}public String getSend_name() {return send_name;}public void setSend_name(String send_name) {this.send_name = send_name;}public String getRe_openid() {return re_openid;}public void setRe_openid(String re_openid) {this.re_openid = re_openid;}public int getTotal_amount() {return total_amount;}public void setTotal_amount(int total_amount) {this.total_amount = total_amount;}public int getTotal_num() {return total_num;}public void setTotal_num(int total_num) {this.total_num = total_num;}public String getWishing() {return wishing;}public void setWishing(String wishing) {this.wishing = wishing;}public String getClient_ip() {return client_ip;}public void setClient_ip(String client_ip) {this.client_ip = client_ip;}public String getAct_name() {return act_name;}public void setAct_name(String act_name) {this.act_name = act_name;}public String getRemark() {return remark;}public void setRemark(String remark) {this.remark = remark;}}

View Code

-----------------------------------------------------------------------------------------------3.服务器端处理  逻辑---------------------------------------------------------------------------------------

package net.shopxx.wx.redPackage;import java.util.Map;
import java.util.UUID;import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;
import javax.servlet.http.HttpServletRequest;import net.shopxx.wx.pay.HttpConnection;
import net.shopxx.wx.pay.WeXinUtil;
import net.shopxx.wx.pay.XmlUtil;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.internal.platform.Platform;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
@RequestMapping("/wx/SendRedPack")
public class SendRedPackController {/*** 公众账号ID*/@Value("${member.appid}")private String APPID;/*** 商户号*/private String MCHID;/*** key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置*/private String KEY;private XmlUtil xmlUtil = new XmlUtil();/*** ②接收请求* @param request* @param open_id* @throws Exception*/@ResponseBody@RequestMapping("/sendRedPack")public void sendRedPack(HttpServletRequest request,String open_id) throws Exception{RedPack pack = new RedPack();pack.setAct_name("活动名称111");pack.setClient_ip(WeXinUtil.getIp(request));pack.setMch_billno("order_id");pack.setMch_id(MCHID);String nonce = UUID.randomUUID().toString().replaceAll("-", "");pack.setNonce_str(nonce);pack.setRe_openid(open_id);pack.setRemark("备注信息");pack.setSend_name("商户名称:谁发的红包");pack.setTotal_amount(1000);pack.setTotal_num(1);pack.setWishing("红包祝福语");pack.setWxappid(APPID);String sign = WeXinUtil.createUnifiedOrderSign(pack,KEY);pack.setSign(sign);/*** 转成XML格式 微信可接受的格式*/xmlUtil.getXstreamInclueUnderline().alias("xml", pack.getClass());String xml = xmlUtil.getXstreamInclueUnderline().toXML(pack);//发起请求前准备RequestBody body = RequestBody.create(MediaType.parse("text/xml;charset=UTF-8"), xml);Request req = new Request.Builder().url("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack").post(body).build();//为http请求设置证书SSLSocketFactory socketFactory = WeXinUtil.getSSL().getSocketFactory();X509TrustManager x509TrustManager = Platform.get().trustManager(socketFactory);OkHttpClient okHttpClient = new OkHttpClient.Builder().sslSocketFactory(socketFactory, x509TrustManager).build();//得到输出内容/***③ ④ 解析结果,判断是否红包发送成功 */Response response = okHttpClient.newCall(req).execute();String content = response.body().string();Map<String, String> responseMap = xmlUtil.parseXML(content);if("SUCCESS".equals(responseMap.get("return_code"))){System.out.println("红包发送成功");System.out.println("签名"+responseMap.get("sign")+"业务结果"+responseMap.get("result_code"));if("SUCCESS".equals(responseMap.get("result_code"))){System.out.println("商户订单号"+responseMap.get("mch_billno")+"商户号"+responseMap.get("mch_id")+"公众账号appid"+responseMap.get("wxappid")+"用户openid"+responseMap.get("re_openid")+"付款金额"+responseMap.get("total_amount")+"微信单号"+responseMap.get("send_listid"));}}else{System.out.println("红包发送失败");}}}

View Code

-----------------------------------------------------------------------------------------------4.XML工具类--------------------------------------------------------------------------------------------------

package net.shopxx.wx.pay;import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;/*** 微信支付   微信公众号发红包* 封装/解析xml消息的工具类* @author SXD**/
public class XmlUtil {public XStream getXstreamInclueUnderline(){XStream stream = new XStream(new XppDriver(new NoNameCoder()) {@Overridepublic PrettyPrintWriter createWriter(Writer out) {return new PrettyPrintWriter(out) {// 对所有xml节点的转换都增加CDATA标记boolean cdata = true;@Override@SuppressWarnings("rawtypes")public void startNode(String name, Class clazz) {super.startNode(name, clazz);}@Overridepublic String encodeNode(String name) {return name;}@Overrideprotected void writeText(QuickWriter writer, String text) {if (cdata) {writer.write("<![CDATA[");writer.write(text);writer.write("]]>");} else {writer.write(text);}}};}});return stream;}/*** 根据字符串 解析XML map集合* @param xml* @return* @throws DocumentException*/public Map<String, String> parseXML(String xml) throws DocumentException{Document document = DocumentHelper.parseText(xml);Element element =document.getRootElement();List<Element> childElements = element.elements();Map<String,String> map = new HashMap<String, String>();map = getAllElements(childElements,map);map.forEach((k,v)->{System.out.println(k+">>>>"+v);});return map;}/*** 获取 子节点的被迭代方法* @param childElements* @param mapEle* @return*/private Map<String, String> getAllElements(List<Element> childElements,Map<String,String> mapEle) {for (Element ele : childElements) {if(ele.elements().size()>0){mapEle = getAllElements(ele.elements(), mapEle);}else{mapEle.put(ele.getName(), ele.getText());}}return mapEle;}}

View Code

-----------------------------------------------------------------------------------------------5.微信工具类---------------------------------------------------------------------------------------------------

package net.shopxx.wx.pay;import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;import javax.net.ssl.SSLContext;
import javax.security.cert.CertificateException;
import javax.servlet.http.HttpServletRequest;import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.ssl.SSLContexts;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;/*** 微信支付  微信公众号发红包 * 工具类* @author SXD**/
public class WeXinUtil {/*** 获取用户IP* @param request* @return*/public static String getIp(HttpServletRequest request){String ipAddress = null;if (request.getHeader("x-forwarded-for") == null) {  ipAddress = request.getRemoteAddr();}else{if(request.getHeader("x-forwarded-for").length()  > 15){String [] aStr = request.getHeader("x-forwarded-for").split(",");ipAddress = aStr[0];} else{ipAddress = request.getHeader("x-forwarded-for");}} return ipAddress;}/*** 签名算法,生成统一下单中 必填项签名* @param unifiedOrder  1.将统一下单实体中各个字段拼接  2.MD5加密  3.全部转化为大写* @return    返回经过签名算法生成的签名 sign* 第一步的规则*     ◆ 参数名ASCII码从小到大排序(字典序);*    ◆ 如果参数的值为空不参与签名;*    ◆ 参数名区分大小写;*    ◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。*    ◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段*//* 手动拼接方式public String createUnifiedOrderSign(Unifiedorder unifiedOrder){StringBuffer sign = new StringBuffer();sign.append("appid=").append(unifiedOrder.getAppid());sign.append("&body=").append(unifiedOrder.getBody());sign.append("&mch_id=").append(unifiedOrder.getMch_id());sign.append("&nonce_str=").append(unifiedOrder.getNonce_str());sign.append("&notify_url=").append(unifiedOrder.getNotify_url());sign.append("&openid=").append(unifiedOrder.getOpenid());sign.append("&out_trade_no=").append(unifiedOrder.getOut_trade_no());sign.append("&spbill_create_ip=").append(unifiedOrder.getSpbill_create_ip());sign.append("&total_fee=").append(unifiedOrder.getTotal_fee());sign.append("&trade_type=").append(unifiedOrder.getTrade_type());sign.append("&key=").append(KEY);return DigestUtils.md5Hex(sign.toString()).toUpperCase();}*//*** 拼接生成sign 签名* @param unifiedOrder* @param KEY* @return* @throws Exception*/public static String createUnifiedOrderSign(Object object,String KEY) throws Exception{StringBuffer sign = new StringBuffer();Map<String, String> map = getSortMap(object);boolean isNotFirst = false;for (Map.Entry<String, String> entry : map.entrySet()) {if(isNotFirst == true){sign.append("&");}else{isNotFirst = true;}sign.append(entry.getKey()).append("=").append(entry.getValue());}sign.append("&key=").append(KEY);return DigestUtils.md5Hex(sign.toString()).toUpperCase();}/*** 使用java反射机制,动态获取对象的属性和参数值,排除值为null的情况,并按字典序排序* @param object* @return* @throws Exception*/private static Map<String, String> getSortMap(Object object) throws Exception{Field[] fields = object.getClass().getDeclaredFields();Map<String, String> map = new HashMap<String, String>();for(Field field : fields){String name = field.getName();String methodName = "get" + name.replaceFirst(name.substring(0, 1), name.substring(0, 1).toUpperCase());// 调用getter方法获取属性值
//                 Method getter = object.getClass().getMethod(methodName);
//                 String value =  getter.invoke(object)+"";field.setAccessible(true);Object value = field.get(object);if (value != null){map.put(name, value.toString());}}Map<String, String> sortMap = new TreeMap<String, String>(new Comparator<String>() {@Overridepublic int compare(String arg0, String arg1) {return arg0.compareTo(arg1);}});sortMap.putAll(map);return sortMap;}public static SSLContext getSSL() throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException, java.security.cert.CertificateException {KeyStore keyStore = KeyStore.getInstance("PKCS12");//证书位置  放在自己的项目下面Resource resource = new ClassPathResource("apiclient_cert.p12");InputStream instream = resource.getInputStream();try {keyStore.load(instream, "填写证书密码,默认为商户号".toCharArray());} finally {instream.close();}SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, "填写证书密码,默认为商户号".toCharArray()).build();return sslcontext;}}

View Code

----------------------------------------------------------------------------------------------至此,微信公众号 发送红包   【待完善】---------------------------------------------------------------

转载于:https://www.cnblogs.com/sxdcgaq8080/p/7511139.html

【微信公众号发红包转账】微信公众号上手机网页接收请求,通过公众号给用户发红包 开发流程...相关推荐

  1. 移动设备wap手机网页html5通过特殊链接:打电话,发短信,发邮件详细教程

    移动设备wap手机网页html5通过特殊链接:打电话,发短信,发邮件详细教程 原文地址:https://www.luoxiao123.cn/1120-2.html 最近逍遥乐在寻找手机网页调用系统短信 ...

  2. 微信团队分享:微信支付代码重构带来的移动端软件架构上的思考

    本文原文由微信客户端高级工程师方秋枋原创发表于WeMobileDev公众号,收录时有修订和加工,感谢作者的无私分享. 1.引言 作为一个重要业务,微信支付在客户端上面临着各种问题. 其中最核心问题就是 ...

  3. python发微信红包_微信公众号开发小记——5.python微信红包

    描述 有时候产品有这么一些需求,当用户满足一定条件时,给他发一定金额的红包. 微信各个服务是独立的,比较蛋疼,要用红包功能,首先你需要注册一个微信商户平台账号. 代码位置 分支pay-20160802 ...

  4. java微信个人订阅号发信息_微信个人公众号开发-java

    一:申请公众号 无聊的去申请一个个人公众号,试了下微信实现自定义菜单与自定义对话的一些基本功能,如果多花点时间,金钱(= =!)还是有不少功能可以使用,还是蛮有意思的. 废话不多说,先看一下申请的流程 ...

  5. 公众号redirect_url配置_Niushop微信支付配置、微信退款配置、微信转账配置操作流程...

    Niushop微信支付配置.微信退款配置.微信转账配置操作流程 前几期,阿牛ger主要与大家分享了关于宝塔配置.接口插件配置.地址设置.版权设置等的代码,今天,阿牛ger与大家分享微信支付配置. 微信 ...

  6. 微信(jspai版本即公众号h5版)支付-微信下单支付及企业转账到零钱

    微信(jspai版本即公众号h5版)支付-微信下单支付及企业转账到零钱 一.后端前置条件 二.配置h5 devServer 三.后端开发代码 四.前端开发代码(uniapp) 一.后端前置条件 准备好 ...

  7. 公众号开发: 给用户发红包

    红包功能简单介绍: 1.商户调用接口时,通过指定发送对象以及发送金额的方式发放红包,这样的方式,允许商户灵活的应用于各种各样丰富的活动场景 2.领取到红包后,用户的资金直接进入微信零钱,避免繁复的领奖 ...

  8. Java开发微信公众号(四)---微信服务器post消息体的接收及消息的处理

    在前几节文章中我们讲述了微信公众号环境的搭建.如何接入微信公众平台.以及微信服务器请求消息,响应消息,事件消息以及工具处理类的封装:接下来我们重点说一下-微信服务器post消息体的接收及消息的处理,这 ...

  9. 从陈坤微信号说起:微信公众平台开发者的江湖

    陈坤的微信公众号这段时间大火,企鹅君其实也想发表点意见的,但无奈不懂娱乐圈,姿势不够只有看的份. 不过看来看去吧,发现个问题:大家关注陈坤微信号如何圈钱的同时,就没想过问下,这个微信公众号到底谁做的? ...

最新文章

  1. 云场景实践研究第74期:科沃斯
  2. Qt控制台工程不能调试问题
  3. 12-多对一添加操作(添加新客户及对应的新订单)
  4. 如何使用 Mybatis 实现数据库 CURD 操作?
  5. C语言实现数字串转数字
  6. 2010年中国企业500强
  7. 杭州电子科技大学acm--2016
  8. 声纹识别开源框架python_GitHub - yeyupiaoling/VoiceprintRecognition-Tensorflow: 使用Tensorflow实现声纹识别,博客地址:...
  9. 【GPT-4】立即停止训练比 GPT-4 更强的模型,至少六个月!马斯克、图灵奖得主等数千 AI 专家紧急呼吁
  10. 移动端网页签名,附上DOM,效果图
  11. /etc/profile和 . profile 文件
  12. Android 文件下载中文名乱码的解决办法
  13. (java)使用createNewFile提示系统找不到指定路径
  14. vagrant+virtualbox搭建centos7
  15. Tailwind Sidebar
  16. 熊猫直播 开启html5,熊猫直播助手使用小葫芦插件教程
  17. wireshark抓包分析数据怎么看 wireshark使用教程
  18. 用来测试的在线小视频url地址
  19. java虚拟服务器,java环境云虚拟服务器
  20. 卫星位置、速度、加速度、加加速度计算公式推导

热门文章

  1. 有人知道要怎么用c++提取出文本里面的信息吗,例如把这个表格里的所有住户账号,密码提取出来
  2. P1397 [NOI2013] 矩阵游戏(矩阵乘法欧拉定理)
  3. 计算机开机主机不停地重启,求救:电脑一直重启,开机自检后,一会就重启
  4. 阿里百度腾讯等34家企业获年度互联网经济大奖
  5. c# mailgun 发送邮件测试
  6. python opencv灰度转rgb
  7. HTML5小游戏之爱心鱼
  8. 前端(HTML+CSS+JS)
  9. 怎么获取微信公众号的音频视频
  10. 安装计算机的显卡出现问题,电脑显卡驱动安装失败如何解决