`
annan211
  • 浏览: 445577 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

微信app支付 签名错误 以及 访问https 的解决办法 Required credentials not available for BASIC <any

阅读更多

请尊重知识,请尊重原创 更多资料参考请见  http://www.cezuwang.com/listFilm?page=1&areaId=906&filmTypeId=1

 

微信app支付 签名错误 以及 访问https 的解决办法
微信支付的接口不同于支付宝等其他第三方接口足够友好,所以这里有必要对 微信签名错误和访问https接口做一些小结以供参考。


签名错误:
  首先总结原因,可能发生签名错误的原因如下:
1 密钥错误,密钥是32位长的一串字符,类似于 f0fnf5872825aien55end044e092le39 ,如果需要重新设置 ,位置在 设置位置:账户设置-安全设置-API安全
2 本地签名程序
    基本遵照微信官方文档说明即可
https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=4_3
传递哪些参数 需要根据文档说明 https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=9_1

参考(内部的一些关键参数只提供参考,位数不对):
sb  字符串   appid=wx5382e5300d7f6e555f&body=Corsair Neutron Series GTX 480GB 固态硬盘&mch_id=1237315833041&nonce_str=1B72746255EF01F9D75400995C62EA12
&notify_url=http://m.dahongwa.com/pay/notify&out_trade_no
=151023113401857821&spbill_create_ip=10.244.1.171&total_fee=84462&trade_type=APP&key=f0fn3f5872825ai4en55end044e092le39

再对此字符串进行md5加密之后调成大写,即为sign签名

生成的xml文档:

<xml>
		<appid>wx5382e5300d7f6e555f</appid>
		<body><![CDATA[Corsair Neutron Series GTX 480GB 固态硬盘]]></body>
		<mch_id>1237315833041</mch_id>
		<nonce_str>1B72746255EF01F9D75400995C62EA12</nonce_str>
		<notify_url>http://m.dahongwa.com/pay/notify</notify_url>
		<out_trade_no>151023113401857821</out_trade_no>
		<sign><![CDATA[CD0DCCA447A6C0B0482C4D43A545A0BA]]></sign>
		<spbill_create_ip>10.244.1.171</spbill_create_ip>
		<total_fee>84462</total_fee>
		<trade_type>APP</trade_type>
	</xml>


生成的xml是提交给 微信的参数,必须和签名的字符串里的值相同
如果返回的微信参数提示 签名错误,可以到微信官方测试测试地址测试
https://pay.weixin.qq.com/wiki/tools/signverify/
微信返回信息中,如果出现签名错误,可以把自己的资料填写在上面的测试用例中获取微信生成的签名,
如果测试sign与自己生成的不同 返回上步检查,如果微信生成的和自己生成的签名相同,但是微信还是返回签名错误,则一定是商品中文(body)编码。
有几个地方的编码必须注意.
设置 sb  字符串 的时候 body一定为utf-8,sb字符串md5加密的时候 必须为utf-8,
传递给 微信的时候 ,此参数也必须为 utf-8 :entity = new StringEntity(xml,"utf-8");

httpclient 头部和参数 也设置成utf-8:
	httpPost.setEntity(entity);
    httpPost.addHeader("Content-Type", "text/html;charset=UTF-8");  
	httpClient.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "UTF-8");
	httpPost.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "UTF-8"); 


这几个编码优先级逐步提高,也就是说后面的会覆盖前面的。

  请尊重知识,请尊重原创 更多资料参考请见  http://www.cezuwang.com/listFilm?page=1&areaId=906&filmTypeId=1
由于微信的接口是https,在生产环境又只能通过代理访问,所以通常的http接口访问会返回错误信息:

WARN,http-apr-9002-exec-4,10-22 20:21:30.393,httpclient.HttpMethodDirector.authenticateHost:288 - Required credentials not available for BASIC <any realm>@api.mch.weixin.qq.com:443
WARN,http-apr-9002-exec-4,10-22 20:21:30.393,httpclient.HttpMethodDirector.authenticateHost:290 - Preemptive authentication requested but no default credentials available
INFO,http-apr-9002-exec-4,10-22 20:21:30.583,httpclient.HttpMethodDirector.executeWithRetry:439 - I/O exception (java.net.ConnectException) caught when processing request: Connection refused
INFO,http-apr-9002-exec-4,10-22 20:21:30.583,httpclient.HttpMethodDirector.executeWithRetry:445 - Retrying request
INFO,http-apr-9002-exec-4,10-22 20:21:30.591,httpclient.HttpMethodDirector.executeWithRetry:439 - I/O exception (java.net.ConnectException) caught when processing request: Connection refused
INFO,http-apr-9002-exec-4,10-22 20:21:30.592,httpclient.HttpMethodDirector.executeWithRetry:445 - Retrying request
INFO,http-apr-9002-exec-4,10-22 20:21:30.594,httpclient.HttpMethodDirector.executeWithRetry:439 - I/O exception (java.net.ConnectException) caught when processing request: Connection refused
INFO,http-apr-9002-exec-4,10-22 20:21:30.595,httpclient.HttpMethodDirector.executeWithRetry:445 - Retrying request
java.net.ConnectException: Connection refused
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:579)
	at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:618)
	at com.legendshop.model.app.wxpay.MySSLProtocolSocketFactory.createSocket(MySSLProtocolSocketFactory.java:92)
	at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)


这是因为代理访问被微信拒绝,所以需要重新设置访问程序:

StringEntity entity;
		HttpResponse httpResponse;
		int proxyPortCon = 0;
		DefaultHttpClient httpClient = new DefaultHttpClient(); //创建默认的httpClient实例
		try {	
			entity = new StringEntity(xml,"utf-8");
			
			if("true".equalsIgnoreCase(useProxy) ){
				
			    X509TrustManager xtm = new X509TrustManager(){  //创建TrustManager
			    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
			    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
			    public X509Certificate[] getAcceptedIssuers() { return null; }
			    };
			    
			    X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier() {
		            public boolean verify(String arg0, SSLSession arg1) {
		                return true;
		            }
		            public void verify(String arg0, SSLSocket arg1) throws IOException {}
		            public void verify(String arg0, String[] arg1, String[] arg2) throws SSLException {}
		            public void verify(String arg0, X509Certificate arg1) throws SSLException {}
		        };
			    
			    //TLS1.0与SSL3.0基本上没有太大的差别,可粗略理解为TLS是SSL的继承者,但它们使用的是相同的SSLContext
	            SSLContext ctx = SSLContext.getInstance("TLS");
	            //使用TrustManager来初始化该上下文,TrustManager只是被SSL的Socket所使用
	            ctx.init(null, new TrustManager[] { xtm }, null);
	            //创建SSLSocketFactory
	            SSLSocketFactory socketFactory = new SSLSocketFactory(ctx);
	            socketFactory.setHostnameVerifier(hostnameVerifier);
	            //通过SchemeRegistry将SSLSocketFactory注册到我们的HttpClient上
	            httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", socketFactory, 443));
	            
			    proxyPortCon = Integer.parseInt(proxyPort);
			    
			    HttpHost proxy = new HttpHost(proxyHost, proxyPortCon);
			    httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
			    
			}
			    HttpPost httpPost = new HttpPost(unifiedorder);  //创建HttpPost
			    httpPost.setEntity(entity);
			    httpPost.addHeader("Content-Type", "text/html;charset=UTF-8");  
			    httpClient.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "UTF-8"); 
			    //httpPost.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "UTF-8");  
			    httpResponse = httpClient.execute(httpPost); //执行POST请求
			    if (AppUtils.isNotBlank(httpResponse)) {
				HttpEntity httpEntity = httpResponse.getEntity();
				String result = EntityUtils.toString(httpEntity, "UTF-8");
				
				}

  


下面贴一些代码 供参考:


app前段调用微信统一下单接口

/**
	 * 微信支付统一下单接口
	 * @param orderInfoJson 请求参数json 
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	@RequestMapping(value = "/pay/unifiedorder", method =RequestMethod.POST)
	@ResponseBody
	public  Result getOrderInfo(HttpServletRequest request, HttpServletResponse response,@RequestParam("code") String code, @RequestParam("orderInfoJson") String orderInfoJson) throws UnsupportedEncodingException {
		Result result = null;
		//日志记录
		AppServiceLog.info("orderInfoJson is {}", orderInfoJson);
		AppServiceLog.visit(AppInterfaceEnum.WECHAT_PAY, "/pay/unifiedorder", getUserName(request));
		
		Map<?, ?> paramMap=JsonToMap.getBody(orderInfoJson);
		final Gson gson =new Gson();
		
		WXPrepayVO orderInfo = gson.fromJson(gson.toJson(paramMap),WXPrepayVO.class);
		
		WXPrepay prePay = new WXPrepay();
		
		//获取订单信息
		result = orderService.payUnifiedorder(request,orderInfo,prePay);
		
		return result;
		
	}



服务器构造对象 向微信服务器发起https访问,以获取预支付id

public Result payUnifiedorder(HttpServletRequest request,WXPrepayVO orderInfo,WXPrepay prePay) throws UnsupportedEncodingException {
		
		Result result = new Result();
		Double totalAmount = new Double(0);
		
		OrderTemp orderTemp = orderTempDao.getOrderByOrderNum(orderInfo.getOut_trade_no());
		Order order = null;
		
		if(AppUtils.isBlank(orderTemp)){
			order = orderDao.getOrderByOrderNumLimitOne(orderInfo.getOut_trade_no());
			if(AppUtils.isNotBlank(order)){
				totalAmount = order.getTotalAmount();
			}
		}else{
			totalAmount = orderTemp.getTotalAmount();
		}
		
		if(AppUtils.isBlank(orderTemp) && AppUtils.isBlank(order)){
			result.setCode(ReturnCode.orderIsNotExist.value());
			result.setMessage(ReturnCode.orderIsNotExist.desc());
			return result;
		}
		
		//商品描述
		String bodyStr = Base64Decoder.Decoder(orderInfo.getBody());
		
		String spbill_create_ip = request.getRemoteAddr();
		
		prePay.setAppid(appId);
		prePay.setBody(bodyStr);
		prePay.setPartnerKey(appKey);
		prePay.setMch_id(mchId);
		prePay.setNotify_url(notifyUrl);
		prePay.setOut_trade_no(orderInfo.getOut_trade_no());
		prePay.setSpbill_create_ip(spbill_create_ip);
		
		DecimalFormat df = new DecimalFormat("#");
		prePay.setTotal_fee(df.format(totalAmount * 10 * 10));
		//prePay.setTotal_fee("1");
		prePay.setTrade_type(PayTypeEnum.WX_APP_PAY.value());
		
		//代理
		String useProxyConfig = PropertiesUtil.getUseProxy();
		String proxyHostConfig = PropertiesUtil.getProxyHost();
		String proxyPortConfig = PropertiesUtil.getProxyPort();
		
        //此处添加获取openid的方法,获取预支付订单需要此参数!!!!!!!!!!! 
		// 获取预支付订单号
		WePayResponse wePayResponse = prePay.submitXmlGetPrepayId(useProxyConfig,proxyHostConfig,proxyPortConfig);
		wePayResponse.setPartnerId(mchId);
		wePayResponse.setPackageS("Sign=WXPay");
		wePayResponse.setNonceStr(OrderUtil.CreateNoncestr());
		wePayResponse.setTimeStamp(new Date().getTime());
		
		if(wePayResponse.getResultCode().equals("SUCCESS")){
			result.setCode(ReturnCode.OK.value());
			result.setMessage(wePayResponse.getReturnMsg());
			result.setSuccess(true);
		}else{
			result.setMessage(wePayResponse.getErrCodeDes());
		}
		
		result.setObject(wePayResponse);
		return result;
	}



/**
	 * 生成预支付订单
	 * 
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	@SuppressWarnings("deprecation")
	public WePayResponse submitXmlGetPrepayId(String useProxy,String proxyHost,String proxyPort) throws UnsupportedEncodingException {
		
		System.out.println(useProxy +"--"+ proxyHost +"---"+ proxyPort);
		String xml = getPackage();
		WePayResponse response = null;
		StringEntity entity;
		HttpResponse httpResponse;
		int proxyPortCon = 0;
		DefaultHttpClient httpClient = new DefaultHttpClient(); //创建默认的httpClient实例
		try {	
			entity = new StringEntity(xml,"utf-8");
			
			if("true".equalsIgnoreCase(useProxy) ){
			
/**
下面这段代码 用来处理访问https的请求
**/	
			    X509TrustManager xtm = new X509TrustManager(){  //创建TrustManager
			    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
			    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
			    public X509Certificate[] getAcceptedIssuers() { return null; }
			    };
			    
			    X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier() {
		            public boolean verify(String arg0, SSLSession arg1) {
		                return true;
		            }
		            public void verify(String arg0, SSLSocket arg1) throws IOException {}
		            public void verify(String arg0, String[] arg1, String[] arg2) throws SSLException {}
		            public void verify(String arg0, X509Certificate arg1) throws SSLException {}
		        };
			    
			    //TLS1.0与SSL3.0基本上没有太大的差别,可粗略理解为TLS是SSL的继承者,但它们使用的是相同的SSLContext
	            SSLContext ctx = SSLContext.getInstance("TLS");
	            //使用TrustManager来初始化该上下文,TrustManager只是被SSL的Socket所使用
	            ctx.init(null, new TrustManager[] { xtm }, null);
	            //创建SSLSocketFactory
	            SSLSocketFactory socketFactory = new SSLSocketFactory(ctx);
	            socketFactory.setHostnameVerifier(hostnameVerifier);
	            //通过SchemeRegistry将SSLSocketFactory注册到我们的HttpClient上
	            httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", socketFactory, 443));
	            
/****
下面这段代码 使用代理访问https外部接口

****/
			    proxyPortCon = Integer.parseInt(proxyPort);
			    
			    HttpHost proxy = new HttpHost(proxyHost, proxyPortCon);
			    httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
			    
			}
			    HttpPost httpPost = new HttpPost(unifiedorder);  //创建HttpPost
			    httpPost.setEntity(entity);
			    httpPost.addHeader("Content-Type", "text/html;charset=UTF-8");  
			    httpClient.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "UTF-8"); 
			    //httpPost.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "UTF-8");  
			    httpResponse = httpClient.execute(httpPost); //执行POST请求
			    
						if (AppUtils.isNotBlank(httpResponse)) {
				HttpEntity httpEntity = httpResponse.getEntity();
				String result = EntityUtils.toString(httpEntity, "UTF-8");
				// 过滤
				result = result.replaceAll("<![CDATA[|]]>", "");
				String prepay_id = Jsoup.parse(result).select("prepay_id").html();
				String trade_type = Jsoup.parse(result).select("trade_type").html();
				String returnCode =  Jsoup.parse(result).select("return_code").html();
				String returnMsg =  Jsoup.parse(result).select("return_msg").html();
				
				String resultCode = Jsoup.parse(result).select("result_code").html();
				String errCode =  Jsoup.parse(result).select("err_code").html();
				String errCodeDes =  Jsoup.parse(result).select("err_code_des").html();
				
				response = WePayResponse.newInstance();
				response.setPrepayId(prepay_id);
				response.setTradeType(trade_type);
				response.setReturnCode(returnCode);
				response.setReturnMsg(returnMsg);
				
				response.setResultCode(resultCode);
				response.setErrCode(errCode);
				response.setErrCodeDes(errCodeDes);
				
				if (response != null)
					return response;
			}
			// 释放资源
		} catch (Exception e) {
			e.printStackTrace();
		}
		return response;
	}







 

分享到:
评论

相关推荐

    jenkins credentials-plugin1.11.hpi

    Credentials Plugin version:1.11 download from github,and have build it by: Run mvn clean package to create the plugin .hpi file. To install: 1. copy the resulting ./target/credentials.hpi file ...

    credentials-java-0.2.4.jar

    credentials-java-0.2.4.jar

    VB编程资源大全(英文源码 网络)

    &lt;END&gt;&lt;br&gt;47 , email1mapi.zip&lt;br&gt;Visual Basic code for Sending email using MAPI control.&lt;END&gt;&lt;br&gt;48 , Dan.zip&lt;br&gt;Dan's All purpose masterful program &lt;END&gt;&lt;br&gt;49 , metasite.zip&lt;br&gt;this vb code executes...

    Microsoft Remote Desktop for Mac

    Support for the "Prompt for Credentials on Client" RDP file setting when NLA is not negotiated. Support for smart card-based login via smart card redirection at the Winlogon prompt when NLA is not ...

    运维OpenStack常见错误排除

    运维OpenStack常见错误排除

    Laravel开发-credentials

    Laravel开发-credentials 在Laravel5中,凭据是一种很酷的身份验证方法。

    Python库 | alibabacloud_credentials-0.0.3.tar.gz

    python库。 资源全名:alibabacloud_credentials-0.0.3.tar.gz

    git 2.7.3 for windows 64bit

    Git for Windows 2.7.3 发布了。 新特性: Git for Windows now ships with the Git Credential Manager for Windows. ...We no longer show asterisks when reading the username for credentials.

    Python库 | aws_role_credentials-0.2.0-py2.py3-none-any.whl

    资源分类:Python库 所属语言:Python 资源全名:aws_role_credentials-0.2.0-py2.py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    Nginx跨域设置Access-Control-Allow-Origin无效的解决办法

    add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET,POST'; 使用以下配置,生效。 if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-...

    jenkins ssh-credentials-plugin 1.6.1 phi

    copy the resulting ./target/credentials.hpi file to the $JENKINS_HOME/plugins directory. Don't forget to restart Jenkins afterwards. 2. or use the plugin management console ...

    Microsoft Remote Desktop for Mac Version 10.2.2 (1268)

    Support for the "Prompt for Credentials on Client" RDP file setting when NLA is not negotiated. Support for smart card-based login via smart card redirection at the Winlogon prompt when NLA is not ...

    Windows Credentials Viewer(浏览器检测工具) v1.2免费版.zip

    Windows Credentials Viewer是一款用来查找浏览器存储凭据的小工具,帮助您检索在Firefox,Chrome或Internet Explorer中随时间存储的凭据。 用户友好和干净的界面,该应用程序不需要安装或配置,直接打开就可以使用...

    ICS delphixe10源码版

    not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any ...

    google api php client

    This means that we will address critical bugs and security issues but will not add any new features. ## Google Cloud Platform For Google Cloud Platform APIs such as Datastore, Cloud Storage or Pub/...

    git 2.7.3 for windows 32bit

    Git for Windows 2.7.3 发布了。 新特性: Git for Windows now ships with the Git Credential Manager for Windows. ...We no longer show asterisks when reading the username for credentials.

    垃圾分类微信小程序

    垃圾分类小程序 小程序实现介绍: 小程序中有用到百度ai的...小程序中有用到云开发,具体介绍请参考微信小程序官方文档,初始化云开发后, 替换app.js中env的值。 wx.cloud.init({ env: '替换成自己的云开发环境id',

    Passwords in the Air: Harvesting Wi-Fi Credentials from SmartCfg Provisioning

    上交做的关于smartconfig wifi凭证泄露的攻击。里面介绍了一些厂商的smartconfig配置方案的细节。

Global site tag (gtag.js) - Google Analytics