微信支付 简单的流程

h5 页面在微信浏览器里调用支付接口  ,写的一个测试的支付流程,比较乱,望勿吐槽。

简要代码如下

前端

1、准备

                                      if (typeof WeixinJSBridge == "undefined"){
					   if( document.addEventListener ){
					       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
					   }else if (document.attachEvent){
					       document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
					       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
					   }
					   onBridgeReady();
					}else{
					   onBridgeReady();
					}


2、获取openId 

function onBridgeReady(){
		window.location.href="https://open.weixin.qq.com/connect/oauth2/authorize?appid=*******&redirect_uri=域名/wx/restf/np-pay-getOpenId?orderId="+$("#mergeId").val()+"&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";
		}

3、拿到openId 获取微信交互权限

@RequestMapping("np-pay-getOpenId")
    public String getOpenId(Model model,HttpServletRequest request) {
		String code = request.getParameter("code");
		String orderId = request.getParameter("orderId");
		PersonOrder order = null;
		NpShop shop = null;
		double totalPrice = 0.0;
		List<PersonOrderMerge> personOrderMerges = null;
		
		if(StringHelper.isNotEmpty(orderId)) {
			personOrderMerges = personOrderMergeManager.findBy("parentId", orderId);
			if(personOrderMerges!=null) {
				for(PersonOrderMerge pom:personOrderMerges) {
					
					order = personOrderManager.findUniqueBy("id", pom.getOrderId());
					shop = shopManager.findUniqueBy("id", order.getShopId());
					totalPrice = totalPrice+order.getTotalPrice();
					
				}
			}
		}
		//获取opendId
		String openId = request.getSession().getAttribute("openId")==null?null:request.getSession().getAttribute("openId")+"";
		String accessTocken = request.getSession().getAttribute("accessTocken")==null?null:request.getSession().getAttribute("accessTocken")+"";
		String ticket = request.getSession().getAttribute("ticket")==null?null:request.getSession().getAttribute("ticket")+"";
		if(StringHelper.isNotEmpty(code)&&StringHelper.isEmpty(openId)) {
			//https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
			String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+ConfigUtil.APPID+"&secret="+ConfigUtil.APP_SECRECT+"&code="+code+"&grant_type=authorization_code";
			String result = CommonUtil.httpsRequest(requestUrl, "POST", null);
			//System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++"+result);
			if(result!=null) {
				JSONArray jsonArray = JSONArray.fromObject("["+result+"]");  
				List<Map<String,Object>> mapListJson = (List)jsonArray;  
		        for (int i = 0; i < mapListJson.size(); i++) {  
		            Map<String,Object> obj=mapListJson.get(i);  
		              
		            for(Entry<String,Object> entry : obj.entrySet()){  
		                String strkey1 = entry.getKey();  
		                Object strval1 = entry.getValue();  
		                System.out.println("KEY:"+strkey1+"  -->  Value:"+strval1+"\n");  
		                if("openid".equals(strkey1)) {
		                	openId = strval1+"";
		                	request.getSession().setAttribute("openId", openId);
		                	request.getSession().setMaxInactiveInterval(7000);
		                }
		            }  
		        } 
			}
		}
		if(StringHelper.isEmpty(accessTocken)) {
			String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ConfigUtil.APPID+"&secret="+ConfigUtil.APP_SECRECT;
			String result = CommonUtil.httpsRequest(requestUrl, "GET", null);
			
			if(result!=null) {
				JSONArray jsonArray = JSONArray.fromObject("["+result+"]");  
				List<Map<String,Object>> mapListJson = (List)jsonArray;  
				for (int i = 0; i < mapListJson.size(); i++) {  
					Map<String,Object> obj=mapListJson.get(i);  
					
					for(Entry<String,Object> entry : obj.entrySet()){  
						String strkey1 = entry.getKey();  
						Object strval1 = entry.getValue();  
						System.out.println("KEY:"+strkey1+"  -->  Value:"+strval1+"\n");  
						if("access_token".equals(strkey1)) {
							accessTocken = strval1+"";
							request.getSession().setAttribute("accessTocken", accessTocken);
		                	request.getSession().setMaxInactiveInterval(7000);
						}
					}  
				} 
			}
		}
		if(StringHelper.isNotEmpty(accessTocken)&&StringHelper.isEmpty(ticket)) {
			String requestUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+accessTocken+"&type=jsapi";
			String result = CommonUtil.httpsRequest(requestUrl, "GET", null);
			
			if(result!=null) {
				JSONArray jsonArray = JSONArray.fromObject("["+result+"]");  
				List<Map<String,Object>> mapListJson = (List)jsonArray;  
		        for (int i = 0; i < mapListJson.size(); i++) {  
		            Map<String,Object> obj=mapListJson.get(i);  
		              
		            for(Entry<String,Object> entry : obj.entrySet()){  
		                String strkey1 = entry.getKey();  
		                Object strval1 = entry.getValue();  
		                System.out.println("KEY:"+strkey1+"  -->  Value:"+strval1+"\n");  
		                if("ticket".equals(strkey1)) {
		                	ticket = strval1+"";
		                	request.getSession().setAttribute("ticket", ticket);
		                	request.getSession().setMaxInactiveInterval(7000);
		                }
		            }  
		        } 
			}
		}
		//下单参数
		SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
		parameters.put("appid", ConfigUtil.APPID);
		parameters.put("mch_id", ConfigUtil.MCH_ID);
		parameters.put("nonce_str", PayCommonUtil.CreateNoncestr());
		parameters.put("body", shop==null?"":shop.getTitle());
		parameters.put("out_trade_no", orderId);
		parameters.put("total_fee", Integer.parseInt(new java.text.DecimalFormat("0").format(totalPrice*100))+"");
		String Ip = IpAddressUtil.getIpAddr(request);
		if(Ip!=null) {
			Ip = Ip.split(",")[0];
		}
		parameters.put("spbill_create_ip",Ip);
		parameters.put("notify_url", ConfigUtil.NOTIFY_URL);
		parameters.put("trade_type", "JSAPI");
		parameters.put("openid", openId);
		String sign = PayCommonUtil.createSign("UTF-8", parameters);
		
		parameters.put("sign", sign);
		String requestXML = PayCommonUtil.getRequestXml(parameters);
		
		String result =CommonUtil.httpsRequest(ConfigUtil.UNIFIED_ORDER_URL, "POST", requestXML);
		
		try {
			Map<String, String> map = XMLUtil.doXMLParse(result);
			
			SortedMap<Object,Object> params = new TreeMap<Object,Object>();
			String timeStamp = Long.toString(new Date().getTime());
			String nonceStr = PayCommonUtil.CreateNoncestr();
			
	        params.put("appId", ConfigUtil.APPID);
	        params.put("timeStamp",timeStamp);
	        params.put("nonceStr", nonceStr);
	        params.put("package", "prepay_id="+map.get("prepay_id"));
	        params.put("signType", ConfigUtil.SIGN_TYPE);
	        String paySign =  PayCommonUtil.createSign("UTF-8", params);
	        params.put("packageValue", "prepay_id="+map.get("prepay_id"));    //这里用packageValue是预防package是关键字在js获取值出错
	        params.put("paySign", paySign);                                                          //paySign的生成规则和Sign的生成规则一致
	        params.put("sendUrl", ConfigUtil.SUCCESS_URL);                               //付款成功后跳转的页面
	        String userAgent = request.getHeader("user-agent");
	        char agent = userAgent.charAt(userAgent.indexOf("MicroMessenger")+15);
	        params.put("agent", new String(new char[]{agent}));//微信版本号,用于前面提到的判断用户手机微信的版本是否是5.0以上版本。
	        
	        model.addAttribute("appId", ConfigUtil.APPID);
	        model.addAttribute("timeStamp", timeStamp);
	        model.addAttribute("nonceStr", nonceStr);
	        model.addAttribute("package", "prepay_id="+map.get("prepay_id"));
	        model.addAttribute("signType", ConfigUtil.SIGN_TYPE);
	        model.addAttribute("packageValue", "prepay_id="+map.get("prepay_id"));
	        model.addAttribute("paySign", paySign);
	        model.addAttribute("sendUrl", ConfigUtil.SUCCESS_URL);
	        model.addAttribute("agent", new String(new char[]{agent}));
	        model.addAttribute("orderId", orderId);
	        SortedMap<Object,Object> parameters_ = new TreeMap<Object,Object>();
	        parameters_.put("jsapi_ticket", ticket);
	        parameters_.put("timestamp", timeStamp);
	        parameters_.put("noncestr", nonceStr);
	        parameters_.put("url", getFullURL(request));
	        String signature = PayCommonUtil.getSignature(parameters_);
	    
	        model.addAttribute("signature", signature);
	       // String json = JSONObject.fromObject(params).toString();
		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}//解析微信返回的信息,以Map形式存储便于取值
		return "h5/wx/topay";
	}

4、跳转到前端页面 调用支付控件

<script src="${ctx }/assets/goods/js/jquery.min.js"></script>
<script type="text/javascript" charset="UTF-8" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

<script type="text/javascript">
function pay(){
    var appId = $('#appId').val();
    var timeStamp = $('#timeStamp').val();
    var nonceStr = $('#nonceStr').val();
    var pk = $('#package').val();
    var signType = $('#signType').val();
    var paySign = $('#paySign').val();
    //config
    var signature = $('#signature').val();
    var activityId = $('#activityId').val();
    wx.config({
        debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: appId, // 必填,公众号的唯一标识
        timestamp:timeStamp, // 必填,生成签名的时间戳
        nonceStr: nonceStr, // 必填,生成签名的随机串
        signature: signature,// 必填,签名,见附录1
        jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
    });
    wx.ready(function(){
        // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
        wx.chooseWXPay({
            timestamp: timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
            nonceStr: nonceStr, // 支付签名随机串,不长于 32 位
            package: pk, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
            signType: signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
            paySign: paySign, // 支付签名
            complete: function (res) {
                // 支付成功后的回调函数
                //location.href=basePath+'/activityorder/activity-order!list.action?activityId='+activityId;
                if(res.errMsg=="chooseWXPay:ok"){
                	$.ajax({ 
  			    	  url: "${ctx}/np/restf/person/np-orders-merge-update", 
  			    	  data:{mergeId:$("#mergeId").val()}, 
  			    	  dataType: "json",
  			    	  async: false,
  			    	  type: 'POST',
  			    	  success: function(data){
  			    		  window.location.href="${ctx}/h5/person-order-list?yhId="+localStorage.getItem("yhId");
  			          }
  			   		 });
                }else{
                	alert("支付失败。");
                	window.location.href="${ctx}/h5/person-order-list?yhId="+localStorage.getItem("yhId");
                }
            	
            }
        });
    });
}
</script>
</head>
<body οnlοad="pay()">

    <input id="mergeId" type="hidden" value="${orderId}" />
    <input id="appId" type="hidden" value="${appId}" />
    <input id="timeStamp" type="hidden" value="${timeStamp}" />
    <input id="nonceStr" type="hidden" value="${nonceStr}" />
    <input id="package" type="hidden" value="${package}" />
    <input id="signType" type="hidden" value="${signType}" />
    <input id="paySign" type="hidden" value="${paySign}"/>

    <input id="signature" type="hidden" value="${signature}"/>
</body>
</html>

完成支付,

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值