微信公众号H5页面支付功能的实现,weixin4j快速开发,以及支付遇到的坑

1.大体流程

调用微信支付的大概流程可以说很简单

 引导用户进入授权,根据用户的code来授权获取用户的基本信息,授权完成之后进入个人操作页面,

然后对支付的参数进行封装,传到前台,前台发起请求调用微信支付

2.使用流程

      1.微信入口

@WebServlet("/wxLogin")
public class LoginServlet extends HttpServlet {


    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //第一步:引导用户进入授权页面同意授权,获取code
        //授权页面地址
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+ WXAuthUtil.APPID
                + "&redirect_uri="+ URLEncoder.encode(WXAuthUtil.getBackUrl(),"UTF-8")
                + "&response_type=code"
                + "&scope=snsapi_userinfo"
                + "&state=STATE#wechat_redirect";
        //重定向到授权页面
        response.sendRedirect(url);
    }
}

    2.编写回调controller

   

     @RequestMapping("/authback.do")
    public void authCallback(HttpServletRequest request, HttpServletResponse response) throws Exception {
        LOG.info("授权回调开始.......");
        String redirectUrl = "";
        //  第一步 获取微信用户基本信息 code
        String code = request.getParameter("code");
        if (StringUtils.isNotBlank(code)) {
            //第二步:通过code换取网页授权access_token
            String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + WXAuthUtil.APPID
                    + "&secret=" + WXAuthUtil.APPSECRET
                    + "&code=" + code
                    + "&grant_type=authorization_code";
            JSONObject jsonObject = WXAuthUtil.doGetJson(url);
            String openid = jsonObject.getString("openid");
            String access_token = jsonObject.getString("access_token");
            String refresh_token = jsonObject.getString("refresh_token");
            //第五步验证access_token是否失效;
            String chickUrl = "https://api.weixin.qq.com/sns/auth?access_token=" + access_token + "&openid=" + openid;
            JSONObject chickuserInfo = WXAuthUtil.doGetJson(chickUrl);
            System.out.println(chickuserInfo.toString());
            if (!"0".equals(chickuserInfo.getString("errcode"))) {
                // 第三步:刷新access_token(如果需要)-----暂时没有使用
                String refreshTokenUrl = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + openid + "&grant_type=refresh_token&refresh_token=" + refresh_token;
                JSONObject refreshInfo = WXAuthUtil.doGetJson(chickUrl);
                System.out.println(refreshInfo.toString());
                access_token = refreshInfo.getString("access_token");
            }
            // 第四步:拉取用户信息(需scope为 snsapi_userinfo)
            String infoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token
                    + "&openid=" + openid
                    + "&lang=zh_CN";
            System.out.println("infoUrl:" + infoUrl);
            JSONObject userInfo = WXAuthUtil.doGetJson(infoUrl);

        /*
         {  "openid":" OPENID",
            " nickname": NICKNAME,
            "sex":"1",
            "province":"PROVINCE"
            "city":"CITY",
            "country":"COUNTRY",
            "headimgurl":    "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
            "privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
            "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
            }
         **/

        } else {
            LOG.info("没有获取到code......");
            LOG.info("重新登录");
            redirectUrl = "/common/500";
        }
        redirectUrl = "xxxxxx";
        //商户操作界面
        //获取到用户信息后就可以进行重定向,
        response.sendRedirect(redirectUrl);
    }
请求工具类
public class WXAuthUtil {

    public static  String APPID;
    public static  String APPSECRET;
    private static  String TOKEN;
    private static String backUrl;
    //这边主要是获取公众号的一些信息配置
    static {
        String properValue = ProperUtil.getProperValue("weixin4j.properties", "weixin4j.account");
         backUrl = ProperUtil.getProperValue("weixin4j.properties", "weixin4j.user.oauth.redirect.uri");
        WXAuthUtil.setBackUrl(backUrl);
        JSONObject jsonObject = JSON.parseObject(properValue);
        WXAuthUtil.setAPPID(jsonObject.getString("id"));
        WXAuthUtil.setAPPSECRET(jsonObject.getString("secret"));
    }

    public static JSONObject doGetJson(String url) throws ClientProtocolException, IOException {
        JSONObject jsonObject =null;
        DefaultHttpClient client = new DefaultHttpClient();
        HttpGet httpGet =new HttpGet(url);
        HttpResponse response =  client.execute(httpGet);
        HttpEntity entity =response.getEntity();
        if(entity!=null)
        {
            //把返回的结果转换为JSON对象
            String result = EntityUtils.toString(entity, "UTF-8");
            jsonObject = JSON.parseObject(result);
        }
        return jsonObject;
    }

    public static String getBackUrl() {
        return backUrl;
    }

    public static void setBackUrl(String backUrl) {

        WXAuthUtil.backUrl = backUrl;
    }

    public static String getAPPID() {
        return APPID;
    }

    public static String getAPPSECRET() {
        return APPSECRET;
    }

    public static String getTOKEN() {
        return TOKEN;
    }

    public static void setAPPID(String APPID) {
        WXAuthUtil.APPID = APPID;
    }

    public static void setAPPSECRET(String APPSECRET) {
        WXAuthUtil.APPSECRET = APPSECRET;
    }

    public static void setTOKEN(String TOKEN) {
        WXAuthUtil.TOKEN = TOKEN;
    }
}
到这里基本上流程已经走到支付那块,前期就是微信让你认证一下,知道你是个人就好了,接下来就是大活了,需要调用支付了,H5页面自己做个按钮什么之类的

  我这边后台支付用的是WeixinPayProxy 网上可以找一下maven引进来到pom,有这个那就相对来说easy多了。

  先封装一个单例,其实我对java也不熟,自己乱搞呢,能用就行,怎样方便怎样整

public class WeixinPayProxySingle {
    private static Log log = LogFactory.getLog(WeixinPayProxySingle.class);
    private static String fileName = "weixin4j.properties";
    private static String account = "weixin4j.account";
    private static WeixinPayProxy instance;

    private WeixinPayProxySingle() {
    }

    public static WeixinPayProxy getInstance() {
        String properValue = ProperUtil.getProperValue(fileName, account);
        if(StringUtils.isNotBlank(properValue)){
            JSONObject account = JSON.parseObject(properValue);
            if (instance == null) {
                instance = new WeixinPayProxy(new WeixinPayAccount(account.getString("id"), account.getString("paySignKey"), account.getString("mchId")));
            }
        }else{
            log.info("获取配置文件失败");
        }
        return instance;
    }

}

3.接下来就是编写按钮事件controller

public void perPay(){
               WeixinPayProxy weixinPayProxy = WeixinPayProxySingle.getInstance();
              String openId = "o6dsctyXpndCV1L94u_ZixgzxB6Y"
            String body = "";//支付描述,这个微信支付成功会有单子上面有就跟你支付成功会有条消息
            String outTradeNo = "";//"mdsas1212";// "商户侧唯一订单号,如18789913341";
            double totalFee = 0.01d;//金额,先写个一分,你想写一万也行
            LOG.info("金额" + totalFee);
            String notifyUrl = authUrl;//"支付完成后的回调地址,如http://wx.xxx.com/pay/notify";
            String createIp = request.getRemoteAddr();//"发起支付时的客户端IP地址,如192.168.1.1";
            String attach = "微信支付手机充值";//"支付时的附加信息,在回调时会原样带上,可为空";
            LOG.info("用户openid:" + openId);
            // 发起一个JS支付请求
            MchPayRequest payRequest = weixinPayProxy.createJSPayRequest(openId, body, outTradeNo, totalFee, notifyUrl, createIp, attach);
            LOG.info("预支付订单号:" + payRequest.getPrePayId());
requert.getSeeion().setAttribute("jsapi",payRequest.toRequestString());//这个就厉害了,就是你前台需要的封装的参数,用这个吊起微信支付
}

到此处基本上支付就差不多了,别着急,刚开始前台用的是getBrandWCPayRequest 调用微信支付,妈的,坑的呀,,苹果手机直接缺失参数,$key0愣是找不出问题,后来改用chooseWXPay,用这个的话必须进行微信config操作,我下篇文章给大家整,目前getBrandWCPayRequest 的还没解决,有会的也可以给我说,但我用chooseWXPay终于支起来了委屈

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值