微信支付之扫码支付

选择支付模式

点开链接先去了解一下微信支付模式:
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=2_1

web一般选择都是扫码支付。
类似于这个:

准备账号

公众账号ID(AppID)

首先要申请一个公共账号,最好申请的时候就是服务号,因为微信支付的前提必须是服务号
如果是公众号需要先申请验证才能升级为服务号。

下面链接可以帮助你去找到这个账号:
http://jingyan.baidu.com/article/22fe7ced23fa183002617fa1.html

应用秘钥 (AppSecret)

在公共号平台上找

下面链接可以帮助你去找到这个账号:
http://jingyan.baidu.com/article/22fe7ced23fa183002617fa1.html

注意:

以上两个账号都可以在类型为服务号的公众号上找到,下面的两个账号就必须要在商户平台上才可以找到。
大概步骤:
一、公众号为服务号
http://jingyan.baidu.com/article/fea4511a7eaf2cf7bb9125a7.html
二、申请微信认证
http://kf.qq.com/faq/120911VrYVrA150929Fjqeei.html
三、申请扫码支付
升级完之后左侧菜单会多一个“微信支付”选项

第三步成功之后会收到一个邮件,邮件中会有登录商户平台的账号和密码

商户id(mch_id)

申请支付成功之后登录商户平台就可以看到这个值了。

API秘钥 (api_key)

这个必须要登录商户平台去设置。
以上两个账号的值可以参考下面的链接:
http://help.ecmoban.com/article-2085.html

查看扫码支付API了解流程

https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5

进入开发

引入相关的jar包

<!-- 生成二维码所需的jar包 开始 -->
        <dependency>
              <groupId>com.uqihong</groupId>
              <artifactId>qdcode</artifactId>
              <version>1.0.0</version>
        </dependency>
        <dependency>
              <groupId>com.uqihong</groupId>
              <artifactId>qdcodeSwetake</artifactId>
              <version>1.0.0</version>
        </dependency>
        <!-- 生成二维码所需的jar包 结束 -->
<!-- 微信支付需要的jar包 -->
        <dependency>
            <groupId>xmlpull</groupId>
            <artifactId>xmlpull</artifactId>
            <version>1.1.3.1</version>
        </dependency>
        <dependency>
            <groupId>xpp3</groupId>
            <artifactId>xpp3</artifactId>
            <version>1.1.4c</version>
        </dependency>
        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>fluent-hc</artifactId>
            <version>4.3.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.3.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient-cache</artifactId>
            <version>4.3.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.3.5</version>
        </dependency>

调用预生成订单API获取到扫码链接


    /**
     * 创建预支付订单
     * 
     * @param goodsName 商品名称 
     * @param orderId   订单id
     * @param payPrice  支付价格
     * 
     * @return 微信支付二维码链接
    */
    public String createPrePayOrder(String goodsName, String orderId, double payPrice) {
        return dowithWxReturn(sendReqGetPreOrder(goodsName, orderId, payPrice));
    }
            
    /**
     * 处理微信返回
     * <p>
     * 处理的是调用微信预支付订单的返回值
     * 
     * @param result 微信的返回值
     * 
     * @return 二维码链接
     */
    private String dowithWxReturn(String result) {
        String codeUrl = "";
        Map<String, Object> weixinPrepayInfo = MapUtil.map();
        try {
            weixinPrepayInfo = XMLParser.getMapFromXML(result);
            String return_code = (String) weixinPrepayInfo.get("return_code");
            if ("SUCCESS".equals(return_code)) {
                codeUrl = (String) weixinPrepayInfo.get("code_url");
                if (Util.isEmpty(codeUrl)) {
                    throw ExceptionUtil.bEx(ConvertUtil.obj2str(weixinPrepayInfo.get("err_code_des")));
                }
                return codeUrl;
            } else {
                throw ExceptionUtil.bEx("预支付失败");
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            ExceptionUtil.bEx("调用微信预支付接口出错");
        }
        return codeUrl;
    }
    /**
     * 发送预生成订单请求
     * 
     * @param goodsName 商品名称
     * @param orderId 订单号
     * @param payPrice 支付价格
     * 
     * @return 微信处理结果
    */
    private String sendReqGetPreOrder(String goodsName, String orderId, double payPrice) {
        ExceptionUtil.checkEmpty(orderId, "订单id不能为空");
        ExceptionUtil.checkEmpty(goodsName, "商品名称不能为空");
        Map<String, Object> params = MapUtil.map();
        //公共账号id
        params.put("appid", WeixinH5PayConfigure.APPID);
        //商户id
        params.put("mch_id", WeixinH5PayConfigure.MCH_ID);
        //设备号
        //ctrl+alt+T
        params.put("device_info", "WEB");
        //随机字符串
        params.put("nonce_str", RandomUtil.randomString(randomNumLength));
        //商品描述
        params.put("body", goodsName);
        //订单编号
        params.put("out_trade_no", orderId);
        //金额
        params.put("total_fee", AmountUtils.changeY2F(payPrice));
        //回调地址
        params.put("notify_url", WeixinH5PayConfigure.NOTIFY_ACTIVITY_URL);
        params.put("trade_type", WeixinH5PayConfigure.TRADE_TYPE);
        //签名
        String sign = Signature.getSign(params, WeixinH5PayConfigure.API_KEY);
        params.put("sign", sign);
        return HttpRequest.sendPost(WeixinH5PayConfigure.PAY_UNIFIED_ORDER_API, params);
    }

根据扫码链接生成二维码

   /**
     * 获取二维码
     *
     * @param orderId 订单id
     * 
     * @return 二维码的地址
    */
    public Object getQrCode(long orderId) {
        ExceptionUtil.checkId(orderId, "订单id不能为空");
        return getWxCodeImagePath(getWxPayCodeUrl(orderId));
    }
    /**
     * 获取微信二维码支付的链接
     * 
     * @param orderId 订单号
     * 
     * @return 二维码支付的链接
    */
    private String getWxPayCodeUrl(long orderId) {
        OrderEntity order = orderBaseService.getWithEx(orderId);
        PackageEntity pk = packageBaseService.getWithEx(order.getPackageId());
        //double paymentPrice = 0.1;
        double paymentPrice = order.getPaymentPrice();
        String wxPayCodeUrl = wxPayService.createPrePayOrder(pk.getName(), ConvertUtil.obj2str(orderId), paymentPrice);
        return wxPayCodeUrl;
    }
    /**
     * 获取微信二维码的图片地址
     *
     * @param wxPayCodeUrl 微信二维码链接
     * 
     * @return 含有微信扫码支付的二维码地址
    */
    private String getWxCodeImagePath(String wxPayCodeUrl) {
        String qrCodePath = QrcodeUtil.getQrCodePath(kvConfig, UqihongUploadFoldType.QRCODE);
        QrcodeUtil.encoderQRCode(wxPayCodeUrl, qrCodePath);
        return QrcodeUtil.getRelationPath(qrCodePath, kvConfig);
    }

将生成的二维码展示给用户

第二步中的getQrCode()方法返回的就是图片的地址,直接在页面中使用img标签展示给用户就行。

编写微信支付完成的回调逻辑

    /**
     * 微信提醒
     * <P>
     * 微信支付成功的回调
     * 
     * @throws Exception 
     */
    public void wxPayFinishNotify() throws Exception {
        HttpServletRequest request = Mvcs.getReq();
        HttpServletResponse response = Mvcs.getResp();
        String responseString = getWeiXinResponseContent(request);
        PrintWriter out = response.getWriter();
        String resp = "";
        String signKey = WeixinH5PayConfigure.API_KEY;
        boolean verify = Signature.checkIsSignValidFromResponseString(responseString, signKey);
        if (!verify) {
            resp = "签名验证失败";
            out.write(resp);
            out.close();
            return;
        }
        Map<String, Object> map = XMLParser.getMapFromXML(responseString);
        String result_code = ConvertUtil.obj2str(map.get("result_code"));
        if (!"SUCCESS".equalsIgnoreCase(result_code)) {
            resp = PayCommonUtil.getResponseXML("ERROR", "ERROR");
            out.write(resp);
            out.close();
            return;
        }
        resp = handleOrder(map);
        out.write(resp);
        out.close();
    }
    @Aop("txDb")
    private String handleOrder(Map<String, Object> map) throws Exception {
        String resp = PayCommonUtil.getResponseXML("SUCCESS", "OK");
        //微信支付订单号
        String transaction_id = ConvertUtil.obj2str(map.get("transaction_id"));
        //支付完成时间
        String time_end = ConvertUtil.obj2str(map.get("time_end"));
        //订单号
        String out_trade_no = (String) map.get("out_trade_no");
        if (Util.isEmpty(transaction_id) || Util.isEmpty(time_end) || Util.isEmpty(out_trade_no)) {
            resp = PayCommonUtil.getResponseXML("ERROR", "参数错误,微信支付订单号、支付完成时间、订单号均不能为空");
            return resp;
        }
        OrderEntity order = orderBaseService.get(ConvertUtil.obj2long(out_trade_no));
        if (Util.isEmpty(order)) {
            resp = PayCommonUtil.getResponseXML("ERROR", "订单不存在");
            return resp;
        }
        //判断订单状态,避免重复处理
        int orderStatus = order.getStatus();
        if (OrderStatusEnum.FINISHED.intKey() == orderStatus) {
            return resp;
        }
        if (OrderStatusEnum.WAITING_PAY.intKey() == orderStatus) {
            //在这里编写你的逻辑即可
                                。。。。。。
           
        }
        return resp;
    }

资源

https://my.oschina.net/xiaohui249/blog/656511 扫码支付的demo
http://www.cnblogs.com/zhengbin/p/6777639.html 生成二维码

posted @ 2018-01-10 11:26  王森  阅读(862)  评论(0编辑  收藏  举报