文档章节

微信公众号支付模块的开发

叫我老王好吗
 叫我老王好吗
发布于 2016/09/22 17:24
字数 1531
阅读 274
收藏 3

首先介绍一下微信支付:

微信支付是基于微信客户端提供的支付服务功能。同时向商户提供销售经营分析,账户和资金管理的功能支持,用户通过扫描二维码,微信内打开商品页面购买等多种方式调起微信支付模块完成支付。在这里我们主要关注的是微信公众号支付,即基于公众号向用户收款,公众号相当于收款的商户,其中支付方式可以分为JS API支付(网页内支付),Native(原生)支付,商户可以结合业务场景,自助选择支付方式。关于一些用到的参数,参考

http://wenku.baidu.com/link?url=8MsSJXO5EeKLCWQHyRXzqvApXG62j_k4Ono4BwnYPuFxbgKSUT4_Btu3NhyixgcjQef-jbiyWqdyfdybXKh3aQLP6eZ1AzTNkqCNlfoOfke

接下来开始说流程:

1:当用户点击商户连接或者扫描二维码,去往支付页面(/index/topay?sid=_)

如果用户在微信客户端中访问第三方的网页,公众号可以通过微信网页授权机制(网页授权分为四步1:引导用户进入授权页面进行授权,获取code,这里code的作用是换取一个特殊的网页授权access_token,这个和基础支持中的access_token(该access_token用于调用其他接口)不同,2:通过code换取网页授权的access_token,如果网页授权的作用域snsapi_base,则本步骤中获取到网页授权的access_token的同时也获取到了openid,snaspi_base的授权到此为止;3:刷新access_token,由于access_token拥有较短的有效期,当access_token超时后,可以使用refresh_token进行刷新,由于refresh_token有较长的有效期,当refresh_token失效后,用户需要进行重新授权;4:拉取用户信息,需要scope为snsapi_userinfo,如果网页授权的作用域为snsapi_userinfo,这个时候开发者可以通过access_token和openid获取用户信息,

)来获取用户的基本信息,进而实现业务逻辑。如果判断不是微信的内置浏览器的话就直接跳转到支付页面,利用支付宝进行支付;

1):去往输入支付金额的页面

public String topay() throws IOException {
        HttpServletResponse response = this.getHttpResponse();
        if (isWechat()) {
            //如果用户同意授权,页面将跳转到redirect_uri/?code=CODE&state=STATE
            //如果用户禁止授权,重定向后就不会携带code这个参数,仅带上state
            String code = this.getString("code");
            String state = this.getString("state");
            if (code != null && state != null) {
                //获取用户的信息,首先new一个用户
                WxUser user = new WxUser();
                //通过oauthByGet方法获取用户的信息
                user = oauthByGet(user, code);
                //将用户放到struts的数据中心
                this.putData("wxuser", user);
            } else {
                //不是微信的内置浏览器的话就直接跳转到支付页面,非微信浏览器默认使用支付宝支付
                oauthResp(response, "/index/topay");
                return null;
            }
        }

2):获取用户信息

private WxUser oauthByGet(WxUser user, String code) {
        //通过微信用户授权的api接口获得一个URL
        String _url = WexinUrlConst.getWEXIN_USER_TOKEN(WxConfigure.getAPPID(),
                WxConfigure.getAPPSECRET(), code);
        //通过证书生成响应
        String resp = new Con2http().httpsRequest(_url, "GET", null);
        if (!resp.contains("errcode")) {
            JSONObject object = JSONObject.fromObject(resp);
            //获取用户的openid,这是用户对于公众号来说唯一的身份标识
            String openid = object.getString("openid");
            user.setOpenid(openid);

            // 根据openid获取信息
            //开发者需要根据openid和access_token来获取用户的信息
            //获取access_token
            String access_token = object.getString("access_token");
            //返回获得用户信息的路径
            String userUrl = WexinUrlConst.getWEXIN_USER_USERINFO(access_token,
                    openid);
            //获取用户的信息,是一个字符串
            String userInfo = new Con2http().httpsRequest(userUrl, "GET", null);
            if (!userInfo.contains("errcode")) {
                //将这个包含用户信息的字符串转换成json对象
                JSONObject _user = JSONObject.fromObject(userInfo);
                //将各个字段值设置给new的用户返回即可
                user.setCity(_user.getString("city"));
                user.setCountry(_user.getString("country"));
                user.setCreateTime(new Date());
                user.setHeadimgurl(_user.getString("headimgurl"));
                user.setNickname(_user.getString("nickname"));
                user.setProvince(_user.getString("province"));
            }
        }
        return user;
    }

2:填写支付金额,点击支付(微信支付)

1):获取access_token

2):生成预支付订单

public void getPrepay() throws IOException {
        long start = System.currentTimeMillis();
        HttpServletRequest request = this.getHttpRequest();
        HttpServletResponse response = this.getHttpResponse();
        Map<String, Object> map = new HashMap<String, Object>();
        // 请求的IP地址
        String spBillCreateIP = "";
        if (request.getHeader("x-forwarded-for") == null) {
            spBillCreateIP = request.getRemoteAddr();
        } else {
            String _ip = request.getHeader("x-forwarded-for");
            String[] str = _ip.replace(" ", "").split(",");
            if (str.length > 0) {
                spBillCreateIP = str[0];
            } else {
                spBillCreateIP = request.getHeader("x-forwarded-for");
            }

        }
        Order o = getOrder();
        o.setPayType("wechat");
        // 添加订单
        Long oid = orderBiz.create(o);
        o.setId(oid);
        Map<String, String> return_map = WxPayUtil.reqWxpay(o, spBillCreateIP);

        String return_code = return_map.get("return_code");
        String result_code = return_map.get("result_code");
        String returnCode = null;
        String resultCode;
        if (return_code.equals("SUCCESS") && result_code.equals("SUCCESS")) {
            Map<String, Object> treeMap = WxPayUtil.getJsapiJson(return_map
                    .get("prepay_id"));
            resultCode = "100";
            map.put("jsapiData", treeMap);
            map.put("createTime", DateUtil.getDay(null));
        } else {
            resultCode = "104";
            System.out.println("微信支付失败:原因为" + return_map.get("return_msg"));
        }
        map.put("returnCode", returnCode);
        map.put("resultCode", resultCode);
        long end = System.currentTimeMillis();
        map.put("time", (end - start) + "毫秒");
        response.getWriter().print(JsonUtil.getJsonString4JavaPOJO(map));
    }

3):调起微信支付

function onBridgeReady(jsapiData) {
                    //用户发起支付请求时,通过javascript调用getBrandWCPayRequest接口发起微信支付请求,用户进入支付流程
                    //用户成功支付点击完成按钮后,商户的前端,也就是这里会受到javascript的返回值,根据返回值的不同跳转到不同的页面
                    //商户后台收到来自微信后台的支付成工的回调通知,标志该笔订单支付成功!
                    WeixinJSBridge.invoke('getBrandWCPayRequest',jsapiData,
                        function(res) {
                            WeixinJSBridge.log(res.err_msg);
                            if (res.err_msg == "get_brand_wcpay_request:ok") {
                                $.cookie("jsapiData",null,{expires:0});
                                $.cookie("payData",null,{expires:0});
                                window.location.href = 'ok';
                            } else {
                                alert("支付失败");
                            }
                    });
                }

4):微信回调

public void notifyurl() throws Exception {
        HttpServletRequest request = this.getHttpRequest();
        HttpServletResponse response = this.getHttpResponse();
        //解析请求中的数据,因为我们发送给微信的是xml格式的string,微信返回给我们的也是xml格式的string
        TreeMap<String, String> map = WxPayUtil.parseXml(request);
        //新建一个map
        Map<String, String> _map = new HashMap<String, String>();
        
        String return_code = map.get("return_code");
        if (return_code.equals("SUCCESS")) {
            String _return_code = WxPayUtil.isSign(map);
            if (_return_code.equals("OK")) {
                _map.put("return_code", "SUCCESS");
                _map.put("return_msg", _return_code);

                // String orderNum = map.get("out_trade_no");
                String attach = map.get("attach");
                String bank_type = map.get("bank_type");// 银行类型
                String transaction_id = map.get("transaction_id");// 微信订单号

                Long id = Long.parseLong(attach);
                Order order = orderBiz.getById(id);
                order.setPayStaus(String.valueOf(OrderPayStatusEnum.PAY
                        .getValue()));
                order.setPayBankType(bank_type);
                order.setTrade_no(transaction_id);
                order.setPayType("wechat");
                // 更新订单
                orderBiz.update(order);
                // 更新余额
                ShopUser user = shopUserBiz.getById(order.getParentSid());
                Double b = user.getBalance() + order.getTotal();
                user.setBalance(b);
                shopUserBiz.update(user);
            } else {
                _map.put("return_code", "FAIL");
                _map.put("return_msg", _return_code);
            }
        }
        String xml = WxPayUtil.generate(_map.get("return_code"),
                _map.get("return_msg"));
        response.getWriter().print(xml);
    }

公众号支付就给大家简单介绍到这里了。

© 著作权归作者所有

叫我老王好吗

叫我老王好吗

粉丝 15
博文 39
码字总数 37401
作品 0
焦作
后端工程师
私信 提问
微擎模块开发之微信支付报错get_brand_wcpay_request:fail解决方案

微擎模块开发之微信支付报错getbrandwcpay_request:fail解决方案 微擎模块开发之微信支付报错getbrandwcpay_request:fail解决方案 开发过程中遇到这个问题的朋友 请检查修改以下内容 1微擎微...

wx5ca58d86a5c57
04/12
0
0
IJPay 让支付触手可及,2.1.2 添加 QQ 钱包支付

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任...

Javen-IJPay
08/05
1K
8
Magento微信支付接口开发小记

遇到了很多意想不到的问题,首先是微信支付分为四种:刷卡支付(线下)、扫码支付(PC网站)、公众号支付(微信中打开商户的H5页面)、APP支付(移动端支付),客户需要的微信扫码支付,而之前...

Alipaymate
2015/09/17
2.3K
0
IJPay 让支付触手可及,2.1.1 版本发布:扬帆起航

IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任...

Javen-IJPay
07/29
2.5K
6
WxJava 3.5.0 发布

本次版本更新主要是实现了WiFi管理的部分接口,完善了企业微信的一些接口支持,同时还实现了微信小程序模块的 Spring Boot Starter 方便 Spring Boot 应用快速接入小程序开发,并修复了一些 ...

班纳睿
08/10
2.7K
0

没有更多内容

加载失败,请刷新页面

加载更多

spring源码分析6: ApplicationContext的初始化与BeanDefinition的搜集入库

先前几篇都是概念的讲解:回顾下 BeanDefinition 是物料 Bean是成品 BeanFactory是仓库,存储物料与成品 ApplicationContext初始化搜集物料入库,触发生产线,取出物料生产Bean 本文研究spr...

星星之焱
21分钟前
5
0
彻底解决tomcat乱码问题

本地项目请求访问,浏览器中文输出没问题。 部署到服务器上面之后,返回到浏览器的中文就乱码了。 尝试办法: 1.修改tomcat下的conf中的service.xml中的配置信息: 重新启动后,没有效果还是...

诗书易经
37分钟前
5
0
Java开发需要掌握的IDEA插件大全

1、Lombok 解释:这是最基本的插件,2017年就火了,还没用的百度一下吧。 博客链接:Intellij IDEA 安装lombok及使用详解 2、PlantUML integration 解释:各种类之间的关联图,高级开发必备。...

木九天
38分钟前
6
0
python学习10.05:Python range()快速初始化数字列表

实际场景中,经常需要存储一组数字。例如在游戏中,需要跟踪每个角色的位置,还可能需要跟踪玩家的几个最高得分。在数据可视化中,处理的几乎都是由数字(如温度、距离、人口数量、经度和纬度...

太空堡垒185
45分钟前
4
0
java单元测试,PowerMockito模拟方法内new对象

在做单元测试中有时候需要对方法内new出来的对象进行隔离,这是我们需要使用PowerMockito。 添加依赖 <dependency> <groupId>org.powermock</groupId> <artifactId>......

如梦之猿
47分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部