java微信支付_java微信支付面试题 - CSDN
精华内容
参与话题
  • java集成微信支付(完整流程)

    万次阅读 多人点赞 2019-07-09 14:41:12
    java集成微信支付(完整流程) 1.申请微信支付能力 * 要想使用微信支付能力,不管是app支付、公众号支付、h5支付等支付方式都需要先在微信商户平台申请开通支付能力。 * 申请开通支付能力的资料有公司营业执照...

    java集成微信支付(完整流程)

    1.申请微信支付能力

     * 要想使用微信支付能力,不管是app支付、公众号支付、h5支付等支付方式都需要先在微信商户平台申请开通支付能力。
     * 申请开通支付能力的资料有公司营业执照、负责人身份证正反面等图片,相关所需的所有资料在微信官方商户平台上有说明。
     * 申请完开通支付能力后,我们会得到商户号以及appId,然后设置32位官方密钥。
    

    2.准备工作

      * 如果你是h5支付,还需要去微信商户平台设置支付URL的IP或者域名,一般最多可以设置5个IP或者域名,建议同时将正式环境和测试环境的IP或者域名设置好。
      * 如果你是公众号支付,同上,你也需要设置你的支付IP或者域名,注意,异步通知的URL也要在你设置的IP或者域名下。
    

    3.开始集成

     *** APP支付**
     
         支付集成流程如下:
         步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。(app端向服务端发起请求)
         步骤2:商户后台收到用户支付单,调用微信支付统一下单接口。(服务端向微信请求)
         步骤3:统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appid,partnerid,prepayid,noncestr,timestamp,package。注意:package的值格式为Sign=WXPay(将微信回传的prepayid与其他参数组合返回给app端)
         步骤4:商户APP调起微信支付。(app端利用服务端回传的参数调起微信支付)
         步骤5:商户后台接收支付通知。(微信将支付结果异步通知服务端)
         步骤6:商户后台查询支付结果。(微信将支付结果同步通知app端)
         上代码:
       
    
    
     DecimalFormat df = new DecimalFormat("######0.00"); 
        //根据订单id查询出该订单的金额
    	money=df.format(Double.parseDouble(okamiOrder.getReallMoney()));
    	//定义返回值
    	ReturnValue    rv=new ReturnValue();
    	String token=request.getParameter("token");
    	//当前用户的id
    	String userId=TokenParmValue.getUserId(token);
    	//开始组装调用统一下单接口所需的参数
    	String currTime = TenpayUtil.getCurrTime();
    	// 8位日期
    	String strTime = currTime.substring(8, currTime.length());
    	// 四位随机数
    	String strRandom = TenpayUtil.buildRandom(4) + "";
    	// 10位序列号,可以自行调整。
    	String strReq =strTime+strRandom;
    	SONObject retMsgJson = new JSONObject();
       //应用配置
    	String  appId="";                //appid
    	String  appSecret="";            //微信支付appsecret
    	String  partner="";              //微信商户号
    	String  partnerkey="";           //api密钥
    	//定义应用支付配置
    	appId=WeixinPayUtil.appid;
        appSecret=WeixinPayUtil.appsecret;
        partner=WeixinPayUtil.partner;
        partnerkey=WeixinPayUtil.partnerkey;
       //********************************************当前微信支付业务处理开始
    	// 时间戳加后四位随机数作为商户订单号
    		String sjbh = RandomUtil.getRandomFileName();
    		// 封装参数
    		TreeMap<String, String> treeMap = new TreeMap<String, String>();
    		// 微信支付所需要的appId
    		treeMap.put("appid",appId);
    		// 微信商户号
    		treeMap.put("mch_id",partner);
    		// 随机数
    		treeMap.put("nonce_str", strReq);
    		// 订单内容
    		treeMap.put("body",subject);
    		// 商户订单号
    		treeMap.put("out_trade_no", sjbh);
    		// 终端ip(下单生成机器的ip),可以获取支付接口的请求IP
    		treeMap.put("spbill_create_ip", Property.getProperty("weixinIp"));
    		// 订单金额
    		treeMap.put("total_fee",money);
    		// 支付类型            
    		treeMap.put("trade_type",WeixinPayUtil.trade_type);
    		// 微信异步通知地址
    		treeMap.put("notify_url",Property.getProperty("okamiWeixinUrl").trim());
    		//禁止充值的时候使用信用卡
    		if("3".equals(payType)){
    			treeMap.put("limit_pay","no_credit");   
    		}
    		StringBuilder sb = new StringBuilder();
    		for (String key : treeMap.keySet()) {
    			sb.append(key).append("=").append(treeMap.get(key)).append("&");
    		}
    		sb.append("key="+partnerkey);
    		// 获得微信支付验签 
    		RequestHandler reqHandler = new RequestHandler(request, response);
    		reqHandler.init(appId,appSecret,partnerkey);
    		// 参数加签名认证
    		String sign = reqHandler.createSign(treeMap);// 获取签名
    		treeMap.put("sign", sign);
    		StringBuilder xml = new StringBuilder();
    		xml.append("<xml>\n");
    		for (Map.Entry<String, String> entry : treeMap.entrySet()) {
    			if ("body".equals(entry.getKey()) || "sign".equals(entry.getKey())) {
    				xml.append("<" + entry.getKey() + "><![CDATA[").append(entry.getValue()).append("]]></" + entry.getKey() + ">\n");
    			} else {
    				xml.append("<" + entry.getKey() + ">").append(entry.getValue()).append("</" + entry.getKey() + ">\n");
    			}
    		}
    		xml.append("</xml>");
           //开始调用统一下单接口
    		String createOrderURL = WeixinPayUtil.createOrderURL;
    		String prepay_id = "";
    		try {
    			// 获得预下单的订单号
    			prepay_id = GetWxOrderno.getPayNo(createOrderURL,xml.toString());
    
    		} catch (Exception e1) {
    			 e1.printStackTrace();
    			 rv.setResult("error");
    			 rv.setMsg(ReturnUtil.PAYMENT_FAILURE);
    		     return new JsonMapper().toJson(rv);
    		}
    		log.info("微信支付prepay_id的值为:----------------"+prepay_id);
    		// 获取到prepayid后对以下字段进行签名最终发送给app
    			SortedMap<Object, Object> finalpackage = new TreeMap<Object, Object>();
    			String timestamp = Sha1Util.getTimeStamp();
    			finalpackage.put("appid",appId);
    			finalpackage.put("noncestr", strReq);
    			finalpackage.put("partnerid", partner);
    			finalpackage.put("timestamp", timestamp);
    			finalpackage.put("package", "Sign=WXPay");
    			finalpackage.put("prepayid", prepay_id);
    			String wenXinSign=WenXinPay.createSign("UTF-8",finalpackage,partnerkey);
    			retMsgJson.put("appid",appId);
    			retMsgJson.put("timestamp",timestamp);
    			retMsgJson.put("noncestr", strReq);
    			retMsgJson.put("partnerid",partner);
    			retMsgJson.put("prepayid", prepay_id);
    			retMsgJson.put("packageX", "Sign=WXPay");
    			retMsgJson.put("sign", wenXinSign);
    			// 最终给app的参数
    			String json = retMsgJson.toString();
    			以上是app端发起微信支付,服务端回传app端所需要的参数。
    
    
    
    
    
    异步通知处理:
             在做异步通知功能之前一定要设计好异步通知功能,防止重复通知,建议通知成功后将记录储存与缓存或者数据库中,以避免重复异步通知。
      @RequestMapping(value = "payment/wechatAsynchronous",method=RequestMethod.POST,produces = "text/html;charset=UTF-8")
    @ResponseBody
    	public    void   wechatAsynchronous(HttpServletRequest requestWechat,HttpServletResponse response) throws Exception{
    		log.info("进入微信异步通知啦"+moduleName+"方法名为:wechatAsynchronous");
    		DecimalFormat df = new DecimalFormat("######0.00");
    		DecimalFormat dformat = new DecimalFormat("######0");
    		requestWechat.setCharacterEncoding("UTF-8");
    		response.setCharacterEncoding("UTF-8");
    		response.setContentType("text/html;charset=UTF-8");
    		response.setHeader("Access-Control-Allow-Origin", "*"); 
    		InputStream in = requestWechat.getInputStream();
    		ByteArrayOutputStream out = new ByteArrayOutputStream();
    		byte[] buffer = new byte[1024];
    		int len = 0;
    		while ((len = in.read(buffer)) != -1) {
    			out.write(buffer, 0, len);
    		}
    		out.close();
    		in.close();
    		String msgxml = new String(out.toByteArray(), "utf-8");// xml数据
    		System.out.println(msgxml);
    		log.info("msgxml的值为:-----------------"+msgxml);
    		Map map = XmlToMap.xmlToMap(msgxml);
    		 //过滤空 设置 TreeMap  
            SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();        
            Iterator it = map.keySet().iterator();  
            while (it.hasNext()) {  
                String parameter = (String) it.next();  
                String parameterValue = (String) map .get(parameter);  
    
                String v = "";  
                if(null != parameterValue) {  
                    v = parameterValue.trim();  
                }  
                packageParams.put(parameter, v);  
            }  
            log.info("进入微信异步通知啦"+moduleName+"异步通知参数:"+packageParams);
    		// 获得支付结果
    		String result_code = (String) map.get("result_code");
    		// 获得商户订单号
    		String out_trade_no = (String) map.get("out_trade_no");
    		// 获得订单签名
    		String sign = (String) map.get("sign");
    		log.info("sign订单签名为:---------------------"+sign);
    	    //买家实际支付金额
    		String total_fee=(String)map.get("total_fee");
    		String realMoney=String.valueOf(Double.parseDouble(total_fee)/100);
    		// 交易记录表的id
    		String tranId = out_trade_no.replace(" ", "");
    		log.info("参数 tranId:" + tranId);
    		log.info("微信支付的result_code为-----------------------:" + result_code);
    		// 根据交易id查询一条交易记录
    		Transaction tran = tranService.findById(tranId);
    		if(tran!=null){
    	
    			log.info("tran对象的值不为空:--------------------");
    			// 订单表的id
    			String orderId = tran.getOrderId();
    			log.info("参数订单主键 orderId:" + orderId);
    			// 微信支付成功
    			if (result_code.equals("SUCCESS")){
    			   //防止重复通知
    				long  size=requestRedisTemplate.boundValueOps("weixinpay:lock:"+out_trade_no).increment(1);
    			 	requestRedisTemplate.expire("weixinpay:lock:"+out_trade_no,24,TimeUnit.HOURS);
    			 	if(size==1){
    			 		  log.info("进入微信异步通知啦"+moduleName+"异步通知请求进入!!!");
    			 		//插入异步通知日志
    					asyncService.insertResrcord("weixin",tran.getUserId(),(String)map.get("transaction_id"),realMoney,tranId);
    			 	    // 财付通订单号
    					String transaction_id = (String) map.get("transaction_id");
    					//获得微支付商户号
    					String  mch_id=(String) map.get("mch_id");
    					//获得微信支付appid---->异步通知
    					String  appid=(String) map.get("appid");
    				
    					if(StringUtils.isNotBlank(mch_id)&&StringUtils.isNotBlank(appid)){
    						log.info("商户号与appid不为空");
    						
    						//根据不同的appid校验应用配置
    						//应用1
    						String  appId_local_one=WeixinPayUtil.appid;
    						//应用2
    						String  appId_local_two=WeixinPayUtil.appid_two;
    						//应用3
    						String  appId_local_three=WeixinPayUtil.appid_three;
    						String	partner_local=WeixinPayUtil.partner;
    						String	partnerKey_local=WeixinPayUtil.partnerkey;
    						String	appVersion="1";
    				
    						// 验证商户号是否正确
    						if (mch_id.equals(partner_local)) {
    							log.info("微信商户号与appid验证验证成功");
    							//验证签名
    							if(WenXinPay.isTenpaySign("UTF-8", packageParams,partnerKey_local)){
    										log.info("微信验证签名成功了!!!!!!");
    										// 业务处理
    									
    			 	}else{
    			 		response.getWriter().write(setXml("FAIL", "ERROR")); 
    					log.info("微信支付异步通知失败了!!!!!!");
    			 	}
    				
    			}else{
    				response.getWriter().write(setXml("FAIL", "ERROR")); 
    				log.info("微信支付异步通知失败了!!!!!!");
    			}
    	}
    	
    	   //微信异步通知返回xml格式数据
    	public static String setXml(String return_code, String return_msg) {
    			return "<xml><return_code><![CDATA[" + return_code
    					+ "]]></return_code><return_msg><![CDATA[" + return_msg
    					+ "]]></return_msg></xml>";
    	}
    
    以上就是app支付的所有代码,其中所用的工具类大部分为微信支付开发文档中demo提供,下载地址为:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_3		
      ***h5支付**
      
           记得在微信官方商户平台配置好支付域名
           基本流程:
                1、用户在商户侧完成下单,使用微信支付进行支付。
    			2、由商户后台向微信支付发起下单请求(调用统一下单接口)注:交易类型trade_type=MWEB。
    			3、统一下单接口返回支付相关参数给商户后台,如支付跳转url(参数名“mweb_url”),商户通过mweb_url调起微信支付中间页。
    			4、中间页进行H5权限的校验,安全性检查。
    			5、如支付成功,商户后台会接收到微信侧的异步通知。
    			6、用户在微信支付收银台完成支付或取消支付,返回商户页面。
    			7、商户在展示页面,引导用户主动发起支付结果的查询。
    			8,9、商户后台判断是否接到收微信侧的支付结果通知,如没有,后台调用我们的订单查询接口确认订单状态。
    			10、展示最终的订单支付结果给用户。
    	**此处注意微信h5支付最终的结果是提供前端一个支付链接的字符串。**
    支付接口代码:
    
    
    
    
      /**
        	 * 微信发送支付请求,微信官方h5支付
        	 * @param paramMap
        	 * @return
        	 */
        	@Override
        	public Result officialSend(Map paramMap){
        		Result  result=new Result();
        		String pay_url="";
        		// 封装参数
        		TreeMap<String, String> treeMap = new TreeMap<String, String>();
        		// 微信支付所需要的appId
        		treeMap.put("appid",WeiXinConstant.official_app_id);
        		// 微信商户号
        		treeMap.put("mch_id",WeiXinConstant.official_mch_id);
        		// 随机数
        		treeMap.put("nonce_str",TenpayUtil.getNonceStr());
        		// 订单内容
        		treeMap.put("body",paramMap.get("productname")+"");
        		// 商户订单号
        		treeMap.put("out_trade_no",paramMap.get("orderId")+"");
        		// 终端ip(下单生成机器的ip)
        		treeMap.put("spbill_create_ip",paramMap.get("spbill_create_ip")+"");
        		// 订单金额
        		treeMap.put("total_fee",new Double(Double.valueOf(paramMap.get("money")+"")*100).intValue()+"");
        		// 支付类型            
        		treeMap.put("trade_type","MWEB");//h5支付
        		// 微信异步通知地址
        		treeMap.put("notify_url", PropertiesUtil.getDom()+WeiXinConstant.official_notify_url);
        		//业务参数
        		treeMap.put("attach",paramMap.get("orderId")+"");
        		JSONObject js=new JSONObject();
        		JSONObject jb=new JSONObject();
        		if("1".equals(paramMap.get("source"))){//安卓
        			js.put("type", "Android");
        			js.put("app_name", "8wan游戏");
        			js.put("package_name", "com.xianqing.sdk");
        			jb.put("h5_info", js);
        		}else{//ios
        			js.put("type", "IOS");
        			js.put("bundle_id", "com.xianqing.sdk");
        			js.put("app_name", "8wan游戏");
        			jb.put("h5_info", js);
        		}
        		//场景信息
        		treeMap.put("scene_info",jb.toString());
        		//禁止充值的时候使用信用卡,默认可以使用
        		//treeMap.put("limit_pay","no_credit");   
        		 Map<String,String> params = SignUtils.paraFilter(treeMap);
                 StringBuilder buf = new StringBuilder((params.size() +1) * 10);
                 SignUtils.buildPayParams(buf,params,false);
                 String preStr = buf.toString();
                 String sign = MD5.sign(preStr, "&key=" + WeiXinConstant.partnerkey, "utf-8");
                 treeMap.put("sign", sign);
                 CloseableHttpResponse response = null;
                 CloseableHttpClient client = null;
                 try {
                     HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/pay/unifiedorder");
                     StringEntity entityParams = new StringEntity(WXPayUtil.mapToXml(treeMap),"utf-8");
                     httpPost.setEntity(entityParams);
                     //httpPost.setHeader("Content-Type", "text/xml;charset=ISO-8859-1");
                     client = HttpClients.createDefault();
                     response = client.execute(httpPost);
                     if(response != null && response.getEntity() != null){
                         Map<String,String> resultMap = WXPayUtil.xmlToMap(new         String(EntityUtils.toByteArray(response.getEntity())));
                         if("SUCCESS".equalsIgnoreCase(resultMap.get("return_code"))){
                        	 if("SUCCESS".equalsIgnoreCase(resultMap.get("result_code"))){
                        		 String prepay_id=resultMap.get("prepay_id");
                        		 String mweb_url=resultMap.get("mweb_url");
                        		 logger.info("微信官方支付mweb_url:"+mweb_url);
                        		 String packagevalue="";
                        		 if(mweb_url.indexOf("&package=")!=-1){
                        			 packagevalue=mweb_url.substring(mweb_url.indexOf("&package=")+9,mweb_url.length());
                        		 }		 
                        		 String type="";
             	  			     if(PropertiesUtil.getDom().indexOf("test")!=-1){
             	  					type="1";
             	  			     }else{
             	  					type="2";
             	  				 }
             	  			     pay_url=PropertiesUtil.getDom()+"pay/pay_h5_wx.html?prepay_id="+prepay_id+"&packagevalue="+packagevalue+"&type="+type;
                        	 }
                         }else{
                        	 logger.info("微信官方h5支付失败,失败原因为:"+resultMap.get("return_msg")); 
                         }
                         logger.info("支付结果为:"+resultMap.toString());
                     }else{
                         logger.info("微信官方h5支付失败,请求未响应");
                     }
                 } catch (Exception e) {
                	 logger.info("微信官方支付错误信息:"+e.getMessage());
                 } finally {
                     if(response != null){
                         try {
        					response.close();
        				} catch (IOException e) {
        					 logger.info("微信官方支付,响应关闭错误信息:"+e.getMessage());
        				}
                     }
                     if(client != null){
                         try {
        					client.close();
        				} catch (IOException e) {
        					 logger.info("微信官方支付,请求关闭错误信息:"+e.getMessage());
        				}
                     }
                 }
                 JSONObject job=new JSONObject();
                if(StringUtils.isNotBlank(pay_url)){
                	job.put("res",pay_url);
                }else{
                	job.put("res","");
                }
                result.setData(job);
        		return result;
        	}
        注意,微信h5支付接口最终返回给前端是一个支付链接,此链接所在的页面的IP或者域名必须要在你之前在商户平台配置的IP或者域名之下,另外如果是app请求h5支付接口,也同样将此链接返回给app端,最后贴上支付连接中页面的代码:
           
     
    
            <html>
        	<head>
        		<meta charset="UTF-8">
        		<meta http-equiv="X-UA-Compatible" content="IE=edge">
        		<meta content="width=device-width, initial-scale=1, minimum-scale=1.0, user-scalable=no" name="viewport">
        		<title>微信官方h5支付</title>
              <script type="text/javascript">
                  function GetRequest() {
        		    var url = location.search; //获取url中"?"符后的字串
        		    var theRequest = new Object();
        		    if (url.indexOf("?") != -1) {
        		        var str = url.substr(1);
        		        strs = str.split("&");
        		        for(var i = 0; i < strs.length; i ++) {
        		            theRequest[strs[i].split("=")[0]]=decodeURI(strs[i].split("=")[1]);
        		        }
        		    }
        		    return theRequest;
                  } 
                  var Request = new Object();
        		  Request = GetRequest();
        		  var prepay_id,packagevalue,type,redirect_url;
        		  prepay_id = Request['prepay_id'];
        		  packagevalue = Request['packagevalue'];	
        		  type=Request['type'];	//环境类型   1测试环境  2正式环境
        		  //回调地址
        		  if(type==1){
        		    redirect_url="http://测试域名/pay/wxreturn.html";
        		  }else{
        		    redirect_url="http://正式域名pay/wxreturn.html";
        		  }
                  window.location="https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id="+prepay_id+"&package="+packagevalue+"&redirect_url="+redirect_url;
              </script>
        	</head>
        	<body>	
        	</body>
        </html>
    
    
    
    
    	 异步通知代码:
      
         /**
        	 * 微信支付回调,微信官方h5支付
        	 * @return
        	 */
            @Override
            	public Result callbackUrlOfficial(HttpServletRequest req) throws Exception{
            		 String resString = XmlUtils.parseRequst(req);
            		 logger.info("微信官方h5支付回调参数:"+resString);
            		 Result result = new Result();
            		 if(StringUtils.isNotBlank(resString)){
            			 Map<String,String> map = WXPayUtil.xmlToMap(resString);
            			 logger.info("微信官方h5支付通知map内容:"+map);
            			 String return_code  = map.get("return_code");
            			 logger.info("微信官方h5支付异步通知业务结果为:"+return_code);
            			 if("SUCCESS".equals(return_code)){//通知状态    SUCCESS:成功  
            			   if(map.containsKey("sign")){
            				  if(SignUtils.checkParam(map, WeiXinConstant.partnerkey)){//验证签名通过
            					logger.info("微信官方h5支付异步通知签名通过!!!sign-success");  
            					if("SUCCESS".equals(map.get("result_code"))){//支付结果  SUCCESS:成功
            					  //业务处理
            						//判断微信支付返回值表中是否存在记录,如果不存在则插入返回信息
                        		    List<PayResponseBean> list =payServiceImpl.getPayResponse(map.get("out_trade_no"));
                                	if(list == null || list.size() == 0){
                                		payServiceImpl.addPayResponse(map.get("out_trade_no"), map.get("transaction_id"), "5", map.toString());
                                		//开始业务处理
                                	}
                        	        return result;
            					}else{
            						logger.info("微信官方h5订单支付失败:平台订单编号orderid="+map.get("attach"));
            	                    result.setCode(SystemStatus.WX_ORDER_PAY_ERROR.CODE);
            	                    result.setMsg(SystemStatus.WX_ORDER_PAY_ERROR.MSG);
            	               	    return result;    	
            					}  
            				  }else{
            				    logger.info("微信官方h5支付回调签名错误:平台订单编号orderid="+map.get("attach"));
                                result.setCode(SystemStatus.WX_SIGN_ERR.CODE);
                                result.setMsg(SystemStatus.WX_SIGN_ERR.MSG+"签名错误");
                           	    return result;    
            				  }  
            			   }else{
            				   logger.info("微信官方h5支付回调签名不存在:平台订单编号orderid="+map.get("attach"));
                               result.setCode(SystemStatus.WX_SIGN_ERR.CODE);
                               result.setMsg(SystemStatus.WX_SIGN_ERR.MSG+"签名不存在");
                           	   return result;  
            			   }	 
            			 }else{
            				logger.info("微信官方h5支付异步通知失败,失败原因为"+map.get("return_msg"));
            				result.setCode(SystemStatus.PARAM_ERROR.CODE);
            				result.setMsg(SystemStatus.PARAM_ERROR.MSG);
            				return result;
            			 }
            		 }else{
            			 result.setCode(SystemStatus.PARAM_ERROR.CODE);
            			 result.setMsg(SystemStatus.PARAM_ERROR.MSG);
            			 return result;
            		 }
            	}    
       以上就是微信h5支付的所有代码,其中所涉及到的工具类请大家自己在官方开发文档上下载:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_4
    
    *公众号支付*
       公众号支付与h5支付类似,只需要将支付方式改成公众号支付方式就行,参考文档为:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_3
       同样,公众号支付也是需要在你的公众号后台设置授权域名。
    
    展开全文
  • java实现微信支付

    千次阅读 2019-04-09 09:46:28
    源代码如下 ... 1.什么是手机支付 手机支付也称为移动支付(Mobile Payment),是指允许用户使用其移动终端(通常是指手机)对所消费的...目前最常见的是支付宝和微信支付这两种。 2.微信支付的具体支付方式 ...

    源代码如下

    https://download.csdn.net/download/weixin_39592397/10874079

       

    1.什么是手机支付

    手机支付也称为移动支付(Mobile Payment),是指允许用户使用其移动终端(通常是指手机)对所消费的商品或服务进行账务支付的一种服务方式。

    目前最常见的是支付宝和微信支付这两种。

        2.微信支付的具体支付方式

    1. 刷卡支付

    刷卡支付是用户展示微信钱包内的“刷卡条码/二维码”给商户系统扫描后直接完成支付的模式。主要应用线下面对面收银的场景。

        2.扫码支付

    扫码支付是商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫”完成支付的模式。该模式适用于PC网站支付、实体店单品或订单支付、媒体广告支付等场景。

         3.公众号支付

    公众号支付是用户在微信中打开商户的H5页面,商户在H5页面通过调用微信支付提供的JSAPI接口调起微信支付模块完成支付。应用场景有:

    • 用户在微信公众账号内进入商家公众号,打开某个主页面,完成支付
    • 用户的好友在朋友圈、聊天窗口等分享商家页面连接,用户点击链接打开商家页面,完成支付
    • 将商户页面转换成二维码,用户扫描二维码后在微信浏览器中打开页面后完成支付

      4.APP支付

     APP支付又称移动端支付,是商户通过在移动端应用APP中集成开放SDK调起微信支付模块完成支付的模式。

    1. 简介
    2. appid, 微信公众账号或开放平台APP的唯一标识
    3. mch_id, 微信支付系统中的商户收款账号
    4. partner, 财付通平台的商户账号
    5. partnerkey, 财付通平台的商户密钥
    6. sign, 数字签名, 根据微信官方提供的密钥和一套算法生成的一个加密信息, 就是为了保证交易的安全性



      支付流程如下介绍


       

    7. “二维码页面”发出ajax请求到action中, 该action负责访问微信支付后台生成订单并获得订单信息, 然后把订单信息返回给”二维码页面”, 该页面根据订单信息生成二维码
    8. 用户打开手机微信扫描页面上的二维码进行支付...
    9. ”二维码页面”发出ajax请求到action中,该action负责访问微信支付后台查询订单支付状态, 并把获得支付状态返回给”二维码页面”, 该页面根据支付状态信息跳转到”支付结果”页面上

    申请微信支付需要你们自己申请 现在直接上代码

    1,创建实体类管理我们的appid 秘钥和商户号

    @Component
    @ConfigurationProperties(prefix="qyweixin")
    @PropertySource(value = {"classpath:qiyeweixin.properties"})
    public class Appid {
        public  String sCorpID;
        public  String sToken;
        public  String sEncodingAESKey;
        public  String Secret;

    2,编写创建订单的controller 在点击生成订单按钮时跳转页面直接发送请求创建订单

       

    @RequestMapping("/native")
        @ResponseBody
        public Map<String, String> natives(HttpServletRequest request) throws Exception{
            // 生成订单
            TreeMap<String, String> packageParams = new TreeMap<String, String>();
            // 企业号或公众号id  商户号
            packageParams.put("appid", we.getAppid());
            // 企业收款账号
            packageParams.put("mch_id", we.getPartner());
            // 随机字符串
            String nonce_str = TenpayUtil.getRandomStr();
            packageParams.put("nonce_str", nonce_str);
            //商品名称
            packageParams.put("body", "测试");
            // 附加数据
            packageParams.put("attach", "");
            // 订单号
            String out_trade_no = TenpayUtil.getRandomStr();
            packageParams.put("out_trade_no", out_trade_no);
    
            // 支付总金额(微信官方的支付单位是分)
            String totalFee=TenpayUtil.getMoney("0.01");
            packageParams.put("total_fee", totalFee);
            
            // 生成订单的机器IP
            String ip =     request.getRemoteAddr();
            packageParams.put("spbill_create_ip", ip);
            
            // 回调URL
            packageParams.put("notify_url", we.getNotifyurl());
    
            // 设置支付方式
            packageParams.put("trade_type", "NATIVE");
    
            // 生成数字签名
            String sign = MD5Util.createSign(packageParams, we.getAppid(),
                    we.getPartnerkey());
            //out_trade_no  totalFee  ip
            jdbc.update("insert into t_weixin(id,out_trade_no,totalFee,ip,flag,create_date,create_user)values(?,?,?,?,?,now(),?)",new Object[]{UUID.randomUUID().toString().replaceAll("-",""),out_trade_no,totalFee,ip,"1","张崇俊"});
            // 拼接xml数据
            String xml = "<xml>" + "<appid>" + we.getAppid() + "</appid>"
                    + "<mch_id>" + we.getPartner() + "</mch_id>" + "<nonce_str>"
                    + nonce_str + "</nonce_str>" + "<sign>" + sign + "</sign>"
                    + "<body><![CDATA[测试]]></body>" + "<out_trade_no>"
                    + out_trade_no + "</out_trade_no>" + "<attach>" + ""
                    + "</attach>" + "<total_fee>" + totalFee + "</total_fee>"
                    + "<spbill_create_ip>" + ip    + "</spbill_create_ip>" 
                    + "<notify_url>" + we.getNotifyurl()    + "</notify_url>" 
                    + "<trade_type>" + "NATIVE"    + "</trade_type>" + "</xml>";
            //通过HttpClient对象向微信支付后台发送xml数据
            String code_url="";
            Map<String, String> maps = new TreeMap<String,String>();
            try {
                String createOrederURL="https://api.mch.weixin.qq.com/pay/unifiedorder";
                HttpClient httpClient=new HttpClient(createOrederURL);
                httpClient.setHttps(true);
                httpClient.setXmlParam(xml);
                httpClient.post();
                String xmlStr=httpClient.getContent(); //从微信支付后台获取订单信息
                System.out.println(xmlStr);
                
                //解析xml数据得到用于支付的url地址
                Map<String, String> map =TenpayUtil.doXMLParse(xmlStr);
                maps.put("code_url", map.get("code_url"));
                
                maps.put("out_trade_no", out_trade_no);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //返回订单信息到native.jsp
            return maps;
        }

    3,前台接收订单数据放到二维码中

    var out_trade_no;
        $(function(){
            $.post("http://127.0.0.1:8081/weChars/native",{},function(data){
                var url=data.code_url;  //支付URL
                out_trade_no=data.out_trade_no;  //订单号
            var qr = qrcode(10,'H')
            qr.addData(url);
            qr.make();
            console.log(url);

            $("#qrcode").html(qr.createImgTag());
            $("#qrtext").html("请打开手机微信进行扫描");
            queryPay();
            })
        });

    代码运行结果

     

    到此!整个支付接口已经全部开发基本算完毕

    源代码如下

    https://download.csdn.net/download/weixin_39592397/10874079

     

     

    展开全文
  • JAVA实现微信支付功能

    万次阅读 热门讨论 2019-02-28 09:12:30
    这两天,需要接入微信支付功能。由于我是公众号开发,因此,我选择的微信支付方式是JSAPI支付方式。 二,解决方案 2.1 配置微信平台 ①配置微信公众平台 登录微信公众平台=》公众号设置=》功能设置=》网页授权域名 ...

    一,问题

    这两天,需要接入微信支付功能。由于我是公众号开发,因此,我选择的微信支付方式是JSAPI支付方式。

    二,解决方案

    2.1 配置微信平台

    ①配置微信公众平台

    登录微信公众平台=》公众号设置=》功能设置=》网页授权域名
    

    在这里插入图片描述

    在这里插入图片描述

    ②配置微信商家平台

    产品中心=》开发配置
    

    在这里插入图片描述

    在这里插入图片描述

    2.2 后台代码的实现

    JSAPI官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
    

    ①先去官方下载SDK,并导进项目中

    地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
    

    在这里插入图片描述

    ②准备好11个参数

    appid:商家平台ID。在微信的平台上有
    body:商品描述。
    mch_id:商户ID。在微信的平台上有
    nonce_str:随机字符串,UUID就好了。
    openid:用户标识。因为这边是用户已经登录成功了。所以在session中就能拿到。
    out_trade_no:商户订单号
    spbill_create_ip:终端IP。这个可以从请求头中拿到
    total_fee:支付金额。单位是分。
    trade_type:交易类型。这里我填JSAPI
    notify_url:通知地址。就是用户支付成功之后,微信访问你的哪个接口,跟你传递支付成功的相关信息。
    
    sign:签名。这个签名它是由上面的10个参数计算得出的。
    

    ③源码
    sendPay类:

    import java.io.IOException;
    import java.io.InputStream;
    import java.math.BigDecimal;
    import java.net.URLEncoder;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.http.auth.AUTH;
    import org.hamcrest.core.Is;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import com.jc.util.wxPay.WXPayUtil;
    import com.sun.xml.internal.fastinfoset.Encoder;
    
    import controller.AuthUtil;
    import net.sf.json.JSONObject;
    
    @Controller
    @RequestMapping("/pay")
    public class sendPay {
     
    	/**
    	 * @Description 微信浏览器内微信支付/公众号支付(JSAPI)
    	 * @param request
    	 * @param code
    	 * @return Map
    	 */
    	@RequestMapping(value = "orders")
    	public @ResponseBody Map<String, String> orders(HttpServletRequest request, HttpServletResponse response) {
    		try {
    			 
    			String openId = "用户的openid";
    
    			// 拼接统一下单地址参数
    			Map<String, String> paraMap = new HashMap<String, String>();
    			// 获取请求ip地址
    			String ip = request.getHeader("x-forwarded-for");
    			if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    				ip = request.getHeader("Proxy-Client-IP");
    			}
    			if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    				ip = request.getHeader("WL-Proxy-Client-IP");
    			}
    			if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    				ip = request.getRemoteAddr();
    			}
    			if (ip.indexOf(",") != -1) {
    				String[] ips = ip.split(",");
    				ip = ips[0].trim();
    			}
    
    			paraMap.put("appid", AuthUtil.APPID); // 商家平台ID
    			paraMap.put("body", "纯情小店铺-薯条"); // 商家名称-销售商品类目、String(128)
    			paraMap.put("mch_id", AuthUtil.MCHID); // 商户ID
    			paraMap.put("nonce_str", WXPayUtil.generateNonceStr()); // UUID
    			paraMap.put("openid", openId);
    			paraMap.put("out_trade_no", UUID.randomUUID().toString().replaceAll("-", ""));// 订单号,每次都不同
    			paraMap.put("spbill_create_ip", ip);
    			paraMap.put("total_fee", "1"); // 支付金额,单位分
    			paraMap.put("trade_type", "JSAPI"); // 支付类型
    			paraMap.put("notify_url", "用户支付完成后,你想微信调你的哪个接口");// 此路径是微信服务器调用支付结果通知路径随意写
    			String sign = WXPayUtil.generateSignature(paraMap, AuthUtil.PATERNERKEY);
    			paraMap.put("sign", sign);
    			String xml = WXPayUtil.mapToXml(paraMap);// 将所有参数(map)转xml格式
    
    			// 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder
    			String unifiedorder_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    
    			System.out.println("xml为:" + xml);
    
    			// String xmlStr = HttpRequest.sendPost(unifiedorder_url,
    			// xml);//发送post请求"统一下单接口"返回预支付id:prepay_id
    
    			String xmlStr = HttpRequest.httpsRequest(unifiedorder_url, "POST", xml);
    
    			System.out.println("xmlStr为:" + xmlStr);
    
    			// 以下内容是返回前端页面的json数据
    			String prepay_id = "";// 预支付id
    			if (xmlStr.indexOf("SUCCESS") != -1) {
    				Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);
    				prepay_id = (String) map.get("prepay_id");
    			}
    
    			Map<String, String> payMap = new HashMap<String, String>();
    			payMap.put("appId", AuthUtil.APPID);
    			payMap.put("timeStamp", WXPayUtil.getCurrentTimestamp() + "");
    			payMap.put("nonceStr", WXPayUtil.generateNonceStr());
    			payMap.put("signType", "MD5");
    			payMap.put("package", "prepay_id=" + prepay_id);
    			String paySign = WXPayUtil.generateSignature(payMap, AuthUtil.PATERNERKEY);
    			payMap.put("paySign", paySign);
    			//将这个6个参数传给前端
    			return payMap;
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return null;
    	}
    
    	/**
    	 * @Title: callBack
    	 * @Description: 支付完成的回调函数
    	 * @param:
    	 * @return:
    	 */
    	@RequestMapping("/notify")
    	public String callBack(HttpServletRequest request, HttpServletResponse response) {
    		// System.out.println("微信支付成功,微信发送的callback信息,请注意修改订单信息");
    		InputStream is = null;
    		try {
    
    			is = request.getInputStream();// 获取请求的流信息(这里是微信发的xml格式所有只能使用流来读)
    			String xml = WXPayUtil.InputStream2String(is);
    			Map<String, String> notifyMap = WXPayUtil.xmlToMap(xml);// 将微信发的xml转map
    			
    			System.out.println("微信返回给回调函数的信息为:"+xml);
    			
    			if (notifyMap.get("result_code").equals("SUCCESS")) {
    				String ordersSn = notifyMap.get("out_trade_no");// 商户订单号
    				String amountpaid = notifyMap.get("total_fee");// 实际支付的订单金额:单位 分
    				BigDecimal amountPay = (new BigDecimal(amountpaid).divide(new BigDecimal("100"))).setScale(2);// 将分转换成元-实际支付金额:元
    
    				/*
    				 * 以下是自己的业务处理------仅做参考 更新order对应字段/已支付金额/状态码
    				 */
    				System.out.println("===notify===回调方法已经被调!!!");
    				
    			}
    			
    			// 告诉微信服务器收到信息了,不要在调用回调action了========这里很重要回复微信服务器信息用流发送一个xml即可
    			response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>");
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			if (is != null) {
    				try {
    					is.close();
    				} catch (IOException e) { 
    					e.printStackTrace();
    				}
    			}
    		}
    		
    		return null;
    	}
    
    }
    
    

    HttpRequest类:

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.PrintWriter;
    import java.net.URL;
    import java.net.URLConnection;
    import java.util.List;
    import java.util.Map;
    
    import javax.net.ssl.HttpsURLConnection;
    
    public class HttpRequest {
    	/**
    	 * 向指定URL发送GET方法的请求
    	 * 
    	 * @param url
    	 *            发送请求的URL
    	 * @param param
    	 *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
    	 * @return URL 所代表远程资源的响应结果
    	 */
    	public static String sendGet(String url, String param) {
    		String result = "";
    		BufferedReader in = null;
    		try {
    			String urlNameString = url + "?" + param;
    			System.out.println(urlNameString);
    			URL realUrl = new URL(urlNameString);
    			// 打开和URL之间的连接
    			URLConnection connection = realUrl.openConnection();
    			// 设置通用的请求属性
    			connection.setRequestProperty("accept", "*/*");
    			connection.setRequestProperty("connection", "Keep-Alive");
    			connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
    			// 建立实际的连接
    			connection.connect();
    			// 获取所有响应头字段
    			Map<String, List<String>> map = connection.getHeaderFields();
    			// 遍历所有的响应头字段
    			for (String key : map.keySet()) {
    				System.out.println(key + "--->" + map.get(key));
    			}
    			// 定义 BufferedReader输入流来读取URL的响应
    			in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    			String line;
    			while ((line = in.readLine()) != null) {
    				result += line;
    			}
    		} catch (Exception e) {
    			System.out.println("发送GET请求出现异常!" + e);
    			e.printStackTrace();
    		}
    		// 使用finally块来关闭输入流
    		finally {
    			try {
    				if (in != null) {
    					in.close();
    				}
    			} catch (Exception e2) {
    				e2.printStackTrace();
    			}
    		}
    		return result;
    	}
    
    	/**
    	 * 向指定 URL 发送POST方法的请求
    	 * 
    	 * @param url
    	 *            发送请求的 URL
    	 * @param param
    	 *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
    	 * @return 所代表远程资源的响应结果
    	 */
    	public static String sendPost(String url, String param) {
    		PrintWriter out = null;
    		BufferedReader in = null;
    		String result = "";
    		try {
    			URL realUrl = new URL(url);
    			// 打开和URL之间的连接
    			URLConnection conn = realUrl.openConnection();
    			// 设置通用的请求属性
    			conn.setRequestProperty("accept", "*/*");
    			conn.setRequestProperty("connection", "Keep-Alive");
    			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
    			// 发送POST请求必须设置如下两行
    			conn.setDoOutput(true);
    			conn.setDoInput(true);
    			// 获取URLConnection对象对应的输出流
    			out = new PrintWriter(conn.getOutputStream());
    			// 发送请求参数
    			out.print(param);
    			// flush输出流的缓冲
    			out.flush();
    			// 定义BufferedReader输入流来读取URL的响应
    			in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
    			String line;
    			while ((line = in.readLine()) != null) {
    				result += line;
    			}
    		} catch (Exception e) {
    			System.out.println("发送 POST 请求出现异常!" + e);
    			e.printStackTrace();
    		}
    		// 使用finally块来关闭输出流、输入流
    		finally {
    			try {
    				if (out != null) {
    					out.close();
    				}
    				if (in != null) {
    					in.close();
    				}
    			} catch (IOException ex) {
    				ex.printStackTrace();
    			}
    		}
    		return result;
    	}
    
    	/**
    	 * post请求并得到返回结果
    	 * 
    	 * @param requestUrl
    	 * @param requestMethod
    	 * @param output
    	 * @return
    	 */
    	public static String httpsRequest(String requestUrl, String requestMethod, String output) {
    		try { 
    			URL url = new URL(requestUrl);
    			HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
    			connection.setDoOutput(true);
    			connection.setDoInput(true);
    			connection.setUseCaches(false);
    			connection.setRequestMethod(requestMethod);
    			if (null != output) {
    				OutputStream outputStream = connection.getOutputStream();
    				outputStream.write(output.getBytes("UTF-8"));
    				outputStream.close();
    			}
    			// 从输入流读取返回内容
    			InputStream inputStream = connection.getInputStream();
    			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
    			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
    			String str = null;
    			StringBuffer buffer = new StringBuffer();
    			while ((str = bufferedReader.readLine()) != null) {
    				buffer.append(str);
    			}
    			bufferedReader.close();
    			inputStreamReader.close();
    			inputStream.close();
    			inputStream = null;
    			connection.disconnect();
    			return buffer.toString();
    		} catch (Exception ex) {
    			ex.printStackTrace();
    		}
    
    		return "";
    	}
    }
    

    AuthUtil类

    import java.io.IOException;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.util.EntityUtils;
    
    import net.sf.json.JSONObject;
    public class AuthUtil {
    	public static final String APPID = "平台ID";
    	public static final String APPSECRET = "平台密钥";
    	public static final String MCHID = "商家ID";
    	public static final String PATERNERKEY = "商家密钥";
    	
    	
    	public static JSONObject doGetJson(String url) throws ClientProtocolException, IOException {
    		JSONObject jsonObject = null;
    		// 首先初始化HttpClient对象
    		DefaultHttpClient client = new DefaultHttpClient();
    		// 通过get方式进行提交
    		HttpGet httpGet = new HttpGet(url);
    		// 通过HTTPclient的execute方法进行发送请求
    		HttpResponse response = client.execute(httpGet);
    		// 从response里面拿自己想要的结果
    		HttpEntity entity = response.getEntity();
    		if (entity != null) {
    			String result = EntityUtils.toString(entity, "UTF-8");
    			jsonObject = jsonObject.fromObject(result);
    		}
    		// 把链接释放掉
    		httpGet.releaseConnection();
    		return jsonObject;
    	}
    }
    

    2.3 前端的实现

    这是只用一个jsp页面来做测试

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    	pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript" src="./js/jquery-1.11.0.min.js"></script>
    <title>微信支付JSP</title>
    </head>
    <body> 
    	<input type="button" value="进行微信支付" id="payId">
    
    	<script type="text/javascript">
    	
    		$(function(){
    			var appId,timeStamp,nonceStr,package,signType,paySign; 
    			
    			$("#payId").click(function(){
    				pay();
    			});
    			
    			//去后台拿六个参数
    			function pay(){   
    				var url = "http://localhost:8082/WeChat/pay/orders";
    			  	$.get(url,function(result) {	
    		  				appId = result.appId;
    						timeStamp = result.timeStamp;
    						nonceStr = result.nonceStr;
    						package = result.package;
    						signType = result.signType;
    						paySign = result.paySign;
    						
    						if (typeof WeixinJSBridge == "undefined") {
    							if (document.addEventListener) {
    								document.addEventListener('WeixinJSBridgeReady',
    										onBridgeReady, false);
    							} else if (document.attachEvent) {
    								document.attachEvent('WeixinJSBridgeReady',
    										onBridgeReady);
    								document.attachEvent('onWeixinJSBridgeReady',
    										onBridgeReady);
    							}
    							alert("请在微信上进行支付操作!");
    							onBridgeReady();
    						} else { 
    							onBridgeReady();
    						}
    					});
    				}
    			//去微信那边发起支付请求
    			function onBridgeReady(){
    				
    				 alert("appId:"+appId+" "+"timeStamp:"+timeStamp+" "+"nonceStr:"+nonceStr+" "+"package:"+package+" "+"signType:"+signType+" "+"paySign:"+paySign+" ");
    				
    				  WeixinJSBridge.invoke( 'getBrandWCPayRequest', {
    					  "appId":appId,     //公众号名称,由商户传入     
    			          "timeStamp":timeStamp,         //时间戳,自1970年以来的秒数     
    			          "nonceStr":nonceStr, //随机串     
    			          "package":package,     
    			          "signType":signType,         //微信签名方式:     
    			          "paySign":paySign //微信签名 
    			         }, 
    			         function(res){      
    			      	   if(res.err_msg == "get_brand_wcpay_request:ok" ) {
    			                 //alert('支付成功');
    			                 console.log("支付成功");
    			                 //支付成功后跳转的页面
    			             }else if(res.err_msg == "get_brand_wcpay_request:cancel"){
    			            	 alert('支付取消');
    			             }else if(res.err_msg == "get_brand_wcpay_request:fail"){
    			            	 alert('支付失败');
    			            	 
    			            	 alert(JSON.stringify(res));
    			            	 
    			                 WeixinJSBridge.call('closeWindow');
    			             } //使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
    			   });    
    			}
    		})
    </script>
    
    </body>
    </html>
    

    三,总结

    虽然第一次看官方文档很乱,信息量很多,但仔细总结一下,其实就下面这点流程而已。
    

    在这里插入图片描述

    最后,很感谢网上一位大哥分享了他的经验。
    大哥链接:https://blog.csdn.net/javaYouCome/article/details/79473743

    展开全文
  • 微信支付 Java 官方Demo

    万次阅读 2018-05-29 14:54:23
    很多人说微信支付没有提供Java版的官方Demo这话说对了一半, 可以拿来直接Run的Java程序的确没提供.但是针对每一个功能都提供了java code的小例子, 只不过这些例子全部放在一个README.md文件里了我们会下载到 ...
    很多人说微信支付没有提供Java版的官方Demo
    这话说对了一半, 可以拿来直接Run的Java程序的确没提供.

    但是针对每一个功能都提供了java code的小例子, 只不过这些例子全部放在一个README.md文件里了

    我们会下载到 WxPayAPI_JAVA_v3.zip 这个包是吧?

    解压缩, 在java-sdk-v3里面


    我直接把这里面的内容贴出来了哦

    ---------------------------------------------分割线------------------------------------------------

    微信支付 Java SDK
    ------
    对[微信支付开发者文档](https://pay.weixin.qq.com/wiki/doc/api/index.html)中给出的API进行了封装。
    com.github.wxpay.sdk.WXPay类下提供了对应的方法:

    |方法名 | 说明 |
    |--------|--------|
    |microPay| 刷卡支付 |
    |unifiedOrder | 统一下单|
    |orderQuery | 查询订单 |
    |reverse | 撤销订单 |
    |closeOrder|关闭订单|
    |refund|申请退款|
    |refundQuery|查询退款|
    |downloadBill|下载对账单|
    |report|交易保障|
    |shortUrl|转换短链接|
    |authCodeToOpenid|授权码查询openid|


    * 参数为`Map<String, String>`对象,返回类型也是`Map<String, String>`。
    * 方法内部会将参数会转换成含有`appid`、`mch_id`、`nonce_str`、`sign\_type`和`sign`的XML;
    * 默认使用MD5进行签名;
    * 通过HTTPS请求得到返回数据后会对其做必要的处理(例如验证签名,签名错误则抛出异常)。
    * 对于downloadBill,无论是否成功都返回Map,且都含有`return_code`和`return_msg`。若成功,其中`return_code`为`SUCCESS`,另外`data`对应对账单数据。

    安装maven:

    <dependency>
        <groupId>com.github.wxpay</groupId>
        <artifactId>wxpay-sdk</artifactId>
        <version>0.0.3</version>
    </dependency>
    -----------------------------------------以下为示例----------------------------------------

    配置类MyConfig

    import com.github.wxpay.sdk.WXPayConfig;
    import java.io.*;
    
    public class MyConfig implements WXPayConfig{
    
        private byte[] certData;
    
        public MyConfig() throws Exception {
            String certPath = "/path/to/apiclient_cert.p12";
            File file = new File(certPath);
            InputStream certStream = new FileInputStream(file);
            this.certData = new byte[(int) file.length()];
            certStream.read(this.certData);
            certStream.close();
        }
    
        public String getAppID() {
            return "wx8888888888888888";
        }
    
        public String getMchID() {
            return "12888888";
        }
    
        public String getKey() {
            return "88888888888888888888888888888888";
        }
    
        public InputStream getCertStream() {
            ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
            return certBis;
        }
    
        public int getHttpConnectTimeoutMs() {
            return 8000;
        }
    
        public int getHttpReadTimeoutMs() {
            return 10000;
        }
    }

    统一下单

    import com.github.wxpay.sdk.WXPay;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class WXPayExample {
    
        public static void main(String[] args) throws Exception {
    
            MyConfig config = new MyConfig();
            WXPay wxpay = new WXPay(config);
    
            Map<String, String> data = new HashMap<String, String>();
            data.put("body", "腾讯充值中心-QQ会员充值");
            data.put("out_trade_no", "2016090910595900000012");
            data.put("device_info", "");
            data.put("fee_type", "CNY");
            data.put("total_fee", "1");
            data.put("spbill_create_ip", "123.12.12.123");
            data.put("notify_url", "http://www.example.com/wxpay/notify");
            data.put("trade_type", "NATIVE");  // 此处指定为扫码支付
            data.put("product_id", "12");
    
            try {
                Map<String, String> resp = wxpay.unifiedOrder(data);
                System.out.println(resp);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }

    订单查询

    import com.github.wxpay.sdk.WXPay;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class WXPayExample {
    
        public static void main(String[] args) throws Exception {
    
            MyConfig config = new MyConfig();
            WXPay wxpay = new WXPay(config);
    
            Map<String, String> data = new HashMap<String, String>();
            data.put("out_trade_no", "2016090910595900000012");
    
            try {
                Map<String, String> resp = wxpay.orderQuery(data);
                System.out.println(resp);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    退款查询
    import com.github.wxpay.sdk.WXPay;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class WXPayExample {
    
        public static void main(String[] args) throws Exception {
    
            MyConfig config = new MyConfig();
            WXPay wxpay = new WXPay(config);
    
            Map<String, String> data = new HashMap<String, String>();
            data.put("out_trade_no", "2016090910595900000012");
    
            try {
                Map<String, String> resp = wxpay.refundQuery(data);
                System.out.println(resp);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }

    下载对账单

    import com.github.wxpay.sdk.WXPay;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class WXPayExample {
    
        public static void main(String[] args) throws Exception {
    
            MyConfig config = new MyConfig();
            WXPay wxpay = new WXPay(config);
    
            Map<String, String> data = new HashMap<String, String>();
            data.put("bill_date", "20140603");
            data.put("bill_type", "ALL");
    
            try {
                Map<String, String> resp = wxpay.downloadBill(data);
                System.out.println(resp);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }

    暂时不支持下载压缩格式的对账单,但可以使用该SDK生成请求用的XML数据

    import com.github.wxpay.sdk.WXPay;
    import com.github.wxpay.sdk.WXPayUtil;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class WXPayExample {
    
        public static void main(String[] args) throws Exception {
    
            MyConfig config = new MyConfig();
            WXPay wxpay = new WXPay(config);
    
            Map<String, String> data = new HashMap<String, String>();
            data.put("bill_date", "20140603");
            data.put("bill_type", "ALL");
            data.put("tar_type", "GZIP");
    
            try {
                data = wxpay.fillRequestData(data);
                System.out.println(WXPayUtil.mapToXml(data));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }

    收到支付结果通知时,需要验证签名,可以这样做

    import com.github.wxpay.sdk.WXPay;
    import com.github.wxpay.sdk.WXPayUtil;
    
    import java.util.Map;
    
    public class WXPayExample {
    
        public static void main(String[] args) throws Exception {
    
            String notifyData = "...."; // 支付结果通知的xml格式数据
    
            MyConfig config = new MyConfig();
            WXPay wxpay = new WXPay(config);
    
            Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyData);  // 转换成map
    
            if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
                // 签名正确
                // 进行处理。
                // 注意特殊情况:订单已经退款,但收到了支付结果成功的通知,不应把商户侧订单状态从退款改成支付成功
            }
            else {
                // 签名错误,如果数据里没有sign字段,也认为是签名错误
            }
        }
    
    }

    HTTPS请求默认使用MD5算法签名,若需要使用HMAC-SHA256

    import com.github.wxpay.sdk.WXPay;
    import com.github.wxpay.sdk.WXPayConstants;
    
    public class WXPayExample {
    
        public static void main(String[] args) throws Exception {
            MyConfig config = new MyConfig();
            WXPay wxpay = new WXPay(config, WXPayConstants.SignType.HMACSHA256);
            // ......
        }
    }
    若需要使用sandbox环境
    import com.github.wxpay.sdk.WXPay;
    import com.github.wxpay.sdk.WXPayConstants;
    
    public class WXPayExample {
    
        public static void main(String[] args) throws Exception {
            MyConfig config = new MyConfig();
            WXPay wxpay = new WXPay(config, WXPayConstants.SignType.MD5, true);
            // ......
        }
    
    }

    所需的jar包只有一个:
    wxpay-sdk-0.0.3.jar
    当然如果你需要看源码和文档的话, 可以再加上下面两个:
    wxpay-sdk-0.0.3-javadoc.jar
    wxpay-sdk-0.0.3-sources.jar
    这3个jar 包都在 java-sdk-v3\target 下面


    展开全文
  • 微信支付-java实现微信支付-后端篇

    万次阅读 2019-12-18 22:42:35
    Java 实现微信支付 — 后端篇 技术栈 Spring boot java XML (微信在http协议中数据传输方案) MD5 签名 微信支付术语 openid (OpenID是公众号一对一对应用户身份的标识) app_id (公众号id,登录微信...
  • 本文主要介绍的是JAVA对接支付宝和微信支付,废话少说上代码(部分业务代码就不上了,例如订单等,根据业务需求自行修改): 用到的工具类: maven依赖: <!-- ...
  • 微信APP支付-Java后台实现

    万次阅读 热门讨论 2020-09-23 17:13:42
    因为自己项目上的APP 原来有支付宝支付,现在想要加上微信支付,所以去研究了微信APP支付的相关技术文档。虽然微信的相关的技术文档已经非常的清楚了。但是我还是想记录一下自己研究过程。 1 注册微信开放者平台...
  • java微信app支付-统一下单

    万次阅读 热门讨论 2016-03-18 18:54:59
    估计大多数人和我一样吧,每次要使用腾讯的开发api,都有一种想上吊的感觉,尤其是微信支付和支付宝对比起来文档确实差距还是有点大的 关于微信支付的申请我就不多说了,网上有很多,我们直接来说一下微信支付 微信...
  • 手把手教你--JAVA微信支付(公众号支付JSAPI)

    万次阅读 多人点赞 2019-08-26 17:54:15
    JAVA开发微信支付-公众号支付/微信浏览器支付(JSAPI) 写这篇文章的目的有2个,一是自己的项目刚开发完微信支付功能,趁热回个炉温习一下,二也是帮助像我这样对微信支付不熟悉,反复看了多天文档还是一知半解,原理都...
  • JAVA微信支付

    2020-03-05 13:18:03
    1,简单说明  现在好多项目上都需要用到微信...这个微信支付的微信公众号或者小程序,都是需要微信认证的,不然无法申请微信支付,这个就不说了 ,既然到了这一步,相信所有的前提都已经准备好了。直接上代码吧~...
  • Java调用微信支付

    万次阅读 多人点赞 2020-06-19 09:11:24
    Java 使用微信支付 一. 准备工作 1.
  • 之前没有做过微信支付,在CSDN找了很多案例都没有看明白, 下载后要么是不完整缺少文件,要么是各种原因跑不起来, 要求是传递一个金额值给用户H5页面,用户微信支付。 微信dll306181140,着急在线等,如果能解决...
  • java 微信支付随机字符串生成方法

    万次阅读 2015-07-28 17:26:53
    public static String getRandomStringByLength(int length) { String base = "abcdefghijklmnopqrstuvwxyz0123456789"; Random random = new Random(); StringBuffer sb = new StringBuffe
  • 最近做微信支付,以前也没做过微信方面的东西,所以都不懂。。 只能求助各位大神了。。 微信文档中说明,在支付成功后会根据notify_url中设置的地址通知商户支付成功的信息, 但是现在不管是将地址设置为xxx.do还是...
  • java 微信支付成功后,回调函数方法怎么设置,和如何获得当前支付订单的信息
  • Java调用微信支付接口完整版

    千次阅读 2019-06-24 16:29:21
    Java调用微信支付接口完整版 https://blog.csdn.net/rexueqingchun/article/details/78205441
  • 微信开放平台分账功能实战(Java版)

    千次阅读 2018-05-17 21:56:56
    近期为了接入微信支付以及微信分账等功能,开发了微信类的一系列接口,下面就本着开发的目标,再次记录回顾一下微信开放的步骤。首先,在说我们的目标之前,先把公司大的背景说明一下。背景:公司主要从事移动互联,...
  • Java实现微信和支付宝扫码支付

    千次阅读 2018-04-18 14:27:40
    微信扫码支付模式二 http://www.demodashi.com/demo/10268.html支付宝扫码支付 https://blog.csdn.net/zhulin2012/article/details/53467504
  • 微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等...
  • java 微信支付 demo

    千次阅读 2019-01-29 19:30:13
    首先我只想说微信能把文档写清楚点吗?超级无敌巨坑 首先进入 微信开发者平台 https://open.weixin.qq.com/cgi-bin/index?t=home/index&amp;lang=zh_CN 点击打开链接,   然后找到 微信APP支付接入商户...
1 2 3 4 5 ... 20
收藏数 28,602
精华内容 11,440
关键字:

java微信支付