网站添加微信支付功能(小白填坑)

本周的工作安排就是在网站添加支付功能,包括支付宝、微信、财付通等,今天这篇文章先说一下微信支付吧,支付宝的太容易了基本看一下都会了

1、首先准备工作,开通了支付功能的账号,具体怎么开通的我也不熟悉因为我做的时候都是使用开通好的账号(目前微信支付好像只支持商家不支持个人吧?)

2、按照我的性格当然是百度一下啦,但是微信支付的文档说明事例实在是太坑了,完全不是我这种小白可以一下看懂的,在这夸奖一下支付宝,支付宝的事例文档做的太好了基本做的时候没什么坑

准备工作结束开工:

我的开发环境是java,所以去官方找代码不得不说太TM坑了 java版本的好像是维护的最不好的,人家其他的那么多

你看java的 不说了,没有扫码支付的,但是我这次使用的肯定是扫码啊 ,只好继续百度了。

找到了这个项目,是git上一个人维护的,我看了一下基本符合我的需求,就按照这个改吧

WxPayDto.java是微信发送消息的实体类

WxPayResult.java是接收到回调消息的实体类

具体的操作看下面:

具体的操作之前需要先得到几个必须的参数

	//微信支付商户开通后 微信会提供appid和appsecret和商户号partner
	private static String appid = "";
	private static String appsecret = "";
	private static String partner = "";
	//这个参数partnerkey是在商户后台配置的一个32位的key,微信商户平台-账户设置-安全设置-api安全
	private static String partnerkey = "";
	//openId 是微信用户针对公众号的标识,授权的部分这里不解释
	private static String openId = "";
	//微信支付成功后通知地址 必须要求80端口并且地址不能带参数
	private static String notifyurl = "";

 参数什么的都是直接客户提供给我的,你们如果是自己开发获取这些参数的时候可能不知道具体位置,我建议你百度一下因为如果参数都不知道怎么获取还谈什么开发接口啊

这里有几点需要说明一下的

openid我没设置 不知道是干什么 随便填了成了客户商户ID反正也没报错。

notifyurl 是交易成功后回调的地址,需要在公众账号的后台设置一下,否则即使交易成功返回信息也是错误的。

微信支付的步骤是 获取交易的二维码,这个二维码是通过你传入的商品ID 价格等信息 微信生成的,用户扫码后启动微信的支付客户端,支付成功后回调你设置的回调地址那第一步获取微信支付的二维码看代码:
   //扫码支付
        WxPayDto tpWxPay1 = new WxPayDto();
        tpWxPay1.setBody(gp.getPackname());
        tpWxPay1.setOrderId(of.getOrder_id());
        tpWxPay1.setSpbillCreateIp(request.getRemoteAddr());
        tpWxPay1.setTotalFee(gp.getFee());
        mv.addObject("txcode", getCodeurl(tpWxPay1));
       public String getCodeurl(WxPayDto tpWxPayDto){

            // 1 参数
            // 订单号
            String orderId = tpWxPayDto.getOrderId();
            // 附加数据 原样返回
            String attach = "";
            // 总金额以分为单位,不带小数点
            String totalFee = getMoney(tpWxPayDto.getTotalFee());

            // 订单生成的机器 IP
            String spbill_create_ip = tpWxPayDto.getSpbillCreateIp();
            // 这里notify_url是 支付完成后微信发给该链接信息,可以判断会员是否支付成功,改变订单状态等。
            String notify_url = notifyurl;
            String trade_type = "NATIVE";

            // 商户号
            String mch_id = partner;
            // 随机字符串
            String nonce_str = getNonceStr();

            // 商品描述根据情况修改
            String body = tpWxPayDto.getBody();

            // 商户订单号
            String out_trade_no = orderId;

            SortedMap<String, String> packageParams = new TreeMap<String, String>();
            packageParams.put("appid", appid);
            packageParams.put("mch_id", mch_id);
            packageParams.put("nonce_str", nonce_str);
            packageParams.put("body", body);
            packageParams.put("attach", attach);
            packageParams.put("out_trade_no", out_trade_no);

            // 这里写的金额为1 分到时修改
            packageParams.put("total_fee", totalFee);
            packageParams.put("spbill_create_ip", spbill_create_ip);
            packageParams.put("notify_url", notify_url);

            packageParams.put("trade_type", trade_type);

            RequestHandler reqHandler = new RequestHandler(null, null);
            reqHandler.init(appid, appsecret, partnerkey);

            String sign = reqHandler.createSign(packageParams);
            String xml = "<xml>" + "<appid>" + appid + "</appid>" + "<mch_id>"
                    + mch_id + "</mch_id>" + "<nonce_str>" + nonce_str
                    + "</nonce_str>" + "<sign>" + sign + "</sign>"
                    + "<body><![CDATA[" + body + "]]></body>"
                    + "<out_trade_no>" + out_trade_no
                    + "</out_trade_no>" + "<attach>" + attach + "</attach>"
                    + "<total_fee>" + totalFee + "</total_fee>"
                    + "<spbill_create_ip>" + spbill_create_ip
                    + "</spbill_create_ip>" + "<notify_url>" + notify_url
                    + "</notify_url>" + "<trade_type>" + trade_type
                    + "</trade_type>" + "</xml>";
            String code_url = "";
            String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";

            code_url = new GetWxOrderno().getCodeUrl(createOrderURL, xml);
            System.out.println("code_url----------------"+code_url);

            return code_url;
        }
设置好参数后直接调用getCodeurl()函数就能获取到微信的二维码了,如果返回的信息错误,可以断点跟踪一下看看
 code_url = new GetWxOrderno().getCodeUrl(createOrderURL, xml); 这句返回的具体错误信息。

如果这部成功的话,你应该会得到一个类似这样的地址:weixin://wxpay/bizpayurl?pr=eYaNVZF

在前台直接使用qrcode.js将这个地址生成二维码显示在页面上,我的前台页面代码是这样的
<!doctype html>
<html>
 <head>
  <title>扫码支付前台demo</title>
  <meta name="keywords" content="关键字">
  <meta name="description" content="描述">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <script src=""></script>
  <script src="http://localhost:8080/shopping/resources/newstyle/js/qrcode.js"></script>
 </head>

 <body>

    <div align="center" id="qrcode">
        <p >
        扫码商品二维码付款
        <br><br>
        </p>
    </div>
 </body>

 <script>
     //这个地址是Demo.java生成的code_url,这个很关键
    var url = "weixin://wxpay/bizpayurl?pr=eYaNVZF";

    //参数1表示图像大小,取值范围1-10;参数2表示质量,取值范围‘L‘,‘M‘,‘Q‘,‘H‘
    var qr = qrcode(10, ‘M‘);
    qr.addData(url);
    qr.make();
    var dom=document.createElement(‘DIV‘);
    dom.innerHTML = qr.createImgTag();
    var element=document.getElementById("qrcode");
    element.appendChild(dom);
 </script>
</html>
接下来到了一个小技巧的提供时间了 ,由于微信的回调地址要求必须是80端口还必须是是外网的,咱们开发都是局域网而且也没有域名啊 ,怎么办?当然有办法了神器登场 ngrok如果你用的是原版的ngrok 他每次自动生成的二级域名都是随机生成的 ,这样会很麻烦因为每次都要修改微信的后台,后来又找到了一个国内的,不但不用FQ了还可以定制指定的二级域名http://natapp.cn/ 去这网址,绝对比原版的好用这是我本机的参数配置,zy是二级域名,8080端口是我的resin的启动地址,这样我就可以使用http://zy.ngrok.natapp.cn这样的域名来访问我的本机网站了ngrok -config ngrok.cfg -subdomain  zy 8080回调地址直接配置成:http://zy.ngrok.natapp.cn/你的处理回调页面.jsp这样就可以实现在本机的调试,这东西我是找了好几个小时才发现的 ,真心的好用啊以后微信的相关接口开发都可以使用这个啊

接下来就是接受微信的回调页面了可以说的不多直接上代码
       @RequestMapping({"/notifyurl.htm"})
       public void notifyurl(HttpServletRequest request, HttpServletResponse response) throws IOException {
            //把如下代码贴到的你的处理回调的servlet 或者.do 中即可明白回调操作
            System.out.print("微信支付回调数据开始");
            //示例报文
            //String xml = "<xml><appid><![CDATA[wxb4dc385f953b356e]]></appid><bank_type><![CDATA[CCB_CREDIT]]></bank_type><cash_fee><![CDATA[1]]></cash_fee><fee_type><![CDATA[CNY]]></fee_type><is_subscribe><![CDATA[Y]]></is_subscribe><mch_id><![CDATA[1228442802]]></mch_id><nonce_str><![CDATA[1002477130]]></nonce_str><openid><![CDATA[o-HREuJzRr3moMvv990VdfnQ8x4k]]></openid><out_trade_no><![CDATA[jdg_16042915230001]]></out_trade_no><result_code><![CDATA[SUCCESS]]></result_code><return_code><![CDATA[SUCCESS]]></return_code><sign><![CDATA[1269E03E43F2B8C388A414EDAE185CEE]]></sign><time_end><![CDATA[20150324100405]]></time_end><total_fee>1</total_fee><trade_type><![CDATA[JSAPI]]></trade_type><transaction_id><![CDATA[1009530574201503240036299496]]></transaction_id></xml>";
            String inputLine;
            String notityXml="" ;
            String resXml = "";

            try {
                while ((inputLine = request.getReader().readLine()) != null) {
                    notityXml += inputLine;
                }
                request.getReader().close();
            } catch (Exception e) {
                e.printStackTrace();
            }

            System.out.println("接收到的报文:" + notityXml);
            Map m = parseXmlToList2(notityXml);
            WxPayResult wpr = new WxPayResult();
            wpr.setAppid(m.get("appid").toString());
            wpr.setBankType(m.get("bank_type").toString());
            wpr.setCashFee(m.get("cash_fee").toString());
            wpr.setFeeType(m.get("fee_type").toString());
            wpr.setIsSubscribe(m.get("is_subscribe").toString());
            wpr.setMchId(m.get("mch_id").toString());
            wpr.setNonceStr(m.get("nonce_str").toString());
            wpr.setOpenid(m.get("openid").toString());
            wpr.setOutTradeNo(m.get("out_trade_no").toString());
            wpr.setResultCode(m.get("result_code").toString());
            wpr.setReturnCode(m.get("return_code").toString());
            wpr.setSign(m.get("sign").toString());
            wpr.setTimeEnd(m.get("time_end").toString());
            wpr.setTotalFee(m.get("total_fee").toString());
            wpr.setTradeType(m.get("trade_type").toString());
            wpr.setTransactionId(m.get("transaction_id").toString());

            if("SUCCESS".equals(wpr.getResultCode())){
                //支付成功
                //加入支付成功业务逻辑

                if(this.isczok(wpr.getOutTradeNo()))//判断该笔订单是否在商户网站中已经做过处理
                {

                if(this.addusergoldandlog(wpr.getOutTradeNo()))//增加用户金币写入订单记录
                {
                    if(setorderstate(wpr.getOutTradeNo(),1))
                    {
                        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{
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                + "<return_msg><![CDATA[订单已经处理过了]]></return_msg>" + "</xml> ";
            }
            }
            else
            {
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                + "<return_msg><![CDATA[微信返回结果错误]]></return_msg>" + "</xml> ";
                setorderstate(wpr.getOutTradeNo(),2);//讲订单状态更改成支付失败

            }

            System.out.println("微信支付回调数据结束");

            BufferedOutputStream out = new BufferedOutputStream(
                    response.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();

       }

        /**
         * description: 解析微信通知xml
         *
         * @param xml
         * @return
         * @author ex_yangxiaoyi
         * @see
         */
        @SuppressWarnings({ "unused", "rawtypes", "unchecked" })
        private static Map parseXmlToList2(String xml) {
            Map retMap = new HashMap();
            try {
                StringReader read = new StringReader(xml);
                // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
                InputSource source = new InputSource(read);
                // 创建一个新的SAXBuilder
                SAXBuilder sb = new SAXBuilder();
                // 通过输入源构造一个Document
                Document doc = (Document) sb.build(source);
                Element root = doc.getRootElement();// 指向根节点
                List<Element> es = root.getChildren();
                if (es != null && es.size() != 0) {
                    for (Element element : es) {
                        retMap.put(element.getName(), element.getValue());
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return retMap;
        }

注意:接受到的都是xml格式的数据,腾讯的坑爹团队,都什么年代了还用xml

其中需要注意的是,如果交易成功后要在页面中直接返回

"<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> "我这个代码中的好像没成功,我准备再修改一下,你们谁知道应该怎么写的可以私信我想我这么写虽然交易成功,但是微信一直没收到你的反馈会一直异步请求你的页面,具体会请求多久我没看到文档里写,不过一般其他支付的也就是请求几次

这篇文章写的非常仓促,很多细节都没说到,等接下来有时间一定将文章好好整理一下
 

				
时间: 2024-10-15 02:17:47

网站添加微信支付功能(小白填坑)的相关文章

支付宝和微信支付的各种填坑

填坑 支付宝填坑是每个接入支付宝必经之路,下面是我接入支付宝遇到的问题汇总,希望大家在接入的路上少一点弯路 问题1. Util/base64.h:63:21: Cannot find interface declaration for ‘NSObject’, superclass of ‘Base64’ 解决办法: 这是base64.h中没有加入#import 系统库文件导致,这个错误报错方法直接想喷它一脸.报错方式太恶心. 1 2 解决办法: 这是base64.h中没有加入#import  系

10分钟搞定支付宝和微信支付 的 各种填坑

填坑   支付宝填坑是每个接入支付宝必经之路,下面是我接入支付宝遇到的问题汇总,希望大家在接入的路上少一点弯路 问题1. Util/base64.h:63:21: Cannot find interface declaration for ‘NSObject’, superclass of ‘Base64’ 解决办法: 这是base64.h中没有加入#import  系统库文件导致,这个错误报错方法直接想喷它一脸.报错方式太恶心. 问题2.截图告知你什么问题 解决办法: 这个问题可以同上的,心情

10分钟搞定支付宝和微信支付的各种填坑

支付宝填坑是每个接入支付宝必经之路,下面是我接入支付宝遇到的问题汇总,希望大家在接入的路上少一点弯路. 问题1. Util/base64.h:63:21: Cannot find interface declaration for ‘NSObject’, superclass of ‘Base64’ 解决办法: 这是base64.h中没有加入#import 系统库文件导致,这个错误报错方法直接想喷它一脸.报错方式太恶心. 问题2.截图告知你什么问题 解决办法: 这个问题可以同上的,心情好,截图再

ecshop增加pc扫描二维码微信支付功能代码

ecshop开发网站,如果没有手机版,又想通过微信支付,可以加入pc二维码扫描微信支付功能 工具/原料 ecshop商城系统,phpqrcode,WxPayPubHelper 公众号已申请微信支付 方法/步骤 使用PHP QR Code生成二维码,下载,在商品支付页面加入 include 'phpqrcode/phpqrcode.php'; $pay_url ='http://www.xxx.com/weixin/weixin.php?order_id='.$order['order_sn'];

2017年第一篇博客--关于集成友盟和微信支付等遇到的坑

前几天刚完工的一个定制单,需要用到分享,第三方登录,微信支付功能.因为一直都是用友盟去集成分享和第三方登录,所以项目初期就使用cocopads导入了友盟库. 上个月开始做支付功能,支付宝支付没有什么问题,按照官方文档顺利实现.到微信支付时候,下载了微信包,导入项目,顺利完成支付功能.然后开始做第三方登录,QQ登录和微信登录我打算直接使用友盟,QQ登录顺利完成,但微信登录就没那么顺利了.第一个坑,微信登录不走友盟回调,无限重新拉起授权.起初我以为是bundleid和appkey不对的问题,仔细校验

微信支付趟过的坑

微信支付趟过的坑 标签: 微信支付 2015-01-21 15:49 25791人阅读 评论(30) 收藏 举报  分类: 微信公众号开发 版权声明:本文为博主原创文章,未经博主允许不得转载. 这段时间在做微信支付开发,在公司的公众号审批下来后,我这边的测试用例也已经开发完毕,于是拿着具体的数据来调试了,大段大段的代码就不贴了,demo里有,这里就说说调试过程中遇到的坑. 第一坑:redirect_url参数错误.因为我选择的的“JS API”支付,这种支付需要网页授权,先获取code,再拿co

cordova 打包的项目里加入微信支付功能编译问题。

最近在做公司项目,需要在cordova 打包的项目里加入微信支付功能.而不是使用通过新建single application的项目里开发. 使用从微信开放平台下载来的开发包,按照普通的新建single application项目的方式加了在targets下的Link binary with libraries 里加上libsqlite3.0.dylib, libz.dylib ,  SystemConfiguration.framework        CoreGraphics.framewo

微信小程序 使用微信支付功能实现在线支付订单

以前做过PC页面微信支付,但是这次在小程序 直接调用微信支付功能还是方便很多 先放个微信官方API链接:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=5 先说说整个下单支付流程的整体思路, 0,准备工作: 一,appId,开发帐号中注册时的appId. 二,sdkContent,后台返回的包含有金额,支付方式等信息的数据包. 三,key值,商户申请微信支付功能时所配置的密钥 准备好后, 1,首先选

谈谈开发支付功能碰到的坑

文章原创于公众号:程序猿周先森.本平台不定时更新,喜欢我的文章,欢迎关注我的微信公众号. 最近因为有了新的需求,需要开发支付宝支付功能以及微信支付功能,两三天开发下来碰到了几个Bug,在这里记录下来以供以后可以温故知新.因为支付宝功能是在H5端进行使用,所以使用了支付宝扫码付功能,生成一张支付二维码,然后用户保存二维码去支付宝进行扫码支付操作.一路磕磕碰碰把功能完善出来了,但是碰到了几个坑.支付宝支付开发碰到的问题: 1.无效的APP_ID 这个问题其实是最容易犯的一个错误,因为支付宝支付功能有