博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【微信公众号发红包转账】微信公众号上手机网页接收请求,通过公众号给用户发红包 开发流程...
阅读量:7250 次
发布时间:2019-06-29

本文共 16679 字,大约阅读时间需要 55 分钟。

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

 

准备好这两个架包

 

---------------------------------------------------------------------------------------------------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
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()) {             @Override             public 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);                     }                     @Override                     public String encodeNode(String name) {                         return name;                     }                     @Override                     protected void writeText(QuickWriter writer, String text) {                         if (cdata) {                             writer.write("");                         } else {                             writer.write(text);                         }                     }                 };             }         });                  return stream;    }        /**     * 根据字符串 解析XML map集合     * @param xml     * @return     * @throws DocumentException     */    public Map
parseXML(String xml) throws DocumentException{ Document document = DocumentHelper.parseText(xml); Element element =document.getRootElement(); List
childElements = element.elements(); Map
map = new HashMap
(); map = getAllElements(childElements,map); map.forEach((k,v)->{ System.out.println(k+">>>>"+v); }); return map; } /** * 获取 子节点的被迭代方法 * @param childElements * @param mapEle * @return */ private Map
getAllElements(List
childElements,Map
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
map = getSortMap(object); boolean isNotFirst = false; for (Map.Entry
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
getSortMap(Object object) throws Exception{ Field[] fields = object.getClass().getDeclaredFields(); Map
map = new HashMap
(); 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
sortMap = new TreeMap
( new Comparator
() { @Override public 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

 

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

 

转载地址:http://bnebm.baihongyu.com/

你可能感兴趣的文章
使用实体框架、Dapper和Chain的仓储模式实现策略
查看>>
HTTP/2推送之难,远超想象
查看>>
与Bob McWhirter的问答:WildFly Swarm更名为Thorntail项目
查看>>
新书问答:Agile Management
查看>>
在sublime中实现代码检测
查看>>
活在伟大的Scrum团队是什么感觉
查看>>
Swift 5进入发布倒计时
查看>>
一套代码称霸5大端口,移动金融应用还能这样开发?
查看>>
MIT开发Polaris,使网页载入加快34%
查看>>
微软对macOS和Linux开放量子开发工具集
查看>>
一份关于Angular的倡议清单
查看>>
没有估算,你仍然可以用这些决策策略
查看>>
通过调研开源基准测试集,解读大数据的应用现状和开源未来
查看>>
译文-调整G1收集器窍门
查看>>
时序数据库InfluxDB 2.0 alpha 发布:主推新的Flux查询语言,TICK栈将成为整体
查看>>
开源是项“全民工程”,揭秘开源团队的管理运作
查看>>
基于Gitflow分支模型自动化Java项目工作流
查看>>
ES6学习之一
查看>>
专访何红辉:谈谈Android源码中的设计模式
查看>>
超2亿中国用户简历曝光!MongoDB又一重大安全事故
查看>>