微信支付等相关微信操作工具类

package ************.pay.util;


import cn.stylefeng.guns.core.util.RedisUtils;
import com.alibaba.fastjson.JSONObject;
import com.github.wxpay.sdk.WXPayUtil;
import com.google.gson.Gson;
import lombok.extern.log4j.Log4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.*;


/**
 * 抽取的微信支付工具
 *
 * @author gc
 */
@Component
public class wxPayUtil {


    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 微信appid
     */
    private static final String APPID = "wx·····3add6";
    /**
     * 商户号
     */
    private static final String mchId = "150····391";
    /**
     * 商户API密钥
     * todo 重置商户密钥
     */
    private static final String paternerKey = "GYDh8······5gvbnkiy9yg6";

    /**
     * 微信appsecret  用于获取用户的openId
     */
    private static final String APPSECRET = "4e66c7······f7314ab8c014d";

    /**
     * 终端IP spbilCreateIp
     */
    private static final String spbilCreateIp = "47.···.···.202";
    /**
     * 统一回调地址 notifyUrl+"/xdcj"
     * <p>
     */
    private static final String notifyUrl = "http://····.com";


    /***
     * get 请求发送
     */
    public static String doGet(String urls) throws Exception {
        URL url = new URL(urls);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.connect();
        //获取返回的字符
        InputStream inputStream = connection.getInputStream();
        int size = inputStream.available();
        byte[] bs = new byte[size];
        inputStream.read(bs);
        String message = new String(bs, "UTF-8");
        return message;
    }

    /**
     * 获取微信 access_token  (信息token)
     */
    public static String getAccessToken()  {
        try {
            String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
                    + APPID + "&secret=" + APPSECRET;
            String message = doGet(accessTokenUrl);
            //获取access_token
            JSONObject jsonObject = JSONObject.parseObject(message);
            String accessToken = jsonObject.getString("access_token");
            String expires_in = jsonObject.getString("expires_in");
            return accessToken;
        }catch (Exception e){
            e.printStackTrace();
        }
       return null ;
    }

    /**
     * 获取微信 AuthToken  (授权token -用户登录授权 )
     */
    public static JSONObject getAuthToken(String code)  {
        try {
            String accessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + APPID + "&secret=" + APPSECRET
                                  + "&code=" + code + "&grant_type=authorization_code" ;
            String message = doGet(accessTokenUrl);
            //获取access_token
            JSONObject jsonObject = JSONObject.parseObject(message);
            System.err.println("获取微信 AuthToken :"+ jsonObject);
            return jsonObject;
        }catch (Exception e){
            e.printStackTrace();
        }
       return null ;
    }







    /**
     * 获取微信 code
     */
    public static void getCode(String userName , HttpServletRequest request ,HttpServletResponse response) throws IOException {
        System.err.println("获取微信 code,openId --- 获取到的userName:"+userName);
        String redirect_uri= URLEncoder.encode(notifyUrl+"/api/designer/getUserWXCode?userName="+userName, "UTF-8");
        System.err.println(redirect_uri);
        /**
         *  简单获取openid的话参数response_type与scope与state参数固定写死即可
         */
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+APPID+"&redirect_uri="+redirect_uri+"&response_type=code&scope=snsapi_base&state=123#wechat_redirect" ;
        //这里请不要使用get请求单纯的将页面跳转到该url即可
        System.err.println(url);
        response.sendRedirect(url);

    }



    /**
     * 根据code获取openId
     */
    public static String getOpenId(String code) throws Exception {
        System.err.println("传过来的code:----"+code);
        String accessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+APPID+"&secret="+APPSECRET+"&code="+code+"&grant_type=authorization_code";
        String message = doGet(accessTokenUrl);
        System.err.println("获取的message:"+message);
        //获取openid 返回前端
        JSONObject jsonObject = JSONObject.parseObject(message);
        System.err.println("获取的jsonObject:"+jsonObject);
        String openId = jsonObject.getString("openid");
        return openId ;
    }


    /**
     * 查看用户是否关注公众号
     */
    public static Boolean isAttentionGZH(String openId) throws Exception {
        String accessToken = getAccessToken();
        String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+accessToken+"&openid="+openId+"&lang=zh_CN" ;
        String msg = doGet(url);
        System.err.println("查看用户是否关注公众号:"+msg);
        JSONObject jsonObject = JSONObject.parseObject(msg);
        String subscribe = jsonObject.getString("subscribe");
        if(null != subscribe && "1".equals(subscribe)){
            return true ;
        }
        return false;
    }

    /**
     * 获取用户信息
     */
    public static JSONObject getGZHUserInfo(RedisUtils redisUtils , String openId) throws Exception {
        String accessToken = redisUtils.getKey("accessToken");
        if (null == accessToken) {
            accessToken = wxPayUtil.getAccessToken();
            redisUtils.putKey("accessToken", accessToken, true, 7000);
        }
        String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+accessToken+"&openid="+openId+"&lang=zh_CN" ;
        String msg = doGet(url);
        System.err.println("查看用户信息:"+msg);
        JSONObject jsonObject = JSONObject.parseObject(msg);
        return jsonObject;
    }
    /**
     * 获取用户信息
     */
    public static JSONObject getUserInfo( String code ,String openId) throws Exception {
        JSONObject jsonObject = wxPayUtil.getAuthToken(code);
        String accessToken = jsonObject.get("access_token").toString();

        String url = "https://api.weixin.qq.com/sns/userinfo?access_token="+accessToken+"&openid="+openId+"&lang=zh_CN" ;
        String msg = doGet(url);
        System.err.println("获取用户信息:"+msg);
        JSONObject uerInfo = JSONObject.parseObject(msg);
        return uerInfo;
    }

   /**
     * 获取用户信息
     */
    public static JSONObject getUserInfo( Object accessToken ,Object openId) throws Exception {
        String url = "https://api.weixin.qq.com/sns/userinfo?access_token="+accessToken+"&openid="+openId+"&lang=zh_CN" ;
        String msg = doGet(url);
        System.err.println("获取用户信息:"+msg);
        JSONObject uerInfo = JSONObject.parseObject(msg);
        return uerInfo;
    }










    /**
     * 微信支付的统一下单工具
     *
     * @param openId   用户openId
     * @param payMoney 支付金额  单位:元
     * @param orderNum 订单金额
     * @param title    支付标题(或者买的商品名)
     * @param wxNotifyUrl      (支付回调地址  --   /xxPay   )
     * @param request
     * @param response
     * @throws Exception
     */
    public void wxPrepay(BigDecimal payMoney, String orderNum, String title, String wxNotifyUrl,
                         HttpServletRequest request, HttpServletResponse response, String openId,String WXTradeType) throws Exception {

        logger.info("-------------------------------调起微信支付--------------------------------------");
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");

        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        // 微信小程序ID
        packageParams.put("appid", APPID);
        // 商户ID
        packageParams.put("mch_id", mchId);
        // 随机字符串(32位以内) 这里使用时间戳
        packageParams.put("nonce_str", WXPayUtil.generateNonceStr());
        // 支付主体名称 自定义 商品描述
        packageParams.put("body", title);
        //编号自定义以时间戳+随机数+商品ID
        packageParams.put("out_trade_no", orderNum);
        // 价格 自定义
        packageParams.put("total_fee", payMoney.multiply(new BigDecimal(100)).intValue());
        //终端IP
        packageParams.put("spbill_create_ip", spbilCreateIp);
        //支付返回地址要外网访问的到, localhost不行,调用下面buy方法。(订单存入数据库)
        packageParams.put("notify_url", notifyUrl + wxNotifyUrl);

        //微信付款类型 (  0 - JSAPI   1 - NATIVE)
        if(  "0".equals(WXTradeType)){
            //JSAPI
            packageParams.put("trade_type", "JSAPI");
            //用户的openid
            if(null != openId){
                packageParams.put("openid", openId);
            }
        }else {
            //微信扫码支付
            packageParams.put("trade_type", "NATIVE");

        }
        //获取sign ,paternerKey 最后这个是自己在微信商户设置的32位密钥
        String sign = PayCommonUtil.createSign("UTF-8", packageParams, paternerKey);
        packageParams.put("sign", sign);
        logger.error("生成签名是:" + sign);

        //转成XML
        String requestXML = PayCommonUtil.getRequestXml(packageParams);
        logger.info(" ------- 包装的请求参数requestXML:" + "\n" + requestXML);

        //得到含有prepay_id的XML
        String resXml = HttpUtil.postData("https://api.mch.weixin.qq.com/pay/unifiedorder", requestXML);

        logger.info("---得到含有prepay_id的XML:" + "\n" + resXml);

        // 得到prepay_id
        String prepay_id = "";
        String code_url = "" ;
        if (resXml.indexOf("SUCCESS") != -1) {
            Map<String, String> resXmlMap = WXPayUtil.xmlToMap(resXml);
            prepay_id = resXmlMap.get("prepay_id");
            code_url = resXmlMap.get("code_url");
            logger.info("prepay_id:" + prepay_id);
            logger.info("code_url:" + code_url);
        }
        SortedMap<Object, Object> packageP = new TreeMap<Object, Object>();
        //注意!!!这里是appId,上面是appid
        packageP.put("appId", APPID);
        //时间戳
        packageP.put("timeStamp", System.currentTimeMillis());
        //随机字符串
        packageP.put("nonceStr", WXPayUtil.generateNonceStr());
        //必须把package写成 "prepay_id="+prepay_id这种形式
        packageP.put("package", "prepay_id=" + prepay_id);
        if(  "1".equals(WXTradeType)){
            packageP.put("codeUrl", code_url);
        }
        //paySign加密
        packageP.put("signType", "MD5");
        //得到paySign
        String paySign = PayCommonUtil.createSign("UTF-8", packageP, paternerKey);
        packageP.put("paySign", paySign);
        //将packageP数据返回给小程序
        Gson gson = new Gson();
        String json = gson.toJson(packageP);
        PrintWriter pw = response.getWriter();
        pw.write(json);
        pw.close();
    }


}






//下面这个是controller的回调代码



    /**
     * 微信支付的回调函数  回调的就是这个方法
     * 上面参数 packageParams.put("notify_url", "http://你的IP地址/order/buy.action");
     *
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping("/wxNotifyUrl")
    public void wxToBuy(HttpServletRequest request, HttpServletResponse response) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        //sb为微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";
        Map map = XMLUtil.doXMLParse(notityXml);
        String returnCode = (String) map.get("return_code");
        //返回信息
        String returnMsg = (String) map.get("return_msg");
        // 实际支付订单的金额 单位:分
        String payMoney = (String) map.get("total_fee");
        // 时间戳
        String nonce_str = (String) map.get("nonce_str");
        //商户订单号
        String orderNum = (String) map.get("out_trade_no");
        //查看订单
        DesignerRegisterOrder registerOrder = registerOrderService.selectByOrderNum(orderNum);
        registerOrder.setPayDate(new Date());
        if (returnCode.equals("SUCCESS")) {
            //更新业务逻辑
            Boolean bool = registerOrderService.updatePaySuccess(orderNum);
            if (bool) {
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            } else {
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                        + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
            }

        } else {

            Boolean bool = registerOrderService.updatePayLose(orderNum);

            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        BufferedOutputStream out = new BufferedOutputStream(
                response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }















 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值