`
annan211
  • 浏览: 464387 次
  • 性别: 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;
	}







 

分享到:
评论

相关推荐

    http basic authentication通过post方式访问api示例分享 basic认证示例

    credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(USERNAME, PASSWORD)); httpClient.setCredentialsProvider(credentialsProvider); // 创建POST请求 ...

    SVN各种错误提示产生原因及处理方法大全

    SVN 错误提示产生原因及处理方法大全 SVN(Subversion)是一种版本控制系统,广泛应用于软件开发、文档管理等领域。然而,在使用 SVN 过程中,可能会遇到各种错误提示,影响工作效率。本文将对 SVN 中常见的错误...

    解密第三方登录-微信扫码登录

    第三方登录-微信扫码登录 微信扫码登录是当前最流行的第三方登录方式之一,通过微信扫码,用户可以快速登录到第三方应用,提高用户体验,简化登录过程,降低注册门槛,获取海量用户,有效降低用户流失。微信扫码...

    Invalid Login Credentials(解决方案).md

    Invalid Login Credentials(解决方案).md

    credentials-java-0.2.4.jar

    credentials-java-0.2.4.jar

    垃圾分类微信小程序.zip

    grantType = 'client_credentials', secretKey = '替换成自己的secretKey', url = `https://aip.baidubce.com/oauth/2.0/token`小程序中有用到云开发,具体介绍请参考微信小程序官方文档,初始化云开发后, 替换app....

    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 ...

    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...

    运维OpenStack常见错误排除

    ### 运维OpenStack常见错误排除 #### 一、OpenStack错误排除方法 在运维OpenStack过程中,遇到问题时常见的排除方法主要包括查看日志和使用debug模式两种。 **方法1:查看日志** 查看日志是排查问题的第一步。...

    Python库 | alibabacloud_credentials-0.0.3.tar.gz

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

    前端开源库-express-basic-auth

    - **错误处理**:你可以通过监听`401 Unauthorized`状态码来自定义错误处理。 - **多级授权**:可以结合其他中间件实现更复杂的权限控制。 - **加密密码**:为了安全起见,实际应用中不应明文存储密码,可以使用哈希...

    WebClient访问间歇性返回403解决方案.docx

    "WebClient 访问间歇性返回 403 解决方案" 在本解决方案中,我们将讨论 WebClient 访问间歇性返回 403 的问题及其解决方法。首先,让我们来分析错误信息。WebClient 是一个常用的网络访问类,它可以模拟浏览器的...

    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 ...

    Spring MVC Security-添加自定义登录表单,显示无效凭据、基于角色的访问、自定义访问被拒绝的错误消息.zip

    这个压缩包包含的项目"SpringMVCSecurity-master"很可能是用来演示如何配置和使用Spring Security来实现自定义登录表单、处理无效凭证、基于角色的访问控制以及自定义访问拒绝错误消息的示例代码。 在Spring ...

    Laravel开发-credentials

    "Laravel开发-credentials"指的是Laravel 5版本中引入的一种高效的身份验证机制,它旨在简化和加强用户认证流程。让我们深入探讨一下这个话题。 首先,Laravel的凭据(Credentials)主要涉及到用户登录时输入的...

    垃圾分类微信小程序

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

    解决Silverlight跨域访问问题

    总之,解决Silverlight跨域访问自托管WCF服务的问题,主要涉及配置WCF服务的行为、添加跨域策略文件、以及正确配置Silverlight客户端。理解并实施这些步骤,可以有效地打破同源策略的限制,实现跨域TCP通信。

    跨域访问解决方案,关于跨域访问cookie的资料

    ### 跨域访问解决方案与Cookie处理 在现代Web开发中,跨域问题一直是困扰开发者的一大难题。当浏览器出于安全考虑阻止不同源之间的数据交互时,跨域问题便产生了。为了解决这一问题,并确保在跨域场景下可以正确地...

    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-...

Global site tag (gtag.js) - Google Analytics